Hackster is hosting Hackster Holidays, Ep. 7: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 7 on Friday!
harshitmehra2007
Published © GPL3+

NodeMCU Clock with weather,Time and alot more

Hey, guys today I made one of the best Nodemcu clock which is budget friendly it shows like corona count, time, date, year and weather

BeginnerFull instructions provided709
NodeMCU Clock with weather,Time and alot more

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
Alphanumeric LCD, 16 x 2
Alphanumeric LCD, 16 x 2
×1
Battery, 9 V
Battery, 9 V
×1
Solderless Breadboard Half Size
Solderless Breadboard Half Size
×1
DHT11 Temperature & Humidity Sensor (4 pins)
DHT11 Temperature & Humidity Sensor (4 pins)
×1

Software apps and online services

Arduino IDE
Arduino IDE
ThingSpeak API
ThingSpeak API

Hand tools and fabrication machines

Wire Cutter / Stripper, 5.25 " Overall Length
Wire Cutter / Stripper, 5.25 " Overall Length

Story

Read more

Schematics

The connections

Code

The code

C/C++
 #include <ESP8266WiFi.h> //the library used       //Use ESP8266 functions                                              
 #include <ESP8266HTTPClient.h>
 #include <LiquidCrystal_I2C.h>
 #include "WiFiUdp.h"
 #include "NTPClient.h"
 #include <ArduinoJson.h>
  #include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <dht11.h>
#define DHT11PIN 14// defining the pin for dht11 sensor

dht11 DHT11;
AsyncWebServer server(80);//starting the server for the custom message display feature
 const long utcOffsetInSeconds = 19800;//change according to your timezone 
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
String months[12]={"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};//for the months and day feature do not change

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);
 
 #include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier

  LiquidCrystal_I2C lcd(0x27,16,2);
  String APIKEY = "";     //open weather api key                            
String CityID = "1273294";                                 //Your City ID

  
  const char* ssid = "wifi name";              //WIFI SSID Name                             
  const char* password = "wifi password";        //WIFI Password
  const char* host = "api.thingspeak.com";  //We read the data from this host                                   
  const int httpPortRead = 80;                                           
                                                  
  const char* url1 = "/apps/thinghttp/send_request?api_key=5WX50KDX3R0IBCXQ";     //Change this URL Cases
  const char* url2 = "/apps/thinghttp/send_request?api_key=AHZYGT5QSWRDGCE5";   //Deaths
  const char* url3 = "/apps/thinghttp/send_request?api_key=KCHIW1XDQ4J8G3EE";   //Recovered
  int To_remove;      //There are some irrelevant data on the string and here's how I keep the index
                      //of those characters 
  String Cases,Deaths,Recovered,Time,Data_Raw,Data_Raw_1,Data_Raw_2,Data_Raw_3,Data_Raw_4,Data_Raw_5;  //Here I keep the numbers that I got

  WiFiClient client;      //Create a WiFi client and http client                                                     
  HTTPClient http;
  char servername[]="api.openweathermap.org";              // remote server we will connect to
String result;

int  counter = 60;                                      

