Announcement

Collapse
No announcement yet.

NodeMCU API Sketch With 5 Temp and 1 Humidity Sensor, and 4 Line LCD Panel Example

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • NodeMCU API Sketch With 5 Temp and 1 Humidity Sensor, and 4 Line LCD Panel Example

    This is a small write-up to show how we are monitoring temperature from 5 different points in our garage around the gas water heater. It started out as a project to see if we could monitor temperature using the API sketch and it grew to include humidity and a 4 line LCD.

    The NodeMCU units are fairly small and reasonably priced, so we use them throughout the house to monitor and report on a number of things, such as contacts, temperature, and humidity,

    This unit has 4 DS18B20 One Wire temperature sensors hanging off the NodeMCU. One temp sensor for each water line (hot and cold), the other two sensors monitor temperature from the top and bottom of the water heater unit. The unit also has two LEDs on it that I flash from one to the other as a visual indication that the NodeMCU is reading through the sensors. As the lights jump from one to the other, the LCD also has a flashing spot up in the right upper quadrant. In that section of the LCD there two asterisks that move left and right, sorta like a ping pong ball effect. I have not had any issue with the unit since it was deployed. these things just seem to work. The unit uses the Arduino plugin API to function.

    The NodeMCU unit is mounted in a small Tupperware container. This helps to protect it and also finds a cool use for some of our old Tupperware containers. I also used some Knexs to hold the LCD and right now the digital temperature and humidity sensor is just hanging off to the side. Over the years, along with our kids, we have built countless things with the Knexs (see https://www.knex.com/). Funny, I found a use for them years later with Home Automation. The plan is to mount it in a more suitable location in the garage in the future.

    Some pictures of the completed device in its working location.

    This is a picture of complete unit resting on the side of the water heater, it has the LCD angled down for easy viewing from the workbench.
    Click image for larger version  Name:	HSArduinoProject1.jpg Views:	1 Size:	107.2 KB ID:	1275612

    This is a picture showing the mounting of two DS18B20 waterproof temperature sensors, one for each water line (hot and cold).
    Click image for larger version  Name:	HSArduinoProject2.jpg Views:	1 Size:	22.5 KB ID:	1275613

    This picture shows a close-up of the LCD. Two pictures showing the double asterisks bouncing back and forth.
    Click image for larger version  Name:	HSArduinoProject3.jpg Views:	1 Size:	117.3 KB ID:	1275614

    This is a picture of the inside of the Tupperware container, showing the breadboard, connections, lights power connection and screw terminals. (If you would like more pictures let me know)
    Click image for larger version  Name:	HSArduinoProject4.jpg Views:	1 Size:	131.8 KB ID:	1275615

    These are links the parts used in the project. FYI, I have no vested interested in the sellers of the parts on Amazon. These worked for me, they delivered what I ordered, it was on time and at the time had a reasonable price.










    This is a screenshot of the HomeSeer devices.
    Click image for larger version  Name:	HSDevice1.jpg Views:	1 Size:	50.2 KB ID:	1275611

    This is a screenshot of the Arduino plugin setup for board 5.
    Click image for larger version  Name:	HSArduinoBoard5.jpg Views:	1 Size:	151.7 KB ID:	1275610

    This is the sketch, I changed the SID, password field and removed the IP addresses. Using Arduino Plugin version 1.0.0.147

    Code:
    /*************************************************************
      Arduino to Homeseer 3 Plugin API written by Enigma Theatre.
       V1.0.0.146
     *                                                           *
     *************************************************************/
    int FromHS[50];
    boolean IsConnected = false;
    //************************************************************
    
    
    //**************Declare your variables here*******************
    
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #include "DHT.h"
    #include <Wire.h>  // Comes with Arduino IDE
    #include <LiquidCrystal_I2C.h>
    
    /********************************************************************/
    // Data wire is plugged into a pin on the Arduino
    #define v_one_wire_bus_0 0      // NodeMCU D3 the number of the pin
    #define v_one_wire_bus_2 2      // NodeMCU D4 the number of the pin
    #define v_one_wire_bus_14 14    // NodeMCU D5 the number of the pin
    #define v_one_wire_bus_13 13    // NodeMCU D7 the number of the pin
    
    /********************************************************************/
    // Setup a oneWire instance to communicate with any OneWire devices  
    // (not just Maxim/Dallas temperature ICs)
    OneWire oneWire_0(v_one_wire_bus_0);
    OneWire oneWire_2(v_one_wire_bus_2);
    OneWire oneWire_14(v_one_wire_bus_14);
    OneWire oneWire_13(v_one_wire_bus_13);
    
    /********************************************************************/
    // Pass our oneWire reference to Dallas Temperature.
    DallasTemperature v_sensors_0(&oneWire_0);
    DallasTemperature v_sensors_2(&oneWire_2);
    DallasTemperature v_sensors_14(&oneWire_14);
    DallasTemperature v_sensors_13(&oneWire_13);
    
    int v_current_fahrenheit_0 = 0;
    int v_current_fahrenheit_2 = 0;
    int v_current_fahrenheit_14 = 0;
    int v_current_fahrenheit_13 = 0;
    
    int v_last_fahrenheit_0 = 0;
    int v_last_fahrenheit_2 = 0;
    int v_last_fahrenheit_14 = 0;
    int v_last_fahrenheit_13 = 0;
    
    //   Text Distance   " 0 1 2 3 4 5 6 7 8 9";
    String v_lcd_line_01;
    String v_lcd_line_02;
    String v_lcd_line_03;
    String v_lcd_line_04;
    String v_lcd_status;
    
    /********************************************************************/
    // Data wire is plugged into a pin on the Arduino
    #define v_dht_pin_12 12        // DHT Sensor 1 Pin
    
    // Define Sensor
    #define v_dht_type22_12 DHT22  // DHT 22 Device 1 (AM2302)
    
    DHT v_dht_12(v_dht_pin_12, v_dht_type22_12);
    int v_current_fahrenheit_12 = 0;
    int v_current_humidity_12   = 0;
    
    int v_last_fahrenheit_12 = 0;
    int v_last_humidity_12   = 0;
    
    // constants won't change. Used here to set a pin number:
    const int v_ledPin_15 =  15;            // NodeMCU D8 the number of the pin
    int v_ledState_15 = HIGH;               // v_ledState used to set the LED
    int v_ledValue_15 = 100;                // v_ledValue used to send to HomeSeer
    
    // constants won't change. Used here to set a pin number:
    const int v_ledPin_16 =  16;            // NodeMCU D0 the number of the pin
    int v_ledState_16 = HIGH;               // v_ledState used to set the LED
    int v_ledValue_16 = 100;                // v_ledValue recieved from HomeSeer
    
    // Generally, you should use "unsigned long" for variables that hold time
    // The value will quickly become too large for an int to store
    unsigned long previousMillis = 0;       // will store last time LED was updated
    
    // constants do not change:
    const long interval = 5000;             // interval at which to blink (milliseconds) 5 seconds
    
    // LCD Connections
    // Connect the VCC pin on the LCD display to the VIN pin on the NodeMCU.
    //  The VIN pin on the NodeMCU is tied directly to the 5V pin on the incoming USB port.
    //  If you plan on powering the NodeMCU with something other than USB
    //   you will have to find another way to provide 5V to the display.
    // Connect the GND pin on the LCD display to one of the GND pins on the NodeMCU.
    // Connect the SCL pin on the LCD display to the D1 pin on the NodeMCU.
    // Connect the SDA pin on the LCD display to the D2 pin on the NodeMCU.
    LiquidCrystal_I2C v_lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
    
    /********************************************************************/
    
    
    //****************************************************************
    
    void HSSetup() {
    
      //************************
      //Add YOUR SETUP HERE;
      //************************
    
      pinMode(v_ledPin_15, OUTPUT); // set the digital pin as output:
      pinMode(v_ledPin_16, OUTPUT); // set the digital pin as output:
    
      // start serial port
      Serial.begin(9600);
      Serial.println("Temperature Display");
    
      // Start up the library
      v_sensors_0.begin();
      v_sensors_2.begin();
      v_sensors_14.begin();
      v_sensors_13.begin();
      v_dht_12.begin();     //Start Sensor 16
    
      v_lcd.begin(20,4);    // initialize the lcd for 20 chars 4 lines, turn on backlight
    
    // ------- Quick 3 blinks of backlight  -------------
      for(int i = 0; i< 3; i++)
      {
        v_lcd.backlight();
        v_lcd.noBacklight();
      }
      v_lcd.backlight(); // finish with backlight on  
    
    //-------- Write characters on the display ------------------
      // NOTE: Cursor Position: Lines and Characters start at 0  
      //                     ("0 1 2 3 4 5 6 7 8 9 ");
      v_lcd_line_01  = String("Tmp #1: ???F   ** **");
      v_lcd_line_02  = String("Tmp #2: ???F        ");
      v_lcd_line_03  = String("Tmp #3: ???F #4 ???F");  
      v_lcd_line_04  = String("Tmp/Hum ???F    ???%");
      v_lcd_status   = String("**   ");
    
      v_lcd.setCursor(0,0);
      v_lcd.print(v_lcd_line_01);
      v_lcd.setCursor(0,1);
      v_lcd.print(v_lcd_line_02);
      v_lcd.setCursor(0,2);
      v_lcd.print(v_lcd_line_03);
      v_lcd.setCursor(0,3);
      v_lcd.print(v_lcd_line_04);
    
    }
    
    void HSloop() {
    
      //************************
      //Add YOUR CODE HERE;
      //************************
      /* To Send Data to Homeseer use SendToHS(Device,Value)
        Eg.. SendToHS(1,200); where 1 is the API device in homeseer and 200 is the value to send
        To Recieve data from Homeseer look up the FromHS array that is updated when the device value changes.
        Eg.. FromHS[5] would be the data from API Output device 5
        All code that is located just below this block will execute regardless of connection status!
        You can include SendToHS() calls, however when there isn't an active connection, it will just return and continue.
        If you only want code to execute when HomeSeer is connected, put it inside the if statement below.
      */
    
      /*Execute regardless of connection status*/
    
      if (IsConnected == true) {
       /*Execute ONLY when HomeSeer is connected*/
    
       // Serial.print("LED is: " );    
       // Serial.println(FromHS[0]);
    
       // check to see if it's time to blink the LED; that is, if the difference
       // between the current time and last time you blinked the LED is bigger than
       // the interval at which you want to blink the LED.
       unsigned long currentMillis = millis();
    
       if (currentMillis - previousMillis >= interval) {
         // save the last time you blinked the LED
         previousMillis = currentMillis;
    
         // if the LED is off turn it on and vice-versa:
         if (v_ledState_15 == LOW) {
           v_ledState_15 = HIGH;
           v_ledValue_15 = 100;
           v_ledState_16 = LOW;
           v_ledValue_16 = 0;
           v_lcd.setCursor(15,0);
           v_lcd.print("**   ");
         } else {
           v_ledState_15 = LOW;
           v_ledValue_15 = 0;
           v_ledState_16 = HIGH;
           v_ledValue_16 = 100;
           v_lcd.setCursor(15,0);
           v_lcd.print("   **");
         }
    
         digitalWrite(v_ledPin_15, v_ledState_15);   // set the LED with the ledState of the variable:
         SendToHS(1,v_ledValue_15);
         digitalWrite(v_ledPin_16, v_ledState_16);   // set the LED with the ledState of the variable:
         SendToHS(2,v_ledValue_16);
    
         v_sensors_0.requestTemperatures();  // Send the command to get temperature readings
         v_sensors_2.requestTemperatures();  // Send the command to get temperature readings
         v_sensors_14.requestTemperatures(); // Send the command to get temperature readings
         v_sensors_13.requestTemperatures(); // Send the command to get temperature readings
         /********************************************************************/
         v_current_fahrenheit_0  = v_sensors_0.getTempCByIndex(0)* 1.8 + 32.0;
         v_current_fahrenheit_2  = v_sensors_2.getTempCByIndex(0)* 1.8 + 32.0;
         v_current_fahrenheit_14 = v_sensors_14.getTempCByIndex(0)* 1.8 + 32.0;
         v_current_fahrenheit_13 = v_sensors_13.getTempCByIndex(0)* 1.8 + 32.0;
    
         v_current_fahrenheit_12 = v_dht_12.readTemperature()* 1.8 + 32.0;
         v_current_humidity_12   = v_dht_12.readHumidity();
    
         //
         // Display variable to monitor
         //
         // Serial.print("Temp #1x: ");
         // Serial.println(v_current_fahrenheit_0);
         // Serial.print("Temp #2x: ");
         // Serial.println(v_current_fahrenheit_2);
         // Serial.print("Temp #3x: ");
         // Serial.println(v_current_fahrenheit_14);
         // Serial.print("Temp #4x: ");
         // Serial.println(v_current_fahrenheit_13);
    
         //
         // Temp #1 D3
         //
         if (v_current_fahrenheit_0 == -196) {
            v_lcd.setCursor(8,0);
            v_lcd.print("???");
            Serial.print("Temp #1: ");
            Serial.println(v_current_fahrenheit_0);
            SendToHS(3,v_current_fahrenheit_0);
         }
         else if ((v_current_fahrenheit_0 > 9 && v_current_fahrenheit_0 < 99) &&
                  (v_current_fahrenheit_0 != v_last_fahrenheit_0)) {
            v_lcd.setCursor(8,0);
            v_lcd.print(" ");
            v_lcd.setCursor(9,0);
            v_lcd.print(v_current_fahrenheit_0);
            Serial.print("Temp #1: ");
            Serial.println(v_current_fahrenheit_0);
            SendToHS(3,v_current_fahrenheit_0);
            v_last_fahrenheit_0 = v_current_fahrenheit_0;
         }        
         else if ((v_current_fahrenheit_0 > 99 && v_current_fahrenheit_0 < 195) &&
                  (v_current_fahrenheit_0 != v_last_fahrenheit_0)) {
            v_lcd.setCursor(8,0);
            v_lcd.print(v_current_fahrenheit_0);
            Serial.print("Temp #1: ");
            Serial.println(v_current_fahrenheit_0);
            SendToHS(3,v_current_fahrenheit_0);
            v_last_fahrenheit_0 = v_current_fahrenheit_0;
         }
         else if ((v_current_fahrenheit_0 == 1 && v_current_fahrenheit_0 > 9) &&
                  (v_current_fahrenheit_0 != v_last_fahrenheit_0)) {
            v_lcd.setCursor(8,0);
            v_lcd.print("  ");
            v_lcd.setCursor(10,0);
            v_lcd.print(v_current_fahrenheit_0);
            Serial.print("Temp #1: ");
            Serial.println(v_current_fahrenheit_0);
            SendToHS(3,v_current_fahrenheit_0);
            v_last_fahrenheit_0 = v_current_fahrenheit_0;
         }
         else if ((v_current_fahrenheit_0 < 0 && v_current_fahrenheit_0 > -196) &&
                  (v_current_fahrenheit_0 != v_last_fahrenheit_0)) {
            v_lcd.setCursor(8,0);
            v_lcd.print("  ");
            v_lcd.setCursor(10,0);
            v_lcd.print(v_current_fahrenheit_0);
            Serial.print("Temp #1: ");
            Serial.println(v_current_fahrenheit_0);
            SendToHS(3,v_current_fahrenheit_0);
            v_last_fahrenheit_0 = v_current_fahrenheit_0;
         }
    
         //
         // Temp #2 D4
         //
         if (v_current_fahrenheit_2 == -196) {
            v_lcd.setCursor(8,1);
            v_lcd.print("???");
            Serial.print("Temp #2: ");
            Serial.println(v_current_fahrenheit_2);
            SendToHS(4,v_current_fahrenheit_2);
         }
         else if ((v_current_fahrenheit_2 > 9 && v_current_fahrenheit_2 < 99) &&
                 (v_current_fahrenheit_2 != v_last_fahrenheit_2)) {
            v_lcd.setCursor(8,1);
            v_lcd.print(" ");
            v_lcd.setCursor(9,1);
            v_lcd.print(v_current_fahrenheit_2);
            Serial.print("Temp #2: ");
            Serial.println(v_current_fahrenheit_2);
            SendToHS(4,v_current_fahrenheit_2);
            v_last_fahrenheit_2 = v_current_fahrenheit_2;
         }
         else if ((v_current_fahrenheit_2 > 99 && v_current_fahrenheit_2 < 195) &&
                 (v_current_fahrenheit_2 != v_last_fahrenheit_2)) {
            v_lcd.setCursor(8,1);
            v_lcd.print(v_current_fahrenheit_2);
            Serial.print("Temp #2: ");
            Serial.println(v_current_fahrenheit_2);
            SendToHS(4,v_current_fahrenheit_2);
            v_last_fahrenheit_2 = v_current_fahrenheit_2;
         }
         else if ((v_current_fahrenheit_2 == 1 && v_current_fahrenheit_2 > 9) &&
                    (v_current_fahrenheit_2 != v_last_fahrenheit_2)) {
            v_lcd.setCursor(8,1);
            v_lcd.print("  ");
            v_lcd.setCursor(10,1);
            v_lcd.print(v_current_fahrenheit_2);
            Serial.print("Temp #2: ");
            Serial.println(v_current_fahrenheit_2);
            SendToHS(4,v_current_fahrenheit_2);
            v_last_fahrenheit_2 = v_current_fahrenheit_2;
         }
         else if ((v_current_fahrenheit_2 < 0 && v_current_fahrenheit_2 > -196) &&
                    (v_current_fahrenheit_2 != v_last_fahrenheit_2)) {
            v_lcd.setCursor(8,1);
            v_lcd.print("  ");
            v_lcd.setCursor(10,1);
            v_lcd.print(v_current_fahrenheit_2);
            Serial.print("Temp #2: ");
            Serial.println(v_current_fahrenheit_2);
            SendToHS(4,v_current_fahrenheit_2);
            v_last_fahrenheit_2 = v_current_fahrenheit_2;
         }
    
         //
         // Temp #3 D5
         //
         if (v_current_fahrenheit_14 == -196) {
            v_lcd.setCursor(8,2);
            v_lcd.print("???");
            Serial.print("Temp #3: ");
            Serial.println(v_current_fahrenheit_14);
            SendToHS(5,v_current_fahrenheit_14);
         }
         else if ((v_current_fahrenheit_14 > 9 && v_current_fahrenheit_14 < 99) &&
                 (v_current_fahrenheit_14 != v_last_fahrenheit_14)) {
            v_lcd.setCursor(8,2);
            v_lcd.print(" ");
            v_lcd.setCursor(9,2);
            v_lcd.print(v_current_fahrenheit_14);
            Serial.print("Temp #3: ");
            Serial.println(v_current_fahrenheit_14);
            SendToHS(5,v_current_fahrenheit_14);
            v_last_fahrenheit_14 = v_current_fahrenheit_14;
         }
         else if ((v_current_fahrenheit_14 > 99 && v_current_fahrenheit_14 < 195) &&
                 (v_current_fahrenheit_14 != v_last_fahrenheit_14)) {
            v_lcd.setCursor(8,2);
            v_lcd.print(v_current_fahrenheit_14);
            Serial.print("Temp #3: ");
            Serial.println(v_current_fahrenheit_14);
            SendToHS(5,v_current_fahrenheit_14);
            v_last_fahrenheit_14 = v_current_fahrenheit_14;
         }
         else if ((v_current_fahrenheit_14 == 1 && v_current_fahrenheit_14 > 9) &&
                    (v_current_fahrenheit_14 != v_last_fahrenheit_14)) {
            v_lcd.setCursor(8,2);
            v_lcd.print("  ");
            v_lcd.setCursor(10,2);
            v_lcd.print(v_current_fahrenheit_14);
            Serial.print("Temp #3: ");
            Serial.println(v_current_fahrenheit_14);
            SendToHS(5,v_current_fahrenheit_14);
            v_last_fahrenheit_14 = v_current_fahrenheit_14;
         }
         else if ((v_current_fahrenheit_14 < 0 && v_current_fahrenheit_14 > -196) &&
                    (v_current_fahrenheit_14 != v_last_fahrenheit_14)) {
            v_lcd.setCursor(8,2);
            v_lcd.print("  ");
            v_lcd.setCursor(10,2);
            v_lcd.print(v_current_fahrenheit_14);
            Serial.print("Temp #3: ");
            Serial.println(v_current_fahrenheit_14);
            SendToHS(5,v_current_fahrenheit_14);
            v_last_fahrenheit_14 = v_current_fahrenheit_14;
         }
    
         //
         // Temp #4 D7
         //
         if (v_current_fahrenheit_13 == -196) {
            v_lcd.setCursor(16,2);
            v_lcd.print("???");
            Serial.print("Temp #4: ");
            Serial.println(v_current_fahrenheit_13);
            SendToHS(6,v_current_fahrenheit_13);
         }
         else if ((v_current_fahrenheit_13 > 9 && v_current_fahrenheit_13 < 99) &&
                 (v_current_fahrenheit_13 != v_last_fahrenheit_13)) {
            v_lcd.setCursor(16,2);
            v_lcd.print(" ");
            v_lcd.setCursor(17,2);
            v_lcd.print(v_current_fahrenheit_13);
            Serial.print("Temp #4: ");
            Serial.println(v_current_fahrenheit_13);
            SendToHS(6,v_current_fahrenheit_13);
            v_last_fahrenheit_13 = v_current_fahrenheit_13;
         }
         else if ((v_current_fahrenheit_13 > 99 && v_current_fahrenheit_13 < 195) &&
                 (v_current_fahrenheit_13 != v_last_fahrenheit_13)) {
            v_lcd.setCursor(16,2);
            v_lcd.print(v_current_fahrenheit_13);
            Serial.print("Temp #4: ");
            Serial.println(v_current_fahrenheit_13);
            SendToHS(6,v_current_fahrenheit_13);
            v_last_fahrenheit_13 = v_current_fahrenheit_13;
         }
         else if ((v_current_fahrenheit_13 == 1 && v_current_fahrenheit_13 > 9) &&
                    (v_current_fahrenheit_13 != v_last_fahrenheit_13)) {
            v_lcd.setCursor(16,2);
            v_lcd.print("  ");
            v_lcd.setCursor(18,2);
            v_lcd.print(v_current_fahrenheit_13);
            Serial.print("Temp #4: ");
            Serial.println(v_current_fahrenheit_13);
            SendToHS(6,v_current_fahrenheit_13);
            v_last_fahrenheit_13 = v_current_fahrenheit_13;
         }
         else if ((v_current_fahrenheit_13 < 0 && v_current_fahrenheit_13 > -196) &&
                    (v_current_fahrenheit_13 != v_last_fahrenheit_13)) {
            v_lcd.setCursor(16,2);
            v_lcd.print("  ");
            v_lcd.setCursor(18,2);
            v_lcd.print(v_current_fahrenheit_13);
            Serial.print("Temp #4: ");
            Serial.println(v_current_fahrenheit_13);
            SendToHS(6,v_current_fahrenheit_13);
            v_last_fahrenheit_13 = v_current_fahrenheit_13;
         }
    
         //
         // Temperature D6 - Temp/Humidity Sensor
         //
         if (v_current_fahrenheit_12 == -196) {
            v_lcd.setCursor(8,3);
            v_lcd.print("???");
            Serial.print("Temp #5: ");
            Serial.println(v_current_fahrenheit_12);
            SendToHS(7,v_current_fahrenheit_12);
         }
         else if ((v_current_fahrenheit_12 > 9 && v_current_fahrenheit_12 < 99) &&
                 (v_current_fahrenheit_12 != v_last_fahrenheit_12)) {
            v_lcd.setCursor(8,3);
            v_lcd.print(" ");
            v_lcd.setCursor(9,3);
            v_lcd.print(v_current_fahrenheit_12);
            Serial.print("Temp #5: ");
            Serial.println(v_current_fahrenheit_12);
            SendToHS(7,v_current_fahrenheit_12);
            v_last_fahrenheit_12 = v_current_fahrenheit_12;
         }
         else if ((v_current_fahrenheit_12 > 99 && v_current_fahrenheit_12 < 195) &&
                 (v_current_fahrenheit_12 != v_last_fahrenheit_12)) {
            v_lcd.setCursor(8,3);
            v_lcd.print(v_current_fahrenheit_12);
            Serial.print("Temp #5: ");
            Serial.println(v_current_fahrenheit_12);
            SendToHS(7,v_current_fahrenheit_12);
            v_last_fahrenheit_12 = v_current_fahrenheit_12;
         }
         else if ((v_current_fahrenheit_12 == 1 && v_current_fahrenheit_12 > 9) &&
                    (v_current_fahrenheit_12 != v_last_fahrenheit_12)) {
            v_lcd.setCursor(8,3);
            v_lcd.print("  ");
            v_lcd.setCursor(10,3);
            v_lcd.print(v_current_fahrenheit_12);
            Serial.print("Temp #5: ");
            Serial.println(v_current_fahrenheit_12);
            SendToHS(7,v_current_fahrenheit_12);
            v_last_fahrenheit_12 = v_current_fahrenheit_12;
         }
         else if ((v_current_fahrenheit_12 < 0 && v_current_fahrenheit_12 > -196) &&
                    (v_current_fahrenheit_12 != v_last_fahrenheit_12)) {
            v_lcd.setCursor(8,3);
            v_lcd.print("  ");
            v_lcd.setCursor(10,3);
            v_lcd.print(v_current_fahrenheit_12);
            Serial.print("Temp #5: ");
            Serial.println(v_current_fahrenheit_12);
            SendToHS(7,v_current_fahrenheit_12);
            v_last_fahrenheit_12 = v_current_fahrenheit_12;
         }
    
         //
         // Humidity D6 - Temp/Humidity Sensor
         //
         if (v_current_humidity_12 == -196) {
            v_lcd.setCursor(16,3);
            v_lcd.print("???");
            Serial.print("Humd #5: ");
            Serial.println(v_current_humidity_12);
            SendToHS(8,v_current_humidity_12);
         }
         else if ((v_current_humidity_12 > 9 && v_current_humidity_12 < 99) &&
                 (v_current_humidity_12 != v_last_humidity_12)) {
            v_lcd.setCursor(16,3);
            v_lcd.print(" ");
            v_lcd.setCursor(17,3);
            v_lcd.print(v_current_humidity_12);
            Serial.print("Humd #5: ");
            Serial.println(v_current_humidity_12);
            SendToHS(8,v_current_humidity_12);
            v_last_humidity_12 = v_current_humidity_12;
         }
         else if ((v_current_humidity_12 > 99 && v_current_humidity_12 < 195) &&
                 (v_current_humidity_12 != v_last_humidity_12)) {
            v_lcd.setCursor(16,3);
            v_lcd.print(v_current_humidity_12);
            Serial.print("Humd #5: ");
            Serial.println(v_current_humidity_12);
            SendToHS(8,v_current_humidity_12);
            v_last_humidity_12 = v_current_humidity_12;
         }
         else if ((v_current_humidity_12 == 1 && v_current_humidity_12 > 9) &&
                    (v_current_humidity_12 != v_last_humidity_12)) {
            v_lcd.setCursor(16,3);
            v_lcd.print("  ");
            v_lcd.setCursor(18,3);
            v_lcd.print(v_current_humidity_12);
            Serial.print("Humd #5: ");
            Serial.println(v_current_humidity_12);
            SendToHS(8,v_current_humidity_12);
            v_last_humidity_12 = v_current_humidity_12;
         } else if ((v_current_humidity_12 < 0 && v_current_humidity_12 > -196) &&
                    (v_current_humidity_12 != v_last_humidity_12)) {
            v_lcd.setCursor(16,3);
            v_lcd.print("  ");
            v_lcd.setCursor(18,3);
            v_lcd.print(v_current_humidity_12);
            Serial.print("Humd #5: ");
            Serial.println(v_current_humidity_12);
            SendToHS(8,v_current_humidity_12);
            v_last_humidity_12 = v_current_humidity_12;
         }
        }
      }
    }
    
    //************Do not change anything after Here*****************
    
    #define ISIP 1
    #define BoardType 3
    const byte BoardAdd = 5;
    
    #include <EEPROM.h>
    
    #if BoardType == 3
    #include <ESP8266WiFi.h>
    #include <WiFiUdp.h>
    #include <ESP8266mDNS.h>
    #include <ArduinoOTA.h>
    char ssid[] = "SID";
    char pass[] = "PASSWORD";
    #else
    #include <SPI.h>
    #include <Ethernet.h>
    #include <EthernetUdp.h>
    #endif
    
    
    #if ISIP == 1
    
    
    byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x05};
    IPAddress ip(123,123,123,123);     //IP entered In HS config.
    const unsigned int localPort = 1234;      //port entered In HS config.
    IPAddress HomeseerIP(123,123,123,123); //Homeseer IP address
    IPAddress ServerIP(EEPROM.read(2), EEPROM.read(3), EEPROM.read(4), EEPROM.read(5));
    IPAddress gateway(123,123,123,123);
    IPAddress subnet(255,255,255,0);
    byte EEpromVersion = EEPROM.read(250);
    char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
    const unsigned int ServerPort = 8888;
    #endif
    
    
    
    
    #if BoardType == 3
    WiFiUDP Udp;
    WiFiUDP SendPort;
    #else
    EthernetUDP Udp;
    #endif
    
    #if BoardType == 3
    void resetFunc() {
      ESP.restart();
    }
    #else
    void(* resetFunc) (void) = 0;
    #endif
    
    
    char* Version = "API1.0.0.146";
    
    byte Byte1, Byte2, Byte3;
    unsigned int Byte4, Byte5;
    
    
    void setup() {
    
    #if BoardType == 3
      // WiFi.persistent(false);
      EEPROM.begin(256);
      EEpromVersion = EEPROM.read(250);
    #endif
    
    #if ISIP == 1
      if (EEpromVersion != 22) {
        ServerIP = HomeseerIP;
        EEPROM.write(2, ServerIP[0]);
        EEPROM.write(3, ServerIP[1]);
        EEPROM.write(4, ServerIP[2]);
        EEPROM.write(5, ServerIP[3]);
        EEPROM.write(250, 22); //Store the version where the eeprom data layout was last changed
        EEpromVersion = 22;
      }
    #if BoardType == 3
      //Serial.begin(115200);
      WiFi.begin(ssid, pass);
      WiFi.config(ip, gateway, subnet);
      OTA();
      WiFi.mode(WIFI_STA);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
      }
    #else
      Ethernet.begin(mac, ip, gateway, gateway, subnet);
    #endif
      Udp.begin(localPort);
      Udp.setTimeout(0);
      delay(1000);
      SendConnect();
    #else
      Serial.begin(115200);
      Serial.flush();
      Serial.setTimeout(0);
      delay(1000);
      Serial.print("Connect ");
      Serial.println(BoardAdd);
    #endif=
    
      IsConnected = false;
      HSSetup();
    }
    
    
    void loop() {
    #if BoardType == 3
      ArduinoOTA.handle();
    #endif
      HSloop();
    #if ISIP == 1
      UDPCheck();
    #endif
    }
    
    
    void SendConnect()
    {
    #if ISIP == 0
      Serial.print("Connect ");
      Serial.println(BoardAdd);
    #else
      Udp.beginPacket(HomeseerIP, ServerPort); //First send a connect packet to the dynamic IP stored in eeprom
      Udp.print("Connect ");
      Udp.print(BoardAdd);
      Udp.endPacket();
      if (ServerIP != HomeseerIP) {
        Udp.beginPacket(HomeseerIP, ServerPort); //Then if the stored value doesn't match the pre-specified one, send a connect packet there also
        Udp.print("Connect ");
        Udp.print(BoardAdd);
        Udp.endPacket();
      }
    
    #endif
    }
    
    
    
    #if ISIP == 1
    void UDPCheck() {
      int packetSize = Udp.parsePacket();
      if (packetSize)
      {
    
    #if BoardType == 3
        IPAddress remote = Udp.remoteIP();
        Byte1 = Udp.parseInt();
        Udp.read();
        Byte2 = Udp.read();
        Udp.read();
        Byte3 = Udp.parseInt();
        Udp.read();
        Byte4 = Udp.parseInt();
        Udp.read();
        Byte5 = Udp.parseInt();
        DataEvent();
    #else
    
        ServerIP = Udp.remoteIP();
        Byte1 = Udp.parseInt();
        Udp.read();
        Byte2 = Udp.read();
        Byte3 = Udp.parseInt();;
        Byte4 = Udp.parseInt();
        Byte5 = Udp.parseInt();;
    
        DataEvent();
    #endif
      }
    }
    
    #else
    void serialEvent() {
      while (Serial.available() > 0) {
        delay(17);
    
    
        Byte1 = Serial.parseInt();
        Serial.read();
        Byte2 = Serial.read();
        Byte3 = Serial.parseInt();
        Byte4 = Serial.parseInt();
        Byte5 = Serial.parseInt();
        DataEvent();
      }
    }
    #endif
    
    
    /*
    
      Used Data Input Cases
      D Disconnect
      r reset
      K Keepalive
      O PinMode Output Set
      d Input debounce time set
      C Connect request
      c Connection established - report current status
    */
    void DataEvent() {
    
      if (Byte1 == BoardAdd) {
    
    #if ISIP == 1
        if (Udp.remoteIP() != ServerIP) {
          ServerIP = Udp.remoteIP();
          EEPROM.write(2, ServerIP[0]);
          EEPROM.write(3, ServerIP[1]);
          EEPROM.write(4, ServerIP[2]);
          EEPROM.write(5, ServerIP[3]);
        }
    #endif
    
        switch (Byte2) {
          case 'c':
            IsConnected = true;
            break;
    
          case 'C':
    #if ISIP == 1
            Udp.beginPacket(HomeseerIP, ServerPort);
            Udp.print("Version ");
            Udp.print(BoardAdd);
            Udp.print(" ");
            Udp.print(Version);
            Udp.println(" HS3");
            Udp.endPacket();
    
            Udp.beginPacket(HomeseerIP, ServerPort);
            delay(100);
            Udp.print("Connected ");
            Udp.println(BoardAdd);
            Udp.endPacket();
    #else
            Serial.print("Version ");
            Serial.print(BoardAdd);
            Serial.print(" ");
            Serial.print(Version);
            Serial.println(" HS3");
            delay(100);
            Serial.print("Connected ");
            Serial.println(BoardAdd);
    #endif
            delay(100);
            IsConnected = false;
            break;
    
          case 'K':
            delay(200);
    #if ISIP == 1
            Udp.beginPacket(HomeseerIP, ServerPort);
            Udp.print("Alive ");
            Udp.println(BoardAdd);
            Udp.endPacket();
            if (Udp.remoteIP() != ServerIP) {
              ServerIP = Udp.remoteIP();
              EEPROM.write(2, ServerIP[0]);
              EEPROM.write(3, ServerIP[1]);
              EEPROM.write(4, ServerIP[2]);
              EEPROM.write(5, ServerIP[3]);
            }
    #else
            Serial.print("Alive ");
            Serial.println(BoardAdd);
    #endif
            break;
    
          case 'r':
            delay(200);
            resetFunc();  //call reset
            break;
    
          case 'O':
            FromHS[Byte3] = Byte4;
            break;
    
          case 'D':
            IsConnected = false;
            break;
        }
      }
    }
    
    void SendToHS(byte Device, long Data) {
      if (IsConnected == true) {
    #if ISIP == 1
        Udp.beginPacket(HomeseerIP, ServerPort);
        Udp.print(BoardAdd);
        Udp.print(" API ");
        Udp.print(Device);
        Udp.print(" ");
        Udp.print(Data);
        Udp.endPacket();
    #else
        Serial.print(BoardAdd);
        Serial.print(" API ");
        Serial.print(Device);
        Serial.print(" ");
        Serial.println(Data);
    #endif
      }
    }
    
    void SendToHS(byte Device, int Data) {
      if (IsConnected == true) {
    #if ISIP == 1
        Udp.beginPacket(HomeseerIP, ServerPort);
        Udp.print(BoardAdd);
        Udp.print(" API ");
        Udp.print(Device);
        Udp.print(" ");
        Udp.print(Data);
        Udp.endPacket();
    #else
        Serial.print(BoardAdd);
        Serial.print(" API ");
        Serial.print(Device);
        Serial.print(" ");
        Serial.println(Data);
    #endif
      }
    }
    
    void SendToHS(byte Device, float Data) {
      if (IsConnected == true) {
    #if ISIP == 1
        Udp.beginPacket(HomeseerIP, ServerPort);
        Udp.print(BoardAdd);
        Udp.print(" API ");
        Udp.print(Device);
        Udp.print(" ");
        Udp.print(Data);
        Udp.endPacket();
    #else
        Serial.print(BoardAdd);
        Serial.print(" API ");
        Serial.print(Device);
        Serial.print(" ");
        Serial.println(Data);
    #endif
      }
    }
    
    void SendToHS(byte Device, double Data) {
      if (IsConnected == true) {
    #if ISIP == 1
        Udp.beginPacket(HomeseerIP, ServerPort);
        Udp.print(BoardAdd);
        Udp.print(" API ");
        Udp.print(Device);
        Udp.print(" ");
        Udp.print(Data);
        Udp.endPacket();
    #else
        Serial.print(BoardAdd);
        Serial.print(" API ");
        Serial.print(Device);
        Serial.print(" ");
        Serial.println(Data);
    #endif
      }
    }
    
    //*******************************OTA Update*************************
    void OTA() {
    #if BoardType == 3
      char OTAName[50];
      sprintf(OTAName, "Homeseer API Board:%02i", BoardAdd );
      ArduinoOTA.setHostname(OTAName);
      ArduinoOTA.onStart([]() {
    
      });
      ArduinoOTA.onEnd([]() {
    
      });
      ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    
      });
      ArduinoOTA.onError([](ota_error_t error) {
    
      });
      ArduinoOTA.begin();
    #endif
    }
    I hope this helps, if you need additional information, please let me know.
    Last edited by bdraper; January 21st, 2019, 11:59 AM. Reason: Added additional comments to the project code to help clarify the LCD connections and added a few tags to the post
    Billy Draper

  • #2
    Very cool. Are you using 3.3V for VDD and VPU on the OneWire Devices? If so, are they reliable? I’m getting ready to test some DS18B20 sensors on a NodeMCU for a friend. Are you still using a 4.7K pull-up?
    Randy Prade
    Aurora, CO
    Prades.net

    PHLocation - Pushover - EasyTrigger - UltraECM3 - Ultra1Wire3 - Arduino

    Comment


    • #3
      Originally posted by rprade View Post
      Very cool. Are you using 3.3V for VDD and VPU on the OneWire Devices? If so, are they reliable? I’m getting ready to test some DS18B20 sensors on a NodeMCU for a friend. Are you still using a 4.7K pull-up?
      I am using 10k resistors for the individual DS18B20 temperature sensor runs on the 3.3 volt output. I have experimented with different value resistors on the single temperature sensor runs, these seem to work well in my setup. I bought a kit some time back and it had some in it, thought I would give them a try. Using the 10k resistors on the DS10B20 sensors seem to allow the units to report a little quicker.

      These NodeMCU units work really well, have a small footprint, wireless, reliable, and have lots of potential. If you have not messed with them much before, I believe you will be pleased.

      Thanks
      Billy Draper

      Comment


      • #4
        Bdraper,
        I like it. I especially like the led screen. I use the NodeMCU units as well, but with AM2303 sensors and a barometric sensor. I use one with the sensor and also LEDs to let me know if the hot water recirculate pump is on, or doors are unlocked. I have used the one-wire sensors similar to what you have done, but connected to a raspberry pi and use MQTT protocol to get the data into Homeseer. I haven't attached the one-wire sensors to a NodeMCU before.
        Here are a couple of pictures of my setup:
        The button turns on and off the hot water recirculation pump with mqtt as well.
        Click image for larger version  Name:	esp-sensor-front.jpg Views:	1 Size:	89.4 KB ID:	1275768Click image for larger version  Name:	esp-sensor-inside.jpg Views:	1 Size:	131.6 KB ID:	1275769

        My furnace and Hot water heater one-wire sensors:
        Click image for larger version  Name:	furnaceplot4.png Views:	2 Size:	26.6 KB ID:	1275774
        Click image for larger version  Name:	Furnace-output.jpg Views:	1 Size:	128.3 KB ID:	1275770
        The raspberrypi:
        Click image for larger version  Name:	rasp-pi-connections.jpg Views:	1 Size:	99.3 KB ID:	1275771Click image for larger version  Name:	one-wire-resistor.jpg Views:	1 Size:	133.2 KB ID:	1275772

        Always more to do as well,

        Bruce
        Attached Files

        Comment


        • #5
          Here is the barometric pressure plot from a NodeMCU with MQTT:
          Click image for larger version

