RelayWithButtonActuator - another n00b question



  • So here we go again with the n00b questions...

    Setup:
    Two relays and one button

    Use case:

    1. Press button
      1.1) Relay_1 ON
      1.2) Relay_2 ON
      1.3) delay(1000) then Relay_2 OFF
    2. Press button
      4.1) Relay_1 OFF

    Been trying this a couple of hours today and nothing worked, if I add some delay or change anything in the sketch the button instantly stops working. I have no sketch to share since nothing has been even close. I've searched the forum and nothing.
    Anyone have any pinpointers where to start looking? Links? Anything? 🙂

    I tried different versions like this with only one relay and trying to get it to turn off after 1sec, but with no success....

     void loop() 
     {
       gw.process();
       debouncer.update();
       // Get the update value
       int value = debouncer.read();
       if (value != oldValue && value==0) {
      gw.send(msg.set(state?false:true), true); // Send new state and request ack back
       }
       oldValue = value;
     delay(1000);
     digitalWrite(RELAY_PIN, RELAY_OFF);
     }


  • This was actually useful....
    http://playground.arduino.cc/Code/AvoidDelay



  • @gadu You should be aware that the delay function stop the processing so it is a huge chance that you will miss incoming messages because 99% om the time the mainloop will hang waiting. Try use millis() function instead



  • @olaeke hehe yup, google helped me out there... Sometimes you get stuck on silly things...



  • I'm still at this trying to create a sketch.
    Been playing around with millis() without any luck, ran into a example while google for a solution, however this uses delay.
    Not an issue though that delay is stops the processing, just trying to understand how this works. I've come this far (using led instead of relay), the idea is that when pressing the button the led = high for 1sec then led = low.
    In MQTT I need to see both V_LIGHT=1 and then V_LIGHT=0.

    Any ideas or pinpointers? I know i'm wandering the dark here.. 🙂
    This is the sketch so far, cut&paste from all over...

     #include <MySensor.h>
     #include <SPI.h>
     #include <Bounce2.h>
    
     #define BUTTON_PIN  3
     #define CHILD_ID 1   // Id of the sensor child
     #define RELAY_ON 1
     #define RELAY_OFF 0
    
     // constants won't change. Used here to 
     // set pin numbers:
     const int ledPin =  4;      // the number of the LED pin
     int oldValue=1;
    
     // Variables will change:
     int ledState = LOW;             // ledState used to set the LED
     Bounce debouncer = Bounce();
     bool state;
     MySensor gw;
     MyMessage msg(CHILD_ID,V_LIGHT);
    
     // the follow variables is a long because the time, measured in miliseconds,
     // will quickly become a bigger number than can be stored in an int.
    
     void setup() {
       gw.begin(incomingMessage, AUTO, true);
    
       // Send the sketch version information to the gateway and Controller
       gw.sendSketchInfo("RelayDelay with button", "1.0");
    
      // 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);  
    
       // Register all sensors to gw (they will be created as child devices)
       gw.present(CHILD_ID, S_LIGHT);
    
        // set the digital pin as output:
       pinMode(ledPin, OUTPUT);
       // Make sure relays are off when starting up
       digitalWrite(ledPin, ledState);
    
    // Set relay to last known state (using eeprom storage) 
       state = gw.loadState(CHILD_ID);
       //digitalWrite(ledPin, state?RELAY_ON:RELAY_OFF);
    
     }
    
     void loop()
     {
       debouncer.update();
       int value = debouncer.read();
    
     if(value == 0 && oldValue == 1) {
       if(ledState == HIGH) {
    digitalWrite(ledPin, LOW);
    } else {
       digitalWrite(ledPin, HIGH); 
       //gw.send(msg.set(state?false:true), true);
       delay(1000);
       digitalWrite(ledPin, LOW);
       gw.send(msg.set(state?false:true), true);
     }
     }
     }
     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(ledPin, 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());
        } 
     }

  • Contest Winner

    @gadu said:

    Any ideas or pinpointers? I know i'm wandering the dark here.. 🙂

    try like this... I did not create a device for relay 2...

    (untested, but compiles)

    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    
    #define RELAY_PIN_1  4  // Arduino Digital I/O pin number for relay 
    #define RELAY_PIN_2  5
    #define BUTTON_PIN   3  // 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;
    boolean state;
    unsigned long relayTwoTimerStart;
    MySensor gw;
    MyMessage msg(CHILD_ID,V_LIGHT);
    
    void setup()  
    {  
      gw.begin(incomingMessage, AUTO, true);
      gw.sendSketchInfo("Relay & Button", "1.0");
      pinMode(BUTTON_PIN,INPUT);
      digitalWrite(BUTTON_PIN,HIGH);
      debouncer.attach(BUTTON_PIN);
      debouncer.interval(5);
      gw.present(CHILD_ID, S_LIGHT);
      digitalWrite(RELAY_PIN_1, RELAY_OFF);
      pinMode(RELAY_PIN_1, OUTPUT);   
      pinMode(RELAY_PIN_2, OUTPUT);
      state = gw.loadState(CHILD_ID);
      digitalWrite(RELAY_PIN_1, state?RELAY_ON:RELAY_OFF);
    }
    //
    void loop() 
    {
      gw.process();
      debouncer.update();
      int value = debouncer.read();
      if (value != oldValue && value==0) 
      {
        gw.send(msg.set(state?false:true), true); // Send new state and request ack back
      }
      oldValue = value;
      //
      if (millis() - relayTwoTimerStart < 1000UL)
      {
        if (digitalRead(RELAY_PIN_2) == LOW)
        {
          digitalWrite(RELAY_PIN_2, HIGH);
        }
      }
      else
      {
        if (digitalRead(RELAY_PIN_2) == HIGH)
        {
          digitalWrite(RELAY_PIN_2, LOW);
        }
      }
    } 
    
    void incomingMessage(const MyMessage &message) 
    {
      if (message.isAck()) 
      {
        Serial.println("This is an ack from gateway");
      }
    
      if (message.type == V_LIGHT) 
      {
        state = message.getBool();
        digitalWrite(RELAY_PIN_1, state? RELAY_ON : RELAY_OFF);
        if (state) 
        {
          relayTwoTimerStart = millis();
        }
        gw.saveState(CHILD_ID, state);
        Serial.print("Incoming change for sensor:");
        Serial.print(message.sensor);
        Serial.print(", New status: ");
        Serial.println(message.getBool());
      }
    }
    


  • Omg, works just perfect! Thanks alot!!


  • Contest Winner

    @gadu said:

    Omg, works just perfect! Thanks alot!!

    I got lucky I guess.

    So, what are you doing with this then?



  • @BulldogLowell
    Well, the idea is actually simple. I have today a HTPC hidden on the other side of the livingroom wall (where the tv is). Both are connected to a Master (HTPC) and Slave (TV) power strip (are they called so?)
    When I start the HTPC with a button the PC boots and and the power strip turns on the TV.
    These are a bit pricey and now it has started to give me trouble, so why not let a cheaper arduino with two relays take care of it?
    One relay starts the PC (toggle) and the other relay starts the TV. This gives me also the option to start the HTPC/TV remote as well using OpenHAB and MQTT.
    Before shutting down the PC it can simply publish a command to turn off the TV using mosquitto_pub.

    Perhaps not the most optimal solution, but it's simple which means a higher WAF as well 😉

    Hope it made any sense... 🙂


  • Contest Winner

    @gadu

    String totalProjectSuccess = itWorks + wifeIsHappy;
    

    🙂


 

239
Online

8.7k
Users

9.5k
Topics

99.5k
Posts