MJRoBot (Marcelo Rovai)
Published © GPL3+

IoT Made Easy: Capturing Remote Weather Data

Capturing remote data as UV (Ultra-Violet radiation), air temperature and humidity and sending them to ThingSpeak.

BeginnerFull instructions provided4 hours4,615
IoT Made Easy: Capturing Remote Weather Data

Things used in this project

Hardware components

NodeMCU ESP8266 Breakout Board
NodeMCU ESP8266 Breakout Board
×1
DHT22 Temperature Sensor
DHT22 Temperature Sensor
×1
UV sensor
×1
OLED 1306
×1

Software apps and online services

Arduino IDE
Arduino IDE
ThingSpeak API
ThingSpeak API

Story

Read more

Schematics

Electrical Diagram

Code

Code snippet #1

Plain text
/* Read UV Sensor in mV and call UV index calculation */
void readSensorUV()
{                    
  byte numOfReadings = 5;
  dataSensorUV = 0;
  for (int i=0; i< numOfReadings; i++) 
  {
    dataSensorUV += analogRead(sensorUVPin);
    delay (200);
  }
  dataSensorUV /= numOfReadings;
  dataSensorUV = (dataSensorUV * (3.3 / 1023.0))*1000;
  Serial.println(dataSensorUV);
  indexCalculate();
}

Code snippet #2

Plain text
/*  UV Index calculation */
void indexCalculate()
{
    if (dataSensorUV < 227) indexUV = 0;
    else if (227 <= dataSensorUV && dataSensorUV < 318) indexUV = 1;
    else if (318 <= dataSensorUV && dataSensorUV < 408) indexUV = 2;
    else if (408 <= dataSensorUV && dataSensorUV < 503) indexUV = 3;
    else if (503 <= dataSensorUV && dataSensorUV < 606) indexUV = 4;    
    else if (606 <= dataSensorUV && dataSensorUV < 696) indexUV = 5;
    else if (696 <= dataSensorUV && dataSensorUV < 795) indexUV = 6;
    else if (795 <= dataSensorUV && dataSensorUV < 881) indexUV = 7; 
    else if (881 <= dataSensorUV && dataSensorUV < 976) indexUV = 8;
    else if (976 <= dataSensorUV && dataSensorUV < 1079) indexUV = 9;  
    else if (1079 <= dataSensorUV && dataSensorUV < 1170) indexUV = 10;
    else indexUV = 11;       
}

Code snippet #3

Plain text
/* OLED */
#include "SSD1306Wire.h"
#include "Wire.h"
const int I2C_DISPLAY_ADDRESS = 0x3c;
const int SDA_PIN = 0;
const int SCL_PIN = 2;
SSD1306Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SCL_PIN);

Code snippet #4

Plain text
void init(); // Initialise the display
void displayOn(void); // Turn the display on
void displayOff(void); // Turn the display offs
void clear(void); // Clear the local pixel buffer
void flipScreenVertically(); // Turn the display upside down

Code snippet #6

Plain text
* OLED */
#include "SSD1306Wire.h"
#include "Wire.h"
const int I2C_DISPLAY_ADDRESS = 0x3c;
const int SDA_PIN = 0;
const int SCL_PIN = 2;
SSD1306Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SCL_PIN);

void setup () 
{
  Serial.begin(115200); 
  displaySetup();
}

void loop() 
{ 
}

/* Initiate and display setup data on OLED */
void displaySetup()
{
  display.init();         // initialize display
  display.clear();        // Clear display
  display.flipScreenVertically(); // Turn the display upside down
  display.display();      // Put data on display
  
  Serial.println("Initiating Display Test");
  
  display.setFont(ArialMT_Plain_24);
  display.drawString(30, 0, "OLED");  // (xpos, ypos, "Text")
  display.setFont(ArialMT_Plain_16);
  display.drawString(18, 29, "Test initiated");
  display.setFont(ArialMT_Plain_10);
  display.drawString(10, 52, "Serial BaudRate:");
  display.drawString(90, 52, String(11500));
  display.display();  // Put data on display
  delay (3000);
}

Code snippet #7

Plain text
#define SW_VERSION "UV_Sensor_V.1" 

/* UV Sensor */
#define sensorUVPin A0
int dataSensorUV = 0;
int indexUV = 0;

/* OLED */
#include "SSD1306Wire.h"
#include "Wire.h"
const int I2C_DISPLAY_ADDRESS = 0x3c;
const int SDA_PIN = 0;
const int SCL_PIN = 2;
SSD1306Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SCL_PIN);

void setup()
{
  Serial.begin(115200);
  displaySetup();
}

void loop()
{                    
  readSensorUV();
  displayUV();
  delay (1000);
}

/* Initiate and display setup data on OLED */
void displaySetup()
{
  display.init();                 // initialize display
  display.clear();                // Clear display
  display.flipScreenVertically(); // Turn the display upside down
  display.display();              // Put data on display

  Serial.println("Initiating UV Sensor Test");
  display.setFont(ArialMT_Plain_24);
  display.drawString(10, 0, "MJRoBot");  
  display.setFont(ArialMT_Plain_16);
  display.drawString(0, 29, "UV Sensor Test");
  display.setFont(ArialMT_Plain_10);
  display.drawString(0, 52, "SW Ver.:");
  display.drawString(45, 52, SW_VERSION);
  display.display();
  delay (3000);
}

