Wednesday, October 28, 2020

Home Automation Step2

 In this step we have added Queue using cppQueue.h, it heps to save data in case of WIFI failure.

WIFI connectivity  status and Battery status also display in OLED


  #include <WiFi.h>
    #include <Wire.h>
    #include <PubSubClient.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    #include "DHT.h"              // DHT sensor library
    #include <NTPClient.h>
    #include "Time_a.h"  
    #include <TimeLib.h>  // unix time libray  
    #include <cppQueue.h>
    
    #define IMPLEMENTATION  FIFO
    #define queue_size 3000
    #define OVERWRITE true
    #define SCREEN_WIDTH 128 // OLED display width, in pixels
    #define SCREEN_HEIGHT 64 // OLED display height, in pixels

/////////////////////////////////////////////////////////////////////////
     #define timeSeconds 10
     // Set GPIOs for LED and PIR Motion Sensor
      const int led = 14;
      const int motionSensor = 12;
     // Timer: Auxiliary variables
      unsigned long now_delay = millis();
      unsigned long lastTrigger = 0;
      boolean startTimer = false;
      // Checks if motion was detected, sets LED HIGH and starts a timer
      void IRAM_ATTR detectsMovement() {
              Serial.println("MOTION DETECTED!!!");
              digitalWrite(led, HIGH);

              startTimer = true;
              lastTrigger = millis();
              }
////////////////////////////////////////////////////////////////
    
    
    int battery_level=38;
    
    #define DHTPIN 26     // DHT conected to  pin 26
    #define DHTTYPE DHT11 //   
    
    unsigned long offset_days = 3;    // 3 days
    //unsigned long t_unix_date1;
    
//    
//    const char* ssid     = "AndroidAP"; // change here
//    const char* password = "sema9444"; // change here
//    const char* mqtt_server = "broker.hivemq.com";

   // Change the credentials below, so your ESP8266 connects to your router
      const char* ssid = "Dialog 4G";
      const char* password = "YJNHQ102RD8";
      
   // Change the variable to your Raspberry Pi IP address, so it connects to your MQTT broker
      const char* mqtt_server = "192.168.0.105";

   // Lamp - LED - GPIO 4 = D2 on ESP-12E NodeMCU board
      const int lamp = 4;

   // Lamp - LED - GPIO 12 = D6 on ESP-12E NodeMCU board
      const int lamp1 = 5 ;

    int status = WL_IDLE_STATUS;   // the Wifi radio's status
    
    ////////////////wifi cnnected image////////////////////////////////////////////////////////////////
    static const unsigned char PROGMEM image_wifi[] = {
    // 'wifi-icon-260nw-329468402', 14x14px
    0x07, 0x80, 0x1f, 0xe0, 0x70, 0x30, 0xe3, 0x18, 0xcf, 0xcc, 0x38, 0x70, 0x30, 0x30, 0x0f, 0x80,
    0x0d, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00};
    
    /////////////////////////battery status ///////////////////////////////////////////////////////////
    static const unsigned char PROGMEM battery_empty[] = {                                          ///
    // 'battery empty', 15x24px
    0x00, 0x00, 0x0f, 0xe0, 0x0f, 0xe0, 0x7f, 0xfc, 0x60, 0x0c, 0x60, 0x0c, 0x60, 0x0c, 0x60, 0x0c,
    0x60, 0x0c, 0x60, 0x0c, 0x60, 0x0c, 0x60, 0x0c, 0x60, 0x0c, 0x60, 0x0c, 0x60, 0x0c, 0x6f, 0xec,
    0x6f, 0xec, 0x6f, 0xec, 0x60, 0x0c, 0x60, 0x0c, 0x7f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};///
                                                                                                    ///
    static const unsigned char PROGMEM battery_half[] = {                                           ///
    // 'battery half', 15x24px
    0x00, 0x00, 0x0f, 0xe0, 0x0f, 0xe0, 0x7f, 0xfc, 0x60, 0x0c, 0x60, 0x0c, 0x60, 0x0c, 0x60, 0x0c,
    0x60, 0x0c, 0x60, 0x0c, 0x6f, 0xec, 0x6f, 0xec, 0x6f, 0xec, 0x60, 0x0c, 0x60, 0x0c, 0x6f, 0xec,
    0x6f, 0xec, 0x6f, 0xec, 0x60, 0x0c, 0x7f, 0xfc, 0x7f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};///
                                                                                                    ///
    static const unsigned char PROGMEM battery_full[] = {                                           ///
    // 'battery full', 15x24px
    0x00, 0x00, 0x0f, 0xe0, 0x0f, 0xe0, 0x3f, 0xfc, 0x60, 0x0c, 0x6f, 0xec, 0x6f, 0xec, 0x6f, 0xec,
    0x60, 0x0c, 0x60, 0x0c, 0x6f, 0xec, 0x6f, 0xec, 0x6f, 0xec, 0x60, 0x0c, 0x6f, 0xec, 0x6f, 0xec,
    0x6f, 0xec, 0x60, 0x0c, 0x3f, 0xfc, 0x3f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};//
                                                                                                    ///
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    WiFiClient espClient;
    PubSubClient client(espClient);
    char mqtt_msg[10];
    
    // Define NTP Client to get time
    WiFiUDP ntpUDP;
    NTPClient timeClient(ntpUDP);
    time_t et;
    
    DHT dht(DHTPIN, DHTTYPE);
    
      float dht11_hum, dht11_temp;
      uint32_t t;        //unix time
      uint32_t count=0;
      int len =0;
      Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

     /////////////////////////////////////////////////////////////////////////////////////
       typedef struct strRec {
                  uint16_t  t;
                  float     dht11_temp;
                  float     dht11_hum;
                } Rec;

                //Rec = rec.dht11_temp;
                
                
       Queue q(sizeof(Rec), queue_size, IMPLEMENTATION,OVERWRITE); // Instantiate queue
   
    /////////////////////////////////////////////////////////////////
    void setup() {
      Serial.begin(115200);
      connect_wifi();
      update_time ();
      display.clearDisplay();         //clear OLED
/////////////////////////////////////////////////////////////////////////

      pinMode(lamp, OUTPUT);
   // pinMode(lamp1, OUTPUT)

//////////////////////////////////////////////////////////////////////////////
 // PIR Motion Sensor mode INPUT_PULLUP
    pinMode(motionSensor, INPUT_PULLUP);
 // Set motionSensor pin as interrupt, assign interrupt function and set RISING mode
    attachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, RISING);
 // Set LED to LOW
    pinMode(led, OUTPUT);
    digitalWrite(led, LOW);