Name:	barometricplot5.png
Views:	84
Size:	23.3 KB
ID:	1275776
          Click image for larger version

Name:	atticplot.png
Views:	83
Size:	24.3 KB
ID:	1275777

          Here are the Homeseer devices:

          Click image for larger version

Name:	Screenshot_2019-01-13 HomeSeer Web Control.png
Views:	79
Size:	33.2 KB
ID:	1275779

          Click image for larger version

Name:	Screenshot_2019-01-13 HomeSeer Web Control(1).png
Views:	78
Size:	171.5 KB
ID:	1275780 I can't get the degree symbol to show up in the Homeseer Status field for this device. ???
          Bruce
          Attached Files

          Comment


          • #6
            Originally posted by bdraper View Post

            I am using 10k resistors for the individual DS18B20 temperature sensor runs on the 3.3 volt output. I have experimented with different value resistors on the single temperature sensor runs, these seem to work well in my setup. I bought a kit some time back and it had some in it, thought I would give them a try. Using the 10k resistors on the DS10B20 sensors seem to allow the units to report a little quicker.

            These NodeMCU units work really well, have a small footprint, wireless, reliable, and have lots of potential. If you have not messed with them much before, I believe you will be pleased.

            Thanks
            I am using 4 of them already for LCD displays. I used some little stands I picked up on eBay. I'm testing the new version of Greig's plugin with OneWire and Analog support, so I am going to add a DS18B20 to each. About an hour ago I connected one with a 4.7K and using 3.3V. It is working very well. Tomorrow I may try adding a couple more to the single pin, just for grins.



            I posted about them in 2017 here

            The data is still about the same for the two general displays, I also have one specific to the heating system and another specific to energy.

            Time, outside temp, humidity
            Occupancy schedule, hot water temperature and the + means it is currently heating
            Total energy today and current energy
            Sunrise, sunset and moon percentage

            Click image for larger version  Name:	Capture.PNG Views:	1 Size:	47.0 KB ID:	1275832
            Randy Prade
            Aurora, CO
            Prades.net

            PHLocation - Pushover - EasyTrigger - UltraECM3 - Ultra1Wire3 - Arduino

            Comment


            • #7
              Thanks to all for sharing your setups. I've been wanting to get some temperature readings into Homeseer. This thread pushed me into action - I've ordered a few parts so I can give it a try...

              Mike

              Comment


              • #8
                Thanks Billy (bdraper) for sharing and taking the time to detail your setup. Being an Arduino noob, I cut down your code to just the DHT22 sections and have mine up and reporting temp and Humidity. Can I ask which DHT library you used? That took me the longest to figure out which to install as there are a number of options. I used Seed Studios

                Based on this thread, what attracted me to HS3 instead of other HA software was it flexibility and customization capabilities. What is challenging with HS3 is the flexibility. Just for getting temperature, there is so many ways, its mind boggling. Now I'm going to look at MQTT as that opens up even more possibilities :-)

                Graham

                Comment


                • #9
                  Originally posted by Horse View Post
                  Thanks Billy (bdraper) for sharing and taking the time to detail your setup. Being an Arduino noob, I cut down your code to just the DHT22 sections and have mine up and reporting temp and Humidity. Can I ask which DHT library you used? That took me the longest to figure out which to install as there are a number of options. I used Seed Studios

                  Based on this thread, what attracted me to HS3 instead of other HA software was it flexibility and customization capabilities. What is challenging with HS3 is the flexibility. Just for getting temperature, there is so many ways, its mind boggling. Now I'm going to look at MQTT as that opens up even more possibilities :-)

                  Graham
                  About to go down the MQTT rabbit hole as well... and start playing with this Arduino plugin ordered my first nodemcu over the weekend. I my make an old school physical control panel with buttons switches and LED

                  Comment


                  • #10
                    Originally posted by Horse View Post
                    Thanks Billy (bdraper) for sharing and taking the time to detail your setup. Being an Arduino noob, I cut down your code to just the DHT22 sections and have mine up and reporting temp and Humidity. Can I ask which DHT library you used? That took me the longest to figure out which to install as there are a number of options. I used Seed Studios

                    Based on this thread, what attracted me to HS3 instead of other HA software was it flexibility and customization capabilities. What is challenging with HS3 is the flexibility. Just for getting temperature, there is so many ways, its mind boggling. Now I'm going to look at MQTT as that opens up even more possibilities :-)

                    Graham
                    Sorry, I never even thought about posting any of the libraries... thanks for asking. I will try to update the post this weekend...

                    This is the DHT Library that i have installed.
                    Click image for larger version