String weatherDescription ="";
String weatherLocation = "";
String Country;
String cases = "cases";
float Temperature;
float Humidity;
float Pressure;
String inputMessage="request->getParam(PARAM_INPUT_1)->value()";
String inputMessage2="request->getParam(PARAM_INPUT_2)->value()";
String inputMessage3="request->getParam(PARAM_INPUT_3)->value()";
String inputMessage4="request->getParam(PARAM_INPUT_4)->value()";//for the custom message display
  const char* PARAM_INPUT_1 = "input1";
  const char* PARAM_INPUT_2 = "Alarm Hours";
  const char* PARAM_INPUT_3 = "Alarm Minutes";
  const char* PARAM_INPUT_4 = "Select Screen to display";
  const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
  <title>LCD CLOCK CONTROL PANNEL</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  </head><body>
  <form action="/get">
    input1: <input type="text" name="input1">
    <input type="submit" value="Submit">
  </form><br>
   <form action="/get">
    Alarm Hours: <input type="text" name="Alarm Hours">
    <input type="submit" value="Submit">
  </form><br>
   <form action="/get">
    Alarm Minutes: <input type="text" name="Alarm Minutes">
    <input type="submit" value="Submit">
  </form><br>
  <form action="/get">
    Select Screen to show: <input type="text" name="Select Screen to display">
    <input type="submit" value="Submit">
  </form><br>
  </body></html>)rawliteral";
  void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");//making the webserver for the custom message display
}

 void setup() {
    lcd.begin(16, 2);
    lcd.init();
    lcd.backlight();
    lcd.setCursor(1, 0);
    lcd.print("SMART CLOCK"); //Change Your Country Name
    lcd.setCursor(1, 1);
    lcd.print("EEP");  //Change Name if you want
    
    Serial.begin(115200);
    WiFi.disconnect();             //Disconnect and reconnect to the Wifi you set                                                 
    delay(1000);                                                                  
    WiFi.begin(ssid, password);                                                   
    Serial.println("Connected to the WiFi network");   //Display feedback on the serial monitor                                        
    Serial.println(WiFi.localIP());
    timeClient.begin();
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });

  // Send a GET request to <ESP_IP>/get?input1=<inputMessage>
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputParam;
    // GET input1 value on <ESP_IP>/get?input1=<inputMessage>
    if (request->hasParam(PARAM_INPUT_1)) {
      inputMessage = request->getParam(PARAM_INPUT_1)->value();
      inputParam = PARAM_INPUT_1;
    }
    else  if (request->hasParam(PARAM_INPUT_2)) {
      inputMessage2 = request->getParam(PARAM_INPUT_2)->value();
      inputParam = PARAM_INPUT_2;
    }
     else  if (request->hasParam(PARAM_INPUT_3)) {
      inputMessage3 = request->getParam(PARAM_INPUT_3)->value();
      inputParam = PARAM_INPUT_3;
    }
     else  if (request->hasParam(PARAM_INPUT_4)) {
      inputMessage4 = request->getParam(PARAM_INPUT_4)->value();
      inputParam = PARAM_INPUT_4;
    }
      else {
      inputMessage = "No message sent";
      
      inputParam = "none";
     
    }
    Serial.println(inputMessage);
    Serial.println(inputMessage2);
    Serial.println(inputMessage3);
     Serial.println(inputMessage4);
    request->send(200, "text/html", "HTTP GET request sent to your ESP on input field (" 
                                     + inputParam + ") with value: " + inputMessage +
                                     "<br><a href=\"/\">Return to Home Page</a>");
  });
  server.onNotFound(notFound);
  server.begin();
    }
  

void loop() {
  int chk = DHT11.read(DHT11PIN);
    if( http.begin(host,httpPortRead,url1))        //Connect to the host and the url                                      
      {
        int httpCode = http.GET();                //Check feedback if there's a response                                                  
        if (httpCode > 0)                                                              
        {
          if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) 
            {                
              
              Data_Raw = http.getString();   //Here we store the raw data string
            
              
              Data_Raw_1 = Data_Raw;                                    
              To_remove = Data_Raw_1.indexOf(">");                      // here I remove the /span data                                 
              Data_Raw_1.remove(0,To_remove+1);                        
              To_remove = Data_Raw_1.indexOf("<");                                                 
              Data_Raw_1.remove(To_remove,Data_Raw_1.length());           
              Cases=Data_Raw_1;
              Serial.print("Cases: ");  //I choosed to display it on the serial monitor to help you debug
              Serial.println(Cases); 
              
              Data_Raw_2=Data_Raw;
              To_remove = Data_Raw_2.indexOf("<span>");
              Data_Raw_2.remove(0,To_remove+6);
              Data_Raw_3=Data_Raw_2;
              To_remove = Data_Raw_2.indexOf("</span>");
              Data_Raw_2.remove(To_remove,Data_Raw_2.length());

              Deaths=Data_Raw_2;
              Serial.print("Deaths: ");
              Serial.println(Deaths);
            
              To_remove = Data_Raw_3.indexOf("<span>");
              Data_Raw_3.remove(0,To_remove+6);

              To_remove = Data_Raw_3.indexOf("<");
              Data_Raw_3.remove(To_remove,Data_Raw_3.length());

              Recovered=Data_Raw_3;
              
              Serial.print("Recovered: ");
              Serial.println(Recovered);
                                                                                       
            }
        }
        else //If we can't get data
        {
          Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
        }
        
        http.end();                                                                 
      } 
    else //If we can't connect to the HTTP
      {
        Serial.printf("[HTTP} Unable to connect\n");
      }

    while (WiFi.status() != WL_CONNECTED)     //In case the Wifi connexion is lost                                    
      { 
        
        WiFi.disconnect();                                                        
        delay(1000);                                                             
        
        WiFi.begin(ssid, password);                                              
        Serial.println("Reconnecting to WiFi..");       
        delay(10000);                                                             
      }
      timeClient.update();
      unsigned long epochTime = timeClient.getEpochTime();
  Serial.print("Epoch Time: ");
  Serial.println(epochTime);
  
  struct tm *ptm = gmtime ((time_t *)&epochTime); 

