Friday, November 27, 2015

DHT22 versus BMP180. The winner is ....

For my chronothermostat  project I have evaluated the 5.11USD DHT22 and 2.20 USD BMP180.

I've let them work in parallel for few days and the winner is ..... BMP180.

This is a graph for BMP180.


This is a graph for DHT22.

As you can see the DHT22 had few unwanted spikes which leads to false triggers.

DHT22 has the advantage of using one pin,  BMP180 is i2c so is using 2 pins, but the temperature has no spikes. 

Both sensors:

  •  are reading the same temperature
  •  both are showing a lower value as my current chronothermostat which is responding more quickly on changing the temperature.

If you know other sensors that are more precise and are more temperature responsive, please let me know.

Tuesday, November 24, 2015

Temperature and humidity sender

For my ESP8266 chronothermostat I need a sensor to transmit temperature every two minutes ( humidity is a bonus) and to be battery operated.

Between the transmissions the ESP is in deep sleep. As a sensor I've used the DTH22 for one sensor and BMP180 for the other one.

For rapid development I've installed the Arduino IDE (1.6.5) and update it for ESP8266.

As additional libraries I've used: PubSubClient for MQTT and ArduinoJSON for JSON formatting.

Code is sending two JSON strings one for device capabilities, and one with the data.

#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <PubSubClient.h>
#include <DHT.h>

#define DHTTYPE DHT22
#define DHTPIN  5
#define wifi_ssid "................"
#define wifi_password ".................."
#define mqtt_server "................"
#define mqtt_user "............."
#define mqtt_password "..........."
#define mqtt_port "1880"
#define dth_topic "/62/dth"
#define device_status_topic "/62/device/status"
#define DEBUG false
#define Serial if(DEBUG)Serial

WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(DHTPIN, DHTTYPE, 11); // 11 works fine for ESP8266

float humidity, temp_f;  // Values read from sensor
// Time to sleep (in seconds):
const int sleepTimeS = 120; //120 seconds

* FunctionName: gettemperature                                          
* Description : Read temperature and humidity from sensor
*               Values are stored in humidity and temp_f   
* Parameters  : None                             
* Returns     : None                                                     

