#16 Node-Gateway IoT Architecture: Temperature graph on Cloud using using NodeMCU & Raspberry Pi


IoT Tutorial #16 [ Raspberry Pi Tutorials #4 & NodeMCU Tutorials #4 ]
In Previous post, we have seen how we can initialise CGI server on Raspberry Pi 3 and use it as Gateway for  Node-Gateway IoT Architecture.

Here, I will demonstrate, how we can send live temperature data to ThinkSpeak server using Node-Gateway IoT architecture and observe the real-time Temperature vs Time graph on https://thinkspeak.com

NodeMCU (ESP8266) will be used as Node and RPi3 will be used as Gateway.

Description:

In this program,
Analog Temperature sensor (LM35) is connected to the NodeMCU 1.0 (ESP-12E Module) (ESP8266MOD) board and Its output will be sent to Gateway (Raspberry Pi 3).
  1. A C-Program (NodeMCU_to_RPi3_Temp-APDaga.ino) is written and uploaded on NodeMCU ESP8266, which will collect real-time room temperature using LM35 Sensor. and will then send that temperature data to RPi3 (Gateway).
  2. In order to send the data to RPi3 (Gateway), Above mentioned C-Program will trigger a python script "ts.py" kept in /cgi-bin/ folder on RPi3 using CGI Server
  3. This "ts.py" script, will log the received temperature data into a text file "TS_Out.txt" and then send the same data to thinkspeak server where we can see the graph between temperature vs time.

NOTE:
1. Internal 10 bit ADC (A0) is used to read the Analog output of the Temperature Sensor.
2. Temperature data shown on thinkspeak server grapth will be subset of Logged temperature data in text file on RPi3.
    (Because free version of thinkspeak server accept data with the gap of 16 sec interval)

Steps to configure Arduino IDE to connect to NodeMCU ESP8266 are given Here.


Physical Connections:

NodeMCU Board  ->  LM35 (Analog Tempt Sensor)
 3V3            ->  Vcc (Left Pin - Flat side facing towards you)
 A0             ->  Analog Out (Middle Pin)  (10mV / degree Celcious) 
 GND            ->  Gnd (Right Pin - Flat side facing towards you)


 PIN Diagram of ESP8266MOD NodeMCU 1.0 (ESP-12E Module) Board:
 +-------------------------------------------------------------------------------+
 |  o .  o .  o .  o . o .  o .  o .  o .  o .  o .  o .  o .  o .  o .  o       |
 | Vin  GND  RST  EN  3V3  GND  CLK  SD0  CM0  SD1  SD2  SD3  RSV  RSV  A0       |
 |                                                                        ANTENA |   
 |                                                                Facing ur side |
 |                                                                               |
 | 3V3  GND  Tx   Rx  D8   D7   D6   D5   GND  3V3  D4   D3   D2   D1   D0       |
 |  o .  o .  o .  o . o .  o .  o .  o .  o .  o .  o .  o .  o .  o .  o       |
 +-------------------------------------------------------------------------------+

 Serial Communication with PC through MicroUSB cable (Tx0 and Rx0)



Steps for Execution:

1. Sign up at https://thingspeak.com
2. Channels > New Channel > Update "Name" and "Field 1" field names > Save Channel
3. Click On API keys > Copy "Write API key"
4. Make all the Connections to Arduino Mega board mentioned Above.
5. Check ip address of RPi3 using "ifconfig" command
6. Change Following 3 fields in C-program: (NodeMCU_to_RPi3_Temp-APDaga.ino) to be uploaded on NodeMCU.
   a. ip of RPi3 (from step 5)
   b. ssid_name  (Name of you WiFi)
   c. password   (Password of your WiFi) 
   d. path of file name of python script running on RPi3  // Here it is: ts.py

7. Change the following field in the below python program: (ts.py)
   a. api_key (from step 3)
   and save this python program as "ts.py"
   
8. Place this python program "ts.py" to ~/cgi-bin/ folder.
   and make it executable: chmod +x ~/cgi-bin/Blink_LED_Server.py

9. Start CGI server on RPi3:
   Open Terminal on RPi3:
   a. cd ~
   b. cp /usr/lib/python2.7/CGIHTTPServer.py ~/
   c. python -m CGIHTTPServer

   you will see the response on the terminal as follows:
   Serving HTTP on 0.0.0.0 port 8000 ...
   THIS MEANS CGI SERVER INITIALISED...

10.Upload Program to NodeMCU 1.0 (ESP-12E Module)

11.Open Arduino Serial Monitor on PC (Set Baud Rate to 115200 and set "Both NL & CR")