///////////////////////////////////////////////////////////////////////////////////////
    
    ///////////// to display wifi connection status https://www.arduino.cc/en/Reference/WiFiStatus   
        //if(WiFi.status()== WL_CONNECTED){
        // Draw bitmap on the screen
          display.drawBitmap(112, 0, image_wifi, 14, 14, 1);
          display.display();
       // while(true);};  
    
    ///////////////battery level display ///////////////////////////////   
    if (battery_level<30){                                           
      display.drawBitmap(110, 40, battery_empty, 15, 24, 1);display.display();};                                           
    if(battery_level>31){
       if(battery_level<50){    
       display.drawBitmap(110, 40, battery_half, 15, 24, 1);display.display();}};                                             
    if(battery_level>51){                                            
       display.drawBitmap(110, 40, battery_full, 15, 24, 1);display.display();};                                             
                                                                     
    //splay.clearDisplay();         //clear OLED                   
    ////////////////////////////////////////////////////////////////////  
    
      dht.begin();                      // Start the DHT11 sensor
      client.setServer(mqtt_server, 1883);
      client.setCallback(callback);
    }
    
    void loop() {

      
//////////////////////////////////////////////////////////////////////////////
// Current time for interruprt
   now_delay = millis();
// Turn off the LED after the number of seconds defined in the timeSeconds variable
 if(startTimer && (now_delay - lastTrigger > (timeSeconds*1000))) {
    Serial.println("Motion stopped...");
    digitalWrite(led, LOW);
    startTimer = false;
  }
//////////////////////////////////////////////////////////////////////////////

        if(len>30){
        len=0;
        Serial.println("Queue data lost !");
        }
      
    /// read data from sensors //////////////////////////////////
      dht11_hum  = dht.readHumidity();    // humidity         ///
      dht11_temp = dht.readTemperature(); // temp             ///
      t          = now();                 // time stamp       ///
                                                              ///
    /////////////////////////////////////////////////////////////
    
    ////////////// unix time convert ///////////////////
     Serial.print(t);  // https://arduino.stackexchange.com/questions/38765/convert-to-and-from-unix-timestamp
     printf("  : %4d-%02d-%02d %02d:%02d:%02d\n", year(t), month(t), day(t), hour(t), minute(t), second(t));
    
    display_oled();
    //publish_mqtt ();
    //putInQueue();
 
    //connect_wifi ();
    if(WiFi.status()==WL_CONNECTED){
    subscribeToLamps();
    putInQueuePubToMqtt();}
    
    if(WiFi.status()==WL_CONNECTION_LOST){
      Serial.println("wifi CONNECTION_LOST, Data Write to Queue");
      putInQueue();
      connect_wifi();
              if(WiFi.status()==WL_CONNECTED){
                Serial.println("Queue data due to CONNECTION_LOST");
                pubQueue ();
                Serial.println("Queue data due to CONNECTION_LOST is finished");}   
              }

    if(WiFi.status()==WL_NO_SSID_AVAIL){
      Serial.println("wifi NO_SSID_AVAIL, Data Write to Queue");
      putInQueue();
      connect_wifi();
              if(WiFi.status()==WL_CONNECTED){
                Serial.println("Queue data due to WL_NO_SSID_AVAIL");
                pubQueue ();
                Serial.println("Queue data due to WL_NO_SSID_AVAIL is finished");}   
              }

    if(WiFi.status()==WL_DISCONNECTED){
      Serial.println("wifi DISCONNECTED, Data Write to Queue");
      putInQueue();
      connect_wifi();
              if(WiFi.status()==WL_CONNECTED){
                Serial.println("Queue data due to WL_DISCONNECTED");
                pubQueue ();
                Serial.println("Queue data due to WL_DISCONNECTED is finished");
                }   
              }
    
              
     // WiFi.disconnect();
     // Serial.print("wifi Disconnected");

   
    // delay(30000);
    ////////sleep for 20 secound/////////////////////
    //  esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 0);
//      esp_sleep_enable_timer_wakeup(20000000);  
//      esp_deep_sleep_start();
      
    }
