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. Very close I think...

Very close I think...

Scheduled Pinned Locked Moved Troubleshooting
4 Posts 2 Posters 729 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.
  • I Offline
    I Offline
    iteafreely
    wrote on last edited by
    #1

    Hi folks! I'm glad to be in this community. I've done quite a bit of dabbling and have the network up and running and integrated well with HA. I'm now on to my first project of some complexity. I decided to tackle this since it involved many different things.

    The project is a controller for a low-voltage gas fireplace. It allows HA to control ON/OFF, and also retains the ability to turn it ON/OFF with a wall switch (via a digital pin). It also integrates a gas leak sensor, and sensing of the thermopile voltage. and before it goes live it will have a couple more safety features incorporated. Attributions and stuff will come when I publish.

    As background, I'm new to Arduino, MySensors, and C++ so I have bitten off a bit more than I can chew. But, that's how I learn... Anyway, I've gotten stuck and have been noodling and cursing for a few hours over a problem. When I use the wall switch to turn ON or OFF the fireplace, I want to have HA updated with the new status of the switch. I've gotten closer than the sketch below, but I thought I'd ask if any of you can offer any suggestions or nudges in the right direction.

    Also, since I am a totally new programmer (I did some Cobol back in the day), I welcome any code review if I'm doing anything in a very crappy way.

    // Override Setting for Manual Node ID
    #define MY_NODE_ID 6
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    // Enable radio type attached
    #define MY_RADIO_NRF24
    
    // Libraries
    #include <MySensors.h>
    
    // Child IDs
    #define CHILD_ID_THERMOPILE_VOLTS 0
    #define CHILD_ID_GAS_VOLTS 1
    #define CHILD_ID_GAS_ALARM 2
    #define CHILD_ID_RELAY 3
    
    // Relay Module GPIO States.
    #define RELAY_ON 0    // Low (0):ON
    #define RELAY_OFF 1   // High (1):OFF
    
    // Pin Assignments
    #define RELAY_PIN 3
    #define GAS_ALARM_PIN A4
    #define WALL_SWITCH_PIN 5
    
    // Variables
    bool initialValueSent = false;     // Stores if an initial relay value has been sent
    int lastGasAlarm = -1;
    int wallSwitch = -1;
    int lastWallSwitch = -1;
    int relayState = -1
    long interval = 2000;              // interval at which to sample voltages (milliseconds)
    long gas_warmup_time = 1000;       // Wait time to allow the MQ-5 gas sensor to heat before continuing (milliseconds)
    unsigned long previousMillis = 0;  // Stores last time voltages were updated
    float thermopile_voltage = 0.0;    // Stores the output voltage from the thermopile
    float gas_voltage = 0.0;           // Stores the output voltage from the MQ-5 gas sensor
    
    //Init MyMessage for Each Child ID
    MyMessage msgTPVolt(CHILD_ID_THERMOPILE_VOLTS, V_VOLTAGE);
    MyMessage msgGasVolt(CHILD_ID_GAS_VOLTS, V_VOLTAGE);
    MyMessage msgGasAlarm(CHILD_ID_GAS_ALARM, V_TRIPPED);
    MyMessage msgRelay(CHILD_ID_RELAY, V_LIGHT);
    
    void before() { 
      // Using a Normally Open relay, set the pin high before defining it as output.
      // This prevents the fireplace from igniting during boot.
      digitalWrite(RELAY_PIN, HIGH);
      //Set Relay Pin to output.
      pinMode(RELAY_PIN, OUTPUT);
      //Set Gas Alarm Pin to input
      pinMode(GAS_ALARM_PIN, INPUT);
      //Set wall switch Pin to input
      pinMode(WALL_SWITCH_PIN, INPUT_PULLUP); 
    }
    void setup() {
      wallSwitch = digitalRead(WALL_SWITCH_PIN);     // read the input pin 
      (lastWallSwitch = wallSwitch);
      // Allow the MQ-5 gas sensor to heat before continuing
     
      Serial.print  ("Warming up the MQ-5 gas sensor for ");
      Serial.print (gas_warmup_time);
      Serial.println (" milliseconds.");
      delay(gas_warmup_time);
    }
    
    void presentation()  
    {   
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("GasFireplace", "0.1");
      // Present sensors to the gateway
      present(CHILD_ID_THERMOPILE_VOLTS, S_MULTIMETER);
      present(CHILD_ID_GAS_VOLTS, S_MULTIMETER);
      present(CHILD_ID_GAS_ALARM, S_SMOKE);  
      present(CHILD_ID_RELAY, S_LIGHT);
      wait(10);
    }
    void loop() 
    {
      if (!initialValueSent) {
        send(msgRelay.set(loadState(1)?RELAY_OFF:RELAY_ON),true);
        delay(10);   
      }
      int gasAlarm = digitalRead(GAS_ALARM_PIN);     // read the input pin
      if (gasAlarm != lastGasAlarm) {
        // Send in the new value
        send(msgGasAlarm.set(gasAlarm==HIGH ? 0 : 1));
         (lastGasAlarm = gasAlarm);
      }  
      wallSwitch = digitalRead(WALL_SWITCH_PIN);     // read the input pin
      //Serial.print("WALL_SWITCH_PIN: ");
      //Serial.println(WALL_SWITCH_PIN);
      Serial.print("wallSwitch: ");
      Serial.print(wallSwitch);
      Serial.print("   lastWallSwitch: ");
      Serial.println(lastWallSwitch);
      if (wallSwitch != lastWallSwitch) {
        digitalWrite(RELAY_PIN, !digitalRead(RELAY_PIN));
        (lastWallSwitch = wallSwitch);
        (relayState = RELAY_PIN)
        delay(10);
        //send(msgRelay.set(RELAY_PIN==HIGH ? 0 : 1));
        send(msgRelay.set(RELAY_PIN), false);         // notify controller of current state
      } 
      unsigned long currentMillis = millis();
       if(currentMillis - previousMillis > interval) {
        // save the last time voltage was sampled 
        previousMillis = currentMillis;   
        thermopile_voltage = ((float)analogRead(A2) * 5.015) / 1024.0;
        gas_voltage = ((float)analogRead(A3) * 5.015) / 1024.0;
        Serial.print(thermopile_voltage,3);
        Serial.print (" V    ");
        Serial.print(gas_voltage,3);
        Serial.println (" V");
        send(msgTPVolt.set(thermopile_voltage, 3));
        send(msgGasVolt.set(gas_voltage, 3));    
      }
    }
    void receive(const MyMessage &message) {
      // We only expect one type of message from controller but we better check anyway.
      if (message.type==V_LIGHT)
        if (!initialValueSent) {
          Serial.println("Receiving initial value from controller");
          initialValueSent = true;
        }
         // Update Relay State based on received message from gateway.
          digitalWrite(RELAY_PIN, message.getBool()?RELAY_ON:RELAY_OFF);
         // Send updated relay state back to gateway.
          send(msgRelay.set(message.getBool()?RELAY_OFF:RELAY_ON));
    }
    

    Thanks in advance for any input!

    gohanG 1 Reply Last reply
    0
    • I iteafreely

      Hi folks! I'm glad to be in this community. I've done quite a bit of dabbling and have the network up and running and integrated well with HA. I'm now on to my first project of some complexity. I decided to tackle this since it involved many different things.

      The project is a controller for a low-voltage gas fireplace. It allows HA to control ON/OFF, and also retains the ability to turn it ON/OFF with a wall switch (via a digital pin). It also integrates a gas leak sensor, and sensing of the thermopile voltage. and before it goes live it will have a couple more safety features incorporated. Attributions and stuff will come when I publish.

      As background, I'm new to Arduino, MySensors, and C++ so I have bitten off a bit more than I can chew. But, that's how I learn... Anyway, I've gotten stuck and have been noodling and cursing for a few hours over a problem. When I use the wall switch to turn ON or OFF the fireplace, I want to have HA updated with the new status of the switch. I've gotten closer than the sketch below, but I thought I'd ask if any of you can offer any suggestions or nudges in the right direction.

      Also, since I am a totally new programmer (I did some Cobol back in the day), I welcome any code review if I'm doing anything in a very crappy way.

      // Override Setting for Manual Node ID
      #define MY_NODE_ID 6
      
      // Enable debug prints to serial monitor
      #define MY_DEBUG 
      
      // Enable radio type attached
      #define MY_RADIO_NRF24
      
      // Libraries
      #include <MySensors.h>
      
      // Child IDs
      #define CHILD_ID_THERMOPILE_VOLTS 0
      #define CHILD_ID_GAS_VOLTS 1
      #define CHILD_ID_GAS_ALARM 2
      #define CHILD_ID_RELAY 3
      
      // Relay Module GPIO States.
      #define RELAY_ON 0    // Low (0):ON
      #define RELAY_OFF 1   // High (1):OFF
      
      // Pin Assignments
      #define RELAY_PIN 3
      #define GAS_ALARM_PIN A4
      #define WALL_SWITCH_PIN 5
      
      // Variables
      bool initialValueSent = false;     // Stores if an initial relay value has been sent
      int lastGasAlarm = -1;
      int wallSwitch = -1;
      int lastWallSwitch = -1;
      int relayState = -1
      long interval = 2000;              // interval at which to sample voltages (milliseconds)
      long gas_warmup_time = 1000;       // Wait time to allow the MQ-5 gas sensor to heat before continuing (milliseconds)
      unsigned long previousMillis = 0;  // Stores last time voltages were updated
      float thermopile_voltage = 0.0;    // Stores the output voltage from the thermopile
      float gas_voltage = 0.0;           // Stores the output voltage from the MQ-5 gas sensor
      
      //Init MyMessage for Each Child ID
      MyMessage msgTPVolt(CHILD_ID_THERMOPILE_VOLTS, V_VOLTAGE);
      MyMessage msgGasVolt(CHILD_ID_GAS_VOLTS, V_VOLTAGE);
      MyMessage msgGasAlarm(CHILD_ID_GAS_ALARM, V_TRIPPED);
      MyMessage msgRelay(CHILD_ID_RELAY, V_LIGHT);
      
      void before() { 
        // Using a Normally Open relay, set the pin high before defining it as output.
        // This prevents the fireplace from igniting during boot.
        digitalWrite(RELAY_PIN, HIGH);
        //Set Relay Pin to output.
        pinMode(RELAY_PIN, OUTPUT);
        //Set Gas Alarm Pin to input
        pinMode(GAS_ALARM_PIN, INPUT);
        //Set wall switch Pin to input
        pinMode(WALL_SWITCH_PIN, INPUT_PULLUP); 
      }
      void setup() {
        wallSwitch = digitalRead(WALL_SWITCH_PIN);     // read the input pin 
        (lastWallSwitch = wallSwitch);
        // Allow the MQ-5 gas sensor to heat before continuing
       
        Serial.print  ("Warming up the MQ-5 gas sensor for ");
        Serial.print (gas_warmup_time);
        Serial.println (" milliseconds.");
        delay(gas_warmup_time);
      }
      
      void presentation()  
      {   
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("GasFireplace", "0.1");
        // Present sensors to the gateway
        present(CHILD_ID_THERMOPILE_VOLTS, S_MULTIMETER);
        present(CHILD_ID_GAS_VOLTS, S_MULTIMETER);
        present(CHILD_ID_GAS_ALARM, S_SMOKE);  
        present(CHILD_ID_RELAY, S_LIGHT);
        wait(10);
      }
      void loop() 
      {
        if (!initialValueSent) {
          send(msgRelay.set(loadState(1)?RELAY_OFF:RELAY_ON),true);
          delay(10);   
        }
        int gasAlarm = digitalRead(GAS_ALARM_PIN);     // read the input pin
        if (gasAlarm != lastGasAlarm) {
          // Send in the new value
          send(msgGasAlarm.set(gasAlarm==HIGH ? 0 : 1));
           (lastGasAlarm = gasAlarm);
        }  
        wallSwitch = digitalRead(WALL_SWITCH_PIN);     // read the input pin
        //Serial.print("WALL_SWITCH_PIN: ");
        //Serial.println(WALL_SWITCH_PIN);
        Serial.print("wallSwitch: ");
        Serial.print(wallSwitch);
        Serial.print("   lastWallSwitch: ");
        Serial.println(lastWallSwitch);
        if (wallSwitch != lastWallSwitch) {
          digitalWrite(RELAY_PIN, !digitalRead(RELAY_PIN));
          (lastWallSwitch = wallSwitch);
          (relayState = RELAY_PIN)
          delay(10);
          //send(msgRelay.set(RELAY_PIN==HIGH ? 0 : 1));
          send(msgRelay.set(RELAY_PIN), false);         // notify controller of current state
        } 
        unsigned long currentMillis = millis();
         if(currentMillis - previousMillis > interval) {
          // save the last time voltage was sampled 
          previousMillis = currentMillis;   
          thermopile_voltage = ((float)analogRead(A2) * 5.015) / 1024.0;
          gas_voltage = ((float)analogRead(A3) * 5.015) / 1024.0;
          Serial.print(thermopile_voltage,3);
          Serial.print (" V    ");
          Serial.print(gas_voltage,3);
          Serial.println (" V");
          send(msgTPVolt.set(thermopile_voltage, 3));
          send(msgGasVolt.set(gas_voltage, 3));    
        }
      }
      void receive(const MyMessage &message) {
        // We only expect one type of message from controller but we better check anyway.
        if (message.type==V_LIGHT)
          if (!initialValueSent) {
            Serial.println("Receiving initial value from controller");
            initialValueSent = true;
          }
           // Update Relay State based on received message from gateway.
            digitalWrite(RELAY_PIN, message.getBool()?RELAY_ON:RELAY_OFF);
           // Send updated relay state back to gateway.
            send(msgRelay.set(message.getBool()?RELAY_OFF:RELAY_ON));
      }
      

      Thanks in advance for any input!

      gohanG Offline
      gohanG Offline
      gohan
      Mod
      wrote on last edited by
      #2

      @iteafreely said in Very close I think...:

      (relayState = RELAY_PIN)

      Hi welcome to the forum.

      I think you meant to assign something else to relaystate, otherwise it would always be "3"

      1 Reply Last reply
      0
      • I Offline
        I Offline
        iteafreely
        wrote on last edited by
        #3

        Yes thank you. I want to assign to it the current state of the relay.
        Ultimately though, I don't know if I even need that variable. I just can't figure out how to get the current state of the relay and then send it in a message to the controller.
        It must be obvious, but my brain is fried at this point.

        1 Reply Last reply
        0
        • gohanG Offline
          gohanG Offline
          gohan
          Mod
          wrote on last edited by
          #4

          Have you looked at the relay with button example sketch?

          Then look also here https://forum.mysensors.org/topic/1703/relay-with-switch/4

          You don't have to to read relay status because you are controlling it, so whenever you are doing the digitalwrite just set the relaystate with the same value

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


          18

          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