Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Troubleshooting
  3. Help with pool solar controller code

Help with pool solar controller code

Scheduled Pinned Locked Moved Troubleshooting
14 Posts 3 Posters 127 Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    JCH
    wrote on last edited by
    #1

    I am trying to create a pool solar controller and have run into a couple of issues which i cannot figure out as im not a very good coder :grinning:

    I am going to have a ds18b20 waterproof temp sensor in the pool pump shed which is taped to the pool pipe to reflect the pool temp.
    This node is also going to have a lcd screen which displays the pool temp and well as the roof solar temp.
    I am going to have a 2nd node on the roof measuring the roof water temp and that node is going to send its data back to the controller and also direct to the node (not sure if this is the best way or not) so that it can be displayed on the lcd screen.
    The roof node is powered by solar and reports every 30 seconds and then goes back to sleep.

    Here is the code for the roof sensor

    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * DESCRIPTION
     *
     * Example sketch showing how to send in DS1820B OneWire temperature readings back to the controller
     * http://www.mysensors.org/build/temp
     */
    
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    // Enable and select radio type attached
    #define MY_RADIO_RF24
    #define MY_RF24_PA_LEVEL RF24_PA_LOW
    #define MY_NODE_ID 1
    
    #include <MySensors.h>  
    #include <DallasTemperature.h>
    #include <OneWire.h>
    
    #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No
    
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
    int oldBatteryPcnt = 0;
    
    #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected 
    #define MAX_ATTACHED_DS18B20 16
    unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
    OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
    DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
    float lastTemperature[MAX_ATTACHED_DS18B20];
    int numSensors=0;
    bool receivedConfig = false;
    bool metric = true;
    // Initialize temperature message
    MyMessage msg(0,V_TEMP);
    
    void before()
    {
      // Startup up the OneWire library
      sensors.begin();
    }
    
    void setup()  
    
    {
       
     // use the 1.1 V internal reference for battery mointor
    #if defined(__AVR_ATmega2560__)
      analogReference(INTERNAL1V1);
    #else
      analogReference(INTERNAL);
    #endif
    
      // requestTemperatures() will not block current thread
      sensors.setWaitForConversion(false);
    }
    
    void presentation() {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Roof Temperature Sensor", "1.0");
    
      // Fetch the number of attached temperature sensors  
      numSensors = sensors.getDeviceCount();
    
      // Present all sensors to controller
      for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
         present(i, S_TEMP);
      }
    }
    
    void loop()     
    {
      
    //////////////////////////////////////////////
    ///////////  BATTERY CODE  ///////////////////  
    /////////////////////////////////////////////
    
      // get the battery Voltage
      int sensorValue = analogRead(BATTERY_SENSE_PIN);
    #ifdef MY_DEBUG
      Serial.println(sensorValue);
    #endif
    
      // 1M, 470K divider across battery and using internal ADC ref of 1.1V
      // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
      // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
      // 3.44/1023 = Volts per bit = 0.003363075
    
      int batteryPcnt = sensorValue / 10;
    
    #ifdef MY_DEBUG
      float batteryV  = sensorValue * 0.003363075;
      Serial.print("Battery Voltage: ");
      Serial.print(batteryV);
      Serial.println(" V");
    
      Serial.print("Battery percent: ");
      Serial.print(batteryPcnt);
      Serial.println(" %");
    #endif
    
      if (oldBatteryPcnt != batteryPcnt) {
        // Power up radio after sleep
        sendBatteryLevel(batteryPcnt);
        oldBatteryPcnt = batteryPcnt;
      }
           
    //////////////////////////////////////////////
    ///////////  DALLAS CODE  ///////////////////  
    /////////////////////////////////////////////
    
      // Fetch temperatures from Dallas sensors
      sensors.requestTemperatures();
    
      // query conversion time and sleep until conversion completed
      int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
      // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
      sleep(conversionTime);
    
      // Read temperatures and send them to controller 
      for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
    
        // Fetch and round temperature to one decimal
        float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
    
        // Only send data if temperature has changed and no error
        #if COMPARE_TEMP == 1
        if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
        #else
        if (temperature != -127.00 && temperature != 85.00) {
        #endif
    
          // Send in the new temperature
          send(msg.setSensor(i).set(temperature,1));
          send(msg.setDestination(2).setSensor(1).set(temperature, 1)); // send the temp to Node 2(Pool temp)
          // Save new temperatures for next compare
          lastTemperature[i]=temperature;
        }
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////    
      }
      sleep(SLEEP_TIME);
    }
    

    And here is the code for the pool controller so far.....

    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * DESCRIPTION
     *
     * Example sketch showing how to send in DS1820B OneWire temperature readings back to the controller
     * http://www.mysensors.org/build/temp
     */
    
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    // Enable and select radio type attached
    #define MY_RADIO_RF24
    #define MY_RF24_PA_LEVEL RF24_PA_HIGH
    #define MY_NODE_ID 2
    //#define MY_RADIO_RFM69
    
    #include <MySensors.h>  
    #include <DallasTemperature.h>
    #include <OneWire.h>
    #include <LiquidCrystal_I2C.h>
    
    LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
    
    #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No
    
    #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected 
    #define MAX_ATTACHED_DS18B20 16
    unsigned long SLEEP_TIME = 3000; // Sleep time between reads (in milliseconds)
    OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
    DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
    float lastTemperature[MAX_ATTACHED_DS18B20];
    int numSensors=0;
    bool receivedConfig = false;
    bool metric = true;
    // Initialize temperature message
    MyMessage msg(1,V_TEMP);
    
    void before()
    {
      // Startup up the OneWire library
      sensors.begin();
    }
    
    void setup()  
    { 
      // requestTemperatures() will not block current thread
      sensors.setWaitForConversion(false);
    
        lcd.begin(16, 2);                   // LCD 2 lines * 16 char.
        lcd.setBacklight(HIGH);
        lcd.setCursor(0, 0);
        lcd.setCursor(0, 0);
        lcd.print("Waiting for temperature updates");
        wait(10000);
    }
    
    void presentation() {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Temperature Sensor", "1.1");
    
      // Fetch the number of attached temperature sensors  
      numSensors = sensors.getDeviceCount();
    
      // Present all sensors to controller
      for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
         present(i, S_TEMP);
      }
    }
    
    void loop()     
    { 
          
    //request(1, V_TEMP);  // NO NEED TO REQUEST AS IT IS BEING SENT
    
     }
    
    
    void receive(const MyMessage &message) {
    
        
     if (message.type==V_TEMP) {
       if (message.sensor <= 1) {
    
       
        // Write some debug info
        Serial.print("Incoming change from roof sensor:");
        Serial.print(message.sensor);
        Serial.print("\n");
        Serial.print(", New status: ");
        Serial.println(message.getFloat());
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Roof Temp:");
        lcd.print(" ");
        lcd.print(message.getFloat());
       }
    
       
      // Fetch temperatures from Dallas sensors
      sensors.requestTemperatures();
    
      // query conversion time and sleep until conversion completed
      int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
      // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
      sleep(conversionTime);
    
      // Read temperatures and send them to controller 
      for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
    
        // Fetch and round temperature to one decimal
        float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
    
        // Only send data if temperature has changed and no error
        #if COMPARE_TEMP == 1
        if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
        #else
        if (temperature != -127.00 && temperature != 85.00) {
        #endif
    
          // Send in the new temperature
          send(msg.setSensor(i).set(temperature,1));
          // Save new temperatures for next compare
          lastTemperature[i]=temperature;
    
           lcd.setCursor(0, 1);
           lcd.print("Pool Temp:");
           lcd.print(" ");
           lcd.print(temperature);
    
        }
     }
    
      }
    //  wait(SLEEP_TIME);
      }
      
    

    Now the problem i am having is as the pool node doesn't sleep it basically just waits to receive a message from the pool controller and once it does it reports both sensors and then goes back to start again.... so if the roof node goes down for whatever reason then the whole thing stops working.
    What is the best way around this?

    Also i wasnt getting alot of the messages and figured ouit from the logs that it was bcasue it was being repeated by the gateway... so to get around that i changed

    if (message.sensor == 1)
    

    to

    if (message.sensor <= 1)
    

    to include the gateway ( 0 )

    again i am not sure if thats the best way forward?
    I really am only a weekend hobbyist so not too sure that i am going about this the right way

    BearWithBeardB 1 Reply Last reply
    0
    • J JCH

      I am trying to create a pool solar controller and have run into a couple of issues which i cannot figure out as im not a very good coder :grinning:

      I am going to have a ds18b20 waterproof temp sensor in the pool pump shed which is taped to the pool pipe to reflect the pool temp.
      This node is also going to have a lcd screen which displays the pool temp and well as the roof solar temp.
      I am going to have a 2nd node on the roof measuring the roof water temp and that node is going to send its data back to the controller and also direct to the node (not sure if this is the best way or not) so that it can be displayed on the lcd screen.
      The roof node is powered by solar and reports every 30 seconds and then goes back to sleep.

      Here is the code for the roof sensor

      /**
       * The MySensors Arduino library handles the wireless radio link and protocol
       * between your home built sensors/actuators and HA controller of choice.
       * The sensors forms a self healing radio network with optional repeaters. Each
       * repeater and gateway builds a routing tables in EEPROM which keeps track of the
       * network topology allowing messages to be routed to nodes.
       *
       * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
       * Copyright (C) 2013-2015 Sensnology AB
       * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
       *
       * Documentation: http://www.mysensors.org
       * Support Forum: http://forum.mysensors.org
       *
       * This program is free software; you can redistribute it and/or
       * modify it under the terms of the GNU General Public License
       * version 2 as published by the Free Software Foundation.
       *
       *******************************
       *
       * DESCRIPTION
       *
       * Example sketch showing how to send in DS1820B OneWire temperature readings back to the controller
       * http://www.mysensors.org/build/temp
       */
      
      
      // Enable debug prints to serial monitor
      #define MY_DEBUG 
      
      // Enable and select radio type attached
      #define MY_RADIO_RF24
      #define MY_RF24_PA_LEVEL RF24_PA_LOW
      #define MY_NODE_ID 1
      
      #include <MySensors.h>  
      #include <DallasTemperature.h>
      #include <OneWire.h>
      
      #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No
      
      int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
      int oldBatteryPcnt = 0;
      
      #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected 
      #define MAX_ATTACHED_DS18B20 16
      unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
      OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
      DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
      float lastTemperature[MAX_ATTACHED_DS18B20];
      int numSensors=0;
      bool receivedConfig = false;
      bool metric = true;
      // Initialize temperature message
      MyMessage msg(0,V_TEMP);
      
      void before()
      {
        // Startup up the OneWire library
        sensors.begin();
      }
      
      void setup()  
      
      {
         
       // use the 1.1 V internal reference for battery mointor
      #if defined(__AVR_ATmega2560__)
        analogReference(INTERNAL1V1);
      #else
        analogReference(INTERNAL);
      #endif
      
        // requestTemperatures() will not block current thread
        sensors.setWaitForConversion(false);
      }
      
      void presentation() {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Roof Temperature Sensor", "1.0");
      
        // Fetch the number of attached temperature sensors  
        numSensors = sensors.getDeviceCount();
      
        // Present all sensors to controller
        for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
           present(i, S_TEMP);
        }
      }
      
      void loop()     
      {
        
      //////////////////////////////////////////////
      ///////////  BATTERY CODE  ///////////////////  
      /////////////////////////////////////////////
      
        // get the battery Voltage
        int sensorValue = analogRead(BATTERY_SENSE_PIN);
      #ifdef MY_DEBUG
        Serial.println(sensorValue);
      #endif
      
        // 1M, 470K divider across battery and using internal ADC ref of 1.1V
        // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
        // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
        // 3.44/1023 = Volts per bit = 0.003363075
      
        int batteryPcnt = sensorValue / 10;
      
      #ifdef MY_DEBUG
        float batteryV  = sensorValue * 0.003363075;
        Serial.print("Battery Voltage: ");
        Serial.print(batteryV);
        Serial.println(" V");
      
        Serial.print("Battery percent: ");
        Serial.print(batteryPcnt);
        Serial.println(" %");
      #endif
      
        if (oldBatteryPcnt != batteryPcnt) {
          // Power up radio after sleep
          sendBatteryLevel(batteryPcnt);
          oldBatteryPcnt = batteryPcnt;
        }
             
      //////////////////////////////////////////////
      ///////////  DALLAS CODE  ///////////////////  
      /////////////////////////////////////////////
      
        // Fetch temperatures from Dallas sensors
        sensors.requestTemperatures();
      
        // query conversion time and sleep until conversion completed
        int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
        // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
        sleep(conversionTime);
      
        // Read temperatures and send them to controller 
        for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
      
          // Fetch and round temperature to one decimal
          float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
      
          // Only send data if temperature has changed and no error
          #if COMPARE_TEMP == 1
          if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
          #else
          if (temperature != -127.00 && temperature != 85.00) {
          #endif
      
            // Send in the new temperature
            send(msg.setSensor(i).set(temperature,1));
            send(msg.setDestination(2).setSensor(1).set(temperature, 1)); // send the temp to Node 2(Pool temp)
            // Save new temperatures for next compare
            lastTemperature[i]=temperature;
          }
      
      ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////    
        }
        sleep(SLEEP_TIME);
      }
      

      And here is the code for the pool controller so far.....

      /**
       * The MySensors Arduino library handles the wireless radio link and protocol
       * between your home built sensors/actuators and HA controller of choice.
       * The sensors forms a self healing radio network with optional repeaters. Each
       * repeater and gateway builds a routing tables in EEPROM which keeps track of the
       * network topology allowing messages to be routed to nodes.
       *
       * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
       * Copyright (C) 2013-2015 Sensnology AB
       * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
       *
       * Documentation: http://www.mysensors.org
       * Support Forum: http://forum.mysensors.org
       *
       * This program is free software; you can redistribute it and/or
       * modify it under the terms of the GNU General Public License
       * version 2 as published by the Free Software Foundation.
       *
       *******************************
       *
       * DESCRIPTION
       *
       * Example sketch showing how to send in DS1820B OneWire temperature readings back to the controller
       * http://www.mysensors.org/build/temp
       */
      
      
      // Enable debug prints to serial monitor
      #define MY_DEBUG 
      
      // Enable and select radio type attached
      #define MY_RADIO_RF24
      #define MY_RF24_PA_LEVEL RF24_PA_HIGH
      #define MY_NODE_ID 2
      //#define MY_RADIO_RFM69
      
      #include <MySensors.h>  
      #include <DallasTemperature.h>
      #include <OneWire.h>
      #include <LiquidCrystal_I2C.h>
      
      LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
      
      #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No
      
      #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected 
      #define MAX_ATTACHED_DS18B20 16
      unsigned long SLEEP_TIME = 3000; // Sleep time between reads (in milliseconds)
      OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
      DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
      float lastTemperature[MAX_ATTACHED_DS18B20];
      int numSensors=0;
      bool receivedConfig = false;
      bool metric = true;
      // Initialize temperature message
      MyMessage msg(1,V_TEMP);
      
      void before()
      {
        // Startup up the OneWire library
        sensors.begin();
      }
      
      void setup()  
      { 
        // requestTemperatures() will not block current thread
        sensors.setWaitForConversion(false);
      
          lcd.begin(16, 2);                   // LCD 2 lines * 16 char.
          lcd.setBacklight(HIGH);
          lcd.setCursor(0, 0);
          lcd.setCursor(0, 0);
          lcd.print("Waiting for temperature updates");
          wait(10000);
      }
      
      void presentation() {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Temperature Sensor", "1.1");
      
        // Fetch the number of attached temperature sensors  
        numSensors = sensors.getDeviceCount();
      
        // Present all sensors to controller
        for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
           present(i, S_TEMP);
        }
      }
      
      void loop()     
      { 
            
      //request(1, V_TEMP);  // NO NEED TO REQUEST AS IT IS BEING SENT
      
       }
      
      
      void receive(const MyMessage &message) {
      
          
       if (message.type==V_TEMP) {
         if (message.sensor <= 1) {
      
         
          // Write some debug info
          Serial.print("Incoming change from roof sensor:");
          Serial.print(message.sensor);
          Serial.print("\n");
          Serial.print(", New status: ");
          Serial.println(message.getFloat());
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Roof Temp:");
          lcd.print(" ");
          lcd.print(message.getFloat());
         }
      
         
        // Fetch temperatures from Dallas sensors
        sensors.requestTemperatures();
      
        // query conversion time and sleep until conversion completed
        int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
        // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
        sleep(conversionTime);
      
        // Read temperatures and send them to controller 
        for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
      
          // Fetch and round temperature to one decimal
          float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
      
          // Only send data if temperature has changed and no error
          #if COMPARE_TEMP == 1
          if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
          #else
          if (temperature != -127.00 && temperature != 85.00) {
          #endif
      
            // Send in the new temperature
            send(msg.setSensor(i).set(temperature,1));
            // Save new temperatures for next compare
            lastTemperature[i]=temperature;
      
             lcd.setCursor(0, 1);
             lcd.print("Pool Temp:");
             lcd.print(" ");
             lcd.print(temperature);
      
          }
       }
      
        }
      //  wait(SLEEP_TIME);
        }
        
      

      Now the problem i am having is as the pool node doesn't sleep it basically just waits to receive a message from the pool controller and once it does it reports both sensors and then goes back to start again.... so if the roof node goes down for whatever reason then the whole thing stops working.
      What is the best way around this?

      Also i wasnt getting alot of the messages and figured ouit from the logs that it was bcasue it was being repeated by the gateway... so to get around that i changed

      if (message.sensor == 1)
      

      to

      if (message.sensor <= 1)
      

      to include the gateway ( 0 )

      again i am not sure if thats the best way forward?
      I really am only a weekend hobbyist so not too sure that i am going about this the right way

      BearWithBeardB Offline
      BearWithBeardB Offline
      BearWithBeard
      wrote on last edited by BearWithBeard
      #2

      Hi @JCH

      Have a look at the code of your pool node. You are hiding all your temperature measurement and LCD display logic inside the if (message.type==V_TEMP) condition. So if no message is received, this node will do nothing but continue to listen.

      Besides that - please prove me wrong - I think it is a bad idea to process so much code inside receive() and especially to send out messages from there. This can cause all sorts of weird stuff including recursive loops. You also shouldn't use sleep() on nodes which are supposed to listen to incoming messages. Use the non-blocking wait() instead if you have to.

      I would suggest to move all the code which is related to the temperature sensor and the LCD display into the main loop(), fetch the temperature, send it and update the LCD on fixed intervals.

      In your receive() function, listen for the incoming message only. If you receive a new temperature value, store it in a global variable (for simplicity) like roofTemp which you can access in the loop(). That's all you need to do here.

      You could also set a boolean flag like receivedMessage to true in receive() when a new messages comes in if you want to update the LCD immidiately. But in general, keep it short.

      Also i wasnt getting alot of the messages

      Could be caused by putting the node to sleep aswell. The MCU will propably need less than a second to process all the instructions in your sketch. If you put the node to sleep, it will be in a state where it can't process incoming messages most of the time.

      J 1 Reply Last reply
      1
      • BearWithBeardB BearWithBeard

        Hi @JCH

        Have a look at the code of your pool node. You are hiding all your temperature measurement and LCD display logic inside the if (message.type==V_TEMP) condition. So if no message is received, this node will do nothing but continue to listen.

        Besides that - please prove me wrong - I think it is a bad idea to process so much code inside receive() and especially to send out messages from there. This can cause all sorts of weird stuff including recursive loops. You also shouldn't use sleep() on nodes which are supposed to listen to incoming messages. Use the non-blocking wait() instead if you have to.

        I would suggest to move all the code which is related to the temperature sensor and the LCD display into the main loop(), fetch the temperature, send it and update the LCD on fixed intervals.

        In your receive() function, listen for the incoming message only. If you receive a new temperature value, store it in a global variable (for simplicity) like roofTemp which you can access in the loop(). That's all you need to do here.

        You could also set a boolean flag like receivedMessage to true in receive() when a new messages comes in if you want to update the LCD immidiately. But in general, keep it short.

        Also i wasnt getting alot of the messages

        Could be caused by putting the node to sleep aswell. The MCU will propably need less than a second to process all the instructions in your sketch. If you put the node to sleep, it will be in a state where it can't process incoming messages most of the time.

        J Offline
        J Offline
        JCH
        wrote on last edited by JCH
        #3

        Thanks @BearWithBeard

        Ok how does this look.......

        /**
         * The MySensors Arduino library handles the wireless radio link and protocol
         * between your home built sensors/actuators and HA controller of choice.
         * The sensors forms a self healing radio network with optional repeaters. Each
         * repeater and gateway builds a routing tables in EEPROM which keeps track of the
         * network topology allowing messages to be routed to nodes.
         *
         * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
         * Copyright (C) 2013-2015 Sensnology AB
         * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
         *
         * Documentation: http://www.mysensors.org
         * Support Forum: http://forum.mysensors.org
         *
         * This program is free software; you can redistribute it and/or
         * modify it under the terms of the GNU General Public License
         * version 2 as published by the Free Software Foundation.
         *
         *******************************
         *
         * DESCRIPTION
         *
         * Example sketch showing how to send in DS1820B OneWire temperature readings back to the controller
         * http://www.mysensors.org/build/temp
         */
        
        
        // Enable debug prints to serial monitor
        #define MY_DEBUG 
        
        // Enable and select radio type attached
        #define MY_RADIO_RF24
        #define MY_RF24_PA_LEVEL RF24_PA_HIGH
        #define MY_NODE_ID 2
        //#define MY_RADIO_RFM69
        
        
        #include <MySensors.h>  
        #include <DallasTemperature.h>
        #include <OneWire.h>
        #include <LiquidCrystal_I2C.h>
        
        LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
        
        #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No
        
        #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected 
        #define MAX_ATTACHED_DS18B20 16
        unsigned long SLEEP_TIME = 3000; // Sleep time between reads (in milliseconds)
        OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
        DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
        float lastTemperature[MAX_ATTACHED_DS18B20];
        int numSensors=0;
        int roofTemp;
        bool receivedConfig = false;
        bool metric = true;
        
         
        // Initialize temperature message
        MyMessage msg(1,V_TEMP);
        
        void before()
        {
          // Startup up the OneWire library
          sensors.begin();
        }
        
        void setup()  
        { 
          // requestTemperatures() will not block current thread
          sensors.setWaitForConversion(false);
        
            lcd.begin(16, 2);                   // LCD 2 lines * 16 char.
            lcd.setBacklight(HIGH);
            lcd.setCursor(0, 0);
            lcd.setCursor(0, 0);
            lcd.print("Waiting for temperature updates");
            wait(10000);
        }
        
        void presentation() {
          // Send the sketch version information to the gateway and Controller
          sendSketchInfo("Temperature Sensor", "1.1");
        
          // Fetch the number of attached temperature sensors  
          numSensors = sensors.getDeviceCount();
        
          // Present all sensors to controller
          for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
             present(i, S_TEMP);
          }
        }
        
        void loop()     
        { 
          
        ///////////////////////////////////////////////////////////////////////////////////////       
        //////////////////////////////  MAIN LOOP  ////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////
        
         // Fetch temperatures from Dallas sensors
          sensors.requestTemperatures();
          
          // query conversion time and sleep until conversion completed
          int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
          // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
          wait(conversionTime);
        
          // Read temperatures and send them to controller 
          for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
        
            // Fetch and round temperature to one decimal
            float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
        
            // Only send data if temperature has changed and no error
            #if COMPARE_TEMP == 1
            if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
            #else
            if (temperature != -127.00 && temperature != 85.00) {
            #endif
        
              // Send in the new temperature
              send(msg.setSensor(i).set(temperature,1));
              // Save new temperatures for next compare
              lastTemperature[i]=temperature;
              
               lcd.clear();
               lcd.setCursor(0, 1);
               lcd.print("Pool Temp:");
               lcd.print(" ");
               lcd.print(temperature);
        
        
               lcd.setCursor(0, 0);
               lcd.print("Roof Temp:");
               lcd.print(" ");
               lcd.print(roofTemp);
        
                           }
                   }
          }
          
        ///////////////////////////////////////////////////////////////////////////////////////////////       
        //////////////////////////////  RECIEVE ROOF TEMP  ////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////
        
        void receive(const MyMessage &message) {
        
        
         
         if (message.type==V_TEMP) {
           if (message.sensor <= 1) {
        
           
            // Write some debug info
            Serial.print("Incoming change from roof sensor:");
            Serial.print(message.sensor);
            Serial.print("\n");
            Serial.print(", New status: ");
            Serial.println(message.getFloat());
        
         roofTemp = (message.getFloat());
            }
          }
        } 
         
        
        

        One more question i need help with......
        On the roof sensor , do i send the nodes different msg. or the same?

        skywatchS 1 Reply Last reply
        0
        • J JCH

          Thanks @BearWithBeard

          Ok how does this look.......

          /**
           * The MySensors Arduino library handles the wireless radio link and protocol
           * between your home built sensors/actuators and HA controller of choice.
           * The sensors forms a self healing radio network with optional repeaters. Each
           * repeater and gateway builds a routing tables in EEPROM which keeps track of the
           * network topology allowing messages to be routed to nodes.
           *
           * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
           * Copyright (C) 2013-2015 Sensnology AB
           * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
           *
           * Documentation: http://www.mysensors.org
           * Support Forum: http://forum.mysensors.org
           *
           * This program is free software; you can redistribute it and/or
           * modify it under the terms of the GNU General Public License
           * version 2 as published by the Free Software Foundation.
           *
           *******************************
           *
           * DESCRIPTION
           *
           * Example sketch showing how to send in DS1820B OneWire temperature readings back to the controller
           * http://www.mysensors.org/build/temp
           */
          
          
          // Enable debug prints to serial monitor
          #define MY_DEBUG 
          
          // Enable and select radio type attached
          #define MY_RADIO_RF24
          #define MY_RF24_PA_LEVEL RF24_PA_HIGH
          #define MY_NODE_ID 2
          //#define MY_RADIO_RFM69
          
          
          #include <MySensors.h>  
          #include <DallasTemperature.h>
          #include <OneWire.h>
          #include <LiquidCrystal_I2C.h>
          
          LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
          
          #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No
          
          #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected 
          #define MAX_ATTACHED_DS18B20 16
          unsigned long SLEEP_TIME = 3000; // Sleep time between reads (in milliseconds)
          OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
          DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
          float lastTemperature[MAX_ATTACHED_DS18B20];
          int numSensors=0;
          int roofTemp;
          bool receivedConfig = false;
          bool metric = true;
          
           
          // Initialize temperature message
          MyMessage msg(1,V_TEMP);
          
          void before()
          {
            // Startup up the OneWire library
            sensors.begin();
          }
          
          void setup()  
          { 
            // requestTemperatures() will not block current thread
            sensors.setWaitForConversion(false);
          
              lcd.begin(16, 2);                   // LCD 2 lines * 16 char.
              lcd.setBacklight(HIGH);
              lcd.setCursor(0, 0);
              lcd.setCursor(0, 0);
              lcd.print("Waiting for temperature updates");
              wait(10000);
          }
          
          void presentation() {
            // Send the sketch version information to the gateway and Controller
            sendSketchInfo("Temperature Sensor", "1.1");
          
            // Fetch the number of attached temperature sensors  
            numSensors = sensors.getDeviceCount();
          
            // Present all sensors to controller
            for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
               present(i, S_TEMP);
            }
          }
          
          void loop()     
          { 
            
          ///////////////////////////////////////////////////////////////////////////////////////       
          //////////////////////////////  MAIN LOOP  ////////////////////////////////////////////
          ///////////////////////////////////////////////////////////////////////////////////////
          
           // Fetch temperatures from Dallas sensors
            sensors.requestTemperatures();
            
            // query conversion time and sleep until conversion completed
            int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
            // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
            wait(conversionTime);
          
            // Read temperatures and send them to controller 
            for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
          
              // Fetch and round temperature to one decimal
              float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
          
              // Only send data if temperature has changed and no error
              #if COMPARE_TEMP == 1
              if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
              #else
              if (temperature != -127.00 && temperature != 85.00) {
              #endif
          
                // Send in the new temperature
                send(msg.setSensor(i).set(temperature,1));
                // Save new temperatures for next compare
                lastTemperature[i]=temperature;
                
                 lcd.clear();
                 lcd.setCursor(0, 1);
                 lcd.print("Pool Temp:");
                 lcd.print(" ");
                 lcd.print(temperature);
          
          
                 lcd.setCursor(0, 0);
                 lcd.print("Roof Temp:");
                 lcd.print(" ");
                 lcd.print(roofTemp);
          
                             }
                     }
            }
            
          ///////////////////////////////////////////////////////////////////////////////////////////////       
          //////////////////////////////  RECIEVE ROOF TEMP  ////////////////////////////////////////////
          ///////////////////////////////////////////////////////////////////////////////////////////////
          
          void receive(const MyMessage &message) {
          
          
           
           if (message.type==V_TEMP) {
             if (message.sensor <= 1) {
          
             
              // Write some debug info
              Serial.print("Incoming change from roof sensor:");
              Serial.print(message.sensor);
              Serial.print("\n");
              Serial.print(", New status: ");
              Serial.println(message.getFloat());
          
           roofTemp = (message.getFloat());
              }
            }
          } 
           
          
          

          One more question i need help with......
          On the roof sensor , do i send the nodes different msg. or the same?

          skywatchS Offline
          skywatchS Offline
          skywatch
          wrote on last edited by skywatch
          #4

          @JCH Remove the serial print from receive - I had issues with that before......

          Really this is more complicated than it needs to be. You just need the roof node to send temp to the controller and then the controller can relay that to the pool node.

          Also, what is the reason the roof node sends temp every 30 seconds? Thermal inertia of pool systems is not that fast (even boiling a kettle with a little water is comparitively slow). So why not send every 5 minutes instead? Or just when it hits a max/min temp for your purpose? This will be much less drain from the solar battery.

          J 1 Reply Last reply
          1
          • J Offline
            J Offline
            JCH
            wrote on last edited by
            #5

            Ok i am stuck again.....
            I cant seem to get the push buttons to activate the relays.....
            What am i doing wrong?

            /**
            JH REV 1.0 - 12-04-2020
             */
            
            
            // Enable debug prints to serial monitor
            #define MY_DEBUG 
            
            // Enable and select radio type attached
            #define MY_RADIO_RF24
            #define MY_RF24_PA_LEVEL RF24_PA_HIGH
            #define MY_NODE_ID 50  //////////FOR TESTING
            
            
            #include <MySensors.h>  
            #include <DallasTemperature.h>
            #include <OneWire.h>
            #include <LiquidCrystal_I2C.h>
            #include <Bounce2.h>
            
            LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
            
            #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No
            
            #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected 
            #define MAX_ATTACHED_DS18B20 16
            #define RELAY_PIN 4    
            #define RELAY_PIN_2 5  
            #define RELAY_ON 0
            #define RELAY_OFF 1
            #define BUTTON_PIN_1 7
            #define BUTTON_PIN_2 8
            #define CHILD_ID 4 // Id of the sensor child for 1st relay
            #define CHILD_ID_2 5 // Id of the sensor child for 2nd relay
            
            Bounce debouncer = Bounce();
            Bounce debouncer2 = Bounce();
            
            int oldValue=-1;
            int oldValue2=-1;
            bool state ;
            bool state2 ;
            bool initialValueSent = false;
            
            unsigned long SLEEP_TIME = 3000; // Sleep time between reads (in milliseconds)
            OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
            DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
            float lastTemperature[MAX_ATTACHED_DS18B20];
            int numSensors=0;
            float roofTemp;
            float poolTemp;
            String poolPumpstate;
            String solarPumpstate;
            
            bool receivedConfig = false;
            bool metric = true;
            
            
            
            
             
            // Initialize temperature message
            MyMessage msg(1,V_TEMP);
            
            MyMessage msg2(CHILD_ID, V_LIGHT);
            MyMessage msg3(CHILD_ID_2, V_LIGHT);
            
            void before()
            {
              // Startup up the OneWire library
              sensors.begin();
            }
            
            void setup()  
            { 
            
              pinMode(BUTTON_PIN_1,INPUT);
              // Activate internal pull-up
              digitalWrite(BUTTON_PIN_1,HIGH);
              pinMode(BUTTON_PIN_2,INPUT);
              // Activate internal pull-up
              digitalWrite(BUTTON_PIN_2,HIGH);
            
              debouncer.attach(BUTTON_PIN_1);
              debouncer.interval(5);
              debouncer2.attach(BUTTON_PIN_2);
              debouncer2.interval(5);  
              oldValue = debouncer.read();
              oldValue2 = debouncer2.read();
              
              // requestTemperatures() will not block current thread
              sensors.setWaitForConversion(false);
            
                lcd.begin(16, 2);                   // LCD 2 lines * 16 char.
                lcd.setBacklight(HIGH);
                lcd.setCursor(0, 0);
                lcd.setCursor(0, 0);
                lcd.clear();
                lcd.print("   Contoller  "); 
                lcd.setCursor(0, 1);  
                lcd.print("   Starting  ");
                wait(2000);
            
                 pinMode(RELAY_PIN, OUTPUT);
                 pinMode(RELAY_PIN_2, OUTPUT);        
                 digitalWrite(RELAY_PIN, RELAY_OFF);  
                 digitalWrite(RELAY_PIN_2, RELAY_OFF);       
                 lcd.setCursor(0, 0);
                 lcd.clear();
                 lcd.print("Begin Pump Test"); 
                 wait(2000);  
                 digitalWrite(RELAY_PIN, RELAY_ON);
                 wait(5000);  
                 digitalWrite(RELAY_PIN, RELAY_OFF);     
                 lcd.setCursor(0, 0);
                 lcd.clear();
                 lcd.print("Pool Pump Test");
                 lcd.setCursor(0, 1);
                 lcd.print("OK");     
                 wait(2000);
                 lcd.setCursor(0, 0);
                 lcd.clear();
                 lcd.print("Begin Pump Test"); 
                 digitalWrite(RELAY_PIN_2, RELAY_ON);
                 wait(5000);  
                 digitalWrite(RELAY_PIN_2, RELAY_OFF);     
                 lcd.setCursor(0, 0);
                 lcd.clear();
                 lcd.print("Solar Pump Test"); 
                 lcd.setCursor(0, 1);
                 lcd.print("OK");        
                 wait(2000);
            
                
            wait(10000);
            
            }
            
            void presentation()
            {
              // Send the sketch version information to the gateway and Controller
              sendSketchInfo("Pool Controller", "1.1");
            
              // Fetch the number of attached temperature sensors  
              numSensors = sensors.getDeviceCount();
            
              // Present all sensors to controller
              for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
                 present(i, S_TEMP);
                 present(CHILD_ID, S_BINARY);
                 present(CHILD_ID_2, S_BINARY); 
            
             }
            }
            
            
            
            
            void loop()     
            { 
            
            
            ///////////////////////////////////////////////////////////////////////////////////////       
            ///////////////////  REQUEST AND SEND INITIAL VALUES FOR RELAYS  //////////////////////
            ///////////////////////////////////////////////////////////////////////////////////////
            
              if (!initialValueSent) {
                Serial.println("Sending initial value");
                send(msg2.set(state?RELAY_OFF:RELAY_ON));
                send(msg3.set(state?RELAY_OFF:RELAY_ON));
                Serial.println("Requesting initial value from controller");
                request(CHILD_ID, V_STATUS);
                request(CHILD_ID_2, V_STATUS);
                wait(2000, C_SET, V_STATUS);
            
              
              
              }
                 
            ///////////////////////////////////////////////////////////////////////////////////////       
            //////////////////////////////  MAIN LOOP  ////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////////////////
            {
              
              debouncer.update();
              debouncer2.update();
              // Get the update value
              int value = debouncer.read();
              int value2 = debouncer2.read();
            
              if (value != oldValue) {
                state =  !state;                                                  // Toggle the state
                send(msg.set(state), false);                          // send new state to controller, no ack requested
                digitalWrite(RELAY_PIN, state);                // switch the relay to the new state
                oldValue = value;
              }
              
            
              if (value2 != oldValue2) {
                state2 =  !state2;                                         // Toggle the state
                send(msg2.set(state2), false);                 // send new state to controller, no ack requested
                digitalWrite(RELAY_PIN_2, state2);     // switch the relay to the new state
                oldValue2 = value2;
              }
                  // Fetch temperatures from Dallas sensors
              sensors.requestTemperatures();
              
              // query conversion time and sleep until conversion completed
              int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
              // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
              wait(conversionTime);
            
              // Read temperatures and send them to controller 
              for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
            
                // Fetch and round temperature to one decimal
                float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
            
                // Only send data if temperature has changed and no error
                #if COMPARE_TEMP == 1
                if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
                #else
                if (temperature != -127.00 && temperature != 85.00) {
                #endif
            
                  // Send in the new temperature
                  send(msg.setSensor(i).set(temperature,1));
                  // Save new temperatures for next compare
                  lastTemperature[i]=temperature;
                  poolTemp = temperature;
                          }
                       }
            
                   wait(1000);
              }
                   updateLCD();
              }
                   
                 
            
            
            
            
            
            ///////////////////////////////////////////////////////////////////////////////////////////////       
            //////////////////////////////  RECIEVE TEMPS   ////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////////////////////////
            
            void receive(const MyMessage &message) {
            
            
             
             if (message.type==V_TEMP) {
               if (message.sensor == 1) {
            
               
                // Write some debug info
                Serial.print("Incoming change from roof sensor:");
                Serial.print(message.sensor);
                Serial.print("\n");
                Serial.print(", New status: ");
                Serial.println(message.getFloat());
            
              roofTemp = (message.getFloat());
               }}
            ///////////////////////////////////////////////////////////////////////////////////////////////       
            //////////////////////////////  RECIEVE RELAYS  ////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////////////////////////
                
            
                    else if (message.getType()==V_STATUS) {
                    if (message.sensor == 4){
                    state = (bool)message.getInt();
                    Serial.print(state);
                    digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
                    Serial.print("Incoming change for sensor:");
                    Serial.print(message.getSensor());
                    Serial.print(", New status: ");
                    Serial.println(message.getBool());
                    send(msg2.set(state?RELAY_OFF:RELAY_ON)); 
                    if ((message.getBool())== 1){
                    poolPumpstate = ("Running");}
                    else{
                    poolPumpstate = ("Standby");
                    }}
                    if (message.sensor == 5){
                    state = (bool)message.getInt();
                    Serial.print(state);       
                    digitalWrite(RELAY_PIN_2, state?RELAY_ON:RELAY_OFF);
                    Serial.print("Incoming change for sensor:");
                    Serial.print(message.getSensor());
                    Serial.print(", New status: ");
                    Serial.println(message.getBool());
                    send(msg3.set(state?RELAY_OFF:RELAY_ON)); 
                     if ((message.getBool())== 1){
                    solarPumpstate = ("Running");}
                    else{
                    solarPumpstate = ("Standby");
                    }}
                    if (message.type == V_STATUS) {
                    if (!initialValueSent) {
                    Serial.println("Receiving initial value from controller");
                    initialValueSent = true;
                }}
               }}
                   
            
            void updateLCD()
            {      
              
                lcd.clear();
                lcd.setCursor(0, 1);
                lcd.print("Pool  :");
                lcd.print(" ");
                lcd.print(poolTemp);
                lcd.print((char)223);              
                lcd.print("C");       
                lcd.setCursor(0, 0);
                lcd.print("Solar :");
                lcd.print(" ");
                lcd.print(roofTemp);    
                lcd.print((char)223);       
                lcd.print("C");       
                wait(10000);
                lcd.clear();
                lcd.print("  Pump Status");
                wait(2000);
                lcd.clear();       
                lcd.setCursor(0, 1);
                lcd.print("Pool  :");
                lcd.print(" ");
                lcd.print(poolPumpstate);       
                lcd.setCursor(0, 0);
                lcd.print("Solar :");
                lcd.print(" ");      
                lcd.print(solarPumpstate); 
                wait(10000);       
                lcd.clear();
                lcd.print("  Temperatures");
                wait(2000);     
                   
             }           
                       
                    
            
                
            
            
            1 Reply Last reply
            0
            • skywatchS skywatch

              @JCH Remove the serial print from receive - I had issues with that before......

              Really this is more complicated than it needs to be. You just need the roof node to send temp to the controller and then the controller can relay that to the pool node.

              Also, what is the reason the roof node sends temp every 30 seconds? Thermal inertia of pool systems is not that fast (even boiling a kettle with a little water is comparitively slow). So why not send every 5 minutes instead? Or just when it hits a max/min temp for your purpose? This will be much less drain from the solar battery.

              J Offline
              J Offline
              JCH
              wrote on last edited by
              #6

              @skywatch
              The 30 seconds is while im only testing it.... once it is working as expected i will change the time

              1 Reply Last reply
              0
              • J Offline
                J Offline
                JCH
                wrote on last edited by
                #7

                EDIT: I think the push button wont work if there is a wait for sleep.... Is there anyway around this?

                skywatchS 1 Reply Last reply
                0
                • J JCH

                  EDIT: I think the push button wont work if there is a wait for sleep.... Is there anyway around this?

                  skywatchS Offline
                  skywatchS Offline
                  skywatch
                  wrote on last edited by skywatch
                  #8

                  @JCH You need to use pins D2 and D3 for the buttons and have them attached as interrupts. Interrupts will 'interrupt' the sleep cycle and perform whatever action you have told it to do in your sketch. The only other way to interrupt sleep that I know of is a timer that wakes at set (or random) intervals.

                  Remember that void loop() is not running in sleep mode, so no amount of checking buttons pins will work here during that time.

                  J 1 Reply Last reply
                  0
                  • skywatchS skywatch

                    @JCH You need to use pins D2 and D3 for the buttons and have them attached as interrupts. Interrupts will 'interrupt' the sleep cycle and perform whatever action you have told it to do in your sketch. The only other way to interrupt sleep that I know of is a timer that wakes at set (or random) intervals.

                    Remember that void loop() is not running in sleep mode, so no amount of checking buttons pins will work here during that time.

                    J Offline
                    J Offline
                    JCH
                    wrote on last edited by
                    #9

                    @skywatch Will the interrupt work with wait or only sleep?
                    I ended up going down a rabbit hole trying to implement a non breaking timer as below... it all seems to be working now except the button doesnt switch states everytime.... sometimes have to press it 2 or 3 times?

                    /**
                    JH REV 1.0 - 12-04-2020
                     */
                    
                    
                    // Enable debug prints to serial monitor
                    #define MY_DEBUG 
                    
                    // Enable and select radio type attached
                    #define MY_RADIO_RF24
                    #define MY_RF24_PA_LEVEL RF24_PA_HIGH
                    #define MY_NODE_ID 2  //////////FOR TESTING
                    #define MY_REPEATER_FEATURE
                    
                    #include <MySensors.h>  
                    #include <DallasTemperature.h>
                    #include <OneWire.h>
                    #include <LiquidCrystal_I2C.h>
                    #include <Bounce2.h>
                    #include <SPI.h>
                    
                    LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
                    
                    #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No
                    
                    #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected 
                    #define MAX_ATTACHED_DS18B20 16
                    #define RELAY_PIN 4    
                    #define RELAY_PIN_2 5  
                    #define RELAY_ON 0
                    #define RELAY_OFF 1
                    #define BUTTON_PIN 7
                    #define BUTTON_PIN_2 8
                    #define CHILD_ID 4 // Id of the sensor child for 1st relay
                    #define CHILD_ID_2 5 // Id of the sensor child for 2nd relay
                    
                    bool state;
                    Bounce debouncer = Bounce(); 
                    int oldValue=0;
                    bool state1;
                    Bounce debouncer2 = Bounce();
                    int oldValue2;
                    bool state2;
                    
                    bool initialValueSent = false;
                    
                    
                    unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
                    unsigned long CHECK_TIME = millis();
                    
                    OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
                    DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
                    float lastTemperature[MAX_ATTACHED_DS18B20];
                    int numSensors=0;
                    float roofTemp;
                    float poolTemp;
                    String poolPumpstate;
                    String solarPumpstate;
                    
                    bool receivedConfig = false;
                    bool metric = true;
                    
                    
                    
                    
                     
                    // Initialize temperature message
                    MyMessage msg(1,V_TEMP);
                    
                    MyMessage msg2(CHILD_ID, V_LIGHT);
                    MyMessage msg3(CHILD_ID_2, V_LIGHT);
                    
                    void before()
                    {
                      // Startup up the OneWire library
                      sensors.begin();
                    }
                    
                    void setup()  
                    { 
                      pinMode(BUTTON_PIN, INPUT);
                      // Activate internal pull-up
                      digitalWrite(BUTTON_PIN, HIGH);
                      pinMode(BUTTON_PIN_2, INPUT);
                      // Activate internal pull-up
                      digitalWrite(BUTTON_PIN_2, HIGH);
                    
                      debouncer.attach(BUTTON_PIN);
                      debouncer.interval(5);
                      debouncer2.attach(BUTTON_PIN_2);
                      debouncer2.interval(5);  
                      oldValue = debouncer.read();
                      oldValue2 = debouncer2.read();
                      
                      // requestTemperatures() will not block current thread
                      sensors.setWaitForConversion(false);
                    
                        lcd.begin(16, 2);                   // LCD 2 lines * 16 char.
                        lcd.setBacklight(HIGH);
                        lcd.setCursor(0, 0);
                        lcd.setCursor(0, 0);
                        lcd.clear();
                        lcd.print("   Contoller  "); 
                        lcd.setCursor(0, 1);  
                        lcd.print("   Starting  ");
                        wait(2000);
                    
                         pinMode(RELAY_PIN, OUTPUT);
                         pinMode(RELAY_PIN_2, OUTPUT);        
                         digitalWrite(RELAY_PIN, RELAY_OFF);  
                         digitalWrite(RELAY_PIN_2, RELAY_OFF);       
                     /*    lcd.setCursor(0, 0);
                         lcd.clear();
                         lcd.print("Begin Pump Test"); 
                         wait(2000);  
                         digitalWrite(RELAY_PIN, RELAY_ON);
                         wait(5000);  
                         digitalWrite(RELAY_PIN, RELAY_OFF);     
                         lcd.setCursor(0, 0);
                         lcd.clear();
                         lcd.print("Pool Pump Test");
                         lcd.setCursor(0, 1);
                         lcd.print("OK");     
                         wait(2000);
                         lcd.setCursor(0, 0);
                         lcd.clear();
                         lcd.print("Begin Pump Test"); 
                         digitalWrite(RELAY_PIN_2, RELAY_ON);
                         wait(5000);  
                         digitalWrite(RELAY_PIN_2, RELAY_OFF);     
                         lcd.setCursor(0, 0);
                         lcd.clear();
                         lcd.print("Solar Pump Test"); 
                         lcd.setCursor(0, 1);
                         lcd.print("OK");  */      
                         wait(2000);
                    
                        
                    wait(10000);
                    
                    }
                    
                    void presentation()
                    {
                      // Send the sketch version information to the gateway and Controller
                      sendSketchInfo("Pool Controller", "1.1");
                    
                      // Fetch the number of attached temperature sensors  
                      numSensors = sensors.getDeviceCount();
                    
                      // Present all sensors to controller
                      for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
                         present(i, S_TEMP);
                         present(CHILD_ID, S_BINARY);
                         present(CHILD_ID_2, S_BINARY); 
                    
                     }
                    }
                    
                    
                    
                    
                    void loop()     
                    { 
                      
                    
                        if (!initialValueSent) {
                        Serial.println("Sending initial value");
                        send(msg2.set(state?RELAY_OFF:RELAY_ON));
                        send(msg3.set(state?RELAY_OFF:RELAY_ON));
                        Serial.println("Requesting initial value from controller");
                        request(CHILD_ID, V_STATUS);
                        request(CHILD_ID_2, V_STATUS);
                        wait(2000, C_SET, V_STATUS);
                        }
                    
                    {
                      debouncer.update();
                      // Get the update value
                      int value = debouncer.read();
                      state = !state;
                      if (value != oldValue && value==0) {
                          send(msg2.set(state?true:false), true); // Send new state and request ack back
                      digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);    
                      }
                      oldValue = value;
                      
                    /*  {
                      debouncer2.update();
                      // Get the update value
                      int value = debouncer2.read();
                      state2 = !state2;
                      if (value != oldValue2 && value==0) {
                          send(msg3.set(state2?true:false), false); // Send new state and request ack back
                      digitalWrite(RELAY_PIN_2, state2?RELAY_ON:RELAY_OFF);    
                      }
                      oldValue = value;
                      }*/
                      }
                      
                        unsigned long NOW_TIME = millis();
                      if(NOW_TIME - CHECK_TIME >= SLEEP_TIME) {
                         updateLCDtemps();
                        CHECK_TIME = NOW_TIME;
                         Serial.println("Updating LCD");
                      }
                      
                      updateTemperature(30);
                    
                      if (solarPumpstate == "Running" ){
                        updateLCDstatus;
                      }
                     
                    
                    
                    
                      
                    }
                    
                    
                    
                    
                    
                    
                    
                    ///////////////////////////////////////////////////////////////////////////////////////////////       
                    //////////////////////////////  RECIEVE TEMPS   ////////////////////////////////////////////
                    ///////////////////////////////////////////////////////////////////////////////////////////////
                    
                    void receive(const MyMessage &message) {
                    
                    
                     
                     if (message.type==V_TEMP) {
                       if (message.sensor == 1) {
                    
                       
                        // Write some debug info
                        Serial.print("Incoming change from roof sensor:");
                        Serial.print(message.sensor);
                        Serial.print("\n");
                        Serial.print(", New status: ");
                        Serial.println(message.getFloat());
                    
                      roofTemp = (message.getFloat());
                       }}
                    ///////////////////////////////////////////////////////////////////////////////////////////////       
                    //////////////////////////////  RECIEVE RELAYS  ////////////////////////////////////////////
                    ///////////////////////////////////////////////////////////////////////////////////////////////
                     
                    
                            else if (message.getType()==V_STATUS) {
                            if (message.sensor == 4){
                            state = message.getBool();
                            Serial.print(state);
                            digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
                            Serial.print("Incoming change for sensor:");
                            Serial.print(message.getSensor());
                            Serial.print(", New status: ");
                            Serial.println(message.getBool());
                        //    send(msg2.set(state?RELAY_ON:RELAY_OFF)); 
                            if ((message.getBool())== 1){
                            poolPumpstate = ("Running");}
                            else{
                            poolPumpstate = ("Standby");
                            }}
                            if (message.sensor == 5){
                            state = (bool)message.getInt();
                            Serial.print(state);       
                            digitalWrite(RELAY_PIN_2, state?RELAY_ON:RELAY_OFF);
                            Serial.print("Incoming change for sensor:");
                            Serial.print(message.getSensor());
                            Serial.print(", New status: ");
                            Serial.println(message.getBool());
                            send(msg3.set(state?RELAY_OFF:RELAY_ON)); 
                             if ((message.getBool())== 1){
                            solarPumpstate = ("Running");}
                            else{
                            solarPumpstate = ("Standby");
                            }}
                            if (message.type == V_STATUS) {
                            if (!initialValueSent) {
                            Serial.println("Receiving initial value from controller");
                            initialValueSent = true;
                        }}
                       }
                    }   
                    
                    void updateLCDtemps()
                    {      
                      
                        lcd.clear();
                        lcd.setCursor(0, 1);
                        lcd.print("Pool  :");
                        lcd.print(" ");
                        lcd.print(poolTemp);
                        lcd.print((char)223);              
                        lcd.print("C");       
                        lcd.setCursor(0, 0);
                        lcd.print("Solar :");
                        lcd.print(" ");
                        lcd.print(roofTemp);    
                        lcd.print((char)223);       
                        lcd.print("C");   
                    
                    }
                    
                    void updateLCDstatus()
                    {      
                      
                    
                        lcd.clear();       
                        lcd.setCursor(0, 1);
                        lcd.print("Pool  :");
                        lcd.print(" ");
                        lcd.print(poolPumpstate);       
                        lcd.setCursor(0, 0);
                        lcd.print("Solar :");
                        lcd.print(" ");      
                        lcd.print(solarPumpstate); 
                      
                    
                    }
                      
                           
                                
                               
                    void updateTemperature(int frequency)
                    {
                      static unsigned long lastUpdateTime;
                      if (millis() - lastUpdateTime >= frequency * 1000UL)
                      {
                        sensors.requestTemperatures(); 
                        for (int i=0; i<numSensors && i< MAX_ATTACHED_DS18B20; i++) 
                        {
                          float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
                          if (lastTemperature[i] != temperature && temperature != -127.00) 
                          {
                            send(msg.setSensor(i).set(temperature,1));
                            lastTemperature[i]=temperature;
                            poolTemp = temperature;
                          }
                        }
                        lastUpdateTime += frequency * 1000UL;
                    
                      }
                    }
                    
                    skywatchS 1 Reply Last reply
                    0
                    • J JCH

                      @skywatch Will the interrupt work with wait or only sleep?
                      I ended up going down a rabbit hole trying to implement a non breaking timer as below... it all seems to be working now except the button doesnt switch states everytime.... sometimes have to press it 2 or 3 times?

                      /**
                      JH REV 1.0 - 12-04-2020
                       */
                      
                      
                      // Enable debug prints to serial monitor
                      #define MY_DEBUG 
                      
                      // Enable and select radio type attached
                      #define MY_RADIO_RF24
                      #define MY_RF24_PA_LEVEL RF24_PA_HIGH
                      #define MY_NODE_ID 2  //////////FOR TESTING
                      #define MY_REPEATER_FEATURE
                      
                      #include <MySensors.h>  
                      #include <DallasTemperature.h>
                      #include <OneWire.h>
                      #include <LiquidCrystal_I2C.h>
                      #include <Bounce2.h>
                      #include <SPI.h>
                      
                      LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
                      
                      #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No
                      
                      #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected 
                      #define MAX_ATTACHED_DS18B20 16
                      #define RELAY_PIN 4    
                      #define RELAY_PIN_2 5  
                      #define RELAY_ON 0
                      #define RELAY_OFF 1
                      #define BUTTON_PIN 7
                      #define BUTTON_PIN_2 8
                      #define CHILD_ID 4 // Id of the sensor child for 1st relay
                      #define CHILD_ID_2 5 // Id of the sensor child for 2nd relay
                      
                      bool state;
                      Bounce debouncer = Bounce(); 
                      int oldValue=0;
                      bool state1;
                      Bounce debouncer2 = Bounce();
                      int oldValue2;
                      bool state2;
                      
                      bool initialValueSent = false;
                      
                      
                      unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
                      unsigned long CHECK_TIME = millis();
                      
                      OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
                      DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
                      float lastTemperature[MAX_ATTACHED_DS18B20];
                      int numSensors=0;
                      float roofTemp;
                      float poolTemp;
                      String poolPumpstate;
                      String solarPumpstate;
                      
                      bool receivedConfig = false;
                      bool metric = true;
                      
                      
                      
                      
                       
                      // Initialize temperature message
                      MyMessage msg(1,V_TEMP);
                      
                      MyMessage msg2(CHILD_ID, V_LIGHT);
                      MyMessage msg3(CHILD_ID_2, V_LIGHT);
                      
                      void before()
                      {
                        // Startup up the OneWire library
                        sensors.begin();
                      }
                      
                      void setup()  
                      { 
                        pinMode(BUTTON_PIN, INPUT);
                        // Activate internal pull-up
                        digitalWrite(BUTTON_PIN, HIGH);
                        pinMode(BUTTON_PIN_2, INPUT);
                        // Activate internal pull-up
                        digitalWrite(BUTTON_PIN_2, HIGH);
                      
                        debouncer.attach(BUTTON_PIN);
                        debouncer.interval(5);
                        debouncer2.attach(BUTTON_PIN_2);
                        debouncer2.interval(5);  
                        oldValue = debouncer.read();
                        oldValue2 = debouncer2.read();
                        
                        // requestTemperatures() will not block current thread
                        sensors.setWaitForConversion(false);
                      
                          lcd.begin(16, 2);                   // LCD 2 lines * 16 char.
                          lcd.setBacklight(HIGH);
                          lcd.setCursor(0, 0);
                          lcd.setCursor(0, 0);
                          lcd.clear();
                          lcd.print("   Contoller  "); 
                          lcd.setCursor(0, 1);  
                          lcd.print("   Starting  ");
                          wait(2000);
                      
                           pinMode(RELAY_PIN, OUTPUT);
                           pinMode(RELAY_PIN_2, OUTPUT);        
                           digitalWrite(RELAY_PIN, RELAY_OFF);  
                           digitalWrite(RELAY_PIN_2, RELAY_OFF);       
                       /*    lcd.setCursor(0, 0);
                           lcd.clear();
                           lcd.print("Begin Pump Test"); 
                           wait(2000);  
                           digitalWrite(RELAY_PIN, RELAY_ON);
                           wait(5000);  
                           digitalWrite(RELAY_PIN, RELAY_OFF);     
                           lcd.setCursor(0, 0);
                           lcd.clear();
                           lcd.print("Pool Pump Test");
                           lcd.setCursor(0, 1);
                           lcd.print("OK");     
                           wait(2000);
                           lcd.setCursor(0, 0);
                           lcd.clear();
                           lcd.print("Begin Pump Test"); 
                           digitalWrite(RELAY_PIN_2, RELAY_ON);
                           wait(5000);  
                           digitalWrite(RELAY_PIN_2, RELAY_OFF);     
                           lcd.setCursor(0, 0);
                           lcd.clear();
                           lcd.print("Solar Pump Test"); 
                           lcd.setCursor(0, 1);
                           lcd.print("OK");  */      
                           wait(2000);
                      
                          
                      wait(10000);
                      
                      }
                      
                      void presentation()
                      {
                        // Send the sketch version information to the gateway and Controller
                        sendSketchInfo("Pool Controller", "1.1");
                      
                        // Fetch the number of attached temperature sensors  
                        numSensors = sensors.getDeviceCount();
                      
                        // Present all sensors to controller
                        for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
                           present(i, S_TEMP);
                           present(CHILD_ID, S_BINARY);
                           present(CHILD_ID_2, S_BINARY); 
                      
                       }
                      }
                      
                      
                      
                      
                      void loop()     
                      { 
                        
                      
                          if (!initialValueSent) {
                          Serial.println("Sending initial value");
                          send(msg2.set(state?RELAY_OFF:RELAY_ON));
                          send(msg3.set(state?RELAY_OFF:RELAY_ON));
                          Serial.println("Requesting initial value from controller");
                          request(CHILD_ID, V_STATUS);
                          request(CHILD_ID_2, V_STATUS);
                          wait(2000, C_SET, V_STATUS);
                          }
                      
                      {
                        debouncer.update();
                        // Get the update value
                        int value = debouncer.read();
                        state = !state;
                        if (value != oldValue && value==0) {
                            send(msg2.set(state?true:false), true); // Send new state and request ack back
                        digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);    
                        }
                        oldValue = value;
                        
                      /*  {
                        debouncer2.update();
                        // Get the update value
                        int value = debouncer2.read();
                        state2 = !state2;
                        if (value != oldValue2 && value==0) {
                            send(msg3.set(state2?true:false), false); // Send new state and request ack back
                        digitalWrite(RELAY_PIN_2, state2?RELAY_ON:RELAY_OFF);    
                        }
                        oldValue = value;
                        }*/
                        }
                        
                          unsigned long NOW_TIME = millis();
                        if(NOW_TIME - CHECK_TIME >= SLEEP_TIME) {
                           updateLCDtemps();
                          CHECK_TIME = NOW_TIME;
                           Serial.println("Updating LCD");
                        }
                        
                        updateTemperature(30);
                      
                        if (solarPumpstate == "Running" ){
                          updateLCDstatus;
                        }
                       
                      
                      
                      
                        
                      }
                      
                      
                      
                      
                      
                      
                      
                      ///////////////////////////////////////////////////////////////////////////////////////////////       
                      //////////////////////////////  RECIEVE TEMPS   ////////////////////////////////////////////
                      ///////////////////////////////////////////////////////////////////////////////////////////////
                      
                      void receive(const MyMessage &message) {
                      
                      
                       
                       if (message.type==V_TEMP) {
                         if (message.sensor == 1) {
                      
                         
                          // Write some debug info
                          Serial.print("Incoming change from roof sensor:");
                          Serial.print(message.sensor);
                          Serial.print("\n");
                          Serial.print(", New status: ");
                          Serial.println(message.getFloat());
                      
                        roofTemp = (message.getFloat());
                         }}
                      ///////////////////////////////////////////////////////////////////////////////////////////////       
                      //////////////////////////////  RECIEVE RELAYS  ////////////////////////////////////////////
                      ///////////////////////////////////////////////////////////////////////////////////////////////
                       
                      
                              else if (message.getType()==V_STATUS) {
                              if (message.sensor == 4){
                              state = message.getBool();
                              Serial.print(state);
                              digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
                              Serial.print("Incoming change for sensor:");
                              Serial.print(message.getSensor());
                              Serial.print(", New status: ");
                              Serial.println(message.getBool());
                          //    send(msg2.set(state?RELAY_ON:RELAY_OFF)); 
                              if ((message.getBool())== 1){
                              poolPumpstate = ("Running");}
                              else{
                              poolPumpstate = ("Standby");
                              }}
                              if (message.sensor == 5){
                              state = (bool)message.getInt();
                              Serial.print(state);       
                              digitalWrite(RELAY_PIN_2, state?RELAY_ON:RELAY_OFF);
                              Serial.print("Incoming change for sensor:");
                              Serial.print(message.getSensor());
                              Serial.print(", New status: ");
                              Serial.println(message.getBool());
                              send(msg3.set(state?RELAY_OFF:RELAY_ON)); 
                               if ((message.getBool())== 1){
                              solarPumpstate = ("Running");}
                              else{
                              solarPumpstate = ("Standby");
                              }}
                              if (message.type == V_STATUS) {
                              if (!initialValueSent) {
                              Serial.println("Receiving initial value from controller");
                              initialValueSent = true;
                          }}
                         }
                      }   
                      
                      void updateLCDtemps()
                      {      
                        
                          lcd.clear();
                          lcd.setCursor(0, 1);
                          lcd.print("Pool  :");
                          lcd.print(" ");
                          lcd.print(poolTemp);
                          lcd.print((char)223);              
                          lcd.print("C");       
                          lcd.setCursor(0, 0);
                          lcd.print("Solar :");
                          lcd.print(" ");
                          lcd.print(roofTemp);    
                          lcd.print((char)223);       
                          lcd.print("C");   
                      
                      }
                      
                      void updateLCDstatus()
                      {      
                        
                      
                          lcd.clear();       
                          lcd.setCursor(0, 1);
                          lcd.print("Pool  :");
                          lcd.print(" ");
                          lcd.print(poolPumpstate);       
                          lcd.setCursor(0, 0);
                          lcd.print("Solar :");
                          lcd.print(" ");      
                          lcd.print(solarPumpstate); 
                        
                      
                      }
                        
                             
                                  
                                 
                      void updateTemperature(int frequency)
                      {
                        static unsigned long lastUpdateTime;
                        if (millis() - lastUpdateTime >= frequency * 1000UL)
                        {
                          sensors.requestTemperatures(); 
                          for (int i=0; i<numSensors && i< MAX_ATTACHED_DS18B20; i++) 
                          {
                            float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
                            if (lastTemperature[i] != temperature && temperature != -127.00) 
                            {
                              send(msg.setSensor(i).set(temperature,1));
                              lastTemperature[i]=temperature;
                              poolTemp = temperature;
                            }
                          }
                          lastUpdateTime += frequency * 1000UL;
                      
                        }
                      }
                      
                      skywatchS Offline
                      skywatchS Offline
                      skywatch
                      wrote on last edited by
                      #10

                      @JCH I haven't tried interrupt with wait so I can't really say for sure. But it works for sleep 100%.....

                      I don't know how you got to the point you are at now, but it is easy to reflash an arduino and so I suggest the following.....

                      1. Start again from the begining with the new knowledge you have.
                      2. Look at similar examples and learn how they work.
                      3. Build your code slowly.

                      Start by getting just the buttons to work and monitor them in the serial window or by attaching leds with limiting resistors to the output pins you want to use for the relays. Then add debounce and check all is working. Then add the lcd display and test until working. Keep adding a bit at t time so it is easy to know what you changed and if it worked as expected.

                      When I am doing this I save the sktech after each working version and then update the sketch version for the next addition. It allows me to easily go back to working system if I get unexpected results (which I do in a lot of cases!).....

                      J 1 Reply Last reply
                      1
                      • skywatchS skywatch

                        @JCH I haven't tried interrupt with wait so I can't really say for sure. But it works for sleep 100%.....

                        I don't know how you got to the point you are at now, but it is easy to reflash an arduino and so I suggest the following.....

                        1. Start again from the begining with the new knowledge you have.
                        2. Look at similar examples and learn how they work.
                        3. Build your code slowly.

                        Start by getting just the buttons to work and monitor them in the serial window or by attaching leds with limiting resistors to the output pins you want to use for the relays. Then add debounce and check all is working. Then add the lcd display and test until working. Keep adding a bit at t time so it is easy to know what you changed and if it worked as expected.

                        When I am doing this I save the sktech after each working version and then update the sketch version for the next addition. It allows me to easily go back to working system if I get unexpected results (which I do in a lot of cases!).....

                        J Offline
                        J Offline
                        JCH
                        wrote on last edited by
                        #11

                        @skywatch Good advice.. I will do that today.
                        Thanks

                        1 Reply Last reply
                        1
                        • J Offline
                          J Offline
                          JCH
                          wrote on last edited by
                          #12

                          Ok i need help again please... I cannot get to the bottom of my last little problem......

                          void setup()  
                          { 
                            pinMode(BUTTON_PIN, INPUT);
                            // Activate internal pull-up
                            digitalWrite(BUTTON_PIN, HIGH);
                            pinMode(BUTTON_PIN_2, INPUT);
                            // Activate internal pull-up
                            digitalWrite(BUTTON_PIN_2, HIGH);
                           // pinMode(BUTTON_PIN_3, INPUT);
                            // Activate internal pull-up
                           // digitalWrite(BUTTON_PIN_3, HIGH);
                           
                            debouncer.attach(BUTTON_PIN);
                            debouncer.interval(5);
                            debouncer2.attach(BUTTON_PIN_2);
                            debouncer2.interval(5); 
                            debouncer3.attach(BUTTON_PIN_3);
                            debouncer3.interval(5);
                            oldValue = debouncer.read();
                            oldValue2 = debouncer2.read();
                            oldValue3 = debouncer3.read();  
                          

                          As soon as i tired to add a 3rd button and debouncer the whole code crashes.... as soon a a comment out the above lines it goes good again.... thoughts?

                          Here is the whole code (havent tidyed it up yet :wink:

                          /**
                          JH REV 1.0 - 12-04-2020
                           */
                          
                          
                          // Enable debug prints to serial monitor
                          #define MY_DEBUG 
                          
                          // Enable and select radio type attached
                          #define MY_RADIO_RF24
                          #define MY_RF24_PA_LEVEL RF24_PA_HIGH
                          #define MY_NODE_ID 22  //////////FOR TESTING
                          #define MY_REPEATER_FEATURE
                          
                          #include <MySensors.h>  
                          #include <DallasTemperature.h>
                          #include <OneWire.h>
                          #include <LiquidCrystal_I2C.h>
                          #include <Bounce2.h>
                          #include <SPI.h>
                          
                          LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
                          
                          #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No
                          
                          #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected 
                          #define MAX_ATTACHED_DS18B20 16
                          #define RELAY_PIN 4    
                          #define RELAY_PIN_2 5  
                          #define RELAY_PIN_3 6  
                          #define RELAY_ON 0
                          #define RELAY_OFF 1
                          #define BUTTON_PIN 7
                          #define BUTTON_PIN_2 8
                          #define BUTTON_PIN_3 9
                          #define CHILD_ID 4 // Id of the sensor child for 1st relay
                          #define CHILD_ID_2 5 // Id of the sensor child for 2nd relay
                          #define CHILD_ID_3 6 // Id of the sensor child for 2nd relay
                          
                          bool state;
                          Bounce debouncer = Bounce(); 
                          int oldValue=0;
                          int oldValue1=0;
                          bool state1;
                          Bounce debouncer2 = Bounce();
                          int oldValue2=0;
                          bool state2;
                          Bounce debouncer3 = Bounce();
                          int oldValue3=0;
                          bool state3;
                          
                          bool initialValueSent = false;
                          
                          
                          unsigned long SLEEP_TIME = 60000; // Sleep time between reads (in milliseconds)
                          unsigned long CHECK_TIME = millis();
                          
                          OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
                          DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
                          float lastTemperature[MAX_ATTACHED_DS18B20];
                          int numSensors=0;
                          float roofTemp;
                          float poolTemp;
                          String poolPumpstate;
                          String solarPumpstate;
                          
                          bool receivedConfig = false;
                          bool metric = true;
                          
                          
                          
                          
                           
                          // Initialize temperature message
                          MyMessage msg(1,V_TEMP);
                          
                          MyMessage msg2(CHILD_ID, V_LIGHT);
                          MyMessage msg3(CHILD_ID_2, V_LIGHT);
                          MyMessage msg4(CHILD_ID_3, V_LIGHT);
                          
                          void before()
                          {
                            // Startup up the OneWire library
                            sensors.begin();
                          }
                          
                          void setup()  
                          { 
                            pinMode(BUTTON_PIN, INPUT);
                            // Activate internal pull-up
                            digitalWrite(BUTTON_PIN, HIGH);
                            pinMode(BUTTON_PIN_2, INPUT);
                            // Activate internal pull-up
                            digitalWrite(BUTTON_PIN_2, HIGH);
                           // pinMode(BUTTON_PIN_3, INPUT);
                            // Activate internal pull-up
                           // digitalWrite(BUTTON_PIN_3, HIGH);
                           
                            debouncer.attach(BUTTON_PIN);
                            debouncer.interval(5);
                            debouncer2.attach(BUTTON_PIN_2);
                            debouncer2.interval(5); 
                            debouncer3.attach(BUTTON_PIN_3);
                            debouncer3.interval(5);
                            oldValue = debouncer.read();
                            oldValue2 = debouncer2.read();
                            oldValue3 = debouncer3.read();  
                            
                            
                            // requestTemperatures() will not block current thread
                            sensors.setWaitForConversion(false);
                          
                              lcd.begin(16, 2);                   // LCD 2 lines * 16 char.
                              lcd.setBacklight(HIGH);
                              lcd.setCursor(0, 0);
                              lcd.setCursor(0, 0);
                              lcd.clear();
                              lcd.print("   Contoller  "); 
                              lcd.setCursor(0, 1);  
                              lcd.print("   Starting  ");
                              wait(2000);
                          
                               pinMode(RELAY_PIN, OUTPUT);
                               pinMode(RELAY_PIN_2, OUTPUT);        
                               digitalWrite(RELAY_PIN, RELAY_OFF);  
                               digitalWrite(RELAY_PIN_2, RELAY_OFF);       
                           /*    lcd.setCursor(0, 0);
                               lcd.clear();
                               lcd.print("Begin Pump Test"); 
                               wait(2000);  
                               digitalWrite(RELAY_PIN, RELAY_ON);
                               wait(5000);  
                               digitalWrite(RELAY_PIN, RELAY_OFF);     
                               lcd.setCursor(0, 0);
                               lcd.clear();
                               lcd.print("Pool Pump Test");
                               lcd.setCursor(0, 1);
                               lcd.print("OK");     
                               wait(2000);
                               lcd.setCursor(0, 0);
                               lcd.clear();
                               lcd.print("Begin Pump Test"); 
                               digitalWrite(RELAY_PIN_2, RELAY_ON);
                               wait(5000);  
                               digitalWrite(RELAY_PIN_2, RELAY_OFF);     
                               lcd.setCursor(0, 0);
                               lcd.clear();
                               lcd.print("Solar Pump Test"); 
                               lcd.setCursor(0, 1);
                               lcd.print("OK");  */      
                               wait(2000);
                          
                              
                          wait(10000);
                          
                          }
                          
                          void presentation()
                          {
                            // Send the sketch version information to the gateway and Controller
                            sendSketchInfo("Pool Controller", "1.1");
                          
                            // Fetch the number of attached temperature sensors  
                            numSensors = sensors.getDeviceCount();
                          
                            // Present all sensors to controller
                            for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
                               present(i, S_TEMP);
                               present(CHILD_ID, S_BINARY);
                               present(CHILD_ID_2, S_BINARY); 
                          
                           }
                          }
                          
                          
                          
                          
                          void loop()     
                          { 
                            
                          
                              if (!initialValueSent) {
                              Serial.println("Sending initial value");
                              send(msg2.set(state?RELAY_OFF:RELAY_ON));
                              send(msg3.set(state?RELAY_OFF:RELAY_ON));
                              Serial.println("Requesting initial value from controller");
                              request(CHILD_ID, V_STATUS);
                              request(CHILD_ID_2, V_STATUS);
                              wait(2000, C_SET, V_STATUS);
                              }
                          
                          
                            debouncer.update();
                            debouncer2.update();
                            // Get the update value
                            int value1 = debouncer.read();
                            int value2 = debouncer2.read();
                          
                            if (debouncer.fell()) {
                                state1 = !state1;
                                send(msg2.set(state1?true:false), false); // Send new state and request ack back
                                digitalWrite(RELAY_PIN, state1?RELAY_ON:RELAY_OFF);       // TURN ON / OFF RELAYS
                                oldValue1 = value1;
                            }
                            if (debouncer2.fell()) {
                                state2 = !state2;
                                send(msg3.set(state2?true:false), false); // Send new state and request ack back
                                digitalWrite(RELAY_PIN_2, state2?RELAY_ON:RELAY_OFF);       // TURN ON / OFF RELAYS      
                                oldValue2 = value2;
                            }
                            
                            
                              unsigned long NOW_TIME = millis();
                            if(NOW_TIME - CHECK_TIME >= SLEEP_TIME) {
                               updateLCDtemps();
                              CHECK_TIME = NOW_TIME;
                               Serial.println("Updating LCD");
                            }
                            
                            updateTemperature(30);
                          
                          
                            if (solarPumpstate == "Running" ){
                              updateLCDstatus;
                            }
                           
                          
                          
                          
                            
                          }
                          
                          
                          
                          
                          
                          
                          
                          ///////////////////////////////////////////////////////////////////////////////////////////////       
                          //////////////////////////////  RECIEVE TEMPS   ////////////////////////////////////////////
                          ///////////////////////////////////////////////////////////////////////////////////////////////
                          
                          void receive(const MyMessage &message) {
                          
                          
                           
                           if (message.type==V_TEMP) {
                             if (message.sensor == 1) {
                          
                             
                              // Write some debug info
                              Serial.print("Incoming change from roof sensor:");
                              Serial.print(message.sensor);
                              Serial.print("\n");
                              Serial.print(", New status: ");
                              Serial.println(message.getFloat());
                          
                            roofTemp = (message.getFloat());
                             }}
                          ///////////////////////////////////////////////////////////////////////////////////////////////       
                          //////////////////////////////  RECIEVE RELAYS  ////////////////////////////////////////////
                          ///////////////////////////////////////////////////////////////////////////////////////////////
                           
                          
                                  else if (message.getType()==V_STATUS) {
                                  if (message.sensor == 4){
                                  state1 = message.getBool();
                                  digitalWrite(RELAY_PIN, state1?RELAY_ON:RELAY_OFF);
                                  Serial.print("Incoming change for sensor:");
                                  Serial.print(message.getSensor());
                                  Serial.print(", New status: ");
                                  Serial.println(message.getBool());
                                //  send(msg2.set(state?RELAY_ON:RELAY_OFF)); 
                                  if ((message.getBool())== 1){
                                  poolPumpstate = ("Running");}
                                  else{
                                  poolPumpstate = ("Standby");
                                  }}
                                  if (message.sensor == 5){
                                  state2 = message.getBool();
                                  Serial.print(state);       
                                  digitalWrite(RELAY_PIN_2, state2?RELAY_ON:RELAY_OFF);
                                  Serial.print("Incoming change for sensor:");
                                  Serial.print(message.getSensor());
                                  Serial.print(", New status: ");
                                  Serial.println(message.getBool());
                                 // send(msg3.set(state?RELAY_OFF:RELAY_ON)); 
                                   if ((message.getBool())== 1){
                                  solarPumpstate = ("Running");}
                                  else{
                                  solarPumpstate = ("Standby");
                                  }}
                                  if (message.type == V_STATUS) {
                                  if (!initialValueSent) {
                                  Serial.println("Receiving initial value from controller");
                                  initialValueSent = true;
                              }}
                             }
                          }   
                          
                          void updateLCDtemps()
                          {      
                            
                              lcd.clear();
                              lcd.setCursor(0, 1);
                              lcd.print("Pool  :");
                              lcd.print(" ");
                              lcd.print(poolTemp);
                              lcd.print((char)223);              
                              lcd.print("C");       
                              lcd.setCursor(0, 0);
                              lcd.print("Solar :");
                              lcd.print(" ");
                              lcd.print(roofTemp);    
                              lcd.print((char)223);       
                              lcd.print("C");   
                          
                          }
                          
                          void updateLCDstatus()
                          {      
                            
                          
                              lcd.clear();       
                              lcd.setCursor(0, 1);
                              lcd.print("Pool  :");
                              lcd.print(" ");
                              lcd.print(poolPumpstate);       
                              lcd.setCursor(0, 0);
                              lcd.print("Solar :");
                              lcd.print(" ");      
                              lcd.print(solarPumpstate); 
                            
                          
                          }
                            
                                 
                                      
                                     
                          void updateTemperature(int frequency)
                          {       
                            static unsigned long lastUpdateTime;
                            if (millis() - lastUpdateTime >= frequency * 1000UL)
                            {
                              Serial.println("Updating Dallas Temp");
                              sensors.requestTemperatures(); 
                              for (int i=0; i<numSensors && i< MAX_ATTACHED_DS18B20; i++) 
                              {
                                float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
                                if (lastTemperature[i] != temperature && temperature != -127.00) 
                                {
                                  send(msg.setSensor(i).set(temperature,1));
                                  lastTemperature[i]=temperature;
                                  poolTemp = temperature;
                                   Serial.println("Pool Temp = ");
                                   Serial.println(poolTemp);
                                   updateLCDtemps();
                                }
                              }
                              lastUpdateTime += frequency * 1000UL;
                          
                            }
                          }
                          
                          1 Reply Last reply
                          0
                          • J Offline
                            J Offline
                            JCH
                            wrote on last edited by
                            #13

                            Edit.... Does mysensors use pin 9 for anything? as soon as i try to use it as an input the radio seems to not be communicating with the controller?
                            I loaded a bounce sketch to test the button and pin and it works fine untill i reload my sketch.

                            skywatchS 1 Reply Last reply
                            0
                            • J JCH

                              Edit.... Does mysensors use pin 9 for anything? as soon as i try to use it as an input the radio seems to not be communicating with the controller?
                              I loaded a bounce sketch to test the button and pin and it works fine untill i reload my sketch.

                              skywatchS Offline
                              skywatchS Offline
                              skywatch
                              wrote on last edited by
                              #14

                              @JCH

                              https://www.mysensors.org/build/connect_radio

                              1 Reply Last reply
                              1
                              Reply
                              • Reply as topic
                              Log in to reply
                              • Oldest to Newest
                              • Newest to Oldest
                              • Most Votes


                              8

                              Online

                              11.7k

                              Users

                              11.2k

                              Topics

                              113.1k

                              Posts


                              Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                              • Login

                              • Don't have an account? Register

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • MySensors
                              • OpenHardware.io
                              • Categories
                              • Recent
                              • Tags
                              • Popular