Name:	Library.jpg
Views:	79
Size:	25.7 KB
ID:	1276144

                    Let me know if you need anything else.

                    Thanks
                    Billy Draper

                    Comment


                    • #11
                      bdrapper,

                      Thanks for posting this. Could you possibly point me to the LiquidCrystal_I2C library you used? I'm having trouble finding one that works.

                      Thanks in advance,
                      steve

                      Comment


                      • #12
                        Originally posted by RTFMplease View Post
                        bdrapper,

                        Thanks for posting this. Could you possibly point me to the LiquidCrystal_I2C library you used? I'm having trouble finding one that works.

                        Thanks in advance,
                        steve
                        Sure, no problem. I was going to update the original post but ran into the limit no more than 6 pictures per post.

                        Used Arduino IDE version 1.8.1

                        See this link for the NewLiquidCrystal library used in the project https://bitbucket.org/fmalpartida/ne...stal/wiki/Home

                        These are the libraries and version used in the sketch.

                        Click image for larger version  Name:	nodemcu_temp_hum_lcd_project.png Views:	1 Size:	41.0 KB ID:	1278220

                        Hope this helps, let me know if you have any other questions.
                        Billy Draper

                        Comment


                        • #13
                          This is a graph that is produced using the data from some of the sensors over the last 7 days. I use the Database Graphing Utility by jon00

                          Click image for larger version