void gettemperature() 
  int runs=0;
  do {
       temp_f = dht.readTemperature(false);     
       humidity = dht.readHumidity();          

       if(runs > 0)
           Serial.println("##Failed to read from DHT sensor! ###");
       Serial.println(String(temp_f ).c_str());
       Serial.println(String(humidity ).c_str());
    while(isnan(temp_f) && isnan(humidity));

* FunctionName: setup_wifi                                          
* Description : Setup wifi network   
* Parameters  : None                             
* Returns     : None                                                     

void setup_wifi() {
  // We start by connecting to a WiFi network
  Serial.print("Connecting to ");

  WiFi.begin(wifi_ssid, wifi_password);

  while (WiFi.status() != WL_CONNECTED) {

  Serial.println("WiFi connected");
  Serial.println("IP address: ");

* FunctionName: reconnect                                          
* Description : Reconnect to the wifi network in case the connection
*               is lost  
* Parameters  : None                             
* Returns     : None                                                     
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) 
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    // If you do not want to use a username and password, change next line to
    // if (client.connect("ESP8266Client")) {
    if (client.connect("ESP8266ClientT", mqtt_user, mqtt_password)) {
    } else {
      Serial.print("failed, rc=");
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying

* FunctionName: setup                                          
* Description : SETUP function  
* Parameters  : None                             
* Returns     : None                                                     

void setup() 
  char dev_name[50];  
  Serial.println( "Booting" );
  Serial.printf( "Sketch size: %u\n", ESP.getSketchSize() );
  Serial.printf( "Free size: %u\n", ESP.getFreeSketchSpace() );
  Serial.printf( "Heap: %u\n", ESP.getFreeHeap() );
  Serial.printf( "Boot Vers: %u\n", ESP.getBootVersion() );
  Serial.printf( "CPU: %uMHz\n", ESP.getCpuFreqMHz() );
  Serial.printf( "SDK: %s\n", ESP.getSdkVersion() );
  Serial.printf( "Chip ID: %u\n", ESP.getChipId() );
  Serial.printf( "Flash ID: %u\n", ESP.getFlashChipId() );
  Serial.printf( "Flash Size: %u\n", ESP.getFlashChipRealSize() );
  Serial.printf( "Vcc: %u\n", ESP.getVcc() );
  char json_buffer[512];
  char json_buffer_status[512];
  char my_ip_s[16];

  //this one is static allocation
  StaticJsonBuffer<512> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject(); 

  //This one is dynamic one (just for fun). Avoid this in embeded system
  //Can be changed to Static one like: StaticJsonBuffer<512> jsonDeviceStatus;
  DynamicJsonBuffer jsonDeviceStatus;
  JsonObject& jsondeviceStatus = jsonDeviceStatus.createObject();
  sprintf(dev_name, "ESP_%d", ESP.getChipId());

  client.setServer(mqtt_server, 1880);
  client.connect(dev_name, mqtt_user, mqtt_password);
  if (!client.connected()) 

  IPAddress my_ip_addr = WiFi.localIP();
  sprintf(my_ip_s, "%d.%d.%d.%d",   my_ip_addr[0],my_ip_addr[1],my_ip_addr[2],my_ip_addr[3]);
  jsondeviceStatus ["device_name"] = dev_name;
  jsondeviceStatus["type"] = "dth"; 
  jsondeviceStatus["ipaddress"] = String(my_ip_s).c_str();
  jsondeviceStatus["bgn"] = 3;
  jsondeviceStatus["sdk"] = ESP.getSdkVersion();
  jsondeviceStatus["version"] = "1";
  jsondeviceStatus["uptime"] = 0;
  jsondeviceStatus.printTo(json_buffer_status, sizeof(json_buffer_status));  
  client.publish(device_status_topic, json_buffer_status , false);

  String hum;
  hum = String(humidity ).c_str();  
  root["device_name"] = dev_name;
  root["type"] = "dth";  
  root["temperature"] = String(temp_f).c_str();
  root["humidity"]    = hum; 
  root.printTo(json_buffer, sizeof(json_buffer));  
  client.publish(dth_topic, json_buffer , false);

  Serial.println("Go to sleep!!!!");
  // deepSleep time is defined in microseconds. Multiply
  // seconds by 1e6 
  ESP.deepSleep(sleepTimeS * 1000000); //

* FunctionName: loop                                          
* Description : LOOP function  
* Parameters  : None                             
* Returns     : None                                                     
void loop() {}

Sunday, November 8, 2015

Yellow board

Be aware that on this board the labels for GPIO 4 and GPIO 5 are exchanged.

To write the firmware you will need to put the yellow jumper.

Otherwise it is a good board.

And a better picture :

Friday, November 6, 2015

New kid in town - meet ESP32 an "ESP on steroids"

Today 05 November 2015 Espressif announced an "ESP on steroids"  ESP32. See below the communicate.

If ESP8266 was a big hit, I am expecting the same for the ESP32 which has more from everything (processing power, memory, IO etc) and is running RTOS.

See you on

Thursday, November 5, 2015

Irrigation controller with ESP8266

After almost a year of functionality I am very pleased with my irrigation controller.

It has 4 zones ( I only have 4 electrovalves that are covering all my yard).


-JSON over MQTT communication
-Fully controllable from my Android application
-Fully autonomous because has CRON functionality for each valve
-Accessible from all over the world from Android
-Publish the outside temperature and humidity

The mobile application. At start it send a message and all devices are reporting their status, type, capabilities etc.

Irritool devices that are detected by the mobile application ( I have more but they are under software upgrade)

Backyard irrigation ( in full production mode). As you can see a manual start implies to enter a time of watering ( in case the user fotgets to stop it) and after that time the valve it stops by itself. This is not the case if you command a plug.

Valve 0 is watering for 15 minutes.

My automated watering program for my controller. As you can see you can specify the start hour and minute, day of the week, day of the month, month and the duration for each valve. More programs can be defined for the same valve if is necessary.

All the information is stored in the esp8266 and is controlled from mobile application. Nothing related to programing is stored in my phone. In this case any family member has the same information that is stored in Esp.

Off course that the Linux * can be used so you can combine every week with every month etc.

You can skip one, two, three or how many times you want a watering program. The Esp will know that and will skip that program.

Any program can be suspended for unlimited time with one touch.

Every record can be edited or deleted.

Cron entry editing 

Aditional information about this module.