/* Read UV Sensor in mV and call UV index calculation */
void readSensorUV()
{                    
  byte numOfReadings = 5;
  dataSensorUV = 0;
  for (int i=0; i< numOfReadings; i++) 
  {
    dataSensorUV += analogRead(sensorUVPin);
    delay (200);
  }
  dataSensorUV /= numOfReadings;
  dataSensorUV = (dataSensorUV * (3.3 / 1023.0))*1000;
  Serial.println(dataSensorUV);
  indexCalculate();
}

/*  UV Index calculation */
void indexCalculate()
{
    if (dataSensorUV < 227) indexUV = 0;
    else if (227 <= dataSensorUV && dataSensorUV < 318) indexUV = 1;
    else if (318 <= dataSensorUV && dataSensorUV < 408) indexUV = 2;
    else if (408 <= dataSensorUV && dataSensorUV < 503) indexUV = 3;
    else if (503 <= dataSensorUV && dataSensorUV < 606) indexUV = 4;    
    else if (606 <= dataSensorUV && dataSensorUV < 696) indexUV = 5;
    else if (696 <= dataSensorUV && dataSensorUV < 795) indexUV = 6;
    else if (795 <= dataSensorUV && dataSensorUV < 881) indexUV = 7; 
    else if (881 <= dataSensorUV && dataSensorUV < 976) indexUV = 8;
    else if (976 <= dataSensorUV && dataSensorUV < 1079) indexUV = 9;  
    else if (1079 <= dataSensorUV && dataSensorUV < 1170) indexUV = 10;
    else indexUV = 11;       
}

/*  Display UV Values on local OLED*/
void displayUV()
{
  display.clear();
  display.setFont(ArialMT_Plain_16);
  display.drawString(20, 0, "UV Sensor");
  display.drawString(0, 23, "UV (mV):" );
  display.drawString(80, 23, String(dataSensorUV));
  display.drawString(0, 48, "UV Index:" );
  display.setFont(ArialMT_Plain_24);
  display.drawString(82, 42, String(indexUV));
  display.display();
}

Code snippet #8

Plain text
/* DHT22*/
#include "DHT.h"
#define DHTPIN D2  
#define DHTTYPE DHT22 
DHT dht(DHTPIN, DHTTYPE);
float hum = 0;
float temp = 0;

Code snippet #9

Plain text
/* Get DHT data */
void getDhtData(void)
{
  float tempIni = temp;
  float humIni = hum;
  temp = dht.readTemperature();
  hum = dht.readHumidity();
  if (isnan(hum) || isnan(temp))   // Check if any reads failed and exit early (to try again).
  {
    Serial.println("Failed to read from DHT sensor!");
    temp = tempIni;
    hum = humIni;
    return;
  }
}

Code snippet #10

Plain text
/* ESP12-E & Thinkspeak*/
#include <ESP8266WiFi.h>
WiFiClient client;
const char* MY_SSID = "YOUR SSD ID HERE";
const char* MY_PWD = "YOUR PASSWORD HERE";
const char* TS_SERVER = "api.thingspeak.com";
String TS_API_KEY ="YOUR CHANNEL WRITE API KEY";

Code snippet #12

Plain text
void setup() 
{
  ...
  Serial.begin(115200);
  delay(10);
  ...
  connectWifi();
  timer.setInterval(60000L, sendDataTS);
  ...
}

Code snippet #13

Plain text
void loop() 
{
  ...
  timer.run(); // Initiates SimpleTimer
}

Code snippet #14

Plain text
/***************************************************
 * Connecting WiFi
 **************************************************/
void connectWifi()
{
  Serial.print("Connecting to "+ *MY_SSID);
  WiFi.begin(MY_SSID, MY_PWD);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected");
  Serial.println("");  
}

Code snippet #15

Plain text
/***************************************************
 * Sending Data to Thinkspeak Channel
 **************************************************/
void sendDataTS(void)
{
   if (client.connect(TS_SERVER, 80)) 
   { 
     String postStr = TS_API_KEY;
     postStr += "&field1=";
     postStr += String(dataSensorUV);
     postStr += "&field2=";
     postStr += String(indexUV);
     postStr += "&field3=";
     postStr += String(temp);
     postStr += "&field4=";
     postStr += String(hum);

     postStr += "\r\n\r\n";
   
     client.print("POST /update HTTP/1.1\n");
     client.print("Host: api.thingspeak.com\n");
     client.print("Connection: close\n");
     client.print("X-THINGSPEAKAPIKEY: " + TS_API_KEY + "\n");
     client.print("Content-Type: application/x-www-form-urlencoded\n");
     client.print("Content-Length: ");
     client.print(postStr.length());
     client.print("\n\n");
     client.print(postStr);
     delay(1000); 
   }
   sent++;
   client.stop();
}

Github file

https://github.com/Mjrovai/RPi-NodeMCU-Weather-Station/tree/master/NodeMCU_UV_DHT_Sensor_OLED

Github

https://github.com/adafruit/DHT-sensor-library

Github

https://github.com/squix78/esp8266-oled-ssd1306

Github file

https://github.com/Mjrovai/IoT-Servo-Control/tree/master/NodeMCU_OLED_Test

Credits

MJRoBot (Marcelo Rovai)

MJRoBot (Marcelo Rovai)

60 projects • 912 followers
Professor, Engineer, MBA, Master in Data Science. Writes about Electronics with a focus on Physical Computing, IoT, ML, TinyML and Robotics.

Comments