Combining relay and temperature sketch



  • Hey guys!
    Question....
    I'm trying to combine the temperature and relay sketch from the build section on the website, but for some reason I only see the relays showing up in Domotics.
    I understand that there is a bug in the relay sketch so I have that starting spawning childs at adress 1 till 16. Now I would like to have the temp sensors starting at 17 till 32, but for some reason I can't get it to work......
    Not able to upload my sketch for now.... hoping to get this solved quickly...... Purpose is to automate my greenhouse with aquaponics and hydroponics systems so I need to have 16 relays and 16 ds18b's to monitor the whole process....


  • Mod

    maybe you have something wrong in presentation. Pls post your code. How come you need this many sensors?



  • @gohan thx for your fast reply...
    I wasn't anywhere near my laptop, so I couldn't post the code.

    the reason for that many sensors is:

    pretty big greenhouse with a few aquaponics and hydroponics systems.
    for instance, I have 4 vertical towers from wich I want to monitor the water temp and the temp inside the pvs towers.
    that alone are allready 2 temp sensors and a relay for the pump.....



  • hereby the code that doesn't seem to work...

    // Enable debug prints to serial monitor
    //#define MY_DEBUG 
    
    #define MY_RF24_CE_PIN 49
    #define MY_RF24_CS_PIN 53
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    #define MY_NODE_ID 5
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DallasTemperature.h>
    #include <OneWire.h>
    
    #define COMPARE_TEMP 1 // 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 = 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);
    
    #define RELAY_1  30  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 16 // Total number of attached relays
    #define RELAY_ON 1  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    
    
    
    void before()
    {
      // Startup up the OneWire library
      sensors.begin();
      for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);
        // Set relay to last known state (using eeprom storage)
        digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
      }
    }
    
    void setup()  
    { 
      // requestTemperatures() will not block current thread
      sensors.setWaitForConversion(false);
    }
    
    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=17; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
         present(i, S_TEMP);
         
      for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
       // Register all sensors to gw (they will be created as child devices)
        present(sensor, S_BINARY);
      }
      }
    }
    
    void 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)
      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;
        }
      }
     
    }
    
    void receive(const MyMessage &message)
    {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type==V_STATUS) {
        // Change relay state
        digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
        // Store state in eeprom
        saveState(message.sensor, message.getBool());
        // Write some debug info
        Serial.print("Incoming change for sensor:");
        Serial.print(message.sensor);
        Serial.print(", New status: ");
        Serial.println(message.getBool());
      }
       sleep(SLEEP_TIME);
    }
    

  • Mod

    I think there is an error in the presentation function: you need to close the first for cycle before the second one, otherwise it will present 2 relays for every Dallas sensor.



  • @gohan again, thx for your fast reply,

    How could I miss that...😳😳 lol...
    I'll try it later today....

    Thx upfront!

    Timu


  • Mod

    When doing copy/paste of code it can happen to anyone πŸ™‚



  • @gohan apparently..... πŸ˜‚πŸ˜‚πŸ˜‰



  • Hello,

    I'm trying to do the same thing but with just one relay and a DHT22. So I combined the "air humidity sensor" sketch and the "relay with button" one.

    Each sketch works fine, but when I combine them, I get an error form the DHT
    "Failed reading humidity from DHT
    Failed reading temperature from DHT!"

    But sometimes, I get the temp/hum in the serial monitor. I first thought that I misswired something, but it work perfectly with the other sketch.

    So.. I (obviously) missed something in the program and I can't see what (probably something stupid, I'm new to arduino and mysensors.)

    Here's my code (basicly a copy/paste of the two sketches). Any advice?

    /**
    * 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.
    *
    *******************************
    *
    * REVISION HISTORY
    * Version 1.0: Henrik EKblad
    * Version 1.1 - 2016-07-20: Converted to MySensors v2.0 and added various improvements - Torben Woltjen (mozzbozz)
    * 
    * DESCRIPTION
    * This sketch provides an example of how to implement a humidity/temperature
    * sensor using a DHT11/DHT-22.
    *  
    * For more information, please visit:
    * http://www.mysensors.org/build/humidity
    * 
    */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached 
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    //#define MY_RS485
    
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DHT.h>
    
    //Relay sketch
    #include <Bounce2.h>
    
    
    // Set this to the pin you connected the DHT's data pin to
    #define DHT_DATA_PIN 8
    
    // Set this offset if the sensor has a permanent small offset to the real temperatures
    #define SENSOR_TEMP_OFFSET 0
    
    // Sleep time between sensor updates (in milliseconds)
    // Must be >1000ms for DHT22 and >2000ms for DHT11
    static const uint64_t UPDATE_INTERVAL = 60000;
    
    // Force sending an update of the temperature after n sensor reads, so a controller showing the
    // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
    // the value didn't change since;
    // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
    static const uint8_t FORCE_UPDATE_N_READS = 10;
    
    #define CHILD_ID_HUM 2
    #define CHILD_ID_TEMP 3
    
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    bool metric = true;
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    DHT dht;
    
    //Relay Sketch
    
    #define RELAY_PIN  4  // Arduino Digital I/O pin number for relay 
    #define BUTTON_PIN  5  // Arduino Digital I/O pin number for button 
    #define CHILD_ID 1   // Id of the sensor child
    #define RELAY_ON 1
    #define RELAY_OFF 0
    
    Bounce debouncer = Bounce(); 
    int oldValue=0;
    bool state;
    
    MyMessage msg(CHILD_ID,V_LIGHT);
    
    
    void presentation()  
    { 
    // Send the sketch version information to the gateway
    sendSketchInfo("Test403", "1.1");
    
    // Register all sensors to gw (they will be created as child devices)
    present(CHILD_ID_HUM, S_HUM);
    present(CHILD_ID_TEMP, S_TEMP);
    
    metric = getControllerConfig().isMetric;
    
    present(CHILD_ID, S_LIGHT);
    
    }
    
    
    void setup()
    {
    dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
    if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
      Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
    }
    // Sleep for the time of the minimum sampling period to give the sensor time to power up
    // (otherwise, timeout errors might occure for the first reading)
    sleep(dht.getMinimumSamplingPeriod());
    
    // Setup the button
     pinMode(BUTTON_PIN,INPUT);
     // Activate internal pull-up
     digitalWrite(BUTTON_PIN,HIGH);
     
     // After setting up the button, setup debouncer
     debouncer.attach(BUTTON_PIN);
     debouncer.interval(5);
    
     // Make sure relays are off when starting up
     digitalWrite(RELAY_PIN, RELAY_OFF);
     // Then set relay pins in output mode
     pinMode(RELAY_PIN, OUTPUT);   
         
     // Set relay to last known state (using eeprom storage) 
     state = loadState(CHILD_ID);
     digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
    
    
    }
    
    
    void loop()      
    {  
    // Force reading sensor, so it works also after sleep()
    dht.readSensor(true);
    
    // Get temperature from DHT library
    float temperature = dht.getTemperature();
    if (isnan(temperature)) {
      Serial.println("Failed reading temperature from DHT!");
    } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
      // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
      lastTemp = temperature;
      if (!metric) {
        temperature = dht.toFahrenheit(temperature);
      }
      // Reset no updates counter
      nNoUpdatesTemp = 0;
      temperature += SENSOR_TEMP_OFFSET;
      send(msgTemp.set(temperature, 1));
    
      #ifdef MY_DEBUG
      Serial.print("T: ");
      Serial.println(temperature);
      #endif
    } else {
      // Increase no update counter if the temperature stayed the same
      nNoUpdatesTemp++;
    }
    
    // Get humidity from DHT library
    float humidity = dht.getHumidity();
    if (isnan(humidity)) {
      Serial.println("Failed reading humidity from DHT");
    } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
      // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
      lastHum = humidity;
      // Reset no updates counter
      nNoUpdatesHum = 0;
      send(msgHum.set(humidity, 1));
    
      #ifdef MY_DEBUG
      Serial.print("H: ");
      Serial.println(humidity);
      #endif
    } else {
      // Increase no update counter if the humidity stayed the same
      nNoUpdatesHum++;
    }
    
    //Relay voidloop
    debouncer.update();
    // Get the update value
    int value = debouncer.read();
    if (value != oldValue && value==0) {
        send(msg.set(state?false:true), true); // Send new state and request ack back
    }
    oldValue = value;
    } 
    
    void receive(const MyMessage &message) {
    // We only expect one type of message from controller. But we better check anyway.
    if (message.isAck()) {
       Serial.println("This is an ack from gateway");
    }
    
    if (message.type == V_LIGHT) {
       // Change relay state
       state = message.getBool();
       digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
       // Store state in eeprom
       saveState(CHILD_ID, state);
      
       // Write some debug info
       Serial.print("Incoming change for sensor:");
       Serial.print(message.sensor);
       Serial.print(", New status: ");
       Serial.println(message.getBool());
     } 
    }
    

  • Mod

    try to put a wait(500) at end of loop function, or even wait(1000)



  • This post is deleted!


  • @gohan said in Combining relay and temperature sketch:

    wait(1000)

    Oh.. like I said : something stupid..

    Thanks a lot. πŸ™‚

    I also had "#define MY_NODE_ID 7", because I couldn't see the relay on my Vera.


  • Mod

    DHT sensor doesn't like to work very quickly, it needs some resting time between measurements πŸ˜„



  • @gohan modfied my code..... still the same.... I get 16 children (relays) and no temp...... I have 4 ds18b20's connected.....
    And I get the error switch command on the relays....πŸ˜‘πŸ˜‘



  • Ok, now I have another problem.

    When I build the relay/dht node, I first made the thing work with the relay with button actuator sketch alone (the DHT was plugged, but it was an additional feature I wanted to add).

    Now, it seems that my power source doesn't have enough power to make the relay to close. The led on my relay board blinks when the relay is on and off, but nothing.

    That's weird.. I'll try running the relay sketch alone, just to see.


  • Mod

    @Tim76 ok, let's go back to the beginning. Try with one sensors only, if everything works then add one relay, then add the second and keep adding the sensors until you see something wrong. You need to go step by step, otherwise with all that stuff you have it will be impossible to debug.



  • @gohan ok



  • @gohan both sketches work perfectly stand alone.... but I think the problem lies within the assingment of the child id's...
    James Bruce talks about this "bug" in his video on how to combine sketches.....
    They relay sketch assigns from 1 to 16
    And the temp sketch assigns from 0 to 15
    So they both try to use the same id's for their children when you try to combine them....
    I need a way to get around that and have relays on 1-16 and temp on 17 to 32......
    Or there might just be the same "bug" in the temperature sketch.....😬😬 wich might mean that they can't be combined for now......πŸ˜’πŸ˜’


  • Mod

    if use something like this in presentation?

    for (int i=1; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
         present(i+3, S_TEMP);
    

    you get the idea, just shift the child id of the dallas sensors and leave the first 4-5 IDs for relays



  • @gohan aha! Will be trying that later tonight..... I'll keep you posted! 😊 Thx man!



  • @gohan soooooo...... I tried this:

    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=1; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
         present(i+16, S_TEMP);
      }
      for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);
        // Set relay to last known state (using eeprom storage)
        digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
      }
    }
    
    

    now I get the temp sensors with child id's 1 to 16 and no relays at all


  • Mod

    I probably used wrong sintax



  • @gohan tried this again...... same result.....

    
      // Fetch the number of attached temperature sensors  
      numSensors = sensors.getDeviceCount();
    
      // Present all sensors to controller
      for (int i=17; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
         present(i, S_TEMP);
      }
      for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);
        // Set relay to last known state (using eeprom storage)
        digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
      }
    }
    


  • here's the complete code as she is right now...

    
    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    #define MY_RF24_CE_PIN 49
    #define MY_RF24_CS_PIN 53
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    #define MY_NODE_ID 30
    
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DallasTemperature.h>
    #include <OneWire.h>
    
    
    
    #define COMPARE_TEMP 1 // 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
    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 msgTemp(0,V_TEMP);
    
    
    #define RELAY_1  30  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 16 // Total number of attached relays
    #define RELAY_ON 0  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 1 // GPIO value to write to turn off attached relay
    
    void before()
    {
      // Startup up the OneWire library
      sensors.begin();
    }
    
    void setup()  
    { 
      // requestTemperatures() will not block current thread
      sensors.setWaitForConversion(false);
    }
    
    void presentation() {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Greenhouse main controller", "1.0");
    
      // Fetch the number of attached temperature sensors  
      numSensors = sensors.getDeviceCount();
    
      // Present all sensors to controller
      for (int i=17; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
         present(i, S_TEMP);
      }
      for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);
        // Set relay to last known state (using eeprom storage)
        digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
      }
    }
    
    void 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)
      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(msgTemp.setSensor(i).set(temperature,1));
          // Save new temperatures for next compare
          lastTemperature[i]=temperature;
        }
      }
      wait(3000);
      }
      void receive(const MyMessage &message)
    {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type==V_STATUS) {
        // Change relay state
        digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
        // Store state in eeprom
        saveState(message.sensor, message.getBool());
        // Write some debug info
        Serial.print("Incoming change for sensor:");
        Serial.print(message.sensor);
        Serial.print(", New status: ");
        Serial.println(message.getBool());
      }
    }```

  • Mod

    @Tim76 you forgot to present the relays.... πŸ˜“



  • @gohan no I didn't...

      // Present all sensors to controller
      for (int i=17; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
         present(i, S_TEMP);
      }
      for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);
        // Set relay to last known state (using eeprom storage)
        digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
      }
    }```


  • @gohan seems like it's early for both of us.....;-)


  • Mod

    you only have present(i, S_TEMP) but you also need to add present(sensor, S_BINARY) in the relay section otherwise you will not present any relay at all.



  • @gohan 😳😳😳 seems like it's only early for one of us...... I,ll change it later today.....



  • @gohan so I fixed that....... and now I get this in Domoticz....

    0 Unknown! #1. V_TEMP (20.7) true 2017-05-10 11:44:39
    1 S_LIGHT/S_BINARY #1. V_TEMP (20.7) true 2017-05-10 11:44:43
    2 S_LIGHT/S_BINARY #1. V_TEMP (20.9) true 2017-05-10 11:44:04
    3 S_LIGHT/S_BINARY true 2017-05-10 11:34:13
    4 S_LIGHT/S_BINARY true 2017-05-10 11:34:14
    5 S_LIGHT/S_BINARY true 2017-05-10 11:34:15
    6 S_LIGHT/S_BINARY true 2017-05-10 11:34:15
    7 S_LIGHT/S_BINARY true 2017-05-10 11:34:16
    8 S_LIGHT/S_BINARY true 2017-05-10 11:34:17
    9 S_LIGHT/S_BINARY true 2017-05-10 11:34:17
    10 S_LIGHT/S_BINARY true 2017-05-10 11:34:18
    11 S_LIGHT/S_BINARY true 2017-05-10 11:34:18
    12 S_LIGHT/S_BINARY true 2017-05-10 11:34:19
    13 S_LIGHT/S_BINARY true 2017-05-10 11:34:19
    14 S_LIGHT/S_BINARY true 2017-05-10 11:34:20
    15 S_LIGHT/S_BINARY true 2017-05-10 11:34:20
    16 S_LIGHT/S_BINARY true 2017-05-10 11:34:21
    17 S_TEMP true 2017-05-10 11:34:12
    18 S_TEMP true 2017-05-10 11:34:12
    255 S_ARDUINO_NODE 2.1.1 false 2017-05-10 11:34:12

    so it seems I do get temp Id's from 17 to 32, but the values stay in 0,1,2 where the relays 1 and 2 don't work.....


  • Mod

    There must be a bug in the relay section, I can't check it today, I'm out all day.
    Try to add some debug serial print to see what values are being exchanged



  • @gohan output of the serial port

    0 MCO:BGN:INIT NODE,CP=RNNNA--,VER=2.1.1
    3 MCO:BGN:BFR
    144 TSM:INIT
    145 TSF:WUR:MS=0
    153 TSM:INIT:TSP OK
    154 TSM:INIT:STATID=51
    157 TSF:SID:OK,ID=51
    158 TSM:FPAR
    195 TSF:MSG:SEND,51-51-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    986 TSF:MSG:READ,0-0-51,s=255,c=3,t=8,pt=1,l=1,sg=0:0
    990 TSF:MSG:FPAR OK,ID=0,D=1
    2202 TSM:FPAR:OK
    2203 TSM:ID
    2204 TSM:ID:OK
    2206 TSM:UPL
    2211 TSF:MSG:SEND,51-51-0-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=OK:1
    2232 TSF:MSG:READ,0-0-51,s=255,c=3,t=25,pt=1,l=1,sg=0:1
    2237 TSF:MSG:PONG RECV,HP=1
    2240 TSM:UPL:OK
    2241 TSM:READY:ID=51,PAR=0,DIS=1
    2246 TSF:MSG:SEND,51-51-0-0,s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=OK:0100
    2284 TSF:MSG:READ,0-0-51,s=255,c=3,t=15,pt=6,l=2,sg=0:0100
    2291 TSF:MSG:SEND,51-51-0-0,s=255,c=0,t=17,pt=0,l=5,sg=0,ft=0,st=OK:2.1.1
    2301 TSF:MSG:SEND,51-51-0-0,s=255,c=3,t=6,pt=1,l=1,sg=0,ft=0,st=OK:0
    4329 TSF:MSG:SEND,51-51-0-0,s=255,c=3,t=11,pt=0,l=25,sg=0,ft=0,st=OK:Greenhouse main controlle
    4340 TSF:MSG:SEND,51-51-0-0,s=255,c=3,t=12,pt=0,l=3,sg=0,ft=0,st=OK:1.0
    4350 TSF:MSG:SEND,51-51-0-0,s=17,c=0,t=6,pt=0,l=0,sg=0,ft=0,st=OK:
    4359 TSF:MSG:SEND,51-51-0-0,s=18,c=0,t=6,pt=0,l=0,sg=0,ft=0,st=OK:
    4369 TSF:MSG:SEND,51-51-0-0,s=1,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
    4376 TSF:MSG:SEND,51-51-0-0,s=2,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
    4384 TSF:MSG:SEND,51-51-0-0,s=3,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
    4397 TSF:MSG:SEND,51-51-0-0,s=4,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
    4407 TSF:MSG:SEND,51-51-0-0,s=5,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
    4418 TSF:MSG:SEND,51-51-0-0,s=6,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
    4434 TSF:MSG:SEND,51-51-0-0,s=7,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
    4449 TSF:MSG:SEND,51-51-0-0,s=8,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
    4459 TSF:MSG:SEND,51-51-0-0,s=9,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
    4489 TSF:MSG:SEND,51-51-0-0,s=10,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
    4505 TSF:MSG:SEND,51-51-0-0,s=11,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
    4515 TSF:MSG:SEND,51-51-0-0,s=12,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
    4528 TSF:MSG:SEND,51-51-0-0,s=13,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
    4540 TSF:MSG:SEND,51-51-0-0,s=14,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
    4556 TSF:MSG:SEND,51-51-0-0,s=15,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
    4564 TSF:MSG:SEND,51-51-0-0,s=16,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
    4571 MCO:REG:REQ
    4576 TSF:MSG:SEND,51-51-0-0,s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=OK:2
    4583 TSF:MSG:READ,0-0-51,s=255,c=3,t=27,pt=1,l=1,sg=0:1
    4588 MCO:PIM:NODE REG=1
    4590 MCO:BGN:STP
    4591 MCO:BGN:INIT OK,TSP=1
    4596 MCO:SLP:MS=750,SMS=0,I1=255,M1=255,I2=255,M2=255
    4601 MCO:SLP:TPD
    4602 MCO:SLP:WUP=-1
    4636 TSF:MSG:SEND,51-51-0-0,s=0,c=1,t=0,pt=7,l=5,sg=0,ft=0,st=OK:20.2
    4690 TSF:MSG:SEND,51-51-0-0,s=1,c=1,t=0,pt=7,l=5,sg=0,ft=0,st=OK:20.5
    4755 TSF:MSG:SEND,51-51-0-0,s=2,c=1,t=0,pt=7,l=5,sg=0,ft=0,st=OK:20.4
    7763 MCO:SLP:MS=750,SMS=0,I1=255,M1=255,I2=255,M2=255
    7768 MCO:SLP:TPD
    7770 MCO:SLP:WUP=-1
    10898 MCO:SLP:MS=750,SMS=0,I1=255,M1=255,I2=255,M2=255
    10902 MCO:SLP:TPD
    10904 MCO:SLP:WUP=-1


  • Mod

    I'm talking about adding code to your sketch so that it prints in serial monitor the values before they are sent for presentations and you debug from those, I can't debug it for you from here πŸ˜€



  • @gohan oh.... ok..... pretty new at coding, but I guess you allready figured that out.....;-)


  • Mod

    No problem, it's normal, everybody started from being new at coding.
    For debugging add only 1 or 2 temp sensors and same for relays, work it out simple and then add more



  • @gohan hey Gohan,
    I will not be able to continue to work on my code till after the weekend....πŸ˜‘


  • Mod

    No problem, I'm here anyway πŸ˜€



  • @gohan
    Due to work related schedule problems I won't be able to work on this code for a few weeks...... 😠



  • Did you get this working and if so can you share?



  • @newzwaver I'm curious aswell, been pounding my head all night trying to get a temperature and relay into one sketch.



  • HI

    I did get it to work and will post the sketch later today after work. I have it working on the ESP8266 and Arduino.



  • I figured why wait, this has the temp, hum and 2 relays working not problem. One relay controls my fan for my AV and the other controls my doorbell for my HTD Lync system.

    /**
     * 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.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0: Henrik EKblad
     * Version 1.1 - 2016-07-20: Converted to MySensors v2.0 and added various improvements - Torben Woltjen (mozzbozz)
     * 
     * DESCRIPTION
     * This sketch provides an example of how to implement a humidity/temperature
     * sensor using a DHT11/DHT-22.
     *  
     * For more information, please visit:
     * http://www.mysensors.org/build/humidity
     * 
     */
    
    // Enable debug prints
    #define MY_DEBUG
    #define MY_NODE_ID 29
    // Enable and select radio type attached 
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    //#define MY_RS485
    
    // Enable repeater functionality for this node
    #define MY_REPEATER_FEATURE
    
    
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DHT.h>
    
      
    // Set this to the pin you connected the DHT's data pin to
    #define DHT_DATA_PIN 3
    
    #define RELAY_1  4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define RELAY_2  5  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    
    #define NUMBER_OF_RELAYS 2 // Total number of attached relays
    #define RELAY_ON 1  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    
    // Set this offset if the sensor has a permanent small offset to the real temperatures
    #define SENSOR_TEMP_OFFSET 0
    
    // Sleep time between sensor updates (in milliseconds)
    // Must be >1000ms for DHT22 and >2000ms for DHT11
    static const uint64_t UPDATE_INTERVAL = 60000;
    
    // Force sending an update of the temperature after n sensor reads, so a controller showing the
    // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
    // the value didn't change since;
    // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
    static const uint8_t FORCE_UPDATE_N_READS = 10;
    
    #define CHILD_ID_HUM 28
    #define CHILD_ID_TEMP 30
    
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    bool metric = true;
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    DHT dht;
    void before()
    {
      for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);
        // Set relay to last known state (using eeprom storage)
        digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
      }
    }
    
    void presentation()  
    { 
      // Send the sketch version information to the gateway
      sendSketchInfo("AVCABRelayTempAndHumidity", "1.1");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
    
      metric = getControllerConfig().isMetric;
    }
    
    
    void setup()
    {
      dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
      if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
        Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
      }
      // Sleep for the time of the minimum sampling period to give the sensor time to power up
      // (otherwise, timeout errors might occure for the first reading)
      sleep(dht.getMinimumSamplingPeriod());
    }
    
    
    void receive(const MyMessage &message)     
    {  
      // Force reading sensor, so it works also after sleep()
      dht.readSensor(true);
    
      // Get temperature from DHT library
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
        Serial.println("Failed reading temperature from DHT!");
      } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
        // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
        lastTemp = temperature;
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        }
        // Reset no updates counter
        nNoUpdatesTemp = 0;
        temperature += SENSOR_TEMP_OFFSET;
        send(msgTemp.set(temperature, 1));
    
        #ifdef MY_DEBUG
        Serial.print("T: ");
        Serial.println(temperature);
        #endif
      } else {
        // Increase no update counter if the temperature stayed the same
        nNoUpdatesTemp++;
      }
    
      // Get humidity from DHT library
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
        Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
        // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
        lastHum = humidity;
        // Reset no updates counter
        nNoUpdatesHum = 0;
        send(msgHum.set(humidity, 1));
      if (message.type==V_STATUS) {
    
        // Change relay state
        digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
        // Store state in eeprom
        saveState(message.sensor, message.getBool());
        #ifdef MY_DEBUG
        Serial.print("H: ");
        Serial.println(humidity);
        Serial.print("Incoming change for sensor:");
        Serial.print(message.sensor);
        Serial.print(", New status: ");
        Serial.println(message.getBool());
        #endif
      } else {
        // Increase no update counter if the humidity stayed the same
        nNoUpdatesHum++;
      }
    
      // Sleep for a while to save energy
      sleep(UPDATE_INTERVAL); 
      }}
    


  • @newzwaver your code is pretty hard to read due to not beeing entirely formatted as code.
    Nevertheless there seems not to exist any loop() section and the node is put to sleep after having received anything for a certain periode of time.
    This may work in most cases, but imo is not a "lucky code design".

    Imo better aproach:
    Use the https://www.arduino.cc/en/tutorial/BlinkWithoutDelay - principle. Additionally a wait() is used instead of sleep() for the time to fulfill measurements (DS18B20 in my case).
    If you need a working implementation of the blink-without-delay function within MySensors, see the https://www.mysensors.org/build/pulse_power example.
    At least three of my nodes (combining temperature and relays) work pretty well like that.



  • @rejoe2 said in Combining relay and temperature sketch:

    Thanks Newzwaver

    You wouldn't happen to have a sketch with the DS18B20? I have both DHTs and DS18B20s but plan on using this to turn on and off a fan to keep my AV equipment cool. So I'm not that concerned about humidity although it wouldn't be deal breaker if it did.

    Thanks,



  • @bluezr1 Sure... But imo it is easier to stick with the given examples, they may be much easier to understand than e.g. this one😁


  • MySensors Evangelist

    @rejoe2 NIce example thanks.



  • @sincze Thanks too.
    Just to mention: I don't use the internal functionality for the servo any more - this part didn't work to my personal satisfaction.
    If you're interested: The RS485 variant in the repo is even more complex - it uses three Pins for 1wire with different timings, but may require some tweeks in the libs to compile.



  • Thank you so much Newzwaver. I've been trying to combine two sketches together and this is my first successful one. I may never be as good as most of the people on this forum, although I don't plan on stopping with combining more than one sensor to one node -- need to get rid of my double nodes I have in various places. πŸ™‚

    When I ran your sketch and the relays didn't show up in vera. So after I copied and pasted from the relay sketch posted by hek under void presentation, I ended up with errors. So after comparing the two (yours to hek's) I ended up with this that seems to be working.

    As of right now I'm looking into what rejoe2 said about using wait instead of sleep, unless I'll be fine with what I have?

    /**
     * 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.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0: Henrik EKblad
     * Version 1.1 - 2016-07-20: Converted to MySensors v2.0 and added various improvements - Torben Woltjen (mozzbozz)
     * 
     * DESCRIPTION
     * This sketch provides an example of how to implement a humidity/temperature
     * sensor using a DHT11/DHT-22.
     *  
     * For more information, please visit:
     * http://www.mysensors.org/build/humidity
     * 
     */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached 
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    //#define MY_RS485
    
    // Enable repeater functionality for this node
    //#define MY_REPEATER_FEATURE
    
    #define MY_NODE_ID 10
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DHT.h>
    
      
    // Set this to the pin you connected the DHT's data pin to
    #define DHT_DATA_PIN 3
    
    //#define RELAY1_PIN  4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    //#define RELAY2_PIN  5  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    
    #define RELAY_PIN 4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 2 // Total number of attached relays
    #define RELAY_ON 1  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    
    // Set this offset if the sensor has a permanent small offset to the real temperatures
    #define SENSOR_TEMP_OFFSET 0
    
    // Sleep time between sensor updates (in milliseconds)
    // Must be >1000ms for DHT22 and >2000ms for DHT11
    static const uint64_t UPDATE_INTERVAL = 1000;
    
    // Force sending an update of the temperature after n sensor reads, so a controller showing the
    // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
    // the value didn't change since;
    // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
    static const uint8_t FORCE_UPDATE_N_READS = 10;
    
    #define CHILD_ID_HUM 28
    #define CHILD_ID_TEMP 30
    
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    bool metric = true;
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    DHT dht;
    void before()
    {
        for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Then set relay pins in output mode
            pinMode(pin, OUTPUT);
            // Set relay to last known state (using eeprom storage)
            digitalWrite(pin, loadState(sensor)?RELAY_OFF:RELAY_ON);
        }
    }
    
    void presentation()  
    { 
      // Send the sketch version information to the gateway
      sendSketchInfo("AVCABRelayTempAndHumidity", "1.1");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
      
        for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Register all sensors to gw (they will be created as child devices)
            present(sensor, S_BINARY);
        }
    
      metric = getControllerConfig().isMetric;
    }
    
    
    void setup()
    {
      dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
      if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
        Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
      }
      // Sleep for the time of the minimum sampling period to give the sensor time to power up
      // (otherwise, timeout errors might occure for the first reading)
      sleep(dht.getMinimumSamplingPeriod());
    }
    
    void loop()      
    {
      // Force reading sensor, so it works also after sleep()
      dht.readSensor(true);
    
      // Get temperature from DHT library
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
        Serial.println("Failed reading temperature from DHT!");
      } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
        // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
        lastTemp = temperature;
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        }
        // Reset no updates counter
        nNoUpdatesTemp = 0;
        temperature += SENSOR_TEMP_OFFSET;
        send(msgTemp.set(temperature, 1));
    
        #ifdef MY_DEBUG
        Serial.print("T: ");
        Serial.println(temperature);
        #endif
      } else {
        // Increase no update counter if the temperature stayed the same
        nNoUpdatesTemp++;
      }
    
      // Get humidity from DHT library
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
        Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
        // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
        lastHum = humidity;
        // Reset no updates counter
        nNoUpdatesHum = 0;
        send(msgHum.set(humidity, 1));
    
        #ifdef MY_DEBUG
        Serial.print("H: ");
        Serial.println(humidity);
        #endif
      } else {
        // Increase no update counter if the humidity stayed the same
        nNoUpdatesHum++;
      }
    
      // Sleep for a while to save energy
      sleep(UPDATE_INTERVAL); 
    }
      
    void receive(const MyMessage &message)
    {
        // We only expect one type of message from controller. But we better check anyway.
        if (message.type==V_STATUS) {
            // Change relay state
            digitalWrite(message.sensor-1+RELAY_PIN, message.getBool()?RELAY_OFF:RELAY_ON);
            // Store state in eeprom
            saveState(message.sensor, message.getBool());
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(message.getBool());
        }
    }```


  • @bluezr1 Great to hear about you having first positive results.

    Nevertheless, imo the sketch you posted is designed against some basic principles.

    First: all main functions should be placed in the loop() section (not present in this sketch). The posted sketch does all the measurements within an exceptional routine called receive(). This should be reserved for all functionality that really is related to receive any info from controller side - obviously doing measurements does not belong to that category.

    I also started as complete noob to coding around 30 months ago and just followed the examples (mostly from Build section), so be assured: you will also learn how to do this just by following these examples and ask yourself why things are solved the way they are.

    If you need a good example of a combined sketch, have a look at the atmospheric pressure one (or the DHT (humidity?) sketch you have used here): They already have two children... From the BME180-Preassure you may follow the route to the BME280 examples available in the forum here or in my repo (#98, RS485).

    Btw: In the header section of your sketch there are also two defines left not necessary (just as a info, this does not cause any trouble for the moment).


  • MySensors Evangelist

    haha combining sketches... frees up some hardware πŸ˜‰ for other stuff.

    0_1512839095158_WhatsApp Image 2017-12-09 at 18.04.14.jpeg



  • @rejoe2 I listened to what you said and then went back over it, it's working much better now. What you said "why things are solved the way they are" made me stand back for a moment. I do Maintenance for a living and work on everything from HVAC, boilers, Kitchen equipment to hanging drywall. There's always one thing I always tell myself when troubleshooting something, what's the sequence of operation. Well I'm not to savvy with writing code although the same principles applies. Maybe I just needed someone to tell me that, I don't know.

    Anyways, thank you

    I updated the sketch I posted in my last post with the changes I made.



  • @sincze Does not only free HW for other stuff, but also makes things easier once they work as expected. I have to admitt this in some cases may need hard work to get to that point.
    What's the "other stuff" showed on your picture?

    @bluezr1 Looks like a big step ahead!

    Imo next step in your code should be to have a look at the remarks I already posted and replace the sleep() by wait(). By now, you have a rather fast update rate of your values, this may not be necessary and also may lead to a early wear-out of your DHT (?):

    @rejoe2 said in Combining relay and temperature sketch:

    Imo better aproach:
    Use the https://www.arduino.cc/en/tutorial/BlinkWithoutDelay - principle. Additionally a wait() is used instead of sleep() for the time to fulfill measurements (DS18B20 in my case).
    If you need a working implementation of the blink-without-delay function within MySensors, see the https://www.mysensors.org/build/pulse_power example.

    Please keep in mind changing existent posts like you did may lead to irritation wrt to the remarks in following posts. You may better show the resulting code as an update in your next answer and add a remark wrt. to enhancements in the earlier one.



  • @rejoe2 Just so I know that I’m not heading down the wrong path and wasting everyone’s time, I should be looking into the use of millis correct?



  • @bluezr1 Yes, millis() is the right thing to look for (or the simpleTimer2-lib, that internally does the same things). But keep in mind: sleep() and millis() don't fit well together, as after every sleep() millis() will be reset... Use wait() instead of sleep() in case you need short periods eg. between initialising and completion of measurements.



  • This is where I'm currently at, it seems to be working really well. Thanks rejoe2

    /**
     * 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.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0: Henrik EKblad
     * Version 1.1 - 2016-07-20: Converted to MySensors v2.0 and added various improvements - Torben Woltjen (mozzbozz)
     * 
     * DESCRIPTION
     * This sketch provides an example of how to implement a humidity/temperature
     * sensor using a DHT11/DHT-22.
     *  
     * For more information, please visit:
     * http://www.mysensors.org/build/humidity
     * 
     */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached 
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    //#define MY_RS485
    
    #define MY_NODE_ID 19
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DHT.h>
    
    // Set this to the pin you connected the DHT's data pin to
    #define DHT_DATA_PIN 3
    
    // Set this offset if the sensor has a permanent small offset to the real temperatures
    #define SENSOR_TEMP_OFFSET 0
    
    // Sleep time between sensor updates (in milliseconds)
    // Must be >1000ms for DHT22 and >2000ms for DHT11
    static const uint64_t UPDATE_INTERVAL = 60000;
    
    // Force sending an update of the temperature after n sensor reads, so a controller showing the
    // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
    // the value didn't change since;
    // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
    static const uint8_t FORCE_UPDATE_N_READS = 10;
    
    #define CHILD_ID_HUM 10
    #define CHILD_ID_TEMP 11
    
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    bool metric = true;
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    DHT dht;
    
    #define RELAY_PIN 4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 2 // Total number of attached relays
    #define RELAY_ON 1  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    
    
    void before()
    {
        for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Then set relay pins in output mode
            pinMode(pin, OUTPUT);
            // Set relay to last known state (using eeprom storage)
            digitalWrite(pin, loadState(sensor)?RELAY_OFF:RELAY_ON);
        }
    }
    
    void presentation()  
    { 
      // Send the sketch version information to the gateway
      sendSketchInfo("TempRELAY", "1.1");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
    
      metric = getControllerConfig().isMetric;
    
      for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Register all sensors to gw (they will be created as child devices)
            present(sensor, S_BINARY);
        }
    }
    
    
    void setup()
    {
      dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
      if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
        Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
      }
      // Sleep for the time of the minimum sampling period to give the sensor time to power up
      // (otherwise, timeout errors might occure for the first reading)
      wait(dht.getMinimumSamplingPeriod());
    }
    
    
    void loop()      
    {  
      // Force reading sensor, so it works also after sleep()
      dht.readSensor(true);
    
      // Get temperature from DHT library
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
        Serial.println("Failed reading temperature from DHT!");
      } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
        // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
        lastTemp = temperature;
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        }
        // Reset no updates counter
        nNoUpdatesTemp = 0;
        temperature += SENSOR_TEMP_OFFSET;
        send(msgTemp.set(temperature, 1));
    
        #ifdef MY_DEBUG
        Serial.print("T: ");
        Serial.println(temperature);
        #endif
      } else {
        // Increase no update counter if the temperature stayed the same
        nNoUpdatesTemp++;
      }
    
      // Get humidity from DHT library
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
        Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
        // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
        lastHum = humidity;
        // Reset no updates counter
        nNoUpdatesHum = 0;
        send(msgHum.set(humidity, 1));
    
        #ifdef MY_DEBUG
        Serial.print("H: ");
        Serial.println(humidity);
        #endif
      } else {
        // Increase no update counter if the humidity stayed the same
        nNoUpdatesHum++;
      }
    
      // Sleep for a while to save energy
      wait(UPDATE_INTERVAL); 
    }
    
    void receive(const MyMessage &message)
    {
        // We only expect one type of message from controller. But we better check anyway.
        if (message.type==V_STATUS) {
            // Change relay state
            digitalWrite(message.sensor-1+RELAY_PIN, message.getBool()?RELAY_OFF:RELAY_ON);
            // Store state in eeprom
            saveState(message.sensor, message.getBool());
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(message.getBool());
        }
    }```


  • @bluezr1 Looks already really good.
    Question: does the receive() work while the loop does the wait()? I'm not sure about that, because I am used to do the millis()-nonblocking-loop.



  • @rejoe2 I hope that this answers your question. I use Vera as my home controller and tried multiple times turning (sometimes randomly) on and off both relays without any misses as soon as Vera allowed me. Meaning, Vera won’t let you instantly turn a device on and then off or vise versa.

    Do you think I’ll be ok the way it is or should I keep working on this project?



  • @bluezr1 As it seems to work to your satisfaction, you may leave it as is.
    FHEM as a controller allows direct interaction with switching devices, and it is really astonishing to hear Vera may have some restrictions wrt. that.

    But I didn't test your code in my setup, this is why I asked about your observations.

    I may be wrong, but imo, the code isn't yet perfect, so you might keep that in mind for the future in case you run into trouble. In case you need some sort of timer for other projects, you would miss the opportunity to learn how to use this...



  • @rejoe2 It's working

    Although I'm not sure if this part makes sense?

    static const uint64_t UPDATE_INTERVAL = 60000;
    unsigned long interval = 60000;
    unsigned long previousMillis = 0;```
    
    /**
     * 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.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0: Henrik EKblad
     * Version 1.1 - 2016-07-20: Converted to MySensors v2.0 and added various improvements - Torben Woltjen (mozzbozz)
     * 
     * DESCRIPTION
     * This sketch provides an example of how to implement a humidity/temperature
     * sensor using a DHT11/DHT-22.
     *  
     * For more information, please visit:
     * http://www.mysensors.org/build/humidity
     * 
     */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached 
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    //#define MY_RS485
    
    #define MY_NODE_ID 20
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DHT.h>
    
    // Set this to the pin you connected the DHT's data pin to
    #define DHT_DATA_PIN 3
    
    // Set this offset if the sensor has a permanent small offset to the real temperatures
    #define SENSOR_TEMP_OFFSET 0
    
    // Sleep time between sensor updates (in milliseconds)
    // Must be >1000ms for DHT22 and >2000ms for DHT11
    static const uint64_t UPDATE_INTERVAL = 60000;
    unsigned long interval = 60000;
    unsigned long previousMillis = 0;
    
    // Force sending an update of the temperature after n sensor reads, so a controller showing the
    // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
    // the value didn't change since;
    // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
    static const uint8_t FORCE_UPDATE_N_READS = 10;
    
    #define CHILD_ID_HUM 10
    #define CHILD_ID_TEMP 11
    
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    bool metric = true;
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    DHT dht;
    
    #define RELAY_PIN 4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 2 // Total number of attached relays
    #define RELAY_ON 1  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    
    
    void before()
    {
        for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Then set relay pins in output mode
            pinMode(pin, OUTPUT);
            // Set relay to last known state (using eeprom storage)
            digitalWrite(pin, loadState(sensor)?RELAY_OFF:RELAY_ON);
        }
    }
    
    void presentation()  
    { 
      // Send the sketch version information to the gateway
      sendSketchInfo("TempRELAY", "1.1");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
    
      metric = getControllerConfig().isMetric;
    
      for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Register all sensors to gw (they will be created as child devices)
            present(sensor, S_BINARY);
        }
    }
    
    
    void setup()
    {
      dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
      if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
        Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
      }
      // Sleep for the time of the minimum sampling period to give the sensor time to power up
      // (otherwise, timeout errors might occure for the first reading)
      // wait(dht.getMinimumSamplingPeriod());
    }
    
    
    void loop()      
    { 
     unsigned long currentMillis = millis();
     if ((unsigned long)(currentMillis - previousMillis) >= interval) { 
      // Force reading sensor, so it works also after sleep()
      dht.readSensor(true);
    
      // Get temperature from DHT library
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
        Serial.println("Failed reading temperature from DHT!");
      } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
        // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
        lastTemp = temperature;
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        }
        // Reset no updates counter
        nNoUpdatesTemp = 0;
        temperature += SENSOR_TEMP_OFFSET;
        send(msgTemp.set(temperature, 1));
    
        #ifdef MY_DEBUG
        Serial.print("T: ");
        Serial.println(temperature);
        #endif
      } else {
        // Increase no update counter if the temperature stayed the same
        nNoUpdatesTemp++;
      }
    
      // Get humidity from DHT library
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
        Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
        // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
        lastHum = humidity;
        // Reset no updates counter
        nNoUpdatesHum = 0;
        send(msgHum.set(humidity, 1));
    
        #ifdef MY_DEBUG
        Serial.print("H: ");
        Serial.println(humidity);
        #endif
      } else {
        // Increase no update counter if the humidity stayed the same
        nNoUpdatesTemp++;
      }
      previousMillis = millis();
     }
    }
    
    void receive(const MyMessage &message)
    {
        // We only expect one type of message from controller. But we better check anyway.
        if (message.type==V_STATUS) {
            // Change relay state
            digitalWrite(message.sensor-1+RELAY_PIN, message.getBool()?RELAY_OFF:RELAY_ON);
            // Store state in eeprom
            saveState(message.sensor, message.getBool());
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(message.getBool());
        }
    }
    


  • @bluezr1 Looks like you did a working non-blocking loop 😁
    Didn't do a too close look to all things, but the only header definition that seems to be no longer necessary is the UPDATE_INTERVAL, as this variable isn't used any longer.

    But beside that small remark: πŸ‘



  • <<edit>>It was me, my bad, it's working.

    For some reason if I pull a wire for the relay it'll still show a change within Vera. I can turn them on and off and they'll show up as if they were turned on and off. Before if I pulled a wire to the relays vera wouldn't show any changes.

    Thank you so much rejoe2 for not just giving me the answers but by pushing me to do it myself. You pointed me to where I needed to be and I thank you for that.

    Now you got me wanting to learn even more. πŸ™‚



  • Wanted to post it incase someone else wants to use it.

    /**
     * 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.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0: Henrik EKblad
     * Version 1.1 - 2016-07-20: Converted to MySensors v2.0 and added various improvements - Torben Woltjen (mozzbozz)
     * 
     * DESCRIPTION
     * This sketch provides an example of how to implement a humidity/temperature
     * sensor using a DHT11/DHT-22.
     *  
     * For more information, please visit:
     * http://www.mysensors.org/build/humidity
     * 
     */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached 
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    //#define MY_RS485
    
    #define MY_NODE_ID 20
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DHT.h>
    
    // Set this to the pin you connected the DHT's data pin to
    #define DHT_DATA_PIN 3
    
    // Set this offset if the sensor has a permanent small offset to the real temperatures
    #define SENSOR_TEMP_OFFSET 0
    
    // Sleep time between sensor updates (in milliseconds)
    // Must be >1000ms for DHT22 and >2000ms for DHT11
    //static const uint64_t UPDATE_INTERVAL = 60000;
    unsigned long interval = 60000;
    unsigned long previousMillis = 0;
    
    // Force sending an update of the temperature after n sensor reads, so a controller showing the
    // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
    // the value didn't change since;
    // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
    static const uint8_t FORCE_UPDATE_N_READS = 10;
    
    #define CHILD_ID_HUM 10
    #define CHILD_ID_TEMP 11
    
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    bool metric = true;
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    DHT dht;
    
    #define RELAY_PIN 4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 2 // Total number of attached relays
    #define RELAY_ON 0  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 1 // GPIO value to write to turn off attached relay
    
    
    void before()
    {
        for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Then set relay pins in output mode
            pinMode(pin, OUTPUT);
            // Set relay to last known state (using eeprom storage)
            digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
        }
    }
    
    void presentation()  
    { 
      // Send the sketch version information to the gateway
      sendSketchInfo("TempRELAY", "1.1");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
    
      metric = getControllerConfig().isMetric;
    
      for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Register all sensors to gw (they will be created as child devices)
            present(sensor, S_BINARY);
        }
    }
    
    
    void setup()
    {
      dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
      //if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
       // Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
      //}
      // Sleep for the time of the minimum sampling period to give the sensor time to power up
      // (otherwise, timeout errors might occure for the first reading)
      // wait(dht.getMinimumSamplingPeriod());
    }
    
    
    void loop()      
    { 
     unsigned long currentMillis = millis();
     if ((unsigned long)(currentMillis - previousMillis) >= interval) { 
      // Force reading sensor, so it works also after sleep()
      dht.readSensor(true);
    
      // Get temperature from DHT library
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
        Serial.println("Failed reading temperature from DHT!");
      } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
        // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
        lastTemp = temperature;
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        }
        // Reset no updates counter
        nNoUpdatesTemp = 0;
        temperature += SENSOR_TEMP_OFFSET;
        send(msgTemp.set(temperature, 1));
    
        #ifdef MY_DEBUG
        Serial.print("T: ");
        Serial.println(temperature);
        #endif
      } else {
        // Increase no update counter if the temperature stayed the same
        nNoUpdatesTemp++;
      }
    
      // Get humidity from DHT library
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
        Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
        // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
        lastHum = humidity;
        // Reset no updates counter
        nNoUpdatesHum = 0;
        send(msgHum.set(humidity, 1));
    
        #ifdef MY_DEBUG
        Serial.print("H: ");
        Serial.println(humidity);
        #endif
      } else {
        // Increase no update counter if the humidity stayed the same
        nNoUpdatesTemp++;
      }
      previousMillis = millis();
     }
    }
    
    void receive(const MyMessage &message)
    {
        // We only expect one type of message from controller. But we better check anyway.
        if (message.type==V_STATUS) {
            // Change relay state
            digitalWrite(message.sensor-1+RELAY_PIN, message.getBool()?RELAY_ON:RELAY_OFF);
            // Store state in eeprom
            saveState(message.sensor, message.getBool());
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(message.getBool());
        }
    }```


  • @bluezr1 said in Combining relay and temperature sketch:

    Thank you so much rejoe2 for not just giving me the answers but by pushing me to do it myself. You pointed me to where I needed to be and I thank you for that.

    Now you got me wanting to learn even more. πŸ™‚
    Thanks also a lot for your positive feedback - seems there are more and more people interested in quick fixes, but imo, it's by far better to "learn how to fish".

    For the next steps, I'd recommend to do some more "combinded sketching", based on the existing build examples - but you'll find that easy once you did the next two of them 😁

    One more interesting thing may be working with interrups in non-blocking sketches - please mind the needed type of variable definition to avoid irritating effects πŸ˜‰

    Then you might run into trouble as combining things needs more PINs - then you are forced to have a look on the next level of abstraction: array functions πŸ˜‰ . For a start, you may analyse the multi-button-relay-sketch somwhere around here in the forum.

    Then you are at least on my level of knowledge within one week 😁



  • Hi
    I need help... I want use sketch for 2 relay and sensor temp Dallas SD18b20.
    I have working sketch for 2xrelay and put to it sketch from mysensors
    https://www.mysensors.org/build/temp

    for Dallas but it not working. Not showing temp from Dallas. In DOmotcz on Gateway show only Binary from relay. Not Show Temp.

    /**
       DESCRIPTION
       Sketch for 2x relay with buttons monostable. After back power all relays set OFF and send correct status OFF to controller.  
    */
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_RFM69
    #define MY_RFM69_FREQUENCY RF69_868MHZ
    #define MY_IS_RFM69HW
    
    // Enabled repeater feature for this node
    #define MY_REPEATER_FEATURE
    
    // Node id defaults to AUTO (tries to fetch id from controller)
    #define MY_NODE_ID AUTO
    
    #include <SPI.h>
    #include <MySensors.h>
    #include <Bounce2.h>
    #include <DallasTemperature.h>
    #include <OneWire.h>
    
    // Define Relays
    #define RELAY_ON 0  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 1  // GPIO value to write to turn off attached relay
    
    // Define Sensor ID's
    #define SSR_A_ID 1   // Id of the sensor child
    #define SSR_B_ID 2   // Id of the sensor child
    
    // Define buttons and relays
    const int buttonPinA = 3;
    const int buttonPinB = 4;
    const int relayPinA = 5;
    const int relayPinB = 6;
    
    // Define Variables
    int oldValueA = 0;
    int oldValueB = 0;
    bool stateA = false;
    bool stateB = false;
    int trigger = 0;
    
    // Define Sensors Temperature
    #define COMPARE_TEMP 1 // 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 = 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;
    
    Bounce debouncerA = Bounce();
    Bounce debouncerB = Bounce();
    
    MyMessage msgA(SSR_A_ID, V_STATUS);
    MyMessage msgB(SSR_B_ID, V_STATUS);
    // Initialize temperature message
    MyMessage msg(0,V_TEMP);
    
    void before()
    {
      // Startup up the OneWire library
      sensors.begin();
    }
    
    void setup()
    {
    
      pinMode(buttonPinA, INPUT_PULLUP); // Setup the button Activate internal pull-up
      pinMode(buttonPinB, INPUT_PULLUP); // Setup the button Activate internal pull-up
    
    
      // After setting up the buttons, setup debouncer
      debouncerA.attach(buttonPinA);
      debouncerA.interval(5);
      debouncerB.attach(buttonPinB);
      debouncerB.interval(5);
    
      // Make sure relays are off when starting up
      digitalWrite(relayPinA, RELAY_OFF);
      digitalWrite(relayPinB, RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(relayPinA, OUTPUT);
      pinMode(relayPinB, OUTPUT);
    
      // requestTemperatures() will not block current thread
      sensors.setWaitForConversion(false);
    
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("2xRelay monostable + temp. DS18b20", "2.1.1");
    
      // Register all sensors to gw (they will be created as child devices)
      present(SSR_A_ID, S_LIGHT);
      present(SSR_B_ID, S_LIGHT);
    
      // 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()
    {
    if (trigger == 0){
      send(msgA.set(false)); // Send off state for relayA to ensure controller knows the switch is off
      send(msgB.set(false)); // Send off state for relayB to ensure controller knows the switch is off
      trigger = 1;
    }
      
      debouncerA.update();
      // Get the update value
      int valueA = debouncerA.read();
      if (valueA != oldValueA && valueA == 0) {
        send(msgA.set(stateA ? false : true), true); // Send new state and request ack back
    
      }
      oldValueA = valueA;
     
    
      debouncerB.update();
      // Get the update value
      int valueB = debouncerB.read();
      if (valueB != oldValueB && valueB == 0) {
        send(msgB.set(stateB ? false : true), true); // Send new state and request ack back
    
      }
      oldValueB = valueB;
    
       // 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;
        }
      }
      sleep(SLEEP_TIME);
    }
    
    void receive(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type == V_STATUS) {
          
        switch (message.sensor) {
          case 1:
            stateA = message.getBool();
            digitalWrite(message.sensor + 4, stateA ? RELAY_ON : RELAY_OFF);
            
            break;
          case 2:
            stateB = message.getBool();
            digitalWrite(message.sensor + 4, stateB ? RELAY_ON : RELAY_OFF);
            
            break;
          
        }
       
          // Write some debug info
        Serial.print("Incoming change for sensor:");
        Serial.println(message.sensor);
        Serial.print("from node:");
        Serial.println(message.sender);
        Serial.print(", New status: ");
        Serial.println(message.getBool());
      }
    }```
    
    
    Please help me


  • @pepson
    Imo there are several things to look at:

    1. Pin 3 seems to be used for button a + 1-wire? -> use a different one

    2. How many DS18B20 do you have attached?
      a) In case it's up to three, you try to report Relay and Temp info partly under the same Child_ID (1+2). Imo, it's better to chose a different starting Child ID, something like "present(i+10, S_TEMP)" or use a variable like "FIRST_TEMP_CHILD" (also use the same scheme for sending).
      b) You may also suffer from a wiring problem, if you are able to compile and flash this sketch. Just for testing you could add a debugg-message to serial with the numSensors

    3. Combining relays, debounced buttons and sleep() most likely will cause problems. Better use a non-blocking loop as described in post #45 and following.



  • I use one temp sensor. Ok i try correct but i dont know how correct it for send...please help me for sending...

    And please help me with this:
    Combining relays, debounced buttons and sleep() most likely will cause problems. Better use a non-blocking loop as described in post #45 and following.

    /**
       DESCRIPTION
       Sketch for 2x relay with buttons monostable. After back power all relays set OFF and send correct status OFF to controller.  
    */
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_RFM69
    #define MY_RFM69_FREQUENCY RF69_868MHZ
    #define MY_IS_RFM69HW
    
    // Enabled repeater feature for this node
    #define MY_REPEATER_FEATURE
    
    // Node id defaults to AUTO (tries to fetch id from controller)
    #define MY_NODE_ID AUTO
    
    #include <SPI.h>
    #include <MySensors.h>
    #include <Bounce2.h>
    #include <DallasTemperature.h>
    #include <OneWire.h>
    
    // Define Relays
    #define RELAY_ON 0  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 1  // GPIO value to write to turn off attached relay
    
    // Define Sensor ID's
    #define SSR_A_ID 1   // Id of the sensor child
    #define SSR_B_ID 2   // Id of the sensor child
    
    // Define buttons and relays
    const int buttonPinA = 3;
    const int buttonPinB = 4;
    const int relayPinA = 5;
    const int relayPinB = 6;
    
    // Define Variables
    int oldValueA = 0;
    int oldValueB = 0;
    bool stateA = false;
    bool stateB = false;
    int trigger = 0;
    
    // Define Sensors Temperature
    #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
    
    #define ONE_WIRE_BUS 7 // 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;
    
    Bounce debouncerA = Bounce();
    Bounce debouncerB = Bounce();
    
    MyMessage msgA(SSR_A_ID, V_STATUS);
    MyMessage msgB(SSR_B_ID, V_STATUS);
    // Initialize temperature message
    MyMessage msg(0,V_TEMP);
    
    void before()
    {
      // Startup up the OneWire library
      sensors.begin();
    }
    
    void setup()
    {
    
      pinMode(buttonPinA, INPUT_PULLUP); // Setup the button Activate internal pull-up
      pinMode(buttonPinB, INPUT_PULLUP); // Setup the button Activate internal pull-up
    
    
      // After setting up the buttons, setup debouncer
      debouncerA.attach(buttonPinA);
      debouncerA.interval(5);
      debouncerB.attach(buttonPinB);
      debouncerB.interval(5);
    
      // Make sure relays are off when starting up
      digitalWrite(relayPinA, RELAY_OFF);
      digitalWrite(relayPinB, RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(relayPinA, OUTPUT);
      pinMode(relayPinB, OUTPUT);
    
      // requestTemperatures() will not block current thread
      sensors.setWaitForConversion(false);
    
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("2xRelay monostable + temp. DS18b20", "2.1.1");
    
      // Register all sensors to gw (they will be created as child devices)
      present(SSR_A_ID, S_LIGHT);
      present(SSR_B_ID, S_LIGHT);
    
      // 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+10, S_TEMP);
      }
    
    }
    
    
    void loop()
    {
    if (trigger == 0){
      send(msgA.set(false)); // Send off state for relayA to ensure controller knows the switch is off
      send(msgB.set(false)); // Send off state for relayB to ensure controller knows the switch is off
      trigger = 1;
    }
      
      debouncerA.update();
      // Get the update value
      int valueA = debouncerA.read();
      if (valueA != oldValueA && valueA == 0) {
        send(msgA.set(stateA ? false : true), true); // Send new state and request ack back
    
      }
      oldValueA = valueA;
     
    
      debouncerB.update();
      // Get the update value
      int valueB = debouncerB.read();
      if (valueB != oldValueB && valueB == 0) {
        send(msgB.set(stateB ? false : true), true); // Send new state and request ack back
    
      }
      oldValueB = valueB;
    
       // 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;
        }
      }
      sleep(SLEEP_TIME);
    }
    
    void receive(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type == V_STATUS) {
          
        switch (message.sensor) {
          case 1:
            stateA = message.getBool();
            digitalWrite(message.sensor + 4, stateA ? RELAY_ON : RELAY_OFF);
            
            break;
          case 2:
            stateB = message.getBool();
            digitalWrite(message.sensor + 4, stateB ? RELAY_ON : RELAY_OFF);
            
            break;
          
        }
       
          // Write some debug info
        Serial.print("Incoming change for sensor:");
        Serial.println(message.sensor);
        Serial.print("from node:");
        Serial.println(message.sender);
        Serial.print(", New status: ");
        Serial.println(message.getBool());
      }
    }```


    1. Wrt sending: your controller should show one temperature sensor with Child ID 10. As a consequence, the temp value should also be reported using this ID. So you should adopt this line appropriately, just use the same logic as in presentation() 😁 .
    send(msg.setSensor(i).set(temperature,1));
    
    1. For the non-blocking loop: As already mentionned, within this thread you just should follow @bluezr1 steps and some of my remarks πŸ˜€ .
      The sketch in #63 should be a working solution, but when using dallas temp instead of the DHT, you have also to change the sleep(conversionTime) to wait().


  • I am begginer. Can you give me ready sketch for dallas with one relay ? Please



  • @pepson Especially as a beginner you really should try to follow the necessary steps to develop combined sketches - it's easier than you may think by now.
    Otherwise you may run into the next unexpected trouble without any idea, how things fit together and - even more important - how to debug (or even where to attach what). So asking for ready sketches is not the best idea.

    If you are still convinced about the need of a ready sketch: There's - amongst others - a sketch with #101 using DS18B20 and 4 relays in my repo (link is already available in this thread). , BUT: this is work in progress, may use a modified version of the dallas lib and reports temperatures and relays under the same ChildID - my controller (FHEM) seems not to care about that...
    As I changed communication to RS485 last weekend, I most likely will not do any update, if there are issues or further enhancements on the code (I plan to do some).



  • @rejoe2 said in Combining relay and temperature sketch:

    #10

    I try also ready sketch for only dallas fom mysensors.rg but it also not working:

    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    // Enable and select radio type attached
    #define MY_RADIO_RFM69
    #define MY_RFM69_FREQUENCY RF69_868MHZ
    #define MY_IS_RFM69HW
    
    // Enabled repeater feature for this node
    #define MY_REPEATER_FEATURE
    
    // Node id defaults to AUTO (tries to fetch id from controller)
    #define MY_NODE_ID AUTO
    
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DallasTemperature.h>
    #include <OneWire.h>
    
    #define COMPARE_TEMP 1 // 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 = 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()  
    { 
      // requestTemperatures() will not block current thread
      sensors.setWaitForConversion(false);
    }
    
    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()     
    {     
      // 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;
        }
      }
      sleep(SLEEP_TIME);
    }```


  • @rejoe2 said in Combining relay and temperature sketch:

    b) You may also suffer from a wiring problem, if you are able to compile and flash this sketch. Just for testing you could add a debugg-message to serial with the numSensors

    Did you follow the instructions as described in the "build" section, attached the data line to PIN3 and used an appropriate resistor (measure it's value) ? Then it's most likely a damaged sensor...



  • @rejoe2
    Yes i connected my sensors to PIN 3 and use resistor 4.7
    But in Domoticz on gateway not show any CHILDS for this NODE.



  • @pepson Seems like the sensor is not detected, so the presentation() will have zero sensors to present...
    If you do not want to follow the proposal to print the numSensors to serial (most likely: 0) you should try to test the DS18B20-Hardware by using an example sketch (e.g. Simple.pde) from the dallas temperature lib (without the MySensors-framework) and have a look on the serial console of the IDE. Be aware: "as is", it uses PIN2 and a different baudrate.
    If there are no temperature values printed, it's either still a wiring problem or the sensor's just broken.


 

371
Online

7.7k
Users

8.6k
Topics

92.3k
Posts