12.Go to https://thingspeak.com and login  
   Channels > My Channels > Click on Channel Name (created in step 2) > Private View
   Here you can observe the Grapth of Temperature Vs Day.
13.Check logged data on RPi3:
   Open terminal in RPi3:
   a. cd ~
   b. vi TS_Out.txt
   HERE YOU CAN OBSERVE LOGGED TEMPERATURE DATA 




For Better understanding you can watch demonstration video given below:

Downloads:

Download link is given in the Description of the YouTube video shown below.

Demonstration:




NodeMCU_to_RPi3_Temp-APDaga.ino: (To be uploaded on NodeMCU)

/**************************
*CHANGE FOLLOWING THINGS:
* ip of RPi3
* ssid
* password
* path for ts.py python script (if needed)
**************************/

#include <ESP8266WiFi.h>

const char* host = "192.168.0.35";            // ip of RPi3
//String ApiKey = "FHLRDWDK7GXTF83S";         // Not needed
String path = "/cgi-bin/ts.py?field1=";       // ts.py is the name of python script running on RPi3

const char* ssid = "SuiteUp";                 // ssid_name
const char* pass = "welcome@10";              // password

int sensor = A0;                              // LM35 Analog Output

float tempc; 
float svoltage;

void setup(void){                             // Function to Connect to Wi-Fi
  Serial.begin(115200);
  Serial.println("");

  WiFi.begin(ssid, pass);
  
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");
  }

  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP()); 
}

void loop() {
  float xval = analogRead(sensor);    // Read Analog output from LM35 Temperature Sensor
  svoltage = (xval*3100.0)/1023;      // value in mili volt
  tempc = svoltage/10;                // value in degree celcius

  Serial.println(tempc);              // display on serial monitor

  WiFiClient client;

  const int httpPort = 8000;
  if (!client.connect(host, httpPort)) {    // connect to RPi3 CGI server with port no. 8000
    Serial.println("connection failed");
    return;
  }

  // send temperature data to RPi3 CGI server
  client.print(String("GET ") + path + String(tempc) + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: keep-alive\r\n\r\n");

  // Format of the string for temp=25.4 is:
  // GET /cgi-bin/ts.py?field1=25.4 HTTP/1.1\r\nHost: 192.168.0.35\r\nConnection: keep-alive\r\n\r\n

  delay(10000);                            // wait for 1 sec
}




ts.py:
(To be kept in /cgi-bin/ on RPi3)

#!/usr/bin/env python

##########################
#CHANGE FOLLOWING THINGS:
# api_key (from step 3)
##########################

# importing libraries 
import cgi
import httplib, urllib
import time

sleep = 20

api_key = '7O4GGQFQGGPLYGF5'    # Thinkspeak API_key 

def thermometer(val):           # Function to send data to thinkspeak server using API
    temp = val
    params = urllib.urlencode({'field1': temp, 'key':api_key })                                 # set parameter for post/update request of thinkspeak server
    headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain"}      # set header for post/update request of thinkspeak server
    
 conn = httplib.HTTPConnection("api.thingspeak.com:80")      # connect to thinkspeak server
    
 try:
        conn.request("POST", "/update", params, headers)        # Send post / update request to Thinkspeak server
        response = conn.getresponse()                           # read response from thinkspeak server
        print temp                                              # print temperature
        print response.status, response.reason                  # print response from thinkspeak server
        data = response.read()                                  
        conn.close()                                            # close connection

    except:
        print "connection failed"                               # print error
        #break

if __name__ == "__main__":          # main function start here
    # while True:
    form = cgi.FieldStorage()       # received form from Arduino
 
    val = form.getvalue('field1')   # Temp data from Arduino 
 
    f=open("TS_Out.txt",'a')        # Open file in append mode
    f.write(str(val)+' \n')         # write temperature data in the file 
    f.flush()                       # copy from buffer to file
    f.close()                       # Close file

    thermometer(val)                # Function to send data to thinkspeak server using API

    # time.sleep(sleep)             # wait for desired amount of time


Click here to see more codes for Raspberry Pi 3 and similar Family.
&
Click here to see more codes for NodeMCU ESP8266 and similar Family.
&
Click here to see more codes for Arduino Mega (ATMega 2560) and similar Family.

Feel free to ask doubts in the comment section. I will try my best to solve it.
If you find this helpful by any mean like, comment and share the post.
This is the simplest way to encourage me to keep doing such work.

Thanks and Regards,
-Akshay P. Daga






2 Comments

  1. Is this wifi communication between R-pi and ESP based on MQTT protocol?

    ReplyDelete
    Replies
    1. This is HTTP communication. But you can find MQTT protocol in next blogs. Use Top-Right search bar.

      Delete
Post a Comment
Previous Post Next Post