Introduction: Weather Web App Using Esp8266

About: Hello People, Vibhu Here. An Embedded engineer by profession, Artist by choice and paraglider by chance

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

Hardware used to complete this task:

1. SHT31

2. Adafruit Huzzah ESP8266

3. ESP8266 I2C adapter

4. I2C Cable

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 timeout 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 callback
  • In 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 timeout 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.

Scheduler ts;

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

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.

//I2C task callback void taskI2CCallback()

{ 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;</p><p>  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)); }

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

Step 6: 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 speak
  • Create 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
void taskWiFiCallback(){   

 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 7: Overall Code