Introduction: THINGSPEAK TEMPERATURE AND HUMIDITY APP USING ESP8266

About: For Remote Supervision

While tinkering with my electronic stuff, I got this idea to make web-based weather app. This web app uses the SHT31 sensor for getting the real-time temperature and humidity data. We have deployed our project on ESP8266 WiFi module. Online or offline! No need to worry, whether you are online or offline you will get the weather updates from anywhere and anytime. This web app posts data to the local web server as well as to cloud. For cloud operations, we are using ThingSpeak API. SHT31 uses I2C to get the data from the sensor.

SHT 31 is a Temperature and Humidity Sensors made by Sensirion. The SHT31 provides a high level of accuracy around ±2% RH. Its Humidity range is between 0 to 100% and Temperature range is between -40 to 125 °C. It is much more reliable and fast with 8 sec of Sensor response time. Its functionality includes enhanced signal processing and I2C compatibility. It has different modes of operations which makes it energy efficient.

In this tutorial, we have interfaced SHT 31 with Adafruit Huzzah board. For reading Temperature and Humidity values we have used ESP8266 I2C shield. This adapter makes all pins accessible to the user and offers user-friendly I2C environment.

Step 1: Hardware Required

Step 2: Hardware Connections

This step include the hardware hookup guide. This section basically explains the wiring connections required between the sensor and the ESP8266. The connections are as follows.

  1. The SHT31 works over I2C. The above image demonstrates the connection between ESP8266 and SHT31 module. We are using I2C cable for it either we can use 4 F to F jumper wires.
  2. one wire is used for Vcc, the second wire for GND and other two to SDA and SCL respectively

  3. According to the I2C adapter pin2 and pin 14 of an ESP8266 board are used as SDA and SCL respectively

Step 3: Code for Task Scheduling

In this tutorial, we are performing three operations

  • Read the data from SHT11 using I2C protocol
  • host the web server and post the sensor reading to the webpage
  • post the sensor readings to ThingSpeak API

To achieve this we are using TaskScheduler library. We have scheduled three different tasks referring to three different control operations. this is done as follows

  • Task 1 is for reading the sensor value this task runs for 1 second till it reaches timeout of 10 secs.
  • When the Task1 reaches its time out Task 2 is enabled and Task1 is disabled.
  • We connect to AP in this callback, Two boolean variables are taken to take care of the switching between STA and AP

  • In Task 2 we are hosting a web server at 192.168.1.4 . This task runs for every 5 sec till it reaches its timeout which is 50 sec

  • When Task 2 reaches timeout Task 3 is enabled and Task2 is disabled.

  • We connect to STA(local IP) in this calbackIn Task 3 we are posting the sensor reading to cloud ThingSpeak API

  • Task 3 runs for every five seconds till it reached its timeout i.e 50 sec

  • When the Task3 reaches its time out Task 1 is enabled again and Task3 is disabled.

  • When no callback is called or the device is idle it goes to Light Sleep thus saving power.

void taskI2CCallback();
void taskI2CDisable();
void taskAPCallback();
void taskAPDisable();
void taskWiFiCallback();
void taskWiFiDisable();

//Tasks for i2c, hosting web server and post on thingspeak

Task tI2C(1 * TASK_SECOND, TASK_FOREVER, &taskI2CCallback, &ts, false, NULL, &taskI2CDisable);
Task tI2C(1 * TASK_SECOND, TASK_FOREVER, &taskI2CCallback, &ts, false, NULL, &taskI2CDisable);
Task tAP(5*TASK_SECOND, TASK_FOREVER, &taskAPCallback,&ts,false,NULL,&taskAPDisable);
Task tWiFi(5* TASK_SECOND, TASK_FOREVER, &taskWiFiCallback, &ts, false, NULL, &taskWiFiDisable);
//timeout for tasks 
tI2C.setTimeout(10 * TASK_SECOND); 
tAP.setTimeout(50 * TASK_SECOND); 
tWiFi.setTimeout(50 * TASK_SECOND); 
//enable I2C 
task tI2C.enable();

Step 4: Code for Reading Temperature and Humidity Values

We are using Wire.h library to read the temperature and humidity values. This library facilitates i2c communication between the sensor and the master device. 0x44 is the I2C address for SHT31.

SHT31 operates in a different mode of operations. You can refer to datasheet for that. We are using 0x2C and 0x06 as MSB and LSB respectively for single shot operation.

