automating old device with a momentary push button



  • Hi All,

    after spending alot of time and commenting in the following post link text I finally have a partial working solution. I appreciate if someone can advise what is wrong I am doing. I have one momentary switch on an amplifier and I would like to automate it. After I press a physcial button, it send status as "on" and if if i press the button again it should send off commands or vice versa. however, this is not happening. it only send on commands.

    If I send on off commands from home assistant it shows in the log as off and on without an issue.

    here is my code and logs.

    #define SKETCH_NAME "Oven Control"
    #define SKETCH_VERSION "1.0"
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG //MySensors debug messages
    //#define LOCAL_DEBUG //Code specific debug messages
    
    // Enable and select radio type attached
    #define MY_RADIO_RF24
    //#define MY_RADIO_RFM69
    
    #define MY_RF24_PA_LEVEL RF24_PA_HIGH //Options: RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
    #define MY_RF24_CHANNEL  76
    
    #define MY_NODE_ID 4  //Manually set the node ID here. Comment out to auto assign
    
    #include <MySensors.h>
    #include <Bounce2.h>
    
    #ifndef BAUD_RATE
    #define BAUD_RATE 115200
    #endif
    
    #ifdef LOCAL_DEBUG
    #define dbg(...)   Serial.print(__VA_ARGS__)
    #define dbgln(...) Serial.println(__VA_ARGS__)
    #else
    #define dbg(x)
    #define dbgln(x)
    #endif
    
    #define DWELL_TIME 50 //value used in all wait calls (in milliseconds) this allows for radio to come back to power after a transmission, ideally 0
    
    #define GND_GATE_PIN 3 //arduino control
    #define GND_DETECT_PIN 4 // button pin
    
    #define CHILD_ID_OVEN 1
    
    #define BUTTON_PRESS_DELAY 100 //The amount of delay used for a button press
    
    //Track button presses
    uint8_t gndValuePrev = 1;
    
    //LED button on/off tracking
    uint8_t gndLedOn = 0;  //bool state //The current status of the oven 1 = on, 0 = off
    uint8_t gndLedOnPrev = 0; //The previous status of the oven 1 = on, 0 = off
    
    unsigned long gndMillis;
    
    // Instantiate a Bounce object
    Bounce gndDebouncer = Bounce();
    
    MyMessage msgHeatMode(CHILD_ID_OVEN, V_LIGHT);
    //MyMessage msgHeatMode(CHILD_ID_OVEN, V_LIGHT);
    
    void setup() {
      Serial.begin(115200);
    
      //Setup the pins
      pinMode(GND_GATE_PIN, OUTPUT); //arduino control
      pinMode(GND_DETECT_PIN, INPUT_PULLUP); //button pin
    
      //Start with all outputs (buttons) not enabled (pressed)
      digitalWrite(GND_GATE_PIN, 0);
    
      // After setting up the buttons, setup debouncers
      gndDebouncer.attach(GND_DETECT_PIN);
      gndDebouncer.interval(50);
    
    }
    
    void presentation()
    {
      // Send the sketch version information to the gateway
      sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_OVEN, S_LIGHT);
      wait(DWELL_TIME);
      //metric = getConfig().isMetric; //This has been removed as it will default to metric if connection to the gateway is not established (bad for imperial users)
      //wait(DWELL_TIME);
    }
    
    void loop() {
      unsigned long currentMillis = millis(); //Get the current millis (used for timers)
    
      // Update the debouncers
      gndDebouncer.update();
    
      // Get the update value
      uint8_t gndValue = gndDebouncer.read();
      
      if (gndValue != gndValuePrev)
      {
        if (gndValue == 0 && gndLedOn == 0)
        {
          Serial.println(F("Ground Button Pressed"));
          //Don't echo the button push if it was turned on by the Arduino
          gndMillis = currentMillis + 1000;
          gndLedOn = 1;
          }
        }
        gndValuePrev = gndValue;
     
    
      //Turn on led 1 second after button pressed
      if (gndLedOn == 1 && currentMillis > gndMillis)
      {
        nChannelPress(GND_GATE_PIN);
        //send(msgHeatMode.set(gndLedOn == 0 ? "0" : "1"));
        send(msgHeatMode.set(GND_GATE_PIN == 0 ? "0" : "1"));
        gndLedOn = 0;
      }
      
    
    }
    
    void receive(const MyMessage &message)
    {
      dbg(F("msg data: "));
      dbgln(String(message.data));
    
      if (message.isAck()) {
        dbgln(F("Ack from gateway"));
      }
    
      if (message.type == V_LIGHT && !message.isAck()) {
    
         gndLedOn = message.getBool();
         
         digitalWrite(GND_GATE_PIN, gndLedOn?1:0);
         // Store state in eeprom
         saveState(CHILD_ID_OVEN, gndLedOn);
    
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
         
      }
    
    }
    
    void nChannelPress(uint8_t buttonPinName)
    {
      //Simulate a button press
      digitalWrite(buttonPinName, 1); //VCC to disable
      delay(BUTTON_PRESS_DELAY);
      digitalWrite(buttonPinName, 0); //Ground to enable
      delay(BUTTON_PRESS_DELAY);
    }
    
    Ground Button Pressed
    481010 TSF:MSG:SEND,4-4-0-0,s=1,c=1,t=2,pt=0,l=1,sg=0,ft=0,st=OK:1
    Ground Button Pressed
    485356 TSF:MSG:SEND,4-4-0-0,s=1,c=1,t=2,pt=0,l=1,sg=0,ft=0,st=OK:1
    494491 TSF:MSG:READ,0-0-4,s=1,c=1,t=2,pt=0,l=1,sg=0:0
    494496 TSF:MSG:ECHO REQ
    494500 TSF:MSG:SEND,4-4-0-0,s=1,c=1,t=2,pt=0,l=1,sg=0,ft=0,st=OK:0
    Incoming change for sensor:1, New status: 0
    499511 TSF:MSG:READ,0-0-4,s=1,c=1,t=2,pt=0,l=1,sg=0:1
    499516 TSF:MSG:ECHO REQ
    499522 TSF:MSG:SEND,4-4-0-0,s=1,c=1,t=2,pt=0,l=1,sg=0,ft=0,st=OK:1
    Incoming change for sensor:1, New status: 1
    499732 TSF:MSG:SEND,4-4-0-0,s=1,c=1,t=2,pt=0,l=1,sg=0,ft=0,st=OK:1
    
    


  • Here is the schematics diagram.. thanks to @petewill for his original post and diagram.

    button-hack-n-channel-and-p-channel.jpg


Log in to reply
 

Suggested Topics

0
Online

11.4k
Users

11.1k
Topics

112.7k
Posts