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!