Menu Close

NodeMCU Weather Station on Arduino IDE

This tutorial of Robo India is to make an online weather station on NodeMCU with Arduino IDE.

Detailed Tutorial

1. Introduction:

This tutorial explains how to make an online weather station using ESP8266 wifi module. It is a stand alone weather station that collects weather updates from openweathermap.org and displays the retrieved information on I2C 16X2 LCD.

This tutorial is for NodeMCU on Arduino IDE. Please note that the same tutorial can be performed on LUA as well.

1.2 Hardware required

S.No.ItemQuantity
1NodeMCU 1
2Breadboard 1
3i2c LCD backpack. 1
416×2 LCD with female header 1
5Jumper Male to female 4

2. Building Circuit

Make connection as mentioned ahead

S.NO.         NodeMCU               I2C LCD
 1.VinVCC
 2.GNDGND
 3.D2SDA
 4.D1SCL

 Circuit Layout:

3. Getting API Key

1. Go to http://openweathermap.org/ and create an account if you do not have one.

2. Login to your account you will find API Key in the HOME>SETUP tab.

3. Copy and paste this key to a separate notepad file will need it later.

4. Getting City Code from OpenWeather

Search your city in the search box at openwheather.org. Click on your city on search result and here is your city code as highlighted in the following image.

Another way of getting city code –

http://bulk.openweathermap.org/sample/city.list.json.gz

Download list of city codes from the above file. After downloading extract the file and open the same in Notepad or WordPad and find the code of your city.

5. Programming:

Once the circuit part is done, NodeMCU is needed to be programmed. Here is the code to run this circuit on NodeMCU.

You may download this code (Arduino Sketch) from here.

// Robo India Tutorials
// Hardware: NodeMCU
// simple Code for reading information from openweathermap.org 

#include <ESP8266WiFi.h>
#include <LiquidCrystal_I2C.h>
#include <ArduinoJson.h>
#include <Wire.h>



const char* ssid     = "Your Network Name";                 // SSID of local network
const char* password = "Your Password";                    // Password on network
String APIKEY = "API Key";                                 
String CityID = "CityID";                                 //Your City ID


WiFiClient client;
char servername[]="api.openweathermap.org";              // remote server we will connect to
String result;

int  counter = 60;                                      

String weatherDescription ="";
String weatherLocation = "";
String Country;
float Temperature;
float Humidity;
float Pressure;

LiquidCrystal_I2C lcd(0x3F, 16, 2);    // Address of your i2c LCD back pack should be updated.

void setup() {
  Serial.begin(115200);
  int cursorPosition=0;
  lcd.begin(16, 2);
  lcd.init();
  lcd.backlight();
  lcd.print("   Connecting");  
  Serial.println("Connecting");
  WiFi.begin(ssid, password);
  
             while (WiFi.status() != WL_CONNECTED) 
            {
            delay(500);
            lcd.setCursor(cursorPosition,2); 
            lcd.print(".");
            cursorPosition++;
            }
  lcd.clear();
  lcd.print("   Connected!");
  Serial.println("Connected");
  delay(1000);
}

void loop() {
    if(counter == 60)                                 //Get new data every 10 minutes
    {
      counter = 0;
      displayGettingData();
      delay(1000);
      getWeatherData();
    }else
    {
      counter++;
      displayWeather(weatherLocation,weatherDescription);
      delay(5000);
      displayConditions(Temperature,Humidity,Pressure);
      delay(5000);
    }
}

void getWeatherData()                                //client function to send/receive GET request data.
{
  if (client.connect(servername, 80))   
          {                                         //starts client connection, checks for connection
          client.println("GET /data/2.5/weather?id="+CityID+"&units=metric&APPID="+APIKEY);
          client.println("Host: api.openweathermap.org");
          client.println("User-Agent: ArduinoWiFi/1.1");
          client.println("Connection: close");
          client.println();
          } 
  else {
         Serial.println("connection failed");        //error message if no client connect
          Serial.println();
       }

  while(client.connected() && !client.available()) 
  delay(1);                                          //waits for data
  while (client.connected() || client.available())    
       {                                             //connected or data available
         char c = client.read();                     //gets byte from ethernet buffer
         result = result+c;
       }

client.stop();                                      //stop client
result.replace('[', ' ');
result.replace(']', ' ');
Serial.println(result);
char jsonArray [result.length()+1];
result.toCharArray(jsonArray,sizeof(jsonArray));
jsonArray[result.length() + 1] = '\0';
StaticJsonBuffer<1024> json_buf;
JsonObject &root = json_buf.parseObject(jsonArray);

if (!root.success())
  {
    Serial.println("parseObject() failed");
  }

String location = root["name"];
String country = root["sys"]["country"];
float temperature = root["main"]["temp"];
float humidity = root["main"]["humidity"];
String weather = root["weather"]["main"];
String description = root["weather"]["description"];
float pressure = root["main"]["pressure"];
weatherDescription = description;
weatherLocation = location;
Country = country;
Temperature = temperature;
Humidity = humidity;
Pressure = pressure;

}

void displayWeather(String location,String description)
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(location);
  lcd.print(", ");
  lcd.print(Country);
  lcd.setCursor(0,1);
  lcd.print(description);
}

void displayConditions(float Temperature,float Humidity, float Pressure)
{
 lcd.clear();                            //Printing Temperature
 lcd.print("T:"); 
 lcd.print(Temperature,1);
 lcd.print((char)223);
 lcd.print("C "); 
                                         
 lcd.print(" H:");                       //Printing Humidity
 lcd.print(Humidity,0);
 lcd.print(" %"); 
 
 lcd.setCursor(0,1);                     //Printing Pressure
 lcd.print("P: ");
 lcd.print(Pressure,1);
 lcd.print(" hPa");
}

void displayGettingData()
{
  lcd.clear();
  lcd.print("Getting data");
}



6. Output

The output of the following code will display temperature, Humidity and Pressure (of the selected city) on the I2C 16X2 LCD as well as on Serial Monitor.

If you have any query please write us at support@roboindia.com

Thanks and Regards
Content Development Team 
Robo India
https://roboindia.com

Leave a Reply