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