<p>//I2C task callback void taskI2CCallback(){<br>  Serial.println("taskI2CStarted");  
  unsigned int root[6];   
  //begin transmission from 0x44;    
   Wire.beginTransmission(Addr);    
   //for one shot transmisstion with high repeatability we use 0x2C(MSB) and 0x06(LSB)    
   Wire.write(0x2C);   
    Wire.write(0x06);   
    //end transmission    
   Wire.endTransmission();    
   //request bytes from 0x44         
   Wire.beginTransmission(Addr);    
   Wire.endTransmission();    
   Wire.requestFrom(Addr,6);
    if(Wire.available() == 6){
        //data[0] and data[1] contains 16 bit of temperature.  
    root[0] = Wire.read();        
    root[1] =Wire.read();       
    //data[2] contains 8 bit of CRC        
    root[2] = Wire.read();        
   //data[3] and data[4] contains 16 bit of humidity       
   root[3] = Wire.read();        
   root[4] = Wire.read();        
   //data[5] consists of 8 bit CRC        
  root[5] = Wire.read();      }       
  int temp = (root[0] * 256) + root[1];   
  //shift MSB by 8 bits add LSB  
  float cTemp = -45.0 + (175.0 * temp / 65535.0);  
  float fTemp = (cTemp * 1.8) + 32.0;    
  //shift the MSB by 8 bits add LSB to it devide by full resolution and *100 for percentage     
  float humidity = (100.0 * ((root[3] * 256.0) + root[4])) / 65535.0;
  tempC = cTemp;  
  tempF = fTemp; 
  humid = humidity;      
  Serial.print("Temperature in C:\t");   
  Serial.println(String(cTemp,1));   
 Serial.print("Temperature in F:\t");   
 Serial.println(String(fTemp,1));   
Serial.print("Humidity:\t ");   
Serial.println(String(humidity,1)); }</p>

Step 5: Code for Hosting a Webserver

We have hosted a web server from our device on a static IP.

  • ESP8266WebServer library is used to host the web server
  • First we need to declare IP address, Gateway and subnet mask to create our static IP

  • Now declare ssid and password for your Access point.connect to the Access point from any STA device

  • host the server on port 80 which is a default port for internet communication protocol, Hypertext Transfer Protocol (HTTP)enter 192.168.1.4 on your web browser for intro webpage and 192.168.1.4/Value for sensor reading webpage

<p>//static Ip for AP<br>IPAddress ap_local_IP(192,168,1,4);<br>IPAddress ap_gateway(192,168,1,254);
IPAddress ap_subnet(255,255,255,0);
//ssid and AP for local WiFi in STA mode
const char WiFissid[] = "*********";
const char WiFipass[] = "*********";
//ssid and pass for AP
const char APssid[] = "********";
const char APpass[] = "********";
ESP8266WebServer server(80);
void setup{server.on("/", onHandleDataRoot); 
server.on("/Value",onHandleDataFeed); 
server.onNotFound(onHandleNotFound);}
void taskAPCallback(){    
Serial.println("taskAP started");    
server.handleClient();  }
void onHandleDataRoot(){       
server.send(200, "text/html", PAGE1);    
}
void onHandleDataFeed(){      
server.send(200,"text/html", PAGE2);    
}
void onHandleNotFound(){      
String message = "File Not Found\n\n";      
message += "URI: ";       
message += server.uri();      
message += "\nMethod: ";       
message += (server.method() == HTTP_GET)?"GET":"POST";       
message += "\nArguments: ";       
message += server.args();       
message += "\n";       
server.send(404, "text/plain", message);
} 
void reconnectAPWiFi(){     
WiFi.mode(WIFI_AP_STA);     
delay(100);     
WiFi.disconnect();     
boolean status = WiFi.softAPConfig(ap_local_IP, ap_gateway, ap_subnet);     
if(status ==true){         
Serial.print("Setting soft-AP ... ");         
boolean ap = WiFi.softAP(APssid, APpass);          
if(ap==true){              
Serial.print("connected to:\t");              
//IPAddress myIP = WiFi.softAPIP();               
Serial.println(WiFi.softAPIP());              
}            
server.begin();       
</p>}

Step 6: Thingspeak Setup

ThingSpeak is an IoT platform. ThingSpeak is a free web service that lets you collect and store sensor data in the cloud.

In this Step, I will be giving you a brief procedure to set up your Thing Speak account

  • Sign up for new User Account in ThingSpeak
  • Create a new Channel by selecting Channels, My Channels, and then New Channel
  • Edit your fields
  • These fields contain your sensor data
  • Note the Write API Key and Channel ID
  • On your Arduino sketch, you can use ThingSpeak library for Arduino or you can directly POST the data to ThingSpeak API
  • the next step elaborates about posting the content to Thing Speak API

Step 7: Code for Posting Data to Thing Speak

Here we are posting the sensor readings to Thing Speak. the following steps are needed to complete this task-

  • Create your account in thing speakCreate channels and fields to store your sensor data

  • we can get and post the data from ESP to thingSpeak and vice-versa using GET and POST requests to the api.
  • we can post our data to ThingSpeak as follows

<p>id taskWiFiCallback(){   <br>
 WiFiClient wifiClient;        

if(wifiClient.connect(hostId,80)){            

String postStr = apiKey;            

postStr +="&field1=";            

postStr += String(humid);            

postStr +="&field2=";            

postStr += String(tempC);            

postStr +="&field3=";            

postStr += String(tempF);            

postStr += "\r\n\r\n";

wifiClient.print("POST /update HTTP/1.1\n");

wifiClient.print("Host: api.thingspeak.com\n");                             

wifiClient.print("Connection: close\n");                             

wifiClient.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");                             

wifiClient.print("Content-Type: application/x-www-form-urlencoded\n");                             

wifiClient.print("Content-Length: ");                             

wifiClient.print(postStr.length());                             

wifiClient.print("\n\n");                             

wifiClient.print(postStr); }          

wifiClient.stop();     

}

Step 8: Overall Code

The overall code is available in my GitHub repository

Step 9: Credits