relay with delay feature

  • Hi everyone I have been reading and am struggling getting a grip with this situation.

    I have
    3 Binary switches - need to be read 2-4 times daily
    2 Soil Moisture sensors - need to be read 4 times daily
    1 relay - needs to work on demand

    The issue I have right now is that my 3 binary switches and 2 moisture sensors are susceptible to electrolysis and the current read settings erode my terminals in less than 2 weeks.

    I would like to put a wait/delay/whatever command to only cue those reading to happen 2-4 times a day, this should really extend the life of my cheap sensors!

    What would be the best way to implement this in my code? Currently I have zero gateway sleep commands/delay/etc.

    Below is the void loop and incoming message commands

    void loop() 
      // Get the update value
      int value1 =;
      int value2 =;
      int value3 =;
      int soilValue1 = analogRead(ANALOG_INPUT_SOIL_SENSOR1);
      int soilValue2 = analogRead(ANALOG_INPUT_SOIL_SENSOR2);
      value1 = digitalRead(BUTTON_PIN1);
      value2 = digitalRead(BUTTON_PIN2);
      value3 = digitalRead(BUTTON_PIN3);
      if (value1 != oldValue1) {
         // Send in the new value
         gw.send(msg1.set(value1==HIGH ? 1 : 0));
         oldValue1 = value1;
      if (value2 != oldValue2) {
         // Send in the new value
         gw.send(msg2.set(value2==HIGH ? 1 : 0));
         oldValue2 = value2;
      if (value3 != oldValue3) {
         // Send in the new value
         gw.send(msg3.set(value3==HIGH ? 1 : 0));
         oldValue3 = value3;
      if (soilValue1 != lastSoilValue1) {
        gw.send(msg4.set(constrain(map(soilValue1, 1023, 250, 0, 100),0,100)));
        lastSoilValue1 = soilValue1;
      if (soilValue2 != lastSoilValue2) {
        gw.send(msg5.set(constrain(map(soilValue2, 1023, 250, 0, 100),0,100)));
        lastSoilValue2 = soilValue2;
      // Alway process incoming messages whenever possible
    void incomingMessage(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type==V_LIGHT) {
         // Change relay state
         digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
         // Store state in eeprom
         gw.saveState(message.sensor, message.getBool());
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(", New status: ");

  • Contest Winner

    I'm currently at work and cannot look to deep into your sketch. But a debouncer can only be used on one pin. You have to declare a debouncer for each digital input you want to debounce. And read the input like in the following snippet.

    int value2 =;
    int value3 = debouncer3.update();

    You can also delete these lines. Because you're reading the values from the debouncer:

      value1 = digitalRead(BUTTON_PIN1);
      value2 = digitalRead(BUTTON_PIN2);
      value3 = digitalRead(BUTTON_PIN3);

  • yea this code is messy, I am reworking it today. Any insight on the best way to delay those commands without impacting the relay?

  • Contest Winner

    I use something like this

    unsigned long nextEvent;
    void setup() {
      nextEvent = millis() + ( 5 *  60 + 1000); // 5 hours
    void loop() {
      if ( nextEvent <= millis() ) {
        // do reading
        nextEvent = millis() + ( 5 *  60 + 1000); // 5 hours
      gw.wait( 500 ); // or whatever you want.

    But that's just the algorithm

  • Plugin Developer


    I would implement some way of knowing time passed. Either by sleeping or waiting for a set time. Then each time the loop runs after wake-up, or similar, increment a counter. Define a variable setting the number the counter should have reached when you want to read the sensors. Then implement a function per sensor or sensor type. Call the functions in a conditional statement, checking the counter, in the main loop.

    Check the sensebender micro sketch for example of a counter. That sketch sleeps the sensebender for 1 min in the end of each loop, default settting, so that way you know that at least 1 min has passed for each loop run. Each loop run it increments the counter, so +1 for the counter means +1 min, more or less.


    @TheoL beat me to it, with code example, even. 😃