delay(1000);
  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);
    }
    
    
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Cases");
        lcd.setCursor(0,1);
        lcd.print(Cases);
        delay (10000);
    
    
        //change delay if you want
       
        lcd.clear();
        
        lcd.setCursor(0,0);
        lcd.print("Deaths");
        lcd.setCursor(0,1);
        lcd.print(Deaths);
        delay (10000);
     
          lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Recovered");
        lcd.setCursor(0,1);
        lcd.print(Recovered);
        delay (10000);

        
        lcd.clear();
        
        lcd.setCursor(0,0);
        lcd.print("Time is=");
        lcd.setCursor(0,1);
        lcd.print (timeClient.getHours());
        timeClient.update();
        lcd.setCursor(2,1);
        lcd.print(":");
         lcd.setCursor(3,1);
        lcd.print(timeClient.getMinutes());
         timeClient.update();
         lcd.setCursor(5,1);
        lcd.print(":");
         lcd.setCursor(6,1);
        lcd.print(timeClient.getSeconds());
         timeClient.update();
        
         

         delay (10000);
         lcd.clear();
         lcd.setCursor(0,0);
         lcd.print("Day is");
         lcd.setCursor(1,1);
         lcd.print(daysOfTheWeek[timeClient.getDay()]);
         delay (10000);
         lcd.clear();
         int monthDay = ptm->tm_mday;
  Serial.print("Month day: ");
  Serial.println(monthDay);

  int currentMonth = ptm->tm_mon+1;
  Serial.print("Month: ");
  Serial.println(currentMonth);

  String currentMonthName = months[currentMonth-1];
  Serial.print("Month name: ");
  Serial.println(currentMonthName);

  int currentYear = ptm->tm_year+1900;
  Serial.print("Year: ");
  Serial.println(currentYear);
         
         String currentDate = String(currentYear) + "-" + String(currentMonth) + "-" + String(monthDay);
         lcd.print("Current date: ");
         lcd.setCursor(1,1);
           lcd.print(currentDate);
           delay (10000);
           lcd.clear();
         lcd.setCursor(0,0);
        
       
         lcd.clear();
         lcd.print(inputMessage);
         
         delay(10000);
         lcd.clear();
         lcd.setCursor (0,0);
         lcd.print("Room Temperature");
         lcd.setCursor(0,1);
         lcd.print((float)DHT11.temperature, 2);
         lcd.setCursor(5,1);
         lcd.print("C");
         delay (10000);
         lcd.clear();
         lcd.setCursor (0,0);
         lcd.print("Room Humidity");
         lcd.setCursor(0,1);
         lcd.print((float)DHT11.humidity, 2);
         lcd.setCursor(5,1);
         lcd.print("%");
         delay (10000);
         lcd.clear();
}
      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;
//for taking the external weather conditions
}

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");
}
//thats all in the code

Credits

harshitmehra2007
3 projects • 2 followers

Comments