/////////////////////QUEUE/////////////////////////////////////////////////////////////////
   void subscribeToLamps(){
      client.subscribe("room/lamp");
      client.subscribe("room/lamp1");
    }
    
    
    void putInQueue (){
      
       for (int i=0; i<10; i++){
      
      dht11_hum  = dht.readHumidity();    // humidity         
      dht11_temp = dht.readTemperature(); // temp             
      t          = now();                 // time stamp   
      
      Rec rec;
      rec.t       = t;
      rec.dht11_temp = dht11_temp;
      rec.dht11_hum = dht11_hum;
      q.push(&rec);
 
      delay(10000);
      len=q.getCount();
      Serial.println(" ");
      Serial.print(len);}
 
  }

 void pubQueue(){
 
      len=q.getCount();
      for(len ;len>0; len--){
      Rec rec;
      q.pop(&rec);
      Serial.print(rec.t); Serial.print(" ");
      Serial.print(rec.dht11_temp); Serial.print(" ");
      Serial.print(rec.dht11_hum); Serial.print(" ");
      Serial.println(len);

      sprintf(mqtt_msg,"%u %2.0f %2.1f",t,dht11_hum,dht11_temp);
      //client.connect("mel5405-2018AE03");
      client.publish("mel5405/2018AE03/all",mqtt_msg);
      Serial.println(mqtt_msg);
      //delay(5000);
      delay(300);
     }
     len=0;
 }


 
  //////////////////////QUEUE TO MQTT ///////////////////////////////////////////////
  void putInQueuePubToMqtt(){
    for (int i=0; i<5; i++){
      
      dht11_hum  = dht.readHumidity();    // humidity         
      dht11_temp = dht.readTemperature(); // temp             
      t          = now();                 // time stamp   
      
      Rec rec;
      rec.t       = t;
      rec.dht11_temp = dht11_temp;
      rec.dht11_hum = dht11_hum;
      q.push(&rec);
      delay(10000);}
    
    len=q.getCount();
    if(len%5==0){
      for(len ;len>0; len--){
      Rec rec;
      q.pop(&rec);
      Serial.print(rec.t);
      Serial.print(" ");
      Serial.print(rec.dht11_temp);
      Serial.print(" ");
      Serial.print(rec.dht11_hum);
      Serial.print(" ");
      Serial.println(len);

      sprintf(mqtt_msg,"%u %2.2f %2.2f",rec.t,rec.dht11_temp,rec.dht11_hum);
      client.connect("mel5405-2018AE03");
      client.publish("mel5405/2018AE03/all",mqtt_msg);
      Serial.println(mqtt_msg);
      delay(500);
      
      sprintf(mqtt_msg," %2.2f",rec.dht11_temp);
      client.connect("mel5405-2018AE03");
      client.publish("mel5405/2018AE03/temp",mqtt_msg);
      Serial.println(mqtt_msg);
      delay(500);



//      sprintf(mqtt_msg," %2.2f",rec.dht11_hum);
//      client.connect("mel5405-2018AE03");
//      client.publish("mel5405/2018AE03/hum",mqtt_msg);
//      Serial.println(mqtt_msg);
//      delay(500);
  //  delay(5000);
      
  //  delay(300);
     }
     len=0;
    }
  }


    
  ////////////////////////////////////////////////////////////////////////////////  
