Help with pool solar controller code
-
Ok i am stuck again.....
I cant seem to get the push buttons to activate the relays.....
What am i doing wrong?/** JH REV 1.0 - 12-04-2020 */ // Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_RF24 #define MY_RF24_PA_LEVEL RF24_PA_HIGH #define MY_NODE_ID 50 //////////FOR TESTING #include <MySensors.h> #include <DallasTemperature.h> #include <OneWire.h> #include <LiquidCrystal_I2C.h> #include <Bounce2.h> LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected #define MAX_ATTACHED_DS18B20 16 #define RELAY_PIN 4 #define RELAY_PIN_2 5 #define RELAY_ON 0 #define RELAY_OFF 1 #define BUTTON_PIN_1 7 #define BUTTON_PIN_2 8 #define CHILD_ID 4 // Id of the sensor child for 1st relay #define CHILD_ID_2 5 // Id of the sensor child for 2nd relay Bounce debouncer = Bounce(); Bounce debouncer2 = Bounce(); int oldValue=-1; int oldValue2=-1; bool state ; bool state2 ; bool initialValueSent = false; unsigned long SLEEP_TIME = 3000; // Sleep time between reads (in milliseconds) OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. float lastTemperature[MAX_ATTACHED_DS18B20]; int numSensors=0; float roofTemp; float poolTemp; String poolPumpstate; String solarPumpstate; bool receivedConfig = false; bool metric = true; // Initialize temperature message MyMessage msg(1,V_TEMP); MyMessage msg2(CHILD_ID, V_LIGHT); MyMessage msg3(CHILD_ID_2, V_LIGHT); void before() { // Startup up the OneWire library sensors.begin(); } void setup() { pinMode(BUTTON_PIN_1,INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN_1,HIGH); pinMode(BUTTON_PIN_2,INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN_2,HIGH); debouncer.attach(BUTTON_PIN_1); debouncer.interval(5); debouncer2.attach(BUTTON_PIN_2); debouncer2.interval(5); oldValue = debouncer.read(); oldValue2 = debouncer2.read(); // requestTemperatures() will not block current thread sensors.setWaitForConversion(false); lcd.begin(16, 2); // LCD 2 lines * 16 char. lcd.setBacklight(HIGH); lcd.setCursor(0, 0); lcd.setCursor(0, 0); lcd.clear(); lcd.print(" Contoller "); lcd.setCursor(0, 1); lcd.print(" Starting "); wait(2000); pinMode(RELAY_PIN, OUTPUT); pinMode(RELAY_PIN_2, OUTPUT); digitalWrite(RELAY_PIN, RELAY_OFF); digitalWrite(RELAY_PIN_2, RELAY_OFF); lcd.setCursor(0, 0); lcd.clear(); lcd.print("Begin Pump Test"); wait(2000); digitalWrite(RELAY_PIN, RELAY_ON); wait(5000); digitalWrite(RELAY_PIN, RELAY_OFF); lcd.setCursor(0, 0); lcd.clear(); lcd.print("Pool Pump Test"); lcd.setCursor(0, 1); lcd.print("OK"); wait(2000); lcd.setCursor(0, 0); lcd.clear(); lcd.print("Begin Pump Test"); digitalWrite(RELAY_PIN_2, RELAY_ON); wait(5000); digitalWrite(RELAY_PIN_2, RELAY_OFF); lcd.setCursor(0, 0); lcd.clear(); lcd.print("Solar Pump Test"); lcd.setCursor(0, 1); lcd.print("OK"); wait(2000); wait(10000); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("Pool Controller", "1.1"); // Fetch the number of attached temperature sensors numSensors = sensors.getDeviceCount(); // Present all sensors to controller for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) { present(i, S_TEMP); present(CHILD_ID, S_BINARY); present(CHILD_ID_2, S_BINARY); } } void loop() { /////////////////////////////////////////////////////////////////////////////////////// /////////////////// REQUEST AND SEND INITIAL VALUES FOR RELAYS ////////////////////// /////////////////////////////////////////////////////////////////////////////////////// if (!initialValueSent) { Serial.println("Sending initial value"); send(msg2.set(state?RELAY_OFF:RELAY_ON)); send(msg3.set(state?RELAY_OFF:RELAY_ON)); Serial.println("Requesting initial value from controller"); request(CHILD_ID, V_STATUS); request(CHILD_ID_2, V_STATUS); wait(2000, C_SET, V_STATUS); } /////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////// MAIN LOOP //////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// { debouncer.update(); debouncer2.update(); // Get the update value int value = debouncer.read(); int value2 = debouncer2.read(); if (value != oldValue) { state = !state; // Toggle the state send(msg.set(state), false); // send new state to controller, no ack requested digitalWrite(RELAY_PIN, state); // switch the relay to the new state oldValue = value; } if (value2 != oldValue2) { state2 = !state2; // Toggle the state send(msg2.set(state2), false); // send new state to controller, no ack requested digitalWrite(RELAY_PIN_2, state2); // switch the relay to the new state oldValue2 = value2; } // Fetch temperatures from Dallas sensors sensors.requestTemperatures(); // query conversion time and sleep until conversion completed int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution()); // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater) wait(conversionTime); // Read temperatures and send them to controller for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) { // Fetch and round temperature to one decimal float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.; // Only send data if temperature has changed and no error #if COMPARE_TEMP == 1 if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) { #else if (temperature != -127.00 && temperature != 85.00) { #endif // Send in the new temperature send(msg.setSensor(i).set(temperature,1)); // Save new temperatures for next compare lastTemperature[i]=temperature; poolTemp = temperature; } } wait(1000); } updateLCD(); } /////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////// RECIEVE TEMPS //////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// void receive(const MyMessage &message) { if (message.type==V_TEMP) { if (message.sensor == 1) { // Write some debug info Serial.print("Incoming change from roof sensor:"); Serial.print(message.sensor); Serial.print("\n"); Serial.print(", New status: "); Serial.println(message.getFloat()); roofTemp = (message.getFloat()); }} /////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////// RECIEVE RELAYS //////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// else if (message.getType()==V_STATUS) { if (message.sensor == 4){ state = (bool)message.getInt(); Serial.print(state); digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF); Serial.print("Incoming change for sensor:"); Serial.print(message.getSensor()); Serial.print(", New status: "); Serial.println(message.getBool()); send(msg2.set(state?RELAY_OFF:RELAY_ON)); if ((message.getBool())== 1){ poolPumpstate = ("Running");} else{ poolPumpstate = ("Standby"); }} if (message.sensor == 5){ state = (bool)message.getInt(); Serial.print(state); digitalWrite(RELAY_PIN_2, state?RELAY_ON:RELAY_OFF); Serial.print("Incoming change for sensor:"); Serial.print(message.getSensor()); Serial.print(", New status: "); Serial.println(message.getBool()); send(msg3.set(state?RELAY_OFF:RELAY_ON)); if ((message.getBool())== 1){ solarPumpstate = ("Running");} else{ solarPumpstate = ("Standby"); }} if (message.type == V_STATUS) { if (!initialValueSent) { Serial.println("Receiving initial value from controller"); initialValueSent = true; }} }} void updateLCD() { lcd.clear(); lcd.setCursor(0, 1); lcd.print("Pool :"); lcd.print(" "); lcd.print(poolTemp); lcd.print((char)223); lcd.print("C"); lcd.setCursor(0, 0); lcd.print("Solar :"); lcd.print(" "); lcd.print(roofTemp); lcd.print((char)223); lcd.print("C"); wait(10000); lcd.clear(); lcd.print(" Pump Status"); wait(2000); lcd.clear(); lcd.setCursor(0, 1); lcd.print("Pool :"); lcd.print(" "); lcd.print(poolPumpstate); lcd.setCursor(0, 0); lcd.print("Solar :"); lcd.print(" "); lcd.print(solarPumpstate); wait(10000); lcd.clear(); lcd.print(" Temperatures"); wait(2000); } -
@JCH Remove the serial print from receive - I had issues with that before......
Really this is more complicated than it needs to be. You just need the roof node to send temp to the controller and then the controller can relay that to the pool node.
Also, what is the reason the roof node sends temp every 30 seconds? Thermal inertia of pool systems is not that fast (even boiling a kettle with a little water is comparitively slow). So why not send every 5 minutes instead? Or just when it hits a max/min temp for your purpose? This will be much less drain from the solar battery.
-
EDIT: I think the push button wont work if there is a wait for sleep.... Is there anyway around this?
@JCH You need to use pins D2 and D3 for the buttons and have them attached as interrupts. Interrupts will 'interrupt' the sleep cycle and perform whatever action you have told it to do in your sketch. The only other way to interrupt sleep that I know of is a timer that wakes at set (or random) intervals.
Remember that void loop() is not running in sleep mode, so no amount of checking buttons pins will work here during that time.
-
@JCH You need to use pins D2 and D3 for the buttons and have them attached as interrupts. Interrupts will 'interrupt' the sleep cycle and perform whatever action you have told it to do in your sketch. The only other way to interrupt sleep that I know of is a timer that wakes at set (or random) intervals.
Remember that void loop() is not running in sleep mode, so no amount of checking buttons pins will work here during that time.
@skywatch Will the interrupt work with wait or only sleep?
I ended up going down a rabbit hole trying to implement a non breaking timer as below... it all seems to be working now except the button doesnt switch states everytime.... sometimes have to press it 2 or 3 times?/** JH REV 1.0 - 12-04-2020 */ // Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_RF24 #define MY_RF24_PA_LEVEL RF24_PA_HIGH #define MY_NODE_ID 2 //////////FOR TESTING #define MY_REPEATER_FEATURE #include <MySensors.h> #include <DallasTemperature.h> #include <OneWire.h> #include <LiquidCrystal_I2C.h> #include <Bounce2.h> #include <SPI.h> LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected #define MAX_ATTACHED_DS18B20 16 #define RELAY_PIN 4 #define RELAY_PIN_2 5 #define RELAY_ON 0 #define RELAY_OFF 1 #define BUTTON_PIN 7 #define BUTTON_PIN_2 8 #define CHILD_ID 4 // Id of the sensor child for 1st relay #define CHILD_ID_2 5 // Id of the sensor child for 2nd relay bool state; Bounce debouncer = Bounce(); int oldValue=0; bool state1; Bounce debouncer2 = Bounce(); int oldValue2; bool state2; bool initialValueSent = false; unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) unsigned long CHECK_TIME = millis(); OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. float lastTemperature[MAX_ATTACHED_DS18B20]; int numSensors=0; float roofTemp; float poolTemp; String poolPumpstate; String solarPumpstate; bool receivedConfig = false; bool metric = true; // Initialize temperature message MyMessage msg(1,V_TEMP); MyMessage msg2(CHILD_ID, V_LIGHT); MyMessage msg3(CHILD_ID_2, V_LIGHT); void before() { // Startup up the OneWire library sensors.begin(); } void setup() { pinMode(BUTTON_PIN, INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN, HIGH); pinMode(BUTTON_PIN_2, INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN_2, HIGH); debouncer.attach(BUTTON_PIN); debouncer.interval(5); debouncer2.attach(BUTTON_PIN_2); debouncer2.interval(5); oldValue = debouncer.read(); oldValue2 = debouncer2.read(); // requestTemperatures() will not block current thread sensors.setWaitForConversion(false); lcd.begin(16, 2); // LCD 2 lines * 16 char. lcd.setBacklight(HIGH); lcd.setCursor(0, 0); lcd.setCursor(0, 0); lcd.clear(); lcd.print(" Contoller "); lcd.setCursor(0, 1); lcd.print(" Starting "); wait(2000); pinMode(RELAY_PIN, OUTPUT); pinMode(RELAY_PIN_2, OUTPUT); digitalWrite(RELAY_PIN, RELAY_OFF); digitalWrite(RELAY_PIN_2, RELAY_OFF); /* lcd.setCursor(0, 0); lcd.clear(); lcd.print("Begin Pump Test"); wait(2000); digitalWrite(RELAY_PIN, RELAY_ON); wait(5000); digitalWrite(RELAY_PIN, RELAY_OFF); lcd.setCursor(0, 0); lcd.clear(); lcd.print("Pool Pump Test"); lcd.setCursor(0, 1); lcd.print("OK"); wait(2000); lcd.setCursor(0, 0); lcd.clear(); lcd.print("Begin Pump Test"); digitalWrite(RELAY_PIN_2, RELAY_ON); wait(5000); digitalWrite(RELAY_PIN_2, RELAY_OFF); lcd.setCursor(0, 0); lcd.clear(); lcd.print("Solar Pump Test"); lcd.setCursor(0, 1); lcd.print("OK"); */ wait(2000); wait(10000); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("Pool Controller", "1.1"); // Fetch the number of attached temperature sensors numSensors = sensors.getDeviceCount(); // Present all sensors to controller for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) { present(i, S_TEMP); present(CHILD_ID, S_BINARY); present(CHILD_ID_2, S_BINARY); } } void loop() { if (!initialValueSent) { Serial.println("Sending initial value"); send(msg2.set(state?RELAY_OFF:RELAY_ON)); send(msg3.set(state?RELAY_OFF:RELAY_ON)); Serial.println("Requesting initial value from controller"); request(CHILD_ID, V_STATUS); request(CHILD_ID_2, V_STATUS); wait(2000, C_SET, V_STATUS); } { debouncer.update(); // Get the update value int value = debouncer.read(); state = !state; if (value != oldValue && value==0) { send(msg2.set(state?true:false), true); // Send new state and request ack back digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF); } oldValue = value; /* { debouncer2.update(); // Get the update value int value = debouncer2.read(); state2 = !state2; if (value != oldValue2 && value==0) { send(msg3.set(state2?true:false), false); // Send new state and request ack back digitalWrite(RELAY_PIN_2, state2?RELAY_ON:RELAY_OFF); } oldValue = value; }*/ } unsigned long NOW_TIME = millis(); if(NOW_TIME - CHECK_TIME >= SLEEP_TIME) { updateLCDtemps(); CHECK_TIME = NOW_TIME; Serial.println("Updating LCD"); } updateTemperature(30); if (solarPumpstate == "Running" ){ updateLCDstatus; } } /////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////// RECIEVE TEMPS //////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// void receive(const MyMessage &message) { if (message.type==V_TEMP) { if (message.sensor == 1) { // Write some debug info Serial.print("Incoming change from roof sensor:"); Serial.print(message.sensor); Serial.print("\n"); Serial.print(", New status: "); Serial.println(message.getFloat()); roofTemp = (message.getFloat()); }} /////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////// RECIEVE RELAYS //////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// else if (message.getType()==V_STATUS) { if (message.sensor == 4){ state = message.getBool(); Serial.print(state); digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF); Serial.print("Incoming change for sensor:"); Serial.print(message.getSensor()); Serial.print(", New status: "); Serial.println(message.getBool()); // send(msg2.set(state?RELAY_ON:RELAY_OFF)); if ((message.getBool())== 1){ poolPumpstate = ("Running");} else{ poolPumpstate = ("Standby"); }} if (message.sensor == 5){ state = (bool)message.getInt(); Serial.print(state); digitalWrite(RELAY_PIN_2, state?RELAY_ON:RELAY_OFF); Serial.print("Incoming change for sensor:"); Serial.print(message.getSensor()); Serial.print(", New status: "); Serial.println(message.getBool()); send(msg3.set(state?RELAY_OFF:RELAY_ON)); if ((message.getBool())== 1){ solarPumpstate = ("Running");} else{ solarPumpstate = ("Standby"); }} if (message.type == V_STATUS) { if (!initialValueSent) { Serial.println("Receiving initial value from controller"); initialValueSent = true; }} } } void updateLCDtemps() { lcd.clear(); lcd.setCursor(0, 1); lcd.print("Pool :"); lcd.print(" "); lcd.print(poolTemp); lcd.print((char)223); lcd.print("C"); lcd.setCursor(0, 0); lcd.print("Solar :"); lcd.print(" "); lcd.print(roofTemp); lcd.print((char)223); lcd.print("C"); } void updateLCDstatus() { lcd.clear(); lcd.setCursor(0, 1); lcd.print("Pool :"); lcd.print(" "); lcd.print(poolPumpstate); lcd.setCursor(0, 0); lcd.print("Solar :"); lcd.print(" "); lcd.print(solarPumpstate); } void updateTemperature(int frequency) { static unsigned long lastUpdateTime; if (millis() - lastUpdateTime >= frequency * 1000UL) { sensors.requestTemperatures(); for (int i=0; i<numSensors && i< MAX_ATTACHED_DS18B20; i++) { float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.; if (lastTemperature[i] != temperature && temperature != -127.00) { send(msg.setSensor(i).set(temperature,1)); lastTemperature[i]=temperature; poolTemp = temperature; } } lastUpdateTime += frequency * 1000UL; } } -
@skywatch Will the interrupt work with wait or only sleep?
I ended up going down a rabbit hole trying to implement a non breaking timer as below... it all seems to be working now except the button doesnt switch states everytime.... sometimes have to press it 2 or 3 times?/** JH REV 1.0 - 12-04-2020 */ // Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_RF24 #define MY_RF24_PA_LEVEL RF24_PA_HIGH #define MY_NODE_ID 2 //////////FOR TESTING #define MY_REPEATER_FEATURE #include <MySensors.h> #include <DallasTemperature.h> #include <OneWire.h> #include <LiquidCrystal_I2C.h> #include <Bounce2.h> #include <SPI.h> LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected #define MAX_ATTACHED_DS18B20 16 #define RELAY_PIN 4 #define RELAY_PIN_2 5 #define RELAY_ON 0 #define RELAY_OFF 1 #define BUTTON_PIN 7 #define BUTTON_PIN_2 8 #define CHILD_ID 4 // Id of the sensor child for 1st relay #define CHILD_ID_2 5 // Id of the sensor child for 2nd relay bool state; Bounce debouncer = Bounce(); int oldValue=0; bool state1; Bounce debouncer2 = Bounce(); int oldValue2; bool state2; bool initialValueSent = false; unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds) unsigned long CHECK_TIME = millis(); OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. float lastTemperature[MAX_ATTACHED_DS18B20]; int numSensors=0; float roofTemp; float poolTemp; String poolPumpstate; String solarPumpstate; bool receivedConfig = false; bool metric = true; // Initialize temperature message MyMessage msg(1,V_TEMP); MyMessage msg2(CHILD_ID, V_LIGHT); MyMessage msg3(CHILD_ID_2, V_LIGHT); void before() { // Startup up the OneWire library sensors.begin(); } void setup() { pinMode(BUTTON_PIN, INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN, HIGH); pinMode(BUTTON_PIN_2, INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN_2, HIGH); debouncer.attach(BUTTON_PIN); debouncer.interval(5); debouncer2.attach(BUTTON_PIN_2); debouncer2.interval(5); oldValue = debouncer.read(); oldValue2 = debouncer2.read(); // requestTemperatures() will not block current thread sensors.setWaitForConversion(false); lcd.begin(16, 2); // LCD 2 lines * 16 char. lcd.setBacklight(HIGH); lcd.setCursor(0, 0); lcd.setCursor(0, 0); lcd.clear(); lcd.print(" Contoller "); lcd.setCursor(0, 1); lcd.print(" Starting "); wait(2000); pinMode(RELAY_PIN, OUTPUT); pinMode(RELAY_PIN_2, OUTPUT); digitalWrite(RELAY_PIN, RELAY_OFF); digitalWrite(RELAY_PIN_2, RELAY_OFF); /* lcd.setCursor(0, 0); lcd.clear(); lcd.print("Begin Pump Test"); wait(2000); digitalWrite(RELAY_PIN, RELAY_ON); wait(5000); digitalWrite(RELAY_PIN, RELAY_OFF); lcd.setCursor(0, 0); lcd.clear(); lcd.print("Pool Pump Test"); lcd.setCursor(0, 1); lcd.print("OK"); wait(2000); lcd.setCursor(0, 0); lcd.clear(); lcd.print("Begin Pump Test"); digitalWrite(RELAY_PIN_2, RELAY_ON); wait(5000); digitalWrite(RELAY_PIN_2, RELAY_OFF); lcd.setCursor(0, 0); lcd.clear(); lcd.print("Solar Pump Test"); lcd.setCursor(0, 1); lcd.print("OK"); */ wait(2000); wait(10000); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("Pool Controller", "1.1"); // Fetch the number of attached temperature sensors numSensors = sensors.getDeviceCount(); // Present all sensors to controller for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) { present(i, S_TEMP); present(CHILD_ID, S_BINARY); present(CHILD_ID_2, S_BINARY); } } void loop() { if (!initialValueSent) { Serial.println("Sending initial value"); send(msg2.set(state?RELAY_OFF:RELAY_ON)); send(msg3.set(state?RELAY_OFF:RELAY_ON)); Serial.println("Requesting initial value from controller"); request(CHILD_ID, V_STATUS); request(CHILD_ID_2, V_STATUS); wait(2000, C_SET, V_STATUS); } { debouncer.update(); // Get the update value int value = debouncer.read(); state = !state; if (value != oldValue && value==0) { send(msg2.set(state?true:false), true); // Send new state and request ack back digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF); } oldValue = value; /* { debouncer2.update(); // Get the update value int value = debouncer2.read(); state2 = !state2; if (value != oldValue2 && value==0) { send(msg3.set(state2?true:false), false); // Send new state and request ack back digitalWrite(RELAY_PIN_2, state2?RELAY_ON:RELAY_OFF); } oldValue = value; }*/ } unsigned long NOW_TIME = millis(); if(NOW_TIME - CHECK_TIME >= SLEEP_TIME) { updateLCDtemps(); CHECK_TIME = NOW_TIME; Serial.println("Updating LCD"); } updateTemperature(30); if (solarPumpstate == "Running" ){ updateLCDstatus; } } /////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////// RECIEVE TEMPS //////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// void receive(const MyMessage &message) { if (message.type==V_TEMP) { if (message.sensor == 1) { // Write some debug info Serial.print("Incoming change from roof sensor:"); Serial.print(message.sensor); Serial.print("\n"); Serial.print(", New status: "); Serial.println(message.getFloat()); roofTemp = (message.getFloat()); }} /////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////// RECIEVE RELAYS //////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// else if (message.getType()==V_STATUS) { if (message.sensor == 4){ state = message.getBool(); Serial.print(state); digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF); Serial.print("Incoming change for sensor:"); Serial.print(message.getSensor()); Serial.print(", New status: "); Serial.println(message.getBool()); // send(msg2.set(state?RELAY_ON:RELAY_OFF)); if ((message.getBool())== 1){ poolPumpstate = ("Running");} else{ poolPumpstate = ("Standby"); }} if (message.sensor == 5){ state = (bool)message.getInt(); Serial.print(state); digitalWrite(RELAY_PIN_2, state?RELAY_ON:RELAY_OFF); Serial.print("Incoming change for sensor:"); Serial.print(message.getSensor()); Serial.print(", New status: "); Serial.println(message.getBool()); send(msg3.set(state?RELAY_OFF:RELAY_ON)); if ((message.getBool())== 1){ solarPumpstate = ("Running");} else{ solarPumpstate = ("Standby"); }} if (message.type == V_STATUS) { if (!initialValueSent) { Serial.println("Receiving initial value from controller"); initialValueSent = true; }} } } void updateLCDtemps() { lcd.clear(); lcd.setCursor(0, 1); lcd.print("Pool :"); lcd.print(" "); lcd.print(poolTemp); lcd.print((char)223); lcd.print("C"); lcd.setCursor(0, 0); lcd.print("Solar :"); lcd.print(" "); lcd.print(roofTemp); lcd.print((char)223); lcd.print("C"); } void updateLCDstatus() { lcd.clear(); lcd.setCursor(0, 1); lcd.print("Pool :"); lcd.print(" "); lcd.print(poolPumpstate); lcd.setCursor(0, 0); lcd.print("Solar :"); lcd.print(" "); lcd.print(solarPumpstate); } void updateTemperature(int frequency) { static unsigned long lastUpdateTime; if (millis() - lastUpdateTime >= frequency * 1000UL) { sensors.requestTemperatures(); for (int i=0; i<numSensors && i< MAX_ATTACHED_DS18B20; i++) { float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.; if (lastTemperature[i] != temperature && temperature != -127.00) { send(msg.setSensor(i).set(temperature,1)); lastTemperature[i]=temperature; poolTemp = temperature; } } lastUpdateTime += frequency * 1000UL; } }@JCH I haven't tried interrupt with wait so I can't really say for sure. But it works for sleep 100%.....
I don't know how you got to the point you are at now, but it is easy to reflash an arduino and so I suggest the following.....
- Start again from the begining with the new knowledge you have.
- Look at similar examples and learn how they work.
- Build your code slowly.
Start by getting just the buttons to work and monitor them in the serial window or by attaching leds with limiting resistors to the output pins you want to use for the relays. Then add debounce and check all is working. Then add the lcd display and test until working. Keep adding a bit at t time so it is easy to know what you changed and if it worked as expected.
When I am doing this I save the sktech after each working version and then update the sketch version for the next addition. It allows me to easily go back to working system if I get unexpected results (which I do in a lot of cases!).....
-
@JCH I haven't tried interrupt with wait so I can't really say for sure. But it works for sleep 100%.....
I don't know how you got to the point you are at now, but it is easy to reflash an arduino and so I suggest the following.....
- Start again from the begining with the new knowledge you have.
- Look at similar examples and learn how they work.
- Build your code slowly.
Start by getting just the buttons to work and monitor them in the serial window or by attaching leds with limiting resistors to the output pins you want to use for the relays. Then add debounce and check all is working. Then add the lcd display and test until working. Keep adding a bit at t time so it is easy to know what you changed and if it worked as expected.
When I am doing this I save the sktech after each working version and then update the sketch version for the next addition. It allows me to easily go back to working system if I get unexpected results (which I do in a lot of cases!).....
-
Ok i need help again please... I cannot get to the bottom of my last little problem......
void setup() { pinMode(BUTTON_PIN, INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN, HIGH); pinMode(BUTTON_PIN_2, INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN_2, HIGH); // pinMode(BUTTON_PIN_3, INPUT); // Activate internal pull-up // digitalWrite(BUTTON_PIN_3, HIGH); debouncer.attach(BUTTON_PIN); debouncer.interval(5); debouncer2.attach(BUTTON_PIN_2); debouncer2.interval(5); debouncer3.attach(BUTTON_PIN_3); debouncer3.interval(5); oldValue = debouncer.read(); oldValue2 = debouncer2.read(); oldValue3 = debouncer3.read();As soon as i tired to add a 3rd button and debouncer the whole code crashes.... as soon a a comment out the above lines it goes good again.... thoughts?
Here is the whole code (havent tidyed it up yet :wink:
/** JH REV 1.0 - 12-04-2020 */ // Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_RF24 #define MY_RF24_PA_LEVEL RF24_PA_HIGH #define MY_NODE_ID 22 //////////FOR TESTING #define MY_REPEATER_FEATURE #include <MySensors.h> #include <DallasTemperature.h> #include <OneWire.h> #include <LiquidCrystal_I2C.h> #include <Bounce2.h> #include <SPI.h> LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected #define MAX_ATTACHED_DS18B20 16 #define RELAY_PIN 4 #define RELAY_PIN_2 5 #define RELAY_PIN_3 6 #define RELAY_ON 0 #define RELAY_OFF 1 #define BUTTON_PIN 7 #define BUTTON_PIN_2 8 #define BUTTON_PIN_3 9 #define CHILD_ID 4 // Id of the sensor child for 1st relay #define CHILD_ID_2 5 // Id of the sensor child for 2nd relay #define CHILD_ID_3 6 // Id of the sensor child for 2nd relay bool state; Bounce debouncer = Bounce(); int oldValue=0; int oldValue1=0; bool state1; Bounce debouncer2 = Bounce(); int oldValue2=0; bool state2; Bounce debouncer3 = Bounce(); int oldValue3=0; bool state3; bool initialValueSent = false; unsigned long SLEEP_TIME = 60000; // Sleep time between reads (in milliseconds) unsigned long CHECK_TIME = millis(); OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. float lastTemperature[MAX_ATTACHED_DS18B20]; int numSensors=0; float roofTemp; float poolTemp; String poolPumpstate; String solarPumpstate; bool receivedConfig = false; bool metric = true; // Initialize temperature message MyMessage msg(1,V_TEMP); MyMessage msg2(CHILD_ID, V_LIGHT); MyMessage msg3(CHILD_ID_2, V_LIGHT); MyMessage msg4(CHILD_ID_3, V_LIGHT); void before() { // Startup up the OneWire library sensors.begin(); } void setup() { pinMode(BUTTON_PIN, INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN, HIGH); pinMode(BUTTON_PIN_2, INPUT); // Activate internal pull-up digitalWrite(BUTTON_PIN_2, HIGH); // pinMode(BUTTON_PIN_3, INPUT); // Activate internal pull-up // digitalWrite(BUTTON_PIN_3, HIGH); debouncer.attach(BUTTON_PIN); debouncer.interval(5); debouncer2.attach(BUTTON_PIN_2); debouncer2.interval(5); debouncer3.attach(BUTTON_PIN_3); debouncer3.interval(5); oldValue = debouncer.read(); oldValue2 = debouncer2.read(); oldValue3 = debouncer3.read(); // requestTemperatures() will not block current thread sensors.setWaitForConversion(false); lcd.begin(16, 2); // LCD 2 lines * 16 char. lcd.setBacklight(HIGH); lcd.setCursor(0, 0); lcd.setCursor(0, 0); lcd.clear(); lcd.print(" Contoller "); lcd.setCursor(0, 1); lcd.print(" Starting "); wait(2000); pinMode(RELAY_PIN, OUTPUT); pinMode(RELAY_PIN_2, OUTPUT); digitalWrite(RELAY_PIN, RELAY_OFF); digitalWrite(RELAY_PIN_2, RELAY_OFF); /* lcd.setCursor(0, 0); lcd.clear(); lcd.print("Begin Pump Test"); wait(2000); digitalWrite(RELAY_PIN, RELAY_ON); wait(5000); digitalWrite(RELAY_PIN, RELAY_OFF); lcd.setCursor(0, 0); lcd.clear(); lcd.print("Pool Pump Test"); lcd.setCursor(0, 1); lcd.print("OK"); wait(2000); lcd.setCursor(0, 0); lcd.clear(); lcd.print("Begin Pump Test"); digitalWrite(RELAY_PIN_2, RELAY_ON); wait(5000); digitalWrite(RELAY_PIN_2, RELAY_OFF); lcd.setCursor(0, 0); lcd.clear(); lcd.print("Solar Pump Test"); lcd.setCursor(0, 1); lcd.print("OK"); */ wait(2000); wait(10000); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("Pool Controller", "1.1"); // Fetch the number of attached temperature sensors numSensors = sensors.getDeviceCount(); // Present all sensors to controller for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) { present(i, S_TEMP); present(CHILD_ID, S_BINARY); present(CHILD_ID_2, S_BINARY); } } void loop() { if (!initialValueSent) { Serial.println("Sending initial value"); send(msg2.set(state?RELAY_OFF:RELAY_ON)); send(msg3.set(state?RELAY_OFF:RELAY_ON)); Serial.println("Requesting initial value from controller"); request(CHILD_ID, V_STATUS); request(CHILD_ID_2, V_STATUS); wait(2000, C_SET, V_STATUS); } debouncer.update(); debouncer2.update(); // Get the update value int value1 = debouncer.read(); int value2 = debouncer2.read(); if (debouncer.fell()) { state1 = !state1; send(msg2.set(state1?true:false), false); // Send new state and request ack back digitalWrite(RELAY_PIN, state1?RELAY_ON:RELAY_OFF); // TURN ON / OFF RELAYS oldValue1 = value1; } if (debouncer2.fell()) { state2 = !state2; send(msg3.set(state2?true:false), false); // Send new state and request ack back digitalWrite(RELAY_PIN_2, state2?RELAY_ON:RELAY_OFF); // TURN ON / OFF RELAYS oldValue2 = value2; } unsigned long NOW_TIME = millis(); if(NOW_TIME - CHECK_TIME >= SLEEP_TIME) { updateLCDtemps(); CHECK_TIME = NOW_TIME; Serial.println("Updating LCD"); } updateTemperature(30); if (solarPumpstate == "Running" ){ updateLCDstatus; } } /////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////// RECIEVE TEMPS //////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// void receive(const MyMessage &message) { if (message.type==V_TEMP) { if (message.sensor == 1) { // Write some debug info Serial.print("Incoming change from roof sensor:"); Serial.print(message.sensor); Serial.print("\n"); Serial.print(", New status: "); Serial.println(message.getFloat()); roofTemp = (message.getFloat()); }} /////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////// RECIEVE RELAYS //////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// else if (message.getType()==V_STATUS) { if (message.sensor == 4){ state1 = message.getBool(); digitalWrite(RELAY_PIN, state1?RELAY_ON:RELAY_OFF); Serial.print("Incoming change for sensor:"); Serial.print(message.getSensor()); Serial.print(", New status: "); Serial.println(message.getBool()); // send(msg2.set(state?RELAY_ON:RELAY_OFF)); if ((message.getBool())== 1){ poolPumpstate = ("Running");} else{ poolPumpstate = ("Standby"); }} if (message.sensor == 5){ state2 = message.getBool(); Serial.print(state); digitalWrite(RELAY_PIN_2, state2?RELAY_ON:RELAY_OFF); Serial.print("Incoming change for sensor:"); Serial.print(message.getSensor()); Serial.print(", New status: "); Serial.println(message.getBool()); // send(msg3.set(state?RELAY_OFF:RELAY_ON)); if ((message.getBool())== 1){ solarPumpstate = ("Running");} else{ solarPumpstate = ("Standby"); }} if (message.type == V_STATUS) { if (!initialValueSent) { Serial.println("Receiving initial value from controller"); initialValueSent = true; }} } } void updateLCDtemps() { lcd.clear(); lcd.setCursor(0, 1); lcd.print("Pool :"); lcd.print(" "); lcd.print(poolTemp); lcd.print((char)223); lcd.print("C"); lcd.setCursor(0, 0); lcd.print("Solar :"); lcd.print(" "); lcd.print(roofTemp); lcd.print((char)223); lcd.print("C"); } void updateLCDstatus() { lcd.clear(); lcd.setCursor(0, 1); lcd.print("Pool :"); lcd.print(" "); lcd.print(poolPumpstate); lcd.setCursor(0, 0); lcd.print("Solar :"); lcd.print(" "); lcd.print(solarPumpstate); } void updateTemperature(int frequency) { static unsigned long lastUpdateTime; if (millis() - lastUpdateTime >= frequency * 1000UL) { Serial.println("Updating Dallas Temp"); sensors.requestTemperatures(); for (int i=0; i<numSensors && i< MAX_ATTACHED_DS18B20; i++) { float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.; if (lastTemperature[i] != temperature && temperature != -127.00) { send(msg.setSensor(i).set(temperature,1)); lastTemperature[i]=temperature; poolTemp = temperature; Serial.println("Pool Temp = "); Serial.println(poolTemp); updateLCDtemps(); } } lastUpdateTime += frequency * 1000UL; } } -
Edit.... Does mysensors use pin 9 for anything? as soon as i try to use it as an input the radio seems to not be communicating with the controller?
I loaded a bounce sketch to test the button and pin and it works fine untill i reload my sketch.