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

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Troubleshooting
  3. Problem with relay+button and dallas temperature sketch combination

Problem with relay+button and dallas temperature sketch combination

Scheduled Pinned Locked Moved Troubleshooting
4 Posts 2 Posters 2.1k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • MixeurM Offline
    MixeurM Offline
    Mixeur
    wrote on last edited by Mixeur
    #1

    Hello,

    I wanted to make a node that both read temperature from 2 dallas sensors and activate a relay (with button option).
    It works pretty fine, but only for an undetermined time. Afeter sometime (1 or 2 days), if I push the button, it crahses, and i have to reset it to get the good behaviour. If I don't use the relay features, everything is working normally a long time.
    Here is the sketch :

    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    #include <DallasTemperature.h>
    #include <OneWire.h>
    
    // Partie Température
    #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
    
    #define ONE_WIRE_BUS 8 // 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;
    boolean receivedConfig = false;
    boolean metric = true; 
    // Initialize temperature message
    MyMessage msg(0,V_TEMP);
    
    // Partie Relay
    #define RELAY_PIN  4  // Arduino Digital I/O pinnumber for relay 
    #define BUTTON_PIN  3  // Arduino Digital I/O pin number for button 
    #define CHILD_ID 17   // Id of the sensor child
    #define RELAY_ON 1
    #define RELAY_OFF 0
    
    Bounce debouncer = Bounce(); 
    int oldValue=0;
    bool state;
    
    unsigned long previousMillis = 0;
    
    MySensor gw;
    MyMessage msg2(CHILD_ID,V_LIGHT);
    
    void setup()  
    {  
      // Startup up the OneWire library
      sensors.begin();
      // requestTemperatures() will not block current thread
      sensors.setWaitForConversion(false);
    
      gw.begin(incomingMessage, AUTO, true);
    
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("Relay & Button", "1.0");
      gw.sendSketchInfo("Temperature Sensor", "1.1");
      
        // Fetch the number of attached temperature sensors  
      numSensors = sensors.getDeviceCount();
      Serial.print(numSensors);
      Serial.println(" temperature sensors detected");
      
     // 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);
    
      // Present all sensors to controller
      for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
         gw.present(i, S_TEMP);
          }
      // Register all sensors to gw (they will be created as child devices)
      gw.present(CHILD_ID, S_LIGHT);
    
      // 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 = gw.loadState(CHILD_ID);
      digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
    }
    
    
    /*
    *  Example on how to asynchronously check for new messages from gw
    */
    void loop() 
    {
      gw.process();
    
      // Relay button
      debouncer.update();
      // Get the update value
      int value = debouncer.read();
      if (value != oldValue && value==0) {
          gw.send(msg2.set(state?false:true), true); // Send new state and request ack back
      }
      oldValue = value;
      
      // Fetch temperatures from Dallas sensors
      sensors.requestTemperatures();
    
      // query conversion time and sleep until conversion completed
      //int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
      unsigned long currentMillis = millis();
      // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
      // gw.wait(conversionTime);
    
    // Read temperatures and send them to controller 
      if (currentMillis - previousMillis >= SLEEP_TIME) {
        // save the last time you read temperature
        previousMillis = currentMillis;
        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>((gw.getConfig().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
            gw.send(msg.setSensor(i).set(temperature,1));
            // Save new temperatures for next compare
            lastTemperature[i]=temperature;
            }
         }
      }
    } 
     
    void incomingMessage(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
         gw.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());
       } 
    }
    

    You will see it is almost a copy-cut of the sketches available here, but without any sleep or wait, that causes the button not to work...

    Anyone see what could be the problem ?

    Thanks.

    AWIA 1 Reply Last reply
    0
    • MixeurM Mixeur

      Hello,

      I wanted to make a node that both read temperature from 2 dallas sensors and activate a relay (with button option).
      It works pretty fine, but only for an undetermined time. Afeter sometime (1 or 2 days), if I push the button, it crahses, and i have to reset it to get the good behaviour. If I don't use the relay features, everything is working normally a long time.
      Here is the sketch :

      #include <MySensor.h>
      #include <SPI.h>
      #include <Bounce2.h>
      #include <DallasTemperature.h>
      #include <OneWire.h>
      
      // Partie Température
      #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
      
      #define ONE_WIRE_BUS 8 // 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;
      boolean receivedConfig = false;
      boolean metric = true; 
      // Initialize temperature message
      MyMessage msg(0,V_TEMP);
      
      // Partie Relay
      #define RELAY_PIN  4  // Arduino Digital I/O pinnumber for relay 
      #define BUTTON_PIN  3  // Arduino Digital I/O pin number for button 
      #define CHILD_ID 17   // Id of the sensor child
      #define RELAY_ON 1
      #define RELAY_OFF 0
      
      Bounce debouncer = Bounce(); 
      int oldValue=0;
      bool state;
      
      unsigned long previousMillis = 0;
      
      MySensor gw;
      MyMessage msg2(CHILD_ID,V_LIGHT);
      
      void setup()  
      {  
        // Startup up the OneWire library
        sensors.begin();
        // requestTemperatures() will not block current thread
        sensors.setWaitForConversion(false);
      
        gw.begin(incomingMessage, AUTO, true);
      
        // Send the sketch version information to the gateway and Controller
        gw.sendSketchInfo("Relay & Button", "1.0");
        gw.sendSketchInfo("Temperature Sensor", "1.1");
        
          // Fetch the number of attached temperature sensors  
        numSensors = sensors.getDeviceCount();
        Serial.print(numSensors);
        Serial.println(" temperature sensors detected");
        
       // 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);
      
        // Present all sensors to controller
        for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
           gw.present(i, S_TEMP);
            }
        // Register all sensors to gw (they will be created as child devices)
        gw.present(CHILD_ID, S_LIGHT);
      
        // 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 = gw.loadState(CHILD_ID);
        digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
      }
      
      
      /*
      *  Example on how to asynchronously check for new messages from gw
      */
      void loop() 
      {
        gw.process();
      
        // Relay button
        debouncer.update();
        // Get the update value
        int value = debouncer.read();
        if (value != oldValue && value==0) {
            gw.send(msg2.set(state?false:true), true); // Send new state and request ack back
        }
        oldValue = value;
        
        // Fetch temperatures from Dallas sensors
        sensors.requestTemperatures();
      
        // query conversion time and sleep until conversion completed
        //int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
        unsigned long currentMillis = millis();
        // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
        // gw.wait(conversionTime);
      
      // Read temperatures and send them to controller 
        if (currentMillis - previousMillis >= SLEEP_TIME) {
          // save the last time you read temperature
          previousMillis = currentMillis;
          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>((gw.getConfig().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
              gw.send(msg.setSensor(i).set(temperature,1));
              // Save new temperatures for next compare
              lastTemperature[i]=temperature;
              }
           }
        }
      } 
       
      void incomingMessage(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
           gw.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());
         } 
      }
      

      You will see it is almost a copy-cut of the sketches available here, but without any sleep or wait, that causes the button not to work...

      Anyone see what could be the problem ?

      Thanks.

      AWIA Offline
      AWIA Offline
      AWI
      Hero Member
      wrote on last edited by
      #2

      @Mixeur A relay generates a lot of noise on the power lines. Much has been written on this issue on the forum. Try powering the relays from a different voltage regulator and a enough decoupling capacitors on the power lines. Especially the radio needs stable power.

      1 Reply Last reply
      0
      • MixeurM Offline
        MixeurM Offline
        Mixeur
        wrote on last edited by Mixeur
        #3

        Actually, It is what I did. I use a LM317 to power all 5V devices from a 12V power supply (arduino, relay and ds18b20).
        3.3V for the radio is obtained from LM1117 (its input is the LM317). The radio also has a 4.7 uF capacitor on power line. So I'm unsure this is a question of noise on powerlines. Also, issue is only happening after a few undetermined time. I can trigger how many I want the relay with any issue after powering the module, without problem.
        It is just a question of time. So I think it can be a software issue, but I don't see anything in my sketch.

        AWIA 1 Reply Last reply
        0
        • MixeurM Mixeur

          Actually, It is what I did. I use a LM317 to power all 5V devices from a 12V power supply (arduino, relay and ds18b20).
          3.3V for the radio is obtained from LM1117 (its input is the LM317). The radio also has a 4.7 uF capacitor on power line. So I'm unsure this is a question of noise on powerlines. Also, issue is only happening after a few undetermined time. I can trigger how many I want the relay with any issue after powering the module, without problem.
          It is just a question of time. So I think it can be a software issue, but I don't see anything in my sketch.

          AWIA Offline
          AWIA Offline
          AWI
          Hero Member
          wrote on last edited by
          #4

          @Mixeur 0_1454875053591_upload-1a3e50aa-5e84-4235-9f46-77db31dad43a start of a difficult journey .... i finally changed the relays for SSD types.

          your sketch looks pretty straightforward.

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


          13

          Online

          11.7k

          Users

          11.2k

          Topics

          113.1k

          Posts


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

          • Don't have an account? Register

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