//    void publish_mqtt() {
//      ////////////////// publish data using MQTT////////////////////////////////   
//      sprintf(mqtt_msg,"%2.4f",dht11_hum);
//      client.connect("mel5405-2018AE03"); // change here
//      client.publish("mel5405/2018AE03/humidity", mqtt_msg);  // change here
//      Serial.println(mqtt_msg);
//      delay(5000);
//      sprintf(mqtt_msg,"%2.4f",dht11_temp);
//      client.connect("mel5405-2018AE03"); // change here
//      client.publish("mel5405/2018AE03/temp", mqtt_msg);   // change here
//      Serial.println(mqtt_msg);
//      delay(5000);
//      sprintf(mqtt_msg,"%u",t);
//      client.connect("mel5405-2018AE03"); // change here
//      client.publish("mel5405/2018AE03/time", mqtt_msg);  // change here
//      Serial.println(mqtt_msg);
//      delay(5000);
//      sprintf(mqtt_msg,"%2.0f-%2.1f",dht11_hum,dht11_temp);
//      client.connect("mel5405-2018AE03");
//      client.publish("mel5405/2018AE03/all",mqtt_msg);
//      Serial.println(mqtt_msg);
//      delay(5000);
//    }
    void display_oled(){
      /////////////Display data on OLED ///////////////////////////
    
      display.setTextSize(1);         //set OLED text size
      display.setTextColor(WHITE);    // set text colour
      display.print(WiFi.localIP());  //Display IP of ESP
      delay(2000);
      //display.clearDisplay();       //clear OLED
     
      display.setTextSize(2);         // Draw 2X-scale text
      display.setTextColor(WHITE);
      display.setCursor(2, 15);
      display.print(dht11_temp);
      display.print(" C");
      display.setCursor(2, 30);
      display.print(dht11_hum);
      display.print(" %");
      display.setTextSize(1);         // Draw 1X-scale text
      display.setCursor(1, 55);
      display.print(t);
      display.setCursor(64, 55);
      display.print(count);
      display.display();
    }
    
    void update_time(){
    
      ///////////////// time update///////////////////////////////////////////////////
       timeClient.begin();
       timeClient.setTimeOffset(0); // GMT +5:30 = 19800
       while(!timeClient.update()) {
       timeClient.forceUpdate();
       delay(100);
       Serial.print("*");
       count ++;
       if (count>3)break;}


       if (count<3){
            Serial.println("");
            Serial.print("NTP time set: ");
            setTime(timeClient.getEpochTime());  // update ESP32 time
           }
       else {
            Serial.println("");
            Serial.println("Time not set");
            }
        if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
        Serial.println(F("SSD1306 allocation failed"));
        for(;;);
      }
     
      delay(100);
      }
    
    void connect_wifi(){
            int count=0;
            Serial.print("Connecting to ");
            Serial.println(ssid);
            WiFi.begin(ssid, password);

            while (WiFi.status() != WL_CONNECTED) {
            delay(500);
            Serial.print(".");
            count ++;
            if (count>40)break;}

            if (count<40){
            Serial.println("");
            Serial.print("Connected to WiFi network with IP Address: ");
            Serial.println(WiFi.localIP());}
                       
            else {(Serial.print("No WiFi"));
               }
        }
void callback(String topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
 
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  // Feel free to add more if statements to control more GPIOs with MQTT
  if(topic=="room/lamp1"){
      Serial.print("Changing Room lamp1 to ");
      if(messageTemp == "on"){
        digitalWrite(lamp1, HIGH);
        Serial.print("On");
      }
      else if(messageTemp == "off"){
        digitalWrite(lamp1, LOW);
        Serial.print("Off");
      }
  }
  Serial.println();
  // If a message is received on the topic room/lamp, you check if the message is either on or off. Turns the lamp GPIO according to the message
  if(topic=="room/lamp"){
      Serial.print("Changing Room lamp to ");
      if(messageTemp == "on"){
        digitalWrite(lamp, HIGH);
        Serial.print("On");
      }
      else if(messageTemp == "off"){
        digitalWrite(lamp, LOW);
        Serial.print("Off");
      }
  }
  Serial.println();
}

No comments:

Search This Blog