Name:	chart014.png
Views:	80
Size:	141.4 KB
ID:	1278223 ​​​​​​​

                          See this link for more info on the Database Graphing Utility, https://forums.homeseer.com/forum/3r...for-homeseer-3
                          Billy Draper

                          Comment


                          • #14
                            Wow, this looks awesome! Thank you for the inspiration and the code!
                            HSPro 3.0.0.458, Z-NET with Z-wave plugin 3.0.1.190, RFXCOM + 2x RFXtrx433E, HSTouch, Squeezebox plugin, iTach IP/WF2IR & GC-100-6 with UltraGCIR, BLDenon, NetcamStudio, Jon00s Webpage builder, Harmony Hub plugin, SCSIP (with FreePBX), Arduino plugin, IFTTT, Pushalot plugin, Device History plugin.
                            Running on Windows 10 (64) virtualized
                            on ESXi (Fujitsu Primergy TX150 S8).
                            WinSeer (for Win10) - TextSeer - FitbitSeer - HSPI_MoskusSample

                            Are you Norwegian (or Scandinavian) and getting started with HomeSeer? Read the "HomeSeer School"!

                            Comment


                            • #15
                              Originally posted by Moskus View Post
                              Wow, this looks awesome! Thank you for the inspiration and the code!
                              Thanks Moskus
                              Billy Draper

                              Comment

                              Working...
                              X