While tinkering with my electronic stuff, I got this idea to make web-based weather app. This web app uses 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 local websever as well as to cloud. For cloud operations we are using ThingSpeak API. SHT31 uses I2C to get the data from the sensor.
Features- Provides you real time analytics and stats using ThingSpeak API.
- The sensor data can also be seen in web server hosted by the device.
- TaskScheduler is used to schedule the task like fetching data from sensors, hosting a web server, posting the readings to cloud.
- It uses I2C protocol to fetch the sensor reading which are more accurate, expandable and scalable.
- Sleep mode when device is idle or no task callback is called.
- Effective task scheduling provides hastle free usage.
This is the basic hardware hookup guide. This section explains the wiring connections required between the sensor and the ESP8266. The connections are as follows:
- 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.
- One wire is used for VCC, the second wire for GND, and the other two to SDA and SCL respectively.
- According to the I2C adapter pin2 and pin 14 of an ESP8266 board are used as SDA and SCL, respectively
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; 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>
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 calback.
- 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 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.
This is how we are doing it
//prototype for task callback
void taskI2CCallback();
void taskI2CDisable();
void taskAPCallback();
void taskAPDisable();
void taskWiFiCallback();
void taskWiFiDisable();
//Tasks for i2c, hosting web server and post on thingspeakTask
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();
Hosting a Web ServerWe 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
//static Ip for AP
IPAddress ap_local_IP(192,168,1,4);
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();
}
Setting Up ThingSpeakThingSpeak 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
Here we are posting the sensor readings to ThingSpeak. The following steps are needed to complete this task.
- Create your account in ThingSpeak
- 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();
}
Credits
Comments