How do i sent "virtual switches" from node to Controller?
-
@Boots33 said:
@SuperKris So the keypad will just control the state of a "virtual" switch on the controller ? and then you will have that virtual switch control other nodes to do the actual hardware switching?
That is exactly what i want!
@tboha said:
@SuperKris : you should consider adding the "sending" routines for MySensors. Maybe dissecting the Binary Switch Example would be a better startingpoint than the RelaySketch.
I tried to integrate these routines into your template. Unfortunately I can´t test this sketch due to the lack of the Keypad. At least the sketch compiles without error.
Thanks! this should really help! I will test this tonight but its already giving me some understanding of how the sending of the messages work. I already have a couple of questions from just looking at you code.
-
I see you did not really use the manual created booleans ("VirtalSwitch1" for example). Do i need these manual created booleans for the function i want, of are these booleans automatically created by the mysensors library?
-
The code you added to sent the "virtual" switches to the controller seems to be the following:
- "MyMessage msgV1(CHILD_ID_V1,S_LIGHT)" presents the existence of the switch to the gateway
- and "send(msgV1.set(1))" sends the status change to the gateway.
Where is the status (boolean?) actually stored? Is this a boolean provided by the mysensors code?
-
Again, if i understand right, the state of a (virtual) switch is always stored on the node. Not on the controller. Can you confirm?
If so, how do i change the state of the (virtual) switch from the controller? For example. 1 keypad button will control the the outside lighting. Inside of the house i will place a 433mhz wallswitch that does the same thing. For this i need the 433mhz wallswitch to be able to change the state of the (virtual) button. The controller (Domoticz) will turn on the lights depending on the state of the virtual switch.
In other words, it seems to me the vitual switches should be controlled by the controller, but i dont see any receiving code. -
I see you wrote some comments about not using pin 0 and 1. I would rather not used them too, but i do not have any pins left. I need:
6 digital pins for the NRF24L01 radio
5 digital pins for the keypad
4 digital pins for relays
1 digital pin for PIR
1 digital pin for TEMP/HUM
1 digital pin for future expansion
This leaves me with no available pins. A5 and A6 are analog only so i have no use for these. Unfortunatly i really need 0 and 1. I can still use then for debugging, but when serial debug is activated i loose 2 collumns of the keypad. For debugging this is not a huge problem.
I see you did not really use the manual created booleans ("VirtalSwitch1" for example). Do i need these manual created booleans for the function i want,
1.) Yes, you need these variables just the way you created them. At the moment they are used for logging (as you used them until now), so they reflect the current state as changed by the switches. More features have to be implemented.
of are these booleans automatically created by the mysensors library?
No, these booleans are not implemented by MySensors, at least not in the way you plan to use them.
"MyMessage msgV1(CHILD_ID_V1,S_LIGHT)" presents the existence of the switch to the gateway
Exact.
and "send(msgV1.set(1))" sends the status change to the gateway.
Where is the status (boolean?) actually stored? Is this a boolean provided by the mysensors code?at last yes, but ... this statement performs two jobs:
- msgV1.set(1) sets the payload of the Message"Container" to "1"
- send(msgV1) performs the actual sending.
- send(msgV1.set(VirtalSwitch1) would probably do the trick - but I was too lazy typing. The current status is stored in the variables you created.
Again, if i understand right, the state of a (virtual) switch is always stored on the node. Not on the controller. Can you confirm?
Yes.
If so, how do i change the state of the (virtual) switch from the controller? For example. 1 keypad button will control the the outside lighting. Inside of the house i will place a 433mhz wallswitch that does the same thing. For this i need the 433mhz wallswitch to be able to change the state of the (virtual) button. The controller (Domoticz) will turn on the lights depending on the state of the virtual switch.
In other words, it seems to me the vitual switches should be controlled by the controller, but i dont see any receiving code.Yes, there is much work left.
I am sorry, these answers are not very helpful at the moment. I´m in a hurry and I will try to explain later in the evening.
Until then I would propose you try to get the first fragment of the above sketch running. It will give you an impression of some possibilities - and also of some restrictions.
Until later.
-
-
Thank you very much thoba! With that info is was able to build a fully working proof of concept!
I attached a test relay to IoPin4 which is linked to VirtalSwitch1. I can see VirtalSwitch1 in the controller, and add it as switch. When i use the keypad it changes the boolean, and the status of the switch is updated in the controller.
I can not change the same boolean trough the controller, as there is no receiving code. This however was easy to write because i figured it would not be much different than the relay pins. I added some code, and it seems to work fine. I can change the boolean in the node with the controller now.
There is still 1 issue with this code. I can not store the state of the boolean to the EEPROM. If i uncomment the last line, the sketch will not compile and i get the following error:
Arduino: 1.6.13 (Windows Store 1.6.13.0) (Windows 10), Board:"Arduino Nano, ATmega328" C:\Users\krist\Desktop\arduino testing\IO_test_0.2\IO_test_0.2.ino: In function 'void receive(const MyMessage&)': IO_test_0.2:207: error: too few arguments to function 'void saveState(uint8_t, uint8_t)' saveState(CHILD_ID_V1), state); //guess this saves the state if child ID 2 to EEPPROM ^ In file included from C:\Users\krist\Documents\Arduino\libraries\MySensors/MySensors.h:293:0, from C:\Users\krist\Desktop\arduino testing\IO_test_0.2\IO_test_0.2.ino:13: C:\Users\krist\Documents\Arduino\libraries\MySensors/core/MySensorsCore.cpp:408:6: note: declared here void saveState(uint8_t pos, uint8_t value) { ^ exit status 1 too few arguments to function 'void saveState(uint8_t, uint8_t)' This report would have more information with "Show verbose output during compilation" option enabled in File -> Preferences.The working code:
// ##### SET PROJECT NAME AND VERSION ##### #define ProjectName "Schuur controller" #define ProjectVersion "0,2" // ##### SET MYSENSOR SETTINGS BEFORE INCLUDIGN LIBRARY ##### #define MY_DEBUG // Enable debug prints to serial monitor #define MY_RADIO_NRF24 // Enable and select radio type attached #define MY_REPEATER_FEATURE // Enabled repeater feature for this node // ##### INCLUDE LIBRARYS ##### #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> #include <Keypad.h> // ##### DEFINE I/O PINS ##### //#define IoPin1 4 // Arduino Digital I/O pin number for I/O 1 #define IoPin2 3 // Arduino Digital I/O pin number for I/O 2 //#define IoPin3 6 // Arduino Digital I/O pin number for I/O 3 #define IoPin4 5 // Arduino Digital I/O pin number for I/O 4 #define IoPin5 8 // Arduino Digital I/O pin number for I/O 5 #define IoPin6 7 // Arduino Digital I/O pin number for I/O 6 #define IoPin7 19 // Arduino Digital I/O pin number for I/O 7 // ##### DEFINE CHILD ID'S ##### #define CHILD_ID1 1 // ID for child 1 (I/O) #define CHILD_ID2 2 // ID for child 2 (I/O) //#define CHILD_ID3 3 // ID for child 3 (I/O) //#define CHILD_ID4 4 // ID for child 4 (I/O) #define CHILD_ID5 5 // ID for child 5 (I/O) #define CHILD_ID6 6 // ID for child 6 (I/O) #define CHILD_ID7 7 // ID for child 7 (I/O) #define CHILD_ID_V1 10 // ID for child virtual switch 1 #define CHILD_ID_V2 11 // ID for child virtual switch 2 #define CHILD_ID_V3 12 // ID for child virtual switch 3 #define CHILD_ID_V4 13 // ID for child virtual switch 4 #define CHILD_ID_V5 14 // ID for child virtual switch 5 // ##### RELAY SETTING ##### #define RELAY_ON 0 // Invert for some relay modules (currently inverted) #define RELAY_OFF 1 // Invert for some relay modules (currently inverted) // ##### OTHER VARIABLES ##### bool state; // not sure what this does // ##### BOOLEANS FOR VIRTUAL SWITCHES ##### bool VirtalSwitch1; // Boolean (status) for virtual switch 1 (controlled by keypad) bool VirtalSwitch2; // Boolean (status) for virtual switch 2 (controlled by keypad) bool VirtalSwitch3; // Boolean (status) for virtual switch 3 (controlled by keypad) bool VirtalSwitch4; // Boolean (status) for virtual switch 4 (controlled by keypad) bool VirtalSwitch5; // Boolean (status) for virtual switch 5 (controlled by keypad) // ##### DEFINE MYSENSORS MESSAGE CONTAINERS TO COMMUNICATE WITH GATEWAY ##### MyMessage msgV1(CHILD_ID_V1,S_LIGHT); // msgV1 sends child ID CHILD_ID_V1 as S_LIGHT MyMessage msgV2(CHILD_ID_V2,S_LIGHT); // msgV2 sends child ID CHILD_ID_V2 as S_LIGHT MyMessage msgV3(CHILD_ID_V3,S_LIGHT); // msgV3 sends child ID CHILD_ID_V3 as S_LIGHT MyMessage msgV4(CHILD_ID_V4,S_LIGHT); // msgV4 sends child ID CHILD_ID_V4 as S_LIGHT MyMessage msgV5(CHILD_ID_V5,S_LIGHT); // msgV5 sends child ID CHILD_ID_V5 as S_LIGHT // ##### KEYPAD SETUP ##### const byte ROWS = 4; // Four rows const byte COLS = 3; // Three columns // Define the Keymap char keys[ROWS][COLS] = { {'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}, {'A', 'B', 'C'} }; // Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins. byte rowPins[ROWS] = { A0, A1, A2, A3 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins. byte colPins[COLS] = { A4, 1, 0 }; //if you got any spare pins - change 0 and 1 accordingly e.g. { A4, 8, 9 } // or see below // Create the Keypad Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); void setup() { // ##### I/O SETUP FOR PHYSICAL I/O ON ARDUINO ##### // Setup I/O 2 pinMode(IoPin2, OUTPUT); // use I/O 2 as output for relay module digitalWrite(IoPin2, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID2); // Load last known state (using eeprom storage) digitalWrite(IoPin2, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 4 Not in use // pinMode(IoPin4, OUTPUT); // use I/O 4 as output for relay module // digitalWrite(IoPin4, RELAY_OFF); // and set switch relay output off // state = loadState(CHILD_ID4); // Load last known state (using eeprom storage) // digitalWrite(IoPin4, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 5 pinMode(IoPin5, OUTPUT); // use I/O 5 as output for relay module digitalWrite(IoPin5, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID5); // Load last known state (using eeprom storage) digitalWrite(IoPin5, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 6 pinMode(IoPin6, OUTPUT); // use I/O 6 as output for relay module digitalWrite(IoPin6, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID6); // Load last known state (using eeprom storage) digitalWrite(IoPin6, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 7 pinMode(IoPin7, OUTPUT); // use I/O 7 as output for relay module digitalWrite(IoPin7, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID7); // Load last known state (using eeprom storage) digitalWrite(IoPin7, state?RELAY_ON:RELAY_OFF); // write last know state // ----- PIN SETUP (FOR TESTING ONLY ----- pinMode(IoPin4, OUTPUT); //use I/O 4 as output for relay module digitalWrite(IoPin4, HIGH);// and set is HIGH so relay stays off } // ###### PRESENT ALL ATTACHED SENSORS TO CONTROLLER ###### void presentation(){ sendSketchInfo(ProjectName, ProjectVersion); // Send the sketch version information to the gateway and Controller // ----- Actual I/O child IDs ----- //present(CHILD_ID1, XXXXXXX); //Register child ID 1 as NONE present(CHILD_ID2, S_LIGHT); //Register child ID 2 as S_LIGHT //present(CHILD_ID3, XXXXXXX); //Register child ID 3 as NONE //present(CHILD_ID4, XXXXXXX); //Register child ID 4 as NONE present(CHILD_ID5, S_LIGHT); //Register child ID 5 as S_LIGHT present(CHILD_ID6, S_LIGHT); //Register child ID 6 as S_LIGHT present(CHILD_ID7, S_LIGHT); //Register child ID 7 as S_LIGHT // ----- virtual switch child ID (keypad) present(CHILD_ID_V1, S_LIGHT); //Register child ID 10 as S_LIGHT present(CHILD_ID_V2, S_LIGHT); //Register child ID 11 as S_LIGHT present(CHILD_ID_V3, S_LIGHT); //Register child ID 12 as S_LIGHT present(CHILD_ID_V4, S_LIGHT); //Register child ID 13 as S_LIGHT present(CHILD_ID_V5, S_LIGHT); //Register child ID 14 as S_LIGHT } void loop() { // ##### KEYPAD CODE TO SET A ACTION FOR A PRESSED KEY ##### char key = kpd.getKey(); // Get key from keypad (if pressed) if (key) { // compare key (defined in keypad setup) switch (key) { // with multiple multiple options below case '1': // If the pressed key compares with "1" VirtalSwitch1 = true; // Change te state of boolean VirtalSwitch1 to true send(msgV1.set(1)); // sending virtual switch state to Gateway Serial.println("1"); // Debug code. Print "1" to show that button 1 was pressed break; // End of code for button 1 case '4': // If the pressed key compares with "4" VirtalSwitch1 = false; // Change te state of boolean VirtalSwitch1 to false send(msgV1.set(0)); // sending virtual switch state to Gateway Serial.println("4"); // Debug code. Print "4" to show that button 4 was pressed break; // End of code for button 4 // Other keys to be added here according to the same template default: // If the pressed key does not match the cases above Serial.println(key); // Print the key that was pressed break; // End of function } } // ----- WRITE BOOLEAN TO PIN (FOR TESTING PURPOSES ONLY) ----- digitalWrite(IoPin4, VirtalSwitch1); } // ##### CODE FOR RECEIVING MYSENSORS MESSAGES FROM CONTROLLER ##### void receive(const MyMessage &message) { //start mysensor receiving code if (message.isAck()) { //Check for gateway acknowledgment Serial.println("This is an ack from gateway"); //Print debug code (serial print) to confirm received ack } // ----- Action taken for child ID 1: Currently set as V_LIGHT to switch relay on IoPin1 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID2) { //if message is V_LIGHT and the child ID is 2 state = message.getBool(); //guess this write the incomming boolean to state? digitalWrite(IoPin2, state?RELAY_ON:RELAY_OFF); //change the the arduino pin from "on" to "off" or other way around saveState(CHILD_ID2, state); //guess this saves the state if child ID 2 to EEPPROM Serial.print("Incoming change for sensor:"); //debug info text Serial.print(message.sensor); //write received child ID Serial.print(", New status: "); //debug info text Serial.println(message.getBool()); //write received boolean } // ----- Action taken for child ID 5: Currently set as V_LIGHT to switch relay on IoPin5 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID5) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin5, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID5, state); } // ----- Action taken for child ID 6: Currently set as V_LIGHT to switch relay on IoPin6 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID6) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin6, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID6, state); } // ----- Action taken for child ID 7: Currently set as V_LIGHT to switch relay on IoPin7 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID7) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin7, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID7, state); } // ----- Action taken for CHILD_ID_V1: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch1) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V1) { //if message is V_LIGHT and the CHILD_ID_V1 state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch1 = state; //copy the received boolean to VirtalSwitch1 //saveState(CHILD_ID_V1), state); //guess this saves the state if child ID 2 to EEPPROM } }``` -
Thank you very much thoba! With that info is was able to build a fully working proof of concept!
I attached a test relay to IoPin4 which is linked to VirtalSwitch1. I can see VirtalSwitch1 in the controller, and add it as switch. When i use the keypad it changes the boolean, and the status of the switch is updated in the controller.
I can not change the same boolean trough the controller, as there is no receiving code. This however was easy to write because i figured it would not be much different than the relay pins. I added some code, and it seems to work fine. I can change the boolean in the node with the controller now.
There is still 1 issue with this code. I can not store the state of the boolean to the EEPROM. If i uncomment the last line, the sketch will not compile and i get the following error:
Arduino: 1.6.13 (Windows Store 1.6.13.0) (Windows 10), Board:"Arduino Nano, ATmega328" C:\Users\krist\Desktop\arduino testing\IO_test_0.2\IO_test_0.2.ino: In function 'void receive(const MyMessage&)': IO_test_0.2:207: error: too few arguments to function 'void saveState(uint8_t, uint8_t)' saveState(CHILD_ID_V1), state); //guess this saves the state if child ID 2 to EEPPROM ^ In file included from C:\Users\krist\Documents\Arduino\libraries\MySensors/MySensors.h:293:0, from C:\Users\krist\Desktop\arduino testing\IO_test_0.2\IO_test_0.2.ino:13: C:\Users\krist\Documents\Arduino\libraries\MySensors/core/MySensorsCore.cpp:408:6: note: declared here void saveState(uint8_t pos, uint8_t value) { ^ exit status 1 too few arguments to function 'void saveState(uint8_t, uint8_t)' This report would have more information with "Show verbose output during compilation" option enabled in File -> Preferences.The working code:
// ##### SET PROJECT NAME AND VERSION ##### #define ProjectName "Schuur controller" #define ProjectVersion "0,2" // ##### SET MYSENSOR SETTINGS BEFORE INCLUDIGN LIBRARY ##### #define MY_DEBUG // Enable debug prints to serial monitor #define MY_RADIO_NRF24 // Enable and select radio type attached #define MY_REPEATER_FEATURE // Enabled repeater feature for this node // ##### INCLUDE LIBRARYS ##### #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> #include <Keypad.h> // ##### DEFINE I/O PINS ##### //#define IoPin1 4 // Arduino Digital I/O pin number for I/O 1 #define IoPin2 3 // Arduino Digital I/O pin number for I/O 2 //#define IoPin3 6 // Arduino Digital I/O pin number for I/O 3 #define IoPin4 5 // Arduino Digital I/O pin number for I/O 4 #define IoPin5 8 // Arduino Digital I/O pin number for I/O 5 #define IoPin6 7 // Arduino Digital I/O pin number for I/O 6 #define IoPin7 19 // Arduino Digital I/O pin number for I/O 7 // ##### DEFINE CHILD ID'S ##### #define CHILD_ID1 1 // ID for child 1 (I/O) #define CHILD_ID2 2 // ID for child 2 (I/O) //#define CHILD_ID3 3 // ID for child 3 (I/O) //#define CHILD_ID4 4 // ID for child 4 (I/O) #define CHILD_ID5 5 // ID for child 5 (I/O) #define CHILD_ID6 6 // ID for child 6 (I/O) #define CHILD_ID7 7 // ID for child 7 (I/O) #define CHILD_ID_V1 10 // ID for child virtual switch 1 #define CHILD_ID_V2 11 // ID for child virtual switch 2 #define CHILD_ID_V3 12 // ID for child virtual switch 3 #define CHILD_ID_V4 13 // ID for child virtual switch 4 #define CHILD_ID_V5 14 // ID for child virtual switch 5 // ##### RELAY SETTING ##### #define RELAY_ON 0 // Invert for some relay modules (currently inverted) #define RELAY_OFF 1 // Invert for some relay modules (currently inverted) // ##### OTHER VARIABLES ##### bool state; // not sure what this does // ##### BOOLEANS FOR VIRTUAL SWITCHES ##### bool VirtalSwitch1; // Boolean (status) for virtual switch 1 (controlled by keypad) bool VirtalSwitch2; // Boolean (status) for virtual switch 2 (controlled by keypad) bool VirtalSwitch3; // Boolean (status) for virtual switch 3 (controlled by keypad) bool VirtalSwitch4; // Boolean (status) for virtual switch 4 (controlled by keypad) bool VirtalSwitch5; // Boolean (status) for virtual switch 5 (controlled by keypad) // ##### DEFINE MYSENSORS MESSAGE CONTAINERS TO COMMUNICATE WITH GATEWAY ##### MyMessage msgV1(CHILD_ID_V1,S_LIGHT); // msgV1 sends child ID CHILD_ID_V1 as S_LIGHT MyMessage msgV2(CHILD_ID_V2,S_LIGHT); // msgV2 sends child ID CHILD_ID_V2 as S_LIGHT MyMessage msgV3(CHILD_ID_V3,S_LIGHT); // msgV3 sends child ID CHILD_ID_V3 as S_LIGHT MyMessage msgV4(CHILD_ID_V4,S_LIGHT); // msgV4 sends child ID CHILD_ID_V4 as S_LIGHT MyMessage msgV5(CHILD_ID_V5,S_LIGHT); // msgV5 sends child ID CHILD_ID_V5 as S_LIGHT // ##### KEYPAD SETUP ##### const byte ROWS = 4; // Four rows const byte COLS = 3; // Three columns // Define the Keymap char keys[ROWS][COLS] = { {'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}, {'A', 'B', 'C'} }; // Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins. byte rowPins[ROWS] = { A0, A1, A2, A3 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins. byte colPins[COLS] = { A4, 1, 0 }; //if you got any spare pins - change 0 and 1 accordingly e.g. { A4, 8, 9 } // or see below // Create the Keypad Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); void setup() { // ##### I/O SETUP FOR PHYSICAL I/O ON ARDUINO ##### // Setup I/O 2 pinMode(IoPin2, OUTPUT); // use I/O 2 as output for relay module digitalWrite(IoPin2, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID2); // Load last known state (using eeprom storage) digitalWrite(IoPin2, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 4 Not in use // pinMode(IoPin4, OUTPUT); // use I/O 4 as output for relay module // digitalWrite(IoPin4, RELAY_OFF); // and set switch relay output off // state = loadState(CHILD_ID4); // Load last known state (using eeprom storage) // digitalWrite(IoPin4, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 5 pinMode(IoPin5, OUTPUT); // use I/O 5 as output for relay module digitalWrite(IoPin5, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID5); // Load last known state (using eeprom storage) digitalWrite(IoPin5, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 6 pinMode(IoPin6, OUTPUT); // use I/O 6 as output for relay module digitalWrite(IoPin6, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID6); // Load last known state (using eeprom storage) digitalWrite(IoPin6, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 7 pinMode(IoPin7, OUTPUT); // use I/O 7 as output for relay module digitalWrite(IoPin7, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID7); // Load last known state (using eeprom storage) digitalWrite(IoPin7, state?RELAY_ON:RELAY_OFF); // write last know state // ----- PIN SETUP (FOR TESTING ONLY ----- pinMode(IoPin4, OUTPUT); //use I/O 4 as output for relay module digitalWrite(IoPin4, HIGH);// and set is HIGH so relay stays off } // ###### PRESENT ALL ATTACHED SENSORS TO CONTROLLER ###### void presentation(){ sendSketchInfo(ProjectName, ProjectVersion); // Send the sketch version information to the gateway and Controller // ----- Actual I/O child IDs ----- //present(CHILD_ID1, XXXXXXX); //Register child ID 1 as NONE present(CHILD_ID2, S_LIGHT); //Register child ID 2 as S_LIGHT //present(CHILD_ID3, XXXXXXX); //Register child ID 3 as NONE //present(CHILD_ID4, XXXXXXX); //Register child ID 4 as NONE present(CHILD_ID5, S_LIGHT); //Register child ID 5 as S_LIGHT present(CHILD_ID6, S_LIGHT); //Register child ID 6 as S_LIGHT present(CHILD_ID7, S_LIGHT); //Register child ID 7 as S_LIGHT // ----- virtual switch child ID (keypad) present(CHILD_ID_V1, S_LIGHT); //Register child ID 10 as S_LIGHT present(CHILD_ID_V2, S_LIGHT); //Register child ID 11 as S_LIGHT present(CHILD_ID_V3, S_LIGHT); //Register child ID 12 as S_LIGHT present(CHILD_ID_V4, S_LIGHT); //Register child ID 13 as S_LIGHT present(CHILD_ID_V5, S_LIGHT); //Register child ID 14 as S_LIGHT } void loop() { // ##### KEYPAD CODE TO SET A ACTION FOR A PRESSED KEY ##### char key = kpd.getKey(); // Get key from keypad (if pressed) if (key) { // compare key (defined in keypad setup) switch (key) { // with multiple multiple options below case '1': // If the pressed key compares with "1" VirtalSwitch1 = true; // Change te state of boolean VirtalSwitch1 to true send(msgV1.set(1)); // sending virtual switch state to Gateway Serial.println("1"); // Debug code. Print "1" to show that button 1 was pressed break; // End of code for button 1 case '4': // If the pressed key compares with "4" VirtalSwitch1 = false; // Change te state of boolean VirtalSwitch1 to false send(msgV1.set(0)); // sending virtual switch state to Gateway Serial.println("4"); // Debug code. Print "4" to show that button 4 was pressed break; // End of code for button 4 // Other keys to be added here according to the same template default: // If the pressed key does not match the cases above Serial.println(key); // Print the key that was pressed break; // End of function } } // ----- WRITE BOOLEAN TO PIN (FOR TESTING PURPOSES ONLY) ----- digitalWrite(IoPin4, VirtalSwitch1); } // ##### CODE FOR RECEIVING MYSENSORS MESSAGES FROM CONTROLLER ##### void receive(const MyMessage &message) { //start mysensor receiving code if (message.isAck()) { //Check for gateway acknowledgment Serial.println("This is an ack from gateway"); //Print debug code (serial print) to confirm received ack } // ----- Action taken for child ID 1: Currently set as V_LIGHT to switch relay on IoPin1 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID2) { //if message is V_LIGHT and the child ID is 2 state = message.getBool(); //guess this write the incomming boolean to state? digitalWrite(IoPin2, state?RELAY_ON:RELAY_OFF); //change the the arduino pin from "on" to "off" or other way around saveState(CHILD_ID2, state); //guess this saves the state if child ID 2 to EEPPROM Serial.print("Incoming change for sensor:"); //debug info text Serial.print(message.sensor); //write received child ID Serial.print(", New status: "); //debug info text Serial.println(message.getBool()); //write received boolean } // ----- Action taken for child ID 5: Currently set as V_LIGHT to switch relay on IoPin5 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID5) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin5, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID5, state); } // ----- Action taken for child ID 6: Currently set as V_LIGHT to switch relay on IoPin6 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID6) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin6, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID6, state); } // ----- Action taken for child ID 7: Currently set as V_LIGHT to switch relay on IoPin7 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID7) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin7, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID7, state); } // ----- Action taken for CHILD_ID_V1: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch1) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V1) { //if message is V_LIGHT and the CHILD_ID_V1 state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch1 = state; //copy the received boolean to VirtalSwitch1 //saveState(CHILD_ID_V1), state); //guess this saves the state if child ID 2 to EEPPROM } }```@SuperKris
From the first look: it could be a simple typo:saveState(CHILD_ID_V1), state);
should be
saveState(CHILD_ID_V1, state);
it may be simply one parenthesis too much. -
@SuperKris
From the first look: it could be a simple typo:saveState(CHILD_ID_V1), state);
should be
saveState(CHILD_ID_V1, state);
it may be simply one parenthesis too much.@tboha said:
@SuperKris
From the first look: it could be a simple typo:saveState(CHILD_ID_V1), state);
should be
saveState(CHILD_ID_V1, state);
it may be simply one parenthesis too much.Wow.. I cant believe i missed that... damn.
Ok, so everything seems to work now. I can just copy paste code and add some "virtual" buttons. Thats great! Thank you so much.
Next i will need to add the PIR setup, but i think i have enough understanding to do this now. After that the DHT22 code. Should be a bit more trick, but i will get there.
Just one more question about the code you written:
present(CHILD_ID_V1, S_LIGHT, "Partylichtjes");What does "partytlichtjes" do? I guess its supposed to send the name of the switch to the controller, but it wont compile if i add it in my sketch.
-
@tboha said:
@SuperKris
From the first look: it could be a simple typo:saveState(CHILD_ID_V1), state);
should be
saveState(CHILD_ID_V1, state);
it may be simply one parenthesis too much.Wow.. I cant believe i missed that... damn.
Ok, so everything seems to work now. I can just copy paste code and add some "virtual" buttons. Thats great! Thank you so much.
Next i will need to add the PIR setup, but i think i have enough understanding to do this now. After that the DHT22 code. Should be a bit more trick, but i will get there.
Just one more question about the code you written:
present(CHILD_ID_V1, S_LIGHT, "Partylichtjes");What does "partytlichtjes" do? I guess its supposed to send the name of the switch to the controller, but it wont compile if i add it in my sketch.
Yes, it is supposed to give a human readable name to your Sensor, which could be displayed by your controller.
strange - within my "testenvironment" it compiled (5 minutes ago) without complaints.
Would you please give the CompilerMessage?
It is not a vital point but it´s anoying.some additional remarks:
Switching to Arduino-MEGA would solve your lack of IO-Pins dramatically (and provides you with huge amounts of Memory and RAM (=Variables)).
Another Option would be to split different functions to different Arduinos. E.g. one Arduino to serve the switches, one Arduino to control an Array of Relays.
Delegate dumb tasks to even dumber Hardware
- IOPort-Expander to control relais http://www.ebay.com/itm/PCF8574T-PCF8574-I2C-8-Bit-IO-GPIO-expander-module-for-Arduino-Raspberry-Pi-/311730563568?var=&hash=item8e2bb3695d
- multifunctional PCB´s for input and display[ http://stores.ebay.de/TxHang-Electronic/_i.html?_nkw=tm1638&submit=Finden&LH_TitleDesc=1&_sid=1103958046
- capacitive switches with i2c http://www.ebay.de/itm/CAP1188-8-Key-Capacitive-Touch-Sensor-Module-SPI-I2C-Captouch-LED-For-Arduino-/401148874426?hash=item5d66560eba]
Frequently read your included headerfiles (especially Mysensors.h) and read the APIs (https://www.mysensors.org/download/sensor_api_20), you will discover a bunch of additional functions.
One function you will discover is direct "internode" communication without gateway and so without controller.
This partially answers your question where to store your virtual items (or makes it more complicated with respect to maintenance). Deploying vital components to your peripherial Units gives great flexibility in choosing your controller. It also makes the integration "Third-Party" components easier. You mentioned your 433Mhz WallSwitch.
-
Yes, it is supposed to give a human readable name to your Sensor, which could be displayed by your controller.
strange - within my "testenvironment" it compiled (5 minutes ago) without complaints.
Would you please give the CompilerMessage?
It is not a vital point but it´s anoying.some additional remarks:
Switching to Arduino-MEGA would solve your lack of IO-Pins dramatically (and provides you with huge amounts of Memory and RAM (=Variables)).
Another Option would be to split different functions to different Arduinos. E.g. one Arduino to serve the switches, one Arduino to control an Array of Relays.
Delegate dumb tasks to even dumber Hardware
- IOPort-Expander to control relais http://www.ebay.com/itm/PCF8574T-PCF8574-I2C-8-Bit-IO-GPIO-expander-module-for-Arduino-Raspberry-Pi-/311730563568?var=&hash=item8e2bb3695d
- multifunctional PCB´s for input and display[ http://stores.ebay.de/TxHang-Electronic/_i.html?_nkw=tm1638&submit=Finden&LH_TitleDesc=1&_sid=1103958046
- capacitive switches with i2c http://www.ebay.de/itm/CAP1188-8-Key-Capacitive-Touch-Sensor-Module-SPI-I2C-Captouch-LED-For-Arduino-/401148874426?hash=item5d66560eba]
Frequently read your included headerfiles (especially Mysensors.h) and read the APIs (https://www.mysensors.org/download/sensor_api_20), you will discover a bunch of additional functions.
One function you will discover is direct "internode" communication without gateway and so without controller.
This partially answers your question where to store your virtual items (or makes it more complicated with respect to maintenance). Deploying vital components to your peripherial Units gives great flexibility in choosing your controller. It also makes the integration "Third-Party" components easier. You mentioned your 433Mhz WallSwitch.
@tboha said:
Yes, it is supposed to give a human readable name to your Sensor, which could be displayed by your controller.
strange - within my "testenvironment" it compiled (5 minutes ago) without complaints.
Would you please give the CompilerMessage?
It is not a vital point but it´s anoying.I tried ir multiple times earlier tonight, but was unable to compile. (i dont know the error anymore). For some reason it works fine now. Very strange!
Switching to a mega is no option at this point. I got all the hardware already soldered together on a PCB, and thats a lot of inputs and outputs to do. I also do not like the size of the mega. The ram i dont need. I'm currently at around 50% and besides the DTH sensor, i'm almost done.
Also i like the challenge of creating what i want with minimal components. I'm pretty sure its going to work in the end!
Same goes for multiple arduino's. I think i have a couple of I/O expander PCBs laying around, but rather not use them either as its complicates the sketch even further.
I have read a lot about the API but i'm still very much struggling to understand anything of it. I will definitely continue to read!
Below my current code. The keypad part is done. Next is the receiving part for the virtual switches.
Thank you very much for your great help! I fear i will have new questions very soon!
// ##### SET PROJECT NAME AND VERSION ##### #define ProjectName "Schuur controller" #define ProjectVersion "0,2" // ##### SET MYSENSOR SETTINGS BEFORE INCLUDIGN LIBRARY ##### #define MY_DEBUG // Enable debug prints to serial monitor #define MY_RADIO_NRF24 // Enable and select radio type attached #define MY_REPEATER_FEATURE // Enabled repeater feature for this node // ##### INCLUDE LIBRARYS ##### #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> #include <Keypad.h> // ##### DEFINE I/O PINS ##### //#define IoPin1 4 // Arduino Digital I/O pin number for I/O 1 #define IoPin2 3 // Arduino Digital I/O pin number for I/O 2 //#define IoPin3 6 // Arduino Digital I/O pin number for I/O 3 #define IoPin4 5 // Arduino Digital I/O pin number for I/O 4 #define IoPin5 8 // Arduino Digital I/O pin number for I/O 5 #define IoPin6 7 // Arduino Digital I/O pin number for I/O 6 #define IoPin7 19 // Arduino Digital I/O pin number for I/O 7 // ##### DEFINE CHILD ID'S ##### #define CHILD_ID1 1 // ID for child 1 (I/O) #define CHILD_ID2 2 // ID for child 2 (I/O) used for relay //#define CHILD_ID3 3 // ID for child 3 (I/O) //#define CHILD_ID4 4 // ID for child 4 (I/O) #define CHILD_ID5 5 // ID for child 5 (I/O) used for relay #define CHILD_ID6 6 // ID for child 6 (I/O) used for relay #define CHILD_ID7 7 // ID for child 7 (I/O) used for relay #define CHILD_ID_V1 10 // ID for child virtual switch 1. Used for Outside lighting button #define CHILD_ID_V2 11 // ID for child virtual switch 2. Used for Heater button #define CHILD_ID_V3 12 // ID for child virtual switch 3. Used for Anit Frost button #define CHILD_ID_V4 13 // ID for child virtual switch 4. Used for Party Lights button #define CHILD_ID_V5 14 // ID for child virtual switch 5. Used for Wifi AP button #define CHILD_ID_V6 15 // ID for child virtual switch 6. Used for Aux 1 button #define CHILD_ID_V7 16 // ID for child virtual switch 7. Used for Aux 2 button #define CHILD_ID_V8 17 // ID for child virtual switch 8. Used for 5 min button // ##### RELAY SETTING ##### #define RELAY_ON 0 // Invert for some relay modules (currently inverted) #define RELAY_OFF 1 // Invert for some relay modules (currently inverted) // ##### OTHER VARIABLES ##### bool state; // not sure what this does // ##### BOOLEANS FOR VIRTUAL SWITCHES ##### bool VirtalSwitch1; // Boolean (status) for virtual switch 1 (controlled by keypad) bool VirtalSwitch2; // Boolean (status) for virtual switch 2 (controlled by keypad) bool VirtalSwitch3; // Boolean (status) for virtual switch 3 (controlled by keypad) bool VirtalSwitch4; // Boolean (status) for virtual switch 4 (controlled by keypad) bool VirtalSwitch5; // Boolean (status) for virtual switch 5 (controlled by keypad) bool VirtalSwitch6; // Boolean (status) for virtual switch 1 (controlled by keypad) bool VirtalSwitch7; // Boolean (status) for virtual switch 1 (controlled by keypad) // ##### DEFINE MYSENSORS MESSAGE CONTAINERS TO COMMUNICATE WITH GATEWAY ##### MyMessage msgV1(CHILD_ID_V1,S_LIGHT); // msgV1 sends child ID CHILD_ID_V1 as S_LIGHT MyMessage msgV2(CHILD_ID_V2,S_LIGHT); // msgV2 sends child ID CHILD_ID_V2 as S_LIGHT MyMessage msgV3(CHILD_ID_V3,S_LIGHT); // msgV3 sends child ID CHILD_ID_V3 as S_LIGHT MyMessage msgV4(CHILD_ID_V4,S_LIGHT); // msgV4 sends child ID CHILD_ID_V4 as S_LIGHT MyMessage msgV5(CHILD_ID_V5,S_LIGHT); // msgV5 sends child ID CHILD_ID_V5 as S_LIGHT MyMessage msgV6(CHILD_ID_V6,S_LIGHT); // msgV6 sends child ID CHILD_ID_V6 as S_LIGHT MyMessage msgV7(CHILD_ID_V7,S_LIGHT); // msgV7 sends child ID CHILD_ID_V7 as S_LIGHT MyMessage msgV8(CHILD_ID_V8,S_LIGHT); // msgV8 sends child ID CHILD_ID_V8 as S_LIGHT // ##### KEYPAD SETUP ##### const byte ROWS = 4; // Four rows const byte COLS = 3; // Three columns // Define the Keymap char keys[ROWS][COLS] = { {'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}, {'A', 'B', 'C'} }; // Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins. byte rowPins[ROWS] = { A0, A1, A2, A3 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins. byte colPins[COLS] = { A4, 1, 0 }; //if you got any spare pins - change 0 and 1 accordingly e.g. { A4, 8, 9 } // or see below // Create the Keypad Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); void setup() { // ##### I/O SETUP FOR PHYSICAL I/O ON ARDUINO ##### // Setup I/O 2 pinMode(IoPin2, OUTPUT); // use I/O 2 as output for relay module digitalWrite(IoPin2, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID2); // Load last known state (using eeprom storage) digitalWrite(IoPin2, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 4 Not in use // pinMode(IoPin4, OUTPUT); // use I/O 4 as output for relay module // digitalWrite(IoPin4, RELAY_OFF); // and set switch relay output off // state = loadState(CHILD_ID4); // Load last known state (using eeprom storage) // digitalWrite(IoPin4, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 5 pinMode(IoPin5, OUTPUT); // use I/O 5 as output for relay module digitalWrite(IoPin5, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID5); // Load last known state (using eeprom storage) digitalWrite(IoPin5, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 6 pinMode(IoPin6, OUTPUT); // use I/O 6 as output for relay module digitalWrite(IoPin6, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID6); // Load last known state (using eeprom storage) digitalWrite(IoPin6, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 7 pinMode(IoPin7, OUTPUT); // use I/O 7 as output for relay module digitalWrite(IoPin7, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID7); // Load last known state (using eeprom storage) digitalWrite(IoPin7, state?RELAY_ON:RELAY_OFF); // write last know state // ----- PIN SETUP (FOR TESTING ONLY ----- pinMode(IoPin4, OUTPUT); //use I/O 4 as output for relay module digitalWrite(IoPin4, HIGH);// and set is HIGH so relay stays off } // ###### PRESENT ALL ATTACHED SENSORS TO CONTROLLER ###### void presentation(){ sendSketchInfo(ProjectName, ProjectVersion); // Send the sketch version information to the gateway and Controller // ----- Actual I/O child IDs ----- //present(CHILD_ID1, XXXXXXX); //Register child ID 1 as NONE present(CHILD_ID2, S_LIGHT); //Register child ID 2 as S_LIGHT //present(CHILD_ID3, XXXXXXX); //Register child ID 3 as NONE //present(CHILD_ID4, XXXXXXX); //Register child ID 4 as NONE present(CHILD_ID5, S_LIGHT); //Register child ID 5 as S_LIGHT present(CHILD_ID6, S_LIGHT); //Register child ID 6 as S_LIGHT present(CHILD_ID7, S_LIGHT); //Register child ID 7 as S_LIGHT // ----- virtual switch child ID (keypad) present(CHILD_ID_V1, S_LIGHT, "Outside light switch"); //Register child ID 10 as S_LIGHT present(CHILD_ID_V2, S_LIGHT); //Register child ID 11 as S_LIGHT present(CHILD_ID_V3, S_LIGHT); //Register child ID 12 as S_LIGHT present(CHILD_ID_V4, S_LIGHT); //Register child ID 13 as S_LIGHT present(CHILD_ID_V5, S_LIGHT); //Register child ID 14 as S_LIGHT present(CHILD_ID_V6, S_LIGHT); //Register child ID 15 as S_LIGHT present(CHILD_ID_V7, S_LIGHT); //Register child ID 16 as S_LIGHT present(CHILD_ID_V8, S_LIGHT); //Register child ID 17 as S_LIGHT } void loop() { // ##### KEYPAD CODE TO SET A ACTION FOR A PRESSED KEY ##### char key = kpd.getKey(); // Get key from keypad (if pressed) if (key) { // compare key (defined in keypad setup) switch (key) { // with multiple multiple options below // On button for outside light case '1': // If the pressed key compares with "1" VirtalSwitch1 = true; // Change te state of boolean VirtalSwitch1 to true (on) send(msgV1.set(1)); // Sent "on" command to gateway for CHILD_ID_V1 Serial.println("KEY 1"); // Debug code. Print "KEY 1" to show that button 1 was pressed break; // End of code for button 1 // Off button for outside light case '2': // If the pressed key compares with "2" VirtalSwitch1 = false; // Change te state of boolean VirtalSwitch1 to false (off) send(msgV1.set(0)); // Sent "off" command to gateway for CHILD_ID_V1 Serial.println("KEY 2"); // Debug code. Print "KEY 2" to show that button 2 was pressed break; // End of code for button 2 // 5 minute button case '3': // If the pressed key compares with "3" send(msgV8.set(1)); // Sent "on" command to gateway for CHILD_ID_V8 Serial.println("KEY 4"); // Debug code. Print "KEY 4" to show that button 4 was pressed break; // End of code for button 4 // On button for heating case '4': // If the pressed key compares with "4" VirtalSwitch2 = true; // Change te state of boolean VirtalSwitch2 to true (on). This is the heater VirtalSwitch3 = false; // Change te state of boolean VirtalSwitch3 to false (off). This is the anti frost funtion send(msgV2.set(1)); // Sent "on" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(0)); // Sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 4"); // Debug code. Print "KEY 4" to show that button 4 was pressed break; // End of code for button 4 // Off button for heating case '5': // If the pressed key compares with "5" VirtalSwitch2 = false; // Change te state of boolean VirtalSwitch2 to false (off). This is the heater VirtalSwitch3 = false; // Change te state of boolean VirtalSwitch3 to false (off). This is the anti frost funtion send(msgV2.set(0)); // Sent "off" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(0)); // Sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 5"); // Debug code. Print "KEY 5" to show that button 5 was pressed break; // End of code for button 5 // On button for anti frost case '6': // If the pressed key compares with "6" VirtalSwitch2 = false; // Change te state of boolean VirtalSwitch2 to false (off). This is the heater VirtalSwitch3 = true; // Change te state of boolean VirtalSwitch3 to true (on). This is the anti frost funtion send(msgV2.set(0)); // Sent "off" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(1)); // Sent "on" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 6"); // Debug code. Print "KEY 6" to show that button 6 was pressed break; // End of code for button 6 // On button for party lights case '7': // If the pressed key compares with "7" VirtalSwitch4 = true; // Change te state of boolean VirtalSwitch1 to true (on) send(msgV4.set(1)); // Sent "on" command to gateway for CHILD_ID_V4 Serial.println("KEY 7"); // Debug code. Print "KEY 7" to show that button 7 was pressed break; // End of code for button 7 // Off button for party lights case '8': // If the pressed key compares with "8" VirtalSwitch4 = false; // Change te state of boolean VirtalSwitch1 to false (off) send(msgV4.set(0)); // Sent "off" command to gateway for CHILD_ID_V4 Serial.println("KEY 8"); // Debug code. Print "KEY 8" to show that button 8 was pressed break; // End of code for button 8 // Aux ON/OFF buton 1 case '9':{ // If the pressed key compares with "9" if (VirtalSwitch6 == false){ // check if the virtual switch (VirtalSwitch6) is OFF. If so, do the following VirtalSwitch6 = true; // set the new status of the virtual swich to ON send(msgV6.set(1)); // Sent "on" command to gateway for CHILD_ID_V6 } else { // If the virtual switch was not OFF, it must have been ON, so do the following VirtalSwitch6 = false; // set the new status of the virtual swich to OFF send(msgV6.set(0)); // Sent "off" command to gateway for CHILD_ID_V6 } } Serial.println("KEY 9"); // Debug code. Print "KEY 9" to show that button 9 was pressed break; // End of code for button 9 // On button for Wifi AP case 'A': // If the pressed key compares with "A" VirtalSwitch5 = true; // Change te state of boolean VirtalSwitch5 to true (on) send(msgV5.set(1)); // Sent "on" command to gateway for CHILD_ID_V5 Serial.println("KEY A"); // Debug code. Print "KEY A" to show that button A was pressed break; // End of code for button A // Off button for Wifi AP case 'B': // If the pressed key compares with "B" VirtalSwitch5 = false; // Change te state of boolean VirtalSwitch5 to false (off) send(msgV5.set(0)); // Sent "off" command to gateway for CHILD_ID_V5 Serial.println("KEY B"); // Debug code. Print "KEY B" to show that button B was pressed break; // End of code for button B // Aux ON/OFF buton 2 case 'C':{ // If the pressed key compares with "C" if (VirtalSwitch7 == false){ // check if the virtual switch (VirtalSwitch7) is OFF. If so, do the following VirtalSwitch7 = true; // set the new status of the virtual swich to ON send(msgV7.set(1)); // Sent "on" command to gateway for CHILD_ID_V7 } else { // If the virtual switch was not OFF, it must have been ON, so do the following VirtalSwitch7 = false; // set the new status of the virtual swich to OFF send(msgV7.set(0)); // Sent "off" command to gateway for CHILD_ID_V7 } } Serial.println("KEY C"); // Debug code. Print "KEY C" to show that button C was pressed break; // End of code for button C default: // If the pressed key does not match the cases above Serial.print(key); // Print the key that was pressed Serial.println(" was pressed but not recognized by the keypadcode. Something is wrong!"); // print warning break; // End of function } } // ----- WRITE BOOLEAN TO PIN (FOR TESTING PURPOSES ONLY) ----- //digitalWrite(IoPin4, VirtalSwitch6); } // ##### CODE FOR RECEIVING MYSENSORS MESSAGES FROM CONTROLLER ##### void receive(const MyMessage &message) { //start mysensor receiving code if (message.isAck()) { //Check for gateway acknowledgment Serial.println("This is an ack from gateway"); //Print debug code (serial print) to confirm received ack } // ----- Action taken for child ID 1: Currently set as V_LIGHT to switch relay on IoPin1 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID2) { //if message is V_LIGHT and the child ID is 2 state = message.getBool(); //guess this write the incomming boolean to state? digitalWrite(IoPin2, state?RELAY_ON:RELAY_OFF); //change the the arduino pin from "on" to "off" or other way around saveState(CHILD_ID2, state); //guess this saves the state if child ID 2 to EEPPROM Serial.print("Incoming change for sensor:"); //debug info text Serial.print(message.sensor); //write received child ID Serial.print(", New status: "); //debug info text Serial.println(message.getBool()); //write received boolean } // ----- Action taken for child ID 5: Currently set as V_LIGHT to switch relay on IoPin5 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID5) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin5, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID5, state); } // ----- Action taken for child ID 6: Currently set as V_LIGHT to switch relay on IoPin6 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID6) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin6, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID6, state); } // ----- Action taken for child ID 7: Currently set as V_LIGHT to switch relay on IoPin7 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID7) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin7, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID7, state); } // ----- Action taken for CHILD_ID_V1: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch1) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V1) { //if message is V_LIGHT and the CHILD_ID_V1 state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch1 = state; //copy the received boolean to VirtalSwitch1 saveState(CHILD_ID_V1, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } }``` -
@tboha said:
Yes, it is supposed to give a human readable name to your Sensor, which could be displayed by your controller.
strange - within my "testenvironment" it compiled (5 minutes ago) without complaints.
Would you please give the CompilerMessage?
It is not a vital point but it´s anoying.I tried ir multiple times earlier tonight, but was unable to compile. (i dont know the error anymore). For some reason it works fine now. Very strange!
Switching to a mega is no option at this point. I got all the hardware already soldered together on a PCB, and thats a lot of inputs and outputs to do. I also do not like the size of the mega. The ram i dont need. I'm currently at around 50% and besides the DTH sensor, i'm almost done.
Also i like the challenge of creating what i want with minimal components. I'm pretty sure its going to work in the end!
Same goes for multiple arduino's. I think i have a couple of I/O expander PCBs laying around, but rather not use them either as its complicates the sketch even further.
I have read a lot about the API but i'm still very much struggling to understand anything of it. I will definitely continue to read!
Below my current code. The keypad part is done. Next is the receiving part for the virtual switches.
Thank you very much for your great help! I fear i will have new questions very soon!
// ##### SET PROJECT NAME AND VERSION ##### #define ProjectName "Schuur controller" #define ProjectVersion "0,2" // ##### SET MYSENSOR SETTINGS BEFORE INCLUDIGN LIBRARY ##### #define MY_DEBUG // Enable debug prints to serial monitor #define MY_RADIO_NRF24 // Enable and select radio type attached #define MY_REPEATER_FEATURE // Enabled repeater feature for this node // ##### INCLUDE LIBRARYS ##### #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> #include <Keypad.h> // ##### DEFINE I/O PINS ##### //#define IoPin1 4 // Arduino Digital I/O pin number for I/O 1 #define IoPin2 3 // Arduino Digital I/O pin number for I/O 2 //#define IoPin3 6 // Arduino Digital I/O pin number for I/O 3 #define IoPin4 5 // Arduino Digital I/O pin number for I/O 4 #define IoPin5 8 // Arduino Digital I/O pin number for I/O 5 #define IoPin6 7 // Arduino Digital I/O pin number for I/O 6 #define IoPin7 19 // Arduino Digital I/O pin number for I/O 7 // ##### DEFINE CHILD ID'S ##### #define CHILD_ID1 1 // ID for child 1 (I/O) #define CHILD_ID2 2 // ID for child 2 (I/O) used for relay //#define CHILD_ID3 3 // ID for child 3 (I/O) //#define CHILD_ID4 4 // ID for child 4 (I/O) #define CHILD_ID5 5 // ID for child 5 (I/O) used for relay #define CHILD_ID6 6 // ID for child 6 (I/O) used for relay #define CHILD_ID7 7 // ID for child 7 (I/O) used for relay #define CHILD_ID_V1 10 // ID for child virtual switch 1. Used for Outside lighting button #define CHILD_ID_V2 11 // ID for child virtual switch 2. Used for Heater button #define CHILD_ID_V3 12 // ID for child virtual switch 3. Used for Anit Frost button #define CHILD_ID_V4 13 // ID for child virtual switch 4. Used for Party Lights button #define CHILD_ID_V5 14 // ID for child virtual switch 5. Used for Wifi AP button #define CHILD_ID_V6 15 // ID for child virtual switch 6. Used for Aux 1 button #define CHILD_ID_V7 16 // ID for child virtual switch 7. Used for Aux 2 button #define CHILD_ID_V8 17 // ID for child virtual switch 8. Used for 5 min button // ##### RELAY SETTING ##### #define RELAY_ON 0 // Invert for some relay modules (currently inverted) #define RELAY_OFF 1 // Invert for some relay modules (currently inverted) // ##### OTHER VARIABLES ##### bool state; // not sure what this does // ##### BOOLEANS FOR VIRTUAL SWITCHES ##### bool VirtalSwitch1; // Boolean (status) for virtual switch 1 (controlled by keypad) bool VirtalSwitch2; // Boolean (status) for virtual switch 2 (controlled by keypad) bool VirtalSwitch3; // Boolean (status) for virtual switch 3 (controlled by keypad) bool VirtalSwitch4; // Boolean (status) for virtual switch 4 (controlled by keypad) bool VirtalSwitch5; // Boolean (status) for virtual switch 5 (controlled by keypad) bool VirtalSwitch6; // Boolean (status) for virtual switch 1 (controlled by keypad) bool VirtalSwitch7; // Boolean (status) for virtual switch 1 (controlled by keypad) // ##### DEFINE MYSENSORS MESSAGE CONTAINERS TO COMMUNICATE WITH GATEWAY ##### MyMessage msgV1(CHILD_ID_V1,S_LIGHT); // msgV1 sends child ID CHILD_ID_V1 as S_LIGHT MyMessage msgV2(CHILD_ID_V2,S_LIGHT); // msgV2 sends child ID CHILD_ID_V2 as S_LIGHT MyMessage msgV3(CHILD_ID_V3,S_LIGHT); // msgV3 sends child ID CHILD_ID_V3 as S_LIGHT MyMessage msgV4(CHILD_ID_V4,S_LIGHT); // msgV4 sends child ID CHILD_ID_V4 as S_LIGHT MyMessage msgV5(CHILD_ID_V5,S_LIGHT); // msgV5 sends child ID CHILD_ID_V5 as S_LIGHT MyMessage msgV6(CHILD_ID_V6,S_LIGHT); // msgV6 sends child ID CHILD_ID_V6 as S_LIGHT MyMessage msgV7(CHILD_ID_V7,S_LIGHT); // msgV7 sends child ID CHILD_ID_V7 as S_LIGHT MyMessage msgV8(CHILD_ID_V8,S_LIGHT); // msgV8 sends child ID CHILD_ID_V8 as S_LIGHT // ##### KEYPAD SETUP ##### const byte ROWS = 4; // Four rows const byte COLS = 3; // Three columns // Define the Keymap char keys[ROWS][COLS] = { {'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}, {'A', 'B', 'C'} }; // Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins. byte rowPins[ROWS] = { A0, A1, A2, A3 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins. byte colPins[COLS] = { A4, 1, 0 }; //if you got any spare pins - change 0 and 1 accordingly e.g. { A4, 8, 9 } // or see below // Create the Keypad Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); void setup() { // ##### I/O SETUP FOR PHYSICAL I/O ON ARDUINO ##### // Setup I/O 2 pinMode(IoPin2, OUTPUT); // use I/O 2 as output for relay module digitalWrite(IoPin2, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID2); // Load last known state (using eeprom storage) digitalWrite(IoPin2, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 4 Not in use // pinMode(IoPin4, OUTPUT); // use I/O 4 as output for relay module // digitalWrite(IoPin4, RELAY_OFF); // and set switch relay output off // state = loadState(CHILD_ID4); // Load last known state (using eeprom storage) // digitalWrite(IoPin4, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 5 pinMode(IoPin5, OUTPUT); // use I/O 5 as output for relay module digitalWrite(IoPin5, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID5); // Load last known state (using eeprom storage) digitalWrite(IoPin5, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 6 pinMode(IoPin6, OUTPUT); // use I/O 6 as output for relay module digitalWrite(IoPin6, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID6); // Load last known state (using eeprom storage) digitalWrite(IoPin6, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 7 pinMode(IoPin7, OUTPUT); // use I/O 7 as output for relay module digitalWrite(IoPin7, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID7); // Load last known state (using eeprom storage) digitalWrite(IoPin7, state?RELAY_ON:RELAY_OFF); // write last know state // ----- PIN SETUP (FOR TESTING ONLY ----- pinMode(IoPin4, OUTPUT); //use I/O 4 as output for relay module digitalWrite(IoPin4, HIGH);// and set is HIGH so relay stays off } // ###### PRESENT ALL ATTACHED SENSORS TO CONTROLLER ###### void presentation(){ sendSketchInfo(ProjectName, ProjectVersion); // Send the sketch version information to the gateway and Controller // ----- Actual I/O child IDs ----- //present(CHILD_ID1, XXXXXXX); //Register child ID 1 as NONE present(CHILD_ID2, S_LIGHT); //Register child ID 2 as S_LIGHT //present(CHILD_ID3, XXXXXXX); //Register child ID 3 as NONE //present(CHILD_ID4, XXXXXXX); //Register child ID 4 as NONE present(CHILD_ID5, S_LIGHT); //Register child ID 5 as S_LIGHT present(CHILD_ID6, S_LIGHT); //Register child ID 6 as S_LIGHT present(CHILD_ID7, S_LIGHT); //Register child ID 7 as S_LIGHT // ----- virtual switch child ID (keypad) present(CHILD_ID_V1, S_LIGHT, "Outside light switch"); //Register child ID 10 as S_LIGHT present(CHILD_ID_V2, S_LIGHT); //Register child ID 11 as S_LIGHT present(CHILD_ID_V3, S_LIGHT); //Register child ID 12 as S_LIGHT present(CHILD_ID_V4, S_LIGHT); //Register child ID 13 as S_LIGHT present(CHILD_ID_V5, S_LIGHT); //Register child ID 14 as S_LIGHT present(CHILD_ID_V6, S_LIGHT); //Register child ID 15 as S_LIGHT present(CHILD_ID_V7, S_LIGHT); //Register child ID 16 as S_LIGHT present(CHILD_ID_V8, S_LIGHT); //Register child ID 17 as S_LIGHT } void loop() { // ##### KEYPAD CODE TO SET A ACTION FOR A PRESSED KEY ##### char key = kpd.getKey(); // Get key from keypad (if pressed) if (key) { // compare key (defined in keypad setup) switch (key) { // with multiple multiple options below // On button for outside light case '1': // If the pressed key compares with "1" VirtalSwitch1 = true; // Change te state of boolean VirtalSwitch1 to true (on) send(msgV1.set(1)); // Sent "on" command to gateway for CHILD_ID_V1 Serial.println("KEY 1"); // Debug code. Print "KEY 1" to show that button 1 was pressed break; // End of code for button 1 // Off button for outside light case '2': // If the pressed key compares with "2" VirtalSwitch1 = false; // Change te state of boolean VirtalSwitch1 to false (off) send(msgV1.set(0)); // Sent "off" command to gateway for CHILD_ID_V1 Serial.println("KEY 2"); // Debug code. Print "KEY 2" to show that button 2 was pressed break; // End of code for button 2 // 5 minute button case '3': // If the pressed key compares with "3" send(msgV8.set(1)); // Sent "on" command to gateway for CHILD_ID_V8 Serial.println("KEY 4"); // Debug code. Print "KEY 4" to show that button 4 was pressed break; // End of code for button 4 // On button for heating case '4': // If the pressed key compares with "4" VirtalSwitch2 = true; // Change te state of boolean VirtalSwitch2 to true (on). This is the heater VirtalSwitch3 = false; // Change te state of boolean VirtalSwitch3 to false (off). This is the anti frost funtion send(msgV2.set(1)); // Sent "on" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(0)); // Sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 4"); // Debug code. Print "KEY 4" to show that button 4 was pressed break; // End of code for button 4 // Off button for heating case '5': // If the pressed key compares with "5" VirtalSwitch2 = false; // Change te state of boolean VirtalSwitch2 to false (off). This is the heater VirtalSwitch3 = false; // Change te state of boolean VirtalSwitch3 to false (off). This is the anti frost funtion send(msgV2.set(0)); // Sent "off" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(0)); // Sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 5"); // Debug code. Print "KEY 5" to show that button 5 was pressed break; // End of code for button 5 // On button for anti frost case '6': // If the pressed key compares with "6" VirtalSwitch2 = false; // Change te state of boolean VirtalSwitch2 to false (off). This is the heater VirtalSwitch3 = true; // Change te state of boolean VirtalSwitch3 to true (on). This is the anti frost funtion send(msgV2.set(0)); // Sent "off" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(1)); // Sent "on" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 6"); // Debug code. Print "KEY 6" to show that button 6 was pressed break; // End of code for button 6 // On button for party lights case '7': // If the pressed key compares with "7" VirtalSwitch4 = true; // Change te state of boolean VirtalSwitch1 to true (on) send(msgV4.set(1)); // Sent "on" command to gateway for CHILD_ID_V4 Serial.println("KEY 7"); // Debug code. Print "KEY 7" to show that button 7 was pressed break; // End of code for button 7 // Off button for party lights case '8': // If the pressed key compares with "8" VirtalSwitch4 = false; // Change te state of boolean VirtalSwitch1 to false (off) send(msgV4.set(0)); // Sent "off" command to gateway for CHILD_ID_V4 Serial.println("KEY 8"); // Debug code. Print "KEY 8" to show that button 8 was pressed break; // End of code for button 8 // Aux ON/OFF buton 1 case '9':{ // If the pressed key compares with "9" if (VirtalSwitch6 == false){ // check if the virtual switch (VirtalSwitch6) is OFF. If so, do the following VirtalSwitch6 = true; // set the new status of the virtual swich to ON send(msgV6.set(1)); // Sent "on" command to gateway for CHILD_ID_V6 } else { // If the virtual switch was not OFF, it must have been ON, so do the following VirtalSwitch6 = false; // set the new status of the virtual swich to OFF send(msgV6.set(0)); // Sent "off" command to gateway for CHILD_ID_V6 } } Serial.println("KEY 9"); // Debug code. Print "KEY 9" to show that button 9 was pressed break; // End of code for button 9 // On button for Wifi AP case 'A': // If the pressed key compares with "A" VirtalSwitch5 = true; // Change te state of boolean VirtalSwitch5 to true (on) send(msgV5.set(1)); // Sent "on" command to gateway for CHILD_ID_V5 Serial.println("KEY A"); // Debug code. Print "KEY A" to show that button A was pressed break; // End of code for button A // Off button for Wifi AP case 'B': // If the pressed key compares with "B" VirtalSwitch5 = false; // Change te state of boolean VirtalSwitch5 to false (off) send(msgV5.set(0)); // Sent "off" command to gateway for CHILD_ID_V5 Serial.println("KEY B"); // Debug code. Print "KEY B" to show that button B was pressed break; // End of code for button B // Aux ON/OFF buton 2 case 'C':{ // If the pressed key compares with "C" if (VirtalSwitch7 == false){ // check if the virtual switch (VirtalSwitch7) is OFF. If so, do the following VirtalSwitch7 = true; // set the new status of the virtual swich to ON send(msgV7.set(1)); // Sent "on" command to gateway for CHILD_ID_V7 } else { // If the virtual switch was not OFF, it must have been ON, so do the following VirtalSwitch7 = false; // set the new status of the virtual swich to OFF send(msgV7.set(0)); // Sent "off" command to gateway for CHILD_ID_V7 } } Serial.println("KEY C"); // Debug code. Print "KEY C" to show that button C was pressed break; // End of code for button C default: // If the pressed key does not match the cases above Serial.print(key); // Print the key that was pressed Serial.println(" was pressed but not recognized by the keypadcode. Something is wrong!"); // print warning break; // End of function } } // ----- WRITE BOOLEAN TO PIN (FOR TESTING PURPOSES ONLY) ----- //digitalWrite(IoPin4, VirtalSwitch6); } // ##### CODE FOR RECEIVING MYSENSORS MESSAGES FROM CONTROLLER ##### void receive(const MyMessage &message) { //start mysensor receiving code if (message.isAck()) { //Check for gateway acknowledgment Serial.println("This is an ack from gateway"); //Print debug code (serial print) to confirm received ack } // ----- Action taken for child ID 1: Currently set as V_LIGHT to switch relay on IoPin1 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID2) { //if message is V_LIGHT and the child ID is 2 state = message.getBool(); //guess this write the incomming boolean to state? digitalWrite(IoPin2, state?RELAY_ON:RELAY_OFF); //change the the arduino pin from "on" to "off" or other way around saveState(CHILD_ID2, state); //guess this saves the state if child ID 2 to EEPPROM Serial.print("Incoming change for sensor:"); //debug info text Serial.print(message.sensor); //write received child ID Serial.print(", New status: "); //debug info text Serial.println(message.getBool()); //write received boolean } // ----- Action taken for child ID 5: Currently set as V_LIGHT to switch relay on IoPin5 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID5) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin5, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID5, state); } // ----- Action taken for child ID 6: Currently set as V_LIGHT to switch relay on IoPin6 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID6) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin6, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID6, state); } // ----- Action taken for child ID 7: Currently set as V_LIGHT to switch relay on IoPin7 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID7) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin7, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID7, state); } // ----- Action taken for CHILD_ID_V1: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch1) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V1) { //if message is V_LIGHT and the CHILD_ID_V1 state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch1 = state; //copy the received boolean to VirtalSwitch1 saveState(CHILD_ID_V1, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } }```@SuperKris : You are welcome!
-
So right now i think i have all the code for the keypad en de relays complete. It does exactly what i want. I just have one problem...
The damn thing keeps giving serial prints. In the sketch below not from the mysensors library, but from the keypad code. The problem with this is that i really need all the digital ports, including 1 and 0. At this point there is no real way around that.
In the keypad code i posted in my 2nd post, this issue only happened when there was a serial print active. Its currently not in the sketch at all, or is working from the library?
Does anyone has any clue how i can give the digital pin 0 and 1 back to the keypad again?
My current code
// ##### SET PROJECT NAME AND VERSION ##### #define ProjectName "Shed controller" #define ProjectVersion "0,3" // ##### SET MYSENSOR SETTINGS BEFORE INCLUDIGN LIBRARY ##### //#define MY_DEBUG // Enable debug prints to serial monitor #define MY_RADIO_NRF24 // Enable and select radio type attached #define MY_REPEATER_FEATURE // Enabled repeater feature for this node // ##### INCLUDE LIBRARYS ##### #include <SPI.h> #include <MySensors.h> #include <Keypad.h> // ##### DEFINE I/O PINS ##### //#define IoPin1 4 // Arduino Digital I/O pin number for I/O 1 #define IoPin2 3 // Arduino Digital I/O pin number for I/O 2 //#define IoPin3 6 // Arduino Digital I/O pin number for I/O 3 #define IoPin4 5 // Arduino Digital I/O pin number for I/O 4 #define IoPin5 8 // Arduino Digital I/O pin number for I/O 5 #define IoPin6 7 // Arduino Digital I/O pin number for I/O 6 #define IoPin7 19 // Arduino Digital I/O pin number for I/O 7 // ##### DEFINE CHILD ID'S ##### #define CHILD_ID1 1 // ID for child 1 (I/O) #define CHILD_ID2 2 // ID for child 2 (I/O) used for relay //#define CHILD_ID3 3 // ID for child 3 (I/O) //#define CHILD_ID4 4 // ID for child 4 (I/O) #define CHILD_ID5 5 // ID for child 5 (I/O) used for relay #define CHILD_ID6 6 // ID for child 6 (I/O) used for relay #define CHILD_ID7 7 // ID for child 7 (I/O) used for relay #define CHILD_ID_V1 10 // ID for child virtual switch 1. Used for Outside lighting button #define CHILD_ID_V2 11 // ID for child virtual switch 2. Used for Heater button #define CHILD_ID_V3 12 // ID for child virtual switch 3. Used for Anti Frost button #define CHILD_ID_V4 13 // ID for child virtual switch 4. Used for Party Lights button #define CHILD_ID_V5 14 // ID for child virtual switch 5. Used for Wifi AP button #define CHILD_ID_V6 15 // ID for child virtual switch 6. Used for Aux 1 button #define CHILD_ID_V7 16 // ID for child virtual switch 7. Used for Aux 2 button #define CHILD_ID_V8 17 // ID for child virtual switch 8. Used for 5 min button // ##### RELAY SETTING ##### #define RELAY_ON 0 // Invert for some relay modules (currently inverted) #define RELAY_OFF 1 // Invert for some relay modules (currently inverted) // ##### OTHER VARIABLES ##### bool state; // Not realy sure what this exatly does. I guess temporary storage of received messages and loading from EEPROM // ##### BOOLEANS FOR VIRTUAL SWITCHES ##### bool VirtalSwitch1; // Boolean (status) for virtual switch 1 (controlled by keypad) bool VirtalSwitch2; // Boolean (status) for virtual switch 2 (controlled by keypad) bool VirtalSwitch3; // Boolean (status) for virtual switch 3 (controlled by keypad) bool VirtalSwitch4; // Boolean (status) for virtual switch 4 (controlled by keypad) bool VirtalSwitch5; // Boolean (status) for virtual switch 5 (controlled by keypad) bool VirtalSwitch6; // Boolean (status) for virtual switch 6 (controlled by keypad) bool VirtalSwitch7; // Boolean (status) for virtual switch 7 (controlled by keypad) // ##### DEFINE MYSENSORS MESSAGE CONTAINERS TO COMMUNICATE WITH GATEWAY ##### MyMessage msgV1(CHILD_ID_V1,S_LIGHT); // msgV1 sends child ID CHILD_ID_V1 as S_LIGHT MyMessage msgV2(CHILD_ID_V2,S_LIGHT); // msgV2 sends child ID CHILD_ID_V2 as S_LIGHT MyMessage msgV3(CHILD_ID_V3,S_LIGHT); // msgV3 sends child ID CHILD_ID_V3 as S_LIGHT MyMessage msgV4(CHILD_ID_V4,S_LIGHT); // msgV4 sends child ID CHILD_ID_V4 as S_LIGHT MyMessage msgV5(CHILD_ID_V5,S_LIGHT); // msgV5 sends child ID CHILD_ID_V5 as S_LIGHT MyMessage msgV6(CHILD_ID_V6,S_LIGHT); // msgV6 sends child ID CHILD_ID_V6 as S_LIGHT MyMessage msgV7(CHILD_ID_V7,S_LIGHT); // msgV7 sends child ID CHILD_ID_V7 as S_LIGHT MyMessage msgV8(CHILD_ID_V8,S_LIGHT); // msgV8 sends child ID CHILD_ID_V8 as S_LIGHT // ##### KEYPAD SETUP ##### const byte ROWS = 4; // Just settings for keypad library. Enter number of rows here const byte COLS = 3; // Just settings for keypad library. Enter number of columns here // Nameing of very key on the keypad. The output of keypad code will be the charaters used here. char keys[ROWS][COLS] = { {'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}, {'A', 'B', 'C'} }; byte rowPins[ROWS] = { A0, A1, A2, A3 }; // The pins the row wires are connected to (from left to right) byte colPins[COLS] = { A4, 1, 0 }; // The pins the column wires are connected to (from top to bottom) Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); // This creates the actual keypad based on specs above. void setup() { // ##### I/O SETUP FOR PHYSICAL I/O ON ARDUINO ##### // Setup I/O 2 pinMode(IoPin2, OUTPUT); // use I/O 2 as output for relay module digitalWrite(IoPin2, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID2); // Load last known state (using eeprom storage) digitalWrite(IoPin2, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 4 Not in use // pinMode(IoPin4, OUTPUT); // use I/O 4 as output for relay module // digitalWrite(IoPin4, RELAY_OFF); // and set switch relay output off // state = loadState(CHILD_ID4); // Load last known state (using eeprom storage) // digitalWrite(IoPin4, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 5 pinMode(IoPin5, OUTPUT); // use I/O 5 as output for relay module digitalWrite(IoPin5, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID5); // Load last known state (using eeprom storage) digitalWrite(IoPin5, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 6 pinMode(IoPin6, OUTPUT); // use I/O 6 as output for relay module digitalWrite(IoPin6, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID6); // Load last known state (using eeprom storage) digitalWrite(IoPin6, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 7 pinMode(IoPin7, OUTPUT); // use I/O 7 as output for relay module digitalWrite(IoPin7, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID7); // Load last known state (using eeprom storage) digitalWrite(IoPin7, state?RELAY_ON:RELAY_OFF); // write last know state // ----- PIN SETUP (FOR TESTING ONLY ----- // pinMode(IoPin4, OUTPUT); //use I/O 4 as output for relay module // digitalWrite(IoPin4, HIGH);// and set is HIGH so relay stays off } // ###### PRESENT ALL ATTACHED SENSORS TO CONTROLLER ###### void presentation(){ sendSketchInfo(ProjectName, ProjectVersion); // Send the sketch version information to the gateway and Controller // ----- Physical I/O child IDs ----- //present(CHILD_ID1, XXXXXXX); //Register child ID 1 as NONE present(CHILD_ID2, S_LIGHT, "Outside lighting relay"); //Register child ID 2 as S_LIGHT, and sent name to controller. //present(CHILD_ID3, XXXXXXX); //Register child ID 3 as NONE //present(CHILD_ID4, XXXXXXX); //Register child ID 4 as NONE present(CHILD_ID5, S_LIGHT, "Switched outlet heater"); //Register child ID 5 as S_LIGHT, and sent name to controller. present(CHILD_ID6, S_LIGHT, "Sw outlet party lights"); //Register child ID 6 as S_LIGHT, and sent name to controller. present(CHILD_ID7, S_LIGHT, "Gate light relay"); //Register child ID 7 as S_LIGHT, and sent name to controller. // ----- virtual switch child ID (keypad) present(CHILD_ID_V1, S_LIGHT, "Outside light switch"); //Register CHILD_ID_V1 as S_LIGHT, and sent name to controller present(CHILD_ID_V2, S_LIGHT, "Shed heater"); //Register CHILD_ID_V2 as S_LIGHT, and sent name to controller present(CHILD_ID_V3, S_LIGHT, "Anti frost mode"); //Register CHILD_ID_V3 as S_LIGHT, and sent name to controller present(CHILD_ID_V4, S_LIGHT, "Party lights"); //Register CHILD_ID_V4 as S_LIGHT, and sent name to controller present(CHILD_ID_V5, S_LIGHT, "Wifi AP"); //Register CHILD_ID_V5 as S_LIGHT, and sent name to controller present(CHILD_ID_V6, S_LIGHT, "Aux 1"); //Register CHILD_ID_V6 as S_LIGHT, and sent name to controller present(CHILD_ID_V7, S_LIGHT, "Aux 2"); //Register CHILD_ID_V7 as S_LIGHT, and sent name to controller present(CHILD_ID_V8, S_LIGHT, "5 min. button"); //Register CHILD_ID_V8 as S_LIGHT, and sent name to controller } void loop() { // ##### KEYPAD CODE TO SET A ACTION FOR A PRESSED KEY ##### char key = kpd.getKey(); // Get key from keypad (if pressed) if (key) { // compare key (defined in keypad setup) switch (key) { // with multiple multiple options below // On button for outside light case '1': // If the pressed key compares with "1" VirtalSwitch1 = true; // Change te state of boolean VirtalSwitch1 to true (on) send(msgV1.set(1)); // Sent "on" command to gateway for CHILD_ID_V1 Serial.println("KEY 1"); // Debug code. Print "KEY 1" to show that button 1 was pressed break; // End of code for button 1 // Off button for outside light case '2': // If the pressed key compares with "2" VirtalSwitch1 = false; // Change te state of boolean VirtalSwitch1 to false (off) send(msgV1.set(0)); // Sent "off" command to gateway for CHILD_ID_V1 Serial.println("KEY 2"); // Debug code. Print "KEY 2" to show that button 2 was pressed break; // End of code for button 2 // 5 minute button case '3': // If the pressed key compares with "3" send(msgV8.set(1)); // Sent "on" command to gateway for CHILD_ID_V8 Serial.println("KEY 4"); // Debug code. Print "KEY 4" to show that button 4 was pressed break; // End of code for button 4 // On button for heating case '4': // If the pressed key compares with "4" VirtalSwitch2 = true; // Change te state of boolean VirtalSwitch2 to true (on). This is the heater VirtalSwitch3 = false; // Change te state of boolean VirtalSwitch3 to false (off). This is the anti frost funtion send(msgV2.set(1)); // Sent "on" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(0)); // Sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 4"); // Debug code. Print "KEY 4" to show that button 4 was pressed break; // End of code for button 4 // Off button for heating case '5': // If the pressed key compares with "5" VirtalSwitch2 = false; // Change te state of boolean VirtalSwitch2 to false (off). This is the heater VirtalSwitch3 = false; // Change te state of boolean VirtalSwitch3 to false (off). This is the anti frost funtion send(msgV2.set(0)); // Sent "off" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(0)); // Sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 5"); // Debug code. Print "KEY 5" to show that button 5 was pressed break; // End of code for button 5 // On button for anti frost case '6': // If the pressed key compares with "6" VirtalSwitch2 = false; // Change te state of boolean VirtalSwitch2 to false (off). This is the heater VirtalSwitch3 = true; // Change te state of boolean VirtalSwitch3 to true (on). This is the anti frost funtion send(msgV2.set(0)); // Sent "off" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(1)); // Sent "on" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 6"); // Debug code. Print "KEY 6" to show that button 6 was pressed break; // End of code for button 6 // On button for party lights case '7': // If the pressed key compares with "7" VirtalSwitch4 = true; // Change te state of boolean VirtalSwitch1 to true (on) send(msgV4.set(1)); // Sent "on" command to gateway for CHILD_ID_V4 Serial.println("KEY 7"); // Debug code. Print "KEY 7" to show that button 7 was pressed break; // End of code for button 7 // Off button for party lights case '8': // If the pressed key compares with "8" VirtalSwitch4 = false; // Change te state of boolean VirtalSwitch1 to false (off) send(msgV4.set(0)); // Sent "off" command to gateway for CHILD_ID_V4 Serial.println("KEY 8"); // Debug code. Print "KEY 8" to show that button 8 was pressed break; // End of code for button 8 // Aux ON/OFF buton 1 case '9':{ // If the pressed key compares with "9" if (VirtalSwitch6 == false){ // check if the virtual switch (VirtalSwitch6) is OFF. If so, do the following VirtalSwitch6 = true; // set the new status of the virtual swich to ON send(msgV6.set(1)); // Sent "on" command to gateway for CHILD_ID_V6 } else { // If the virtual switch was not OFF, it must have been ON, so do the following VirtalSwitch6 = false; // set the new status of the virtual swich to OFF send(msgV6.set(0)); // Sent "off" command to gateway for CHILD_ID_V6 } } Serial.println("KEY 9"); // Debug code. Print "KEY 9" to show that button 9 was pressed break; // End of code for button 9 // On button for Wifi AP case 'A': // If the pressed key compares with "A" VirtalSwitch5 = true; // Change te state of boolean VirtalSwitch5 to true (on) send(msgV5.set(1)); // Sent "on" command to gateway for CHILD_ID_V5 Serial.println("KEY A"); // Debug code. Print "KEY A" to show that button A was pressed break; // End of code for button A // Off button for Wifi AP case 'B': // If the pressed key compares with "B" VirtalSwitch5 = false; // Change te state of boolean VirtalSwitch5 to false (off) send(msgV5.set(0)); // Sent "off" command to gateway for CHILD_ID_V5 Serial.println("KEY B"); // Debug code. Print "KEY B" to show that button B was pressed break; // End of code for button B // Aux ON/OFF buton 2 case 'C':{ // If the pressed key compares with "C" if (VirtalSwitch7 == false){ // check if the virtual switch (VirtalSwitch7) is OFF. If so, do the following VirtalSwitch7 = true; // set the new status of the virtual swich to ON send(msgV7.set(1)); // Sent "on" command to gateway for CHILD_ID_V7 } else { // If the virtual switch was not OFF, it must have been ON, so do the following VirtalSwitch7 = false; // set the new status of the virtual swich to OFF send(msgV7.set(0)); // Sent "off" command to gateway for CHILD_ID_V7 } } Serial.println("KEY C"); // Debug code. Print "KEY C" to show that button C was pressed break; // End of code for button C default: // If the pressed key does not match the cases above Serial.print(key); // Print the key that was pressed Serial.println(" was pressed but not recognized by the keypadcode. Something is wrong!"); // print warning break; // End of function } } // ----- WRITE BOOLEAN TO PIN (FOR TESTING PURPOSES ONLY) ----- //digitalWrite(IoPin4, VirtalSwitch6); } // ##### CODE FOR RECEIVING MYSENSORS MESSAGES FROM CONTROLLER ##### void receive(const MyMessage &message) { //start mysensor receiving code if (message.isAck()) { //Check for gateway acknowledgment Serial.println("This is an ack from gateway"); //Print debug code (serial print) to confirm received ack } // ----- Relay actors ----- // ----- Action taken for child ID 1: Currently set as V_LIGHT to switch relay on IoPin1 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID2) { //if message is V_LIGHT and the child ID is 2 state = message.getBool(); //guess this write the incomming boolean to state? digitalWrite(IoPin2, state?RELAY_ON:RELAY_OFF); //change the the arduino pin from "on" to "off" or other way around saveState(CHILD_ID2, state); //guess this saves the state if child ID 2 to EEPPROM Serial.print("Incoming change for sensor:"); //debug info text Serial.print(message.sensor); //write received child ID Serial.print(", New status: "); //debug info text Serial.println(message.getBool()); //write received boolean } // ----- Action taken for child ID 5: Currently set as V_LIGHT to switch relay on IoPin5 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID5) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin5, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID5, state); } // ----- Action taken for child ID 6: Currently set as V_LIGHT to switch relay on IoPin6 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID6) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin6, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID6, state); } // ----- Action taken for child ID 7: Currently set as V_LIGHT to switch relay on IoPin7 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID7) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin7, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID7, state); } // ----- Virtual switches ----- // ----- Action taken for CHILD_ID_V1: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch1) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V1) { //if message is V_LIGHT, the child ID is CHILD_ID_V1 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch1 = state; //copy the received boolean to VirtalSwitch1 saveState(CHILD_ID_V1, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } // ----- Action taken for CHILD_ID_V2: Currently set as V_LIGHT. ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V2 && state == 1) { //if message is V_LIGHT, the CHILD_ID_V2 and the message is 1 (on) VirtalSwitch2 = true; //set VirtalSwitch2 (heating) to 1 (on) VirtalSwitch3 = false; //set VirtalSwitch3 (anti frost) to 0. This prevents the anti frost and heating funtion being on at the same time. send(msgV3.set(0)); //sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion. saveState(CHILD_ID_V2, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } if (message.type == V_LIGHT && message.sensor == CHILD_ID_V2 && state == 0) { //if message is V_LIGHT, the CHILD_ID_V2 and the message is 0 (off) VirtalSwitch2 = false; //set VirtalSwitch2 (heating) to 0 (off) VirtalSwitch3 = false; //set VirtalSwitch3 (anti frost) to 0 ((off) send(msgV3.set(0)); //sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion. saveState(CHILD_ID_V2, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } // ----- Action taken for CHILD_ID_V3: Currently set as V_LIGHT. ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V3 && state == 1) { //if message is V_LIGHT, the CHILD_ID_V3 and the message is 1 (on) VirtalSwitch3 = true; //set VirtalSwitch3 (anti frost) to 1 (on) VirtalSwitch2 = false; //set VirtalSwitch2 (heating) to 0. This prevents the heating and anti frost funtion being on at the same time. send(msgV2.set(0)); //sent "off" command to gateway for CHILD_ID_V2. This is the heating funtion. saveState(CHILD_ID_V3, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } if (message.type == V_LIGHT && message.sensor == CHILD_ID_V3 && state == 0) { //if message is V_LIGHT, the CHILD_ID_V3 and the message is 0 (off) VirtalSwitch3 = false; //set VirtalSwitch3 (anti frost) to 0 ((off) VirtalSwitch2 = false; //set VirtalSwitch2 (heating) to 0 (off) send(msgV2.set(0)); //sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion. saveState(CHILD_ID_V3, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } // ----- Action taken for CHILD_ID_V4: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch4) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V4) { //if message is V_LIGHT, the child ID is CHILD_ID_V4 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch4 = state; //copy the received boolean to VirtalSwitch4 saveState(CHILD_ID_V4, state); //guess this saves the state if CHILD_ID_V4 to EEPPROM } // ----- Action taken for CHILD_ID_V5: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch5) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V5) { //if message is V_LIGHT, the child ID is CHILD_ID_V5 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch5 = state; //copy the received boolean to VirtalSwitch5 saveState(CHILD_ID_V5, state); //guess this saves the state if CHILD_ID_V5 to EEPPROM } // ----- Action taken for CHILD_ID_V6: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch6) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V6) { //if message is V_LIGHT, the child ID is CHILD_ID_V6 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch6 = state; //copy the received boolean to VirtalSwitch6 saveState(CHILD_ID_V6, state); //guess this saves the state if CHILD_ID_V6 to EEPPROM } // ----- Action taken for CHILD_ID_V7: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch7) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V7) { //if message is V_LIGHT, the child ID is CHILD_ID_V7 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch7 = state; //copy the received boolean to VirtalSwitch7 saveState(CHILD_ID_V7, state); //guess this saves the state if CHILD_ID_V6 to EEPPROM } }``` -
Found it!!! I figured there must be a serial begin somewhere in the library. It was not in MySensors.h, but MySensors.h had MySensorsCore.h included which included serval other library's. One of them was MyConfig.h I looked in al library's for a serial begin by searching "serial". In MyConfig.h i found this.
/********************************** * Serial and debug options ***********************************/ // Enable MY_DEBUG in sketch to show debug prints. This option will add a lot to the size of the // final sketch but is helpful to see what is actually is happening during development //#define MY_DEBUG // Enable MY_SPECIAL_DEBUG in sketch to activate I_DEBUG messages if MY_DEBUG is disabled. // I_DEBUG requests are: // R: routing info (only repeaters): received msg XXYY (as stream), where XX is the node and YY the routing node // V: CPU voltage // F: CPU frequency // M: free memory // E: clear MySensors EEPROM area and reboot (i.e. "factory" reset) //#define MY_SPECIAL_DEBUG // Enable MY_DEBUG_VERBOSE_SIGNING flag for verbose debug prints related to signing. // Requires DEBUG to be enabled. // This will add even more to the size of the final sketch! //#define MY_DEBUG_VERBOSE_SIGNING // Enable this in sketch if you want to use TX(1), RX(0) as normal I/O pin //#define MY_DISABLED_SERIAL // Enable MY_CORE_ONLY flag if you want to use core functions without loading the framework //#define MY_CORE_ONLY // Turn off debug if serial pins is used for other stuffAdding "#define MY_DISABLED_SERIAL" to my sketch did the trick, and i can now use the full keypad.
// ##### SET PROJECT NAME AND VERSION ##### #define ProjectName "Shed controller" #define ProjectVersion "0,3" // ##### SET MYSENSOR SETTINGS BEFORE INCLUDIGN LIBRARY ##### //#define MY_DEBUG // Enable debug prints to serial monitor #define MY_DISABLED_SERIAL #define MY_RADIO_NRF24 // Enable and select radio type attached #define MY_REPEATER_FEATURE // Enabled repeater feature for this node // ##### INCLUDE LIBRARYS ##### #include <SPI.h> #include <MySensors.h> #include <Keypad.h> etc..... -
Ok, next problem. I saw this one coming, but i cant figure it out by myself...
I added the DHT code for the temperature and humidity. I took the sketch that under the build section as example. It does compile and work, but the sleep in the sketch is a issue. I was surprised to find the sketch was still responding to messages from the gateway. Maybe i'm understanding sleep wrong, so that is my first question.
- Does sleep stop all code from running, or just the function that its in? In other words; My keypad code is in the loop function. The mysensor code for receiving messages is in another funtion outside the loop function (void receive). Does a sleep in the loop function also blocks void receive, or does it only block the loop part?
So both my keypad code and the DHT code are in the loop part of the sketch. This makes the keypad unresponsive. If i understand right this is caused because the code is sleeping most of the time. If i keep pressing the button until it wakes up for a a fraction of a second the key is registered.
So the easy way would be to disable sleep right.... I do not need to save any batteries, and i want the whole node to be as responsive as possible. Disabling the sleep function (with just a // ) seems to work, but its flooding (debug still enabled off course) the serial monitor "with Failed reading temperature from DHT! Failed reading humidity from DHT"
- So i guess this is just because of the way the DHT works, but i fear this may be slowing down the whole sketch and making the node less responsive. Is it a bad idea to just skip the sleep and keep the rest the same?
From what i learned from earlier experiments where i needed to time things but still needed it to be responsive to other input, i think the only solution is the millis function. I think such a function could be applied to only run the DHT code every 5 seconds. Unfortunately i'm way to much of a noob, and the DHT code is way to advanced to replace the sleep function with a millis function.
- Can anyone help me on my wat to replace the sleep funtion with the millies code?
My current code (its getting pretty big now) can be found below:
// ##### SET PROJECT NAME AND VERSION ##### #define ProjectName "Shed Controller" // Name that is vissible in controller #define ProjectVersion "0,3" // Version that is vissible in controller //#define MY_NODE_ID 10 // Manual Node ID. // ##### SET MYSENSOR SETTINGS BEFORE INCLUDIGN LIBRARY ##### #define MY_DEBUG // Enable debug prints to serial monitor // #define MY_DISABLED_SERIAL // Disable serial monitor so pins 0 and 1 can be used for the keypad. Disable this line with comment to use serial monitor so debug code works #define MY_RADIO_NRF24 // Enable and select radio type attached #define MY_REPEATER_FEATURE // Enabled repeater feature for this node // ##### INCLUDE LIBRARYS ##### #include <SPI.h> #include <MySensors.h> #include <Keypad.h> #include <DHT.h> // ##### DEFINE I/O PINS ##### //#define IoPin1 4 // Arduino Digital I/O pin number for I/O 1 #define IoPin2 3 // Arduino Digital I/O pin number for I/O 2 #define IoPin3 6 // Arduino Digital I/O pin number for I/O 3 #define IoPin4 5 // Arduino Digital I/O pin number for I/O 4 #define IoPin5 8 // Arduino Digital I/O pin number for I/O 5 #define IoPin6 7 // Arduino Digital I/O pin number for I/O 6 #define IoPin7 19 // Arduino Digital I/O pin number for I/O 7 // ##### DEFINE CHILD ID'S ##### #define CHILD_ID1 1 // ID for child 1 (I/O) #define CHILD_ID2 2 // ID for child 2 (I/O) used for relay //#define CHILD_ID4 4 // ID for child 4 (I/O) #define CHILD_ID5 5 // ID for child 5 (I/O) used for relay #define CHILD_ID6 6 // ID for child 6 (I/O) used for relay #define CHILD_ID7 7 // ID for child 7 (I/O) used for relay #define CHILD_ID_V1 10 // ID for child virtual switch 1. Used for Outside lighting button #define CHILD_ID_V2 11 // ID for child virtual switch 2. Used for Heater button #define CHILD_ID_V3 12 // ID for child virtual switch 3. Used for Anti Frost button #define CHILD_ID_V4 13 // ID for child virtual switch 4. Used for Party Lights button #define CHILD_ID_V5 14 // ID for child virtual switch 5. Used for Wifi AP button #define CHILD_ID_V6 15 // ID for child virtual switch 6. Used for Aux 1 button #define CHILD_ID_V7 16 // ID for child virtual switch 7. Used for Aux 2 button #define CHILD_ID_V8 17 // ID for child virtual switch 8. Used for 5 min button #define CHILD_ID_TEMP1 30 // ID for child 8 (I/O) used for humidity #define CHILD_ID_HUM1 31 // ID for child 3 (I/O) used for temperature // ##### TEMPERATURE SENSOR SETTINGS ##### #define SENSOR_TEMP_OFFSET 0 // Offset for temperatur sensor can be set here static const uint64_t UPDATE_INTERVAL = 10000; static const uint8_t FORCE_UPDATE_N_READS = 10; float lastTemp; float lastHum; uint8_t nNoUpdatesTemp; uint8_t nNoUpdatesHum; bool metric = true; DHT dht; // ##### RELAY SETTING ##### #define RELAY_ON 0 // Invert for some relay modules (currently inverted) #define RELAY_OFF 1 // Invert for some relay modules (currently inverted) // ##### OTHER VARIABLES ##### bool state; // Not realy sure what this exatly does. I guess temporary storage of received messages and loading from EEPROM // ##### BOOLEANS FOR VIRTUAL SWITCHES ##### bool VirtalSwitch1; // Boolean (status) for virtual switch 1 (controlled by keypad) bool VirtalSwitch2; // Boolean (status) for virtual switch 2 (controlled by keypad) bool VirtalSwitch3; // Boolean (status) for virtual switch 3 (controlled by keypad) bool VirtalSwitch4; // Boolean (status) for virtual switch 4 (controlled by keypad) bool VirtalSwitch5; // Boolean (status) for virtual switch 5 (controlled by keypad) bool VirtalSwitch6; // Boolean (status) for virtual switch 6 (controlled by keypad) bool VirtalSwitch7; // Boolean (status) for virtual switch 7 (controlled by keypad) // ##### DEFINE MYSENSORS MESSAGE CONTAINERS TO COMMUNICATE WITH GATEWAY ##### MyMessage msgTemp(CHILD_ID_TEMP1, V_TEMP); // msgTemp sends child ID CHILD_ID_TEMP1 as V_TEMP MyMessage msgHum(CHILD_ID_HUM1, V_HUM); // msgHum sends child ID CHILD_ID_HUM1 as V_HUM MyMessage msgV1(CHILD_ID_V1,S_LIGHT); // msgV1 sends child ID CHILD_ID_V1 as S_LIGHT MyMessage msgV2(CHILD_ID_V2,S_LIGHT); // msgV2 sends child ID CHILD_ID_V2 as S_LIGHT MyMessage msgV3(CHILD_ID_V3,S_LIGHT); // msgV3 sends child ID CHILD_ID_V3 as S_LIGHT MyMessage msgV4(CHILD_ID_V4,S_LIGHT); // msgV4 sends child ID CHILD_ID_V4 as S_LIGHT MyMessage msgV5(CHILD_ID_V5,S_LIGHT); // msgV5 sends child ID CHILD_ID_V5 as S_LIGHT MyMessage msgV6(CHILD_ID_V6,S_LIGHT); // msgV6 sends child ID CHILD_ID_V6 as S_LIGHT MyMessage msgV7(CHILD_ID_V7,S_LIGHT); // msgV7 sends child ID CHILD_ID_V7 as S_LIGHT MyMessage msgV8(CHILD_ID_V8,S_LIGHT); // msgV8 sends child ID CHILD_ID_V8 as S_LIGHT // ##### KEYPAD SETUP ##### const byte ROWS = 4; // Just settings for keypad library. Enter number of rows here const byte COLS = 3; // Just settings for keypad library. Enter number of columns here // Nameing of very key on the keypad. The output of keypad code will be the charaters used here. char keys[ROWS][COLS] = { {'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}, {'A', 'B', 'C'} }; byte rowPins[ROWS] = { A0, A1, A2, A3 }; // The pins the row wires are connected to (from left to right) byte colPins[COLS] = { A4, 1, 0 }; // The pins the column wires are connected to (from top to bottom) Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); // This creates the actual keypad based on specs above. void setup() { // ##### I/O SETUP FOR PHYSICAL I/O ON ARDUINO ##### // Setup I/O 2 pinMode(IoPin2, OUTPUT); // use I/O 2 as output for relay module digitalWrite(IoPin2, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID2); // Load last known state (using eeprom storage) digitalWrite(IoPin2, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 3 dht.setup(IoPin3); // set data pin of DHT sensor if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) { Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!"); } // Sleep for the time of the minimum sampling period to give the sensor time to power up // (otherwise, timeout errors might occure for the first reading) sleep(dht.getMinimumSamplingPeriod()); // Setup I/O 4 Not in use // pinMode(IoPin4, OUTPUT); // use I/O 4 as output for relay module // digitalWrite(IoPin4, RELAY_OFF); // and set switch relay output off // state = loadState(CHILD_ID4); // Load last known state (using eeprom storage) // digitalWrite(IoPin4, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 5 pinMode(IoPin5, OUTPUT); // use I/O 5 as output for relay module digitalWrite(IoPin5, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID5); // Load last known state (using eeprom storage) digitalWrite(IoPin5, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 6 pinMode(IoPin6, OUTPUT); // use I/O 6 as output for relay module digitalWrite(IoPin6, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID6); // Load last known state (using eeprom storage) digitalWrite(IoPin6, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 7 pinMode(IoPin7, OUTPUT); // use I/O 7 as output for relay module digitalWrite(IoPin7, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID7); // Load last known state (using eeprom storage) digitalWrite(IoPin7, state?RELAY_ON:RELAY_OFF); // write last know state // ----- PIN SETUP (FOR TESTING ONLY ----- // pinMode(IoPin4, OUTPUT); //use I/O 4 as output for relay module // digitalWrite(IoPin4, HIGH);// and set is HIGH so relay stays off } // ###### PRESENT ALL ATTACHED SENSORS TO CONTROLLER ###### void presentation(){ // ----- Sent sketch info ----- sendSketchInfo(ProjectName, ProjectVersion); // Send the sketch version information to the gateway and Controller // ----- Physical I/O child IDs ----- //present(CHILD_ID1, XXXXXXX); //Register child ID 1 as NONE present(CHILD_ID2, S_LIGHT, "Outside lighting relay"); //Register CHILD_ID2 as S_LIGHT, and sent name to controller. //present(CHILD_ID4, XXXXXXX); //Register child ID 4 as NONE present(CHILD_ID5, S_LIGHT, "Switched outlet heater"); //Register CHILD_ID5 as S_LIGHT, and sent name to controller. present(CHILD_ID6, S_LIGHT, "Sw outlet party lights"); //Register CHILD_ID6 as S_LIGHT, and sent name to controller. present(CHILD_ID7, S_LIGHT, "Gate light relay"); //Register CHILD_ID7 as S_LIGHT, and sent name to controller. // ----- virtual switch child ID (keypad) present(CHILD_ID_V1, S_LIGHT, "Outside light switch"); //Register CHILD_ID_V1 as S_LIGHT, and sent name to controller present(CHILD_ID_V2, S_LIGHT, "Shed heater"); //Register CHILD_ID_V2 as S_LIGHT, and sent name to controller present(CHILD_ID_V3, S_LIGHT, "Anti frost mode"); //Register CHILD_ID_V3 as S_LIGHT, and sent name to controller present(CHILD_ID_V4, S_LIGHT, "Party lights"); //Register CHILD_ID_V4 as S_LIGHT, and sent name to controller present(CHILD_ID_V5, S_LIGHT, "Wifi AP"); //Register CHILD_ID_V5 as S_LIGHT, and sent name to controller present(CHILD_ID_V6, S_LIGHT, "Aux 1"); //Register CHILD_ID_V6 as S_LIGHT, and sent name to controller present(CHILD_ID_V7, S_LIGHT, "Aux 2"); //Register CHILD_ID_V7 as S_LIGHT, and sent name to controller present(CHILD_ID_V8, S_LIGHT, "5 min. button"); //Register CHILD_ID_V8 as S_LIGHT, and sent name to controller // ----- Sensor child ID's ----- present(CHILD_ID_TEMP1, S_TEMP, "Temp shed Inside"); //Register CHILD_ID_TEMP1 as S_TEMP, and sent name to controller present(CHILD_ID_HUM1, S_HUM, "Hum. shed Indide"); //Register CHILD_ID_HUM1 as S_HUM, and sent name to controller // ----- Aditional presentation setting ----- metric = getConfig().isMetric; //Not sure what this does, Its needed for DHT sensor } void loop() { // ##### KEYPAD CODE TO SET A ACTION FOR A PRESSED KEY ##### char key = kpd.getKey(); // Get key from keypad (if pressed) if (key) { // compare key (defined in keypad setup) switch (key) { // with multiple multiple options below // On button for outside light case '1': // If the pressed key compares with "1" VirtalSwitch1 = true; // Change te state of boolean VirtalSwitch1 to true (on) send(msgV1.set(1)); // Sent "on" command to gateway for CHILD_ID_V1 Serial.println("KEY 1"); // Debug code. Print "KEY 1" to show that button 1 was pressed break; // End of code for button 1 // Off button for outside light case '2': // If the pressed key compares with "2" VirtalSwitch1 = false; // Change te state of boolean VirtalSwitch1 to false (off) send(msgV1.set(0)); // Sent "off" command to gateway for CHILD_ID_V1 Serial.println("KEY 2"); // Debug code. Print "KEY 2" to show that button 2 was pressed break; // End of code for button 2 // 5 minute button case '3': // If the pressed key compares with "3" send(msgV8.set(1)); // Sent "on" command to gateway for CHILD_ID_V8 Serial.println("KEY 4"); // Debug code. Print "KEY 4" to show that button 4 was pressed break; // End of code for button 4 // On button for heating case '4': // If the pressed key compares with "4" VirtalSwitch2 = true; // Change te state of boolean VirtalSwitch2 to true (on). This is the heater VirtalSwitch3 = false; // Change te state of boolean VirtalSwitch3 to false (off). This is the anti frost funtion send(msgV2.set(1)); // Sent "on" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(0)); // Sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 4"); // Debug code. Print "KEY 4" to show that button 4 was pressed break; // End of code for button 4 // Off button for heating case '5': // If the pressed key compares with "5" VirtalSwitch2 = false; // Change te state of boolean VirtalSwitch2 to false (off). This is the heater VirtalSwitch3 = false; // Change te state of boolean VirtalSwitch3 to false (off). This is the anti frost funtion send(msgV2.set(0)); // Sent "off" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(0)); // Sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 5"); // Debug code. Print "KEY 5" to show that button 5 was pressed break; // End of code for button 5 // On button for anti frost case '6': // If the pressed key compares with "6" VirtalSwitch2 = false; // Change te state of boolean VirtalSwitch2 to false (off). This is the heater VirtalSwitch3 = true; // Change te state of boolean VirtalSwitch3 to true (on). This is the anti frost funtion send(msgV2.set(0)); // Sent "off" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(1)); // Sent "on" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 6"); // Debug code. Print "KEY 6" to show that button 6 was pressed break; // End of code for button 6 // On button for party lights case '7': // If the pressed key compares with "7" VirtalSwitch4 = true; // Change te state of boolean VirtalSwitch1 to true (on) send(msgV4.set(1)); // Sent "on" command to gateway for CHILD_ID_V4 Serial.println("KEY 7"); // Debug code. Print "KEY 7" to show that button 7 was pressed break; // End of code for button 7 // Off button for party lights case '8': // If the pressed key compares with "8" VirtalSwitch4 = false; // Change te state of boolean VirtalSwitch1 to false (off) send(msgV4.set(0)); // Sent "off" command to gateway for CHILD_ID_V4 Serial.println("KEY 8"); // Debug code. Print "KEY 8" to show that button 8 was pressed break; // End of code for button 8 // Aux ON/OFF buton 1 case '9':{ // If the pressed key compares with "9" if (VirtalSwitch6 == false){ // check if the virtual switch (VirtalSwitch6) is OFF. If so, do the following VirtalSwitch6 = true; // set the new status of the virtual swich to ON send(msgV6.set(1)); // Sent "on" command to gateway for CHILD_ID_V6 } else { // If the virtual switch was not OFF, it must have been ON, so do the following VirtalSwitch6 = false; // set the new status of the virtual swich to OFF send(msgV6.set(0)); // Sent "off" command to gateway for CHILD_ID_V6 } } Serial.println("KEY 9"); // Debug code. Print "KEY 9" to show that button 9 was pressed break; // End of code for button 9 // On button for Wifi AP case 'A': // If the pressed key compares with "A" VirtalSwitch5 = true; // Change te state of boolean VirtalSwitch5 to true (on) send(msgV5.set(1)); // Sent "on" command to gateway for CHILD_ID_V5 Serial.println("KEY A"); // Debug code. Print "KEY A" to show that button A was pressed break; // End of code for button A // Off button for Wifi AP case 'B': // If the pressed key compares with "B" VirtalSwitch5 = false; // Change te state of boolean VirtalSwitch5 to false (off) send(msgV5.set(0)); // Sent "off" command to gateway for CHILD_ID_V5 Serial.println("KEY B"); // Debug code. Print "KEY B" to show that button B was pressed break; // End of code for button B // Aux ON/OFF buton 2 case 'C':{ // If the pressed key compares with "C" if (VirtalSwitch7 == false){ // check if the virtual switch (VirtalSwitch7) is OFF. If so, do the following VirtalSwitch7 = true; // set the new status of the virtual swich to ON send(msgV7.set(1)); // Sent "on" command to gateway for CHILD_ID_V7 } else { // If the virtual switch was not OFF, it must have been ON, so do the following VirtalSwitch7 = false; // set the new status of the virtual swich to OFF send(msgV7.set(0)); // Sent "off" command to gateway for CHILD_ID_V7 } } Serial.println("KEY C"); // Debug code. Print "KEY C" to show that button C was pressed break; // End of code for button C default: // If the pressed key does not match the cases above Serial.print(key); // Print the key that was pressed Serial.println(" was pressed but not recognized by the keypadcode. Something is wrong!"); // print warning break; // End of function } } // Force reading sensor, so it works also after sleep() dht.readSensor(true); // Get temperature from DHT library float temperature = dht.getTemperature(); if (isnan(temperature)) { Serial.println("Failed reading temperature from DHT!"); } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) { // Only send temperature if it changed since the last measurement or if we didn't send an update for n times lastTemp = temperature; if (!metric) { temperature = dht.toFahrenheit(temperature); } // Reset no updates counter nNoUpdatesTemp = 0; temperature += SENSOR_TEMP_OFFSET; send(msgTemp.set(temperature, 1)); #ifdef MY_DEBUG Serial.print("T: "); Serial.println(temperature); #endif } else { // Increase no update counter if the temperature stayed the same nNoUpdatesTemp++; } // Get humidity from DHT library float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) { // Only send humidity if it changed since the last measurement or if we didn't send an update for n times lastHum = humidity; // Reset no updates counter nNoUpdatesHum = 0; send(msgHum.set(humidity, 1)); #ifdef MY_DEBUG Serial.print("H: "); Serial.println(humidity); #endif } else { // Increase no update counter if the humidity stayed the same nNoUpdatesHum++; } // Sleep for a while to save energy //sleep(UPDATE_INTERVAL); } // ##### CODE FOR RECEIVING MYSENSORS MESSAGES FROM CONTROLLER ##### void receive(const MyMessage &message) { //start mysensor receiving code if (message.isAck()) { //Check for gateway acknowledgment Serial.println("This is an ack from gateway"); //Print debug code (serial print) to confirm received ack } // ----- Relay actors ----- // ----- Action taken for child ID 1: Currently set as V_LIGHT to switch relay on IoPin1 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID2) { //if message is V_LIGHT and the child ID is 2 state = message.getBool(); //guess this write the incomming boolean to state? digitalWrite(IoPin2, state?RELAY_ON:RELAY_OFF); //change the the arduino pin from "on" to "off" or other way around saveState(CHILD_ID2, state); //guess this saves the state if child ID 2 to EEPPROM Serial.print("Incoming change for sensor:"); //debug info text Serial.print(message.sensor); //write received child ID Serial.print(", New status: "); //debug info text Serial.println(message.getBool()); //write received boolean } // ----- Action taken for child ID 5: Currently set as V_LIGHT to switch relay on IoPin5 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID5) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin5, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID5, state); } // ----- Action taken for child ID 6: Currently set as V_LIGHT to switch relay on IoPin6 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID6) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin6, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID6, state); } // ----- Action taken for child ID 7: Currently set as V_LIGHT to switch relay on IoPin7 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID7) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin7, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID7, state); } // ----- Virtual switches ----- // ----- Action taken for CHILD_ID_V1: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch1) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V1) { //if message is V_LIGHT, the child ID is CHILD_ID_V1 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch1 = state; //copy the received boolean to VirtalSwitch1 saveState(CHILD_ID_V1, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } // ----- Action taken for CHILD_ID_V2: Currently set as V_LIGHT. ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V2 && state == 1) { //if message is V_LIGHT, the CHILD_ID_V2 and the message is 1 (on) VirtalSwitch2 = true; //set VirtalSwitch2 (heating) to 1 (on) VirtalSwitch3 = false; //set VirtalSwitch3 (anti frost) to 0. This prevents the anti frost and heating funtion being on at the same time. send(msgV3.set(0)); //sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion. saveState(CHILD_ID_V2, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } if (message.type == V_LIGHT && message.sensor == CHILD_ID_V2 && state == 0) { //if message is V_LIGHT, the CHILD_ID_V2 and the message is 0 (off) VirtalSwitch2 = false; //set VirtalSwitch2 (heating) to 0 (off) VirtalSwitch3 = false; //set VirtalSwitch3 (anti frost) to 0 ((off) send(msgV3.set(0)); //sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion. saveState(CHILD_ID_V2, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } // ----- Action taken for CHILD_ID_V3: Currently set as V_LIGHT. ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V3 && state == 1) { //if message is V_LIGHT, the CHILD_ID_V3 and the message is 1 (on) VirtalSwitch3 = true; //set VirtalSwitch3 (anti frost) to 1 (on) VirtalSwitch2 = false; //set VirtalSwitch2 (heating) to 0. This prevents the heating and anti frost funtion being on at the same time. send(msgV2.set(0)); //sent "off" command to gateway for CHILD_ID_V2. This is the heating funtion. saveState(CHILD_ID_V3, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } if (message.type == V_LIGHT && message.sensor == CHILD_ID_V3 && state == 0) { //if message is V_LIGHT, the CHILD_ID_V3 and the message is 0 (off) VirtalSwitch3 = false; //set VirtalSwitch3 (anti frost) to 0 ((off) VirtalSwitch2 = false; //set VirtalSwitch2 (heating) to 0 (off) send(msgV2.set(0)); //sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion. saveState(CHILD_ID_V3, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } // ----- Action taken for CHILD_ID_V4: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch4) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V4) { //if message is V_LIGHT, the child ID is CHILD_ID_V4 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch4 = state; //copy the received boolean to VirtalSwitch4 saveState(CHILD_ID_V4, state); //guess this saves the state if CHILD_ID_V4 to EEPPROM } // ----- Action taken for CHILD_ID_V5: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch5) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V5) { //if message is V_LIGHT, the child ID is CHILD_ID_V5 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch5 = state; //copy the received boolean to VirtalSwitch5 saveState(CHILD_ID_V5, state); //guess this saves the state if CHILD_ID_V5 to EEPPROM } // ----- Action taken for CHILD_ID_V6: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch6) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V6) { //if message is V_LIGHT, the child ID is CHILD_ID_V6 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch6 = state; //copy the received boolean to VirtalSwitch6 saveState(CHILD_ID_V6, state); //guess this saves the state if CHILD_ID_V6 to EEPPROM } // ----- Action taken for CHILD_ID_V7: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch7) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V7) { //if message is V_LIGHT, the child ID is CHILD_ID_V7 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch7 = state; //copy the received boolean to VirtalSwitch7 saveState(CHILD_ID_V7, state); //guess this saves the state if CHILD_ID_V6 to EEPPROM } } -
Ok, next problem. I saw this one coming, but i cant figure it out by myself...
I added the DHT code for the temperature and humidity. I took the sketch that under the build section as example. It does compile and work, but the sleep in the sketch is a issue. I was surprised to find the sketch was still responding to messages from the gateway. Maybe i'm understanding sleep wrong, so that is my first question.
- Does sleep stop all code from running, or just the function that its in? In other words; My keypad code is in the loop function. The mysensor code for receiving messages is in another funtion outside the loop function (void receive). Does a sleep in the loop function also blocks void receive, or does it only block the loop part?
So both my keypad code and the DHT code are in the loop part of the sketch. This makes the keypad unresponsive. If i understand right this is caused because the code is sleeping most of the time. If i keep pressing the button until it wakes up for a a fraction of a second the key is registered.
So the easy way would be to disable sleep right.... I do not need to save any batteries, and i want the whole node to be as responsive as possible. Disabling the sleep function (with just a // ) seems to work, but its flooding (debug still enabled off course) the serial monitor "with Failed reading temperature from DHT! Failed reading humidity from DHT"
- So i guess this is just because of the way the DHT works, but i fear this may be slowing down the whole sketch and making the node less responsive. Is it a bad idea to just skip the sleep and keep the rest the same?
From what i learned from earlier experiments where i needed to time things but still needed it to be responsive to other input, i think the only solution is the millis function. I think such a function could be applied to only run the DHT code every 5 seconds. Unfortunately i'm way to much of a noob, and the DHT code is way to advanced to replace the sleep function with a millis function.
- Can anyone help me on my wat to replace the sleep funtion with the millies code?
My current code (its getting pretty big now) can be found below:
// ##### SET PROJECT NAME AND VERSION ##### #define ProjectName "Shed Controller" // Name that is vissible in controller #define ProjectVersion "0,3" // Version that is vissible in controller //#define MY_NODE_ID 10 // Manual Node ID. // ##### SET MYSENSOR SETTINGS BEFORE INCLUDIGN LIBRARY ##### #define MY_DEBUG // Enable debug prints to serial monitor // #define MY_DISABLED_SERIAL // Disable serial monitor so pins 0 and 1 can be used for the keypad. Disable this line with comment to use serial monitor so debug code works #define MY_RADIO_NRF24 // Enable and select radio type attached #define MY_REPEATER_FEATURE // Enabled repeater feature for this node // ##### INCLUDE LIBRARYS ##### #include <SPI.h> #include <MySensors.h> #include <Keypad.h> #include <DHT.h> // ##### DEFINE I/O PINS ##### //#define IoPin1 4 // Arduino Digital I/O pin number for I/O 1 #define IoPin2 3 // Arduino Digital I/O pin number for I/O 2 #define IoPin3 6 // Arduino Digital I/O pin number for I/O 3 #define IoPin4 5 // Arduino Digital I/O pin number for I/O 4 #define IoPin5 8 // Arduino Digital I/O pin number for I/O 5 #define IoPin6 7 // Arduino Digital I/O pin number for I/O 6 #define IoPin7 19 // Arduino Digital I/O pin number for I/O 7 // ##### DEFINE CHILD ID'S ##### #define CHILD_ID1 1 // ID for child 1 (I/O) #define CHILD_ID2 2 // ID for child 2 (I/O) used for relay //#define CHILD_ID4 4 // ID for child 4 (I/O) #define CHILD_ID5 5 // ID for child 5 (I/O) used for relay #define CHILD_ID6 6 // ID for child 6 (I/O) used for relay #define CHILD_ID7 7 // ID for child 7 (I/O) used for relay #define CHILD_ID_V1 10 // ID for child virtual switch 1. Used for Outside lighting button #define CHILD_ID_V2 11 // ID for child virtual switch 2. Used for Heater button #define CHILD_ID_V3 12 // ID for child virtual switch 3. Used for Anti Frost button #define CHILD_ID_V4 13 // ID for child virtual switch 4. Used for Party Lights button #define CHILD_ID_V5 14 // ID for child virtual switch 5. Used for Wifi AP button #define CHILD_ID_V6 15 // ID for child virtual switch 6. Used for Aux 1 button #define CHILD_ID_V7 16 // ID for child virtual switch 7. Used for Aux 2 button #define CHILD_ID_V8 17 // ID for child virtual switch 8. Used for 5 min button #define CHILD_ID_TEMP1 30 // ID for child 8 (I/O) used for humidity #define CHILD_ID_HUM1 31 // ID for child 3 (I/O) used for temperature // ##### TEMPERATURE SENSOR SETTINGS ##### #define SENSOR_TEMP_OFFSET 0 // Offset for temperatur sensor can be set here static const uint64_t UPDATE_INTERVAL = 10000; static const uint8_t FORCE_UPDATE_N_READS = 10; float lastTemp; float lastHum; uint8_t nNoUpdatesTemp; uint8_t nNoUpdatesHum; bool metric = true; DHT dht; // ##### RELAY SETTING ##### #define RELAY_ON 0 // Invert for some relay modules (currently inverted) #define RELAY_OFF 1 // Invert for some relay modules (currently inverted) // ##### OTHER VARIABLES ##### bool state; // Not realy sure what this exatly does. I guess temporary storage of received messages and loading from EEPROM // ##### BOOLEANS FOR VIRTUAL SWITCHES ##### bool VirtalSwitch1; // Boolean (status) for virtual switch 1 (controlled by keypad) bool VirtalSwitch2; // Boolean (status) for virtual switch 2 (controlled by keypad) bool VirtalSwitch3; // Boolean (status) for virtual switch 3 (controlled by keypad) bool VirtalSwitch4; // Boolean (status) for virtual switch 4 (controlled by keypad) bool VirtalSwitch5; // Boolean (status) for virtual switch 5 (controlled by keypad) bool VirtalSwitch6; // Boolean (status) for virtual switch 6 (controlled by keypad) bool VirtalSwitch7; // Boolean (status) for virtual switch 7 (controlled by keypad) // ##### DEFINE MYSENSORS MESSAGE CONTAINERS TO COMMUNICATE WITH GATEWAY ##### MyMessage msgTemp(CHILD_ID_TEMP1, V_TEMP); // msgTemp sends child ID CHILD_ID_TEMP1 as V_TEMP MyMessage msgHum(CHILD_ID_HUM1, V_HUM); // msgHum sends child ID CHILD_ID_HUM1 as V_HUM MyMessage msgV1(CHILD_ID_V1,S_LIGHT); // msgV1 sends child ID CHILD_ID_V1 as S_LIGHT MyMessage msgV2(CHILD_ID_V2,S_LIGHT); // msgV2 sends child ID CHILD_ID_V2 as S_LIGHT MyMessage msgV3(CHILD_ID_V3,S_LIGHT); // msgV3 sends child ID CHILD_ID_V3 as S_LIGHT MyMessage msgV4(CHILD_ID_V4,S_LIGHT); // msgV4 sends child ID CHILD_ID_V4 as S_LIGHT MyMessage msgV5(CHILD_ID_V5,S_LIGHT); // msgV5 sends child ID CHILD_ID_V5 as S_LIGHT MyMessage msgV6(CHILD_ID_V6,S_LIGHT); // msgV6 sends child ID CHILD_ID_V6 as S_LIGHT MyMessage msgV7(CHILD_ID_V7,S_LIGHT); // msgV7 sends child ID CHILD_ID_V7 as S_LIGHT MyMessage msgV8(CHILD_ID_V8,S_LIGHT); // msgV8 sends child ID CHILD_ID_V8 as S_LIGHT // ##### KEYPAD SETUP ##### const byte ROWS = 4; // Just settings for keypad library. Enter number of rows here const byte COLS = 3; // Just settings for keypad library. Enter number of columns here // Nameing of very key on the keypad. The output of keypad code will be the charaters used here. char keys[ROWS][COLS] = { {'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}, {'A', 'B', 'C'} }; byte rowPins[ROWS] = { A0, A1, A2, A3 }; // The pins the row wires are connected to (from left to right) byte colPins[COLS] = { A4, 1, 0 }; // The pins the column wires are connected to (from top to bottom) Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); // This creates the actual keypad based on specs above. void setup() { // ##### I/O SETUP FOR PHYSICAL I/O ON ARDUINO ##### // Setup I/O 2 pinMode(IoPin2, OUTPUT); // use I/O 2 as output for relay module digitalWrite(IoPin2, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID2); // Load last known state (using eeprom storage) digitalWrite(IoPin2, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 3 dht.setup(IoPin3); // set data pin of DHT sensor if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) { Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!"); } // Sleep for the time of the minimum sampling period to give the sensor time to power up // (otherwise, timeout errors might occure for the first reading) sleep(dht.getMinimumSamplingPeriod()); // Setup I/O 4 Not in use // pinMode(IoPin4, OUTPUT); // use I/O 4 as output for relay module // digitalWrite(IoPin4, RELAY_OFF); // and set switch relay output off // state = loadState(CHILD_ID4); // Load last known state (using eeprom storage) // digitalWrite(IoPin4, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 5 pinMode(IoPin5, OUTPUT); // use I/O 5 as output for relay module digitalWrite(IoPin5, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID5); // Load last known state (using eeprom storage) digitalWrite(IoPin5, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 6 pinMode(IoPin6, OUTPUT); // use I/O 6 as output for relay module digitalWrite(IoPin6, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID6); // Load last known state (using eeprom storage) digitalWrite(IoPin6, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 7 pinMode(IoPin7, OUTPUT); // use I/O 7 as output for relay module digitalWrite(IoPin7, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID7); // Load last known state (using eeprom storage) digitalWrite(IoPin7, state?RELAY_ON:RELAY_OFF); // write last know state // ----- PIN SETUP (FOR TESTING ONLY ----- // pinMode(IoPin4, OUTPUT); //use I/O 4 as output for relay module // digitalWrite(IoPin4, HIGH);// and set is HIGH so relay stays off } // ###### PRESENT ALL ATTACHED SENSORS TO CONTROLLER ###### void presentation(){ // ----- Sent sketch info ----- sendSketchInfo(ProjectName, ProjectVersion); // Send the sketch version information to the gateway and Controller // ----- Physical I/O child IDs ----- //present(CHILD_ID1, XXXXXXX); //Register child ID 1 as NONE present(CHILD_ID2, S_LIGHT, "Outside lighting relay"); //Register CHILD_ID2 as S_LIGHT, and sent name to controller. //present(CHILD_ID4, XXXXXXX); //Register child ID 4 as NONE present(CHILD_ID5, S_LIGHT, "Switched outlet heater"); //Register CHILD_ID5 as S_LIGHT, and sent name to controller. present(CHILD_ID6, S_LIGHT, "Sw outlet party lights"); //Register CHILD_ID6 as S_LIGHT, and sent name to controller. present(CHILD_ID7, S_LIGHT, "Gate light relay"); //Register CHILD_ID7 as S_LIGHT, and sent name to controller. // ----- virtual switch child ID (keypad) present(CHILD_ID_V1, S_LIGHT, "Outside light switch"); //Register CHILD_ID_V1 as S_LIGHT, and sent name to controller present(CHILD_ID_V2, S_LIGHT, "Shed heater"); //Register CHILD_ID_V2 as S_LIGHT, and sent name to controller present(CHILD_ID_V3, S_LIGHT, "Anti frost mode"); //Register CHILD_ID_V3 as S_LIGHT, and sent name to controller present(CHILD_ID_V4, S_LIGHT, "Party lights"); //Register CHILD_ID_V4 as S_LIGHT, and sent name to controller present(CHILD_ID_V5, S_LIGHT, "Wifi AP"); //Register CHILD_ID_V5 as S_LIGHT, and sent name to controller present(CHILD_ID_V6, S_LIGHT, "Aux 1"); //Register CHILD_ID_V6 as S_LIGHT, and sent name to controller present(CHILD_ID_V7, S_LIGHT, "Aux 2"); //Register CHILD_ID_V7 as S_LIGHT, and sent name to controller present(CHILD_ID_V8, S_LIGHT, "5 min. button"); //Register CHILD_ID_V8 as S_LIGHT, and sent name to controller // ----- Sensor child ID's ----- present(CHILD_ID_TEMP1, S_TEMP, "Temp shed Inside"); //Register CHILD_ID_TEMP1 as S_TEMP, and sent name to controller present(CHILD_ID_HUM1, S_HUM, "Hum. shed Indide"); //Register CHILD_ID_HUM1 as S_HUM, and sent name to controller // ----- Aditional presentation setting ----- metric = getConfig().isMetric; //Not sure what this does, Its needed for DHT sensor } void loop() { // ##### KEYPAD CODE TO SET A ACTION FOR A PRESSED KEY ##### char key = kpd.getKey(); // Get key from keypad (if pressed) if (key) { // compare key (defined in keypad setup) switch (key) { // with multiple multiple options below // On button for outside light case '1': // If the pressed key compares with "1" VirtalSwitch1 = true; // Change te state of boolean VirtalSwitch1 to true (on) send(msgV1.set(1)); // Sent "on" command to gateway for CHILD_ID_V1 Serial.println("KEY 1"); // Debug code. Print "KEY 1" to show that button 1 was pressed break; // End of code for button 1 // Off button for outside light case '2': // If the pressed key compares with "2" VirtalSwitch1 = false; // Change te state of boolean VirtalSwitch1 to false (off) send(msgV1.set(0)); // Sent "off" command to gateway for CHILD_ID_V1 Serial.println("KEY 2"); // Debug code. Print "KEY 2" to show that button 2 was pressed break; // End of code for button 2 // 5 minute button case '3': // If the pressed key compares with "3" send(msgV8.set(1)); // Sent "on" command to gateway for CHILD_ID_V8 Serial.println("KEY 4"); // Debug code. Print "KEY 4" to show that button 4 was pressed break; // End of code for button 4 // On button for heating case '4': // If the pressed key compares with "4" VirtalSwitch2 = true; // Change te state of boolean VirtalSwitch2 to true (on). This is the heater VirtalSwitch3 = false; // Change te state of boolean VirtalSwitch3 to false (off). This is the anti frost funtion send(msgV2.set(1)); // Sent "on" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(0)); // Sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 4"); // Debug code. Print "KEY 4" to show that button 4 was pressed break; // End of code for button 4 // Off button for heating case '5': // If the pressed key compares with "5" VirtalSwitch2 = false; // Change te state of boolean VirtalSwitch2 to false (off). This is the heater VirtalSwitch3 = false; // Change te state of boolean VirtalSwitch3 to false (off). This is the anti frost funtion send(msgV2.set(0)); // Sent "off" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(0)); // Sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 5"); // Debug code. Print "KEY 5" to show that button 5 was pressed break; // End of code for button 5 // On button for anti frost case '6': // If the pressed key compares with "6" VirtalSwitch2 = false; // Change te state of boolean VirtalSwitch2 to false (off). This is the heater VirtalSwitch3 = true; // Change te state of boolean VirtalSwitch3 to true (on). This is the anti frost funtion send(msgV2.set(0)); // Sent "off" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(1)); // Sent "on" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 6"); // Debug code. Print "KEY 6" to show that button 6 was pressed break; // End of code for button 6 // On button for party lights case '7': // If the pressed key compares with "7" VirtalSwitch4 = true; // Change te state of boolean VirtalSwitch1 to true (on) send(msgV4.set(1)); // Sent "on" command to gateway for CHILD_ID_V4 Serial.println("KEY 7"); // Debug code. Print "KEY 7" to show that button 7 was pressed break; // End of code for button 7 // Off button for party lights case '8': // If the pressed key compares with "8" VirtalSwitch4 = false; // Change te state of boolean VirtalSwitch1 to false (off) send(msgV4.set(0)); // Sent "off" command to gateway for CHILD_ID_V4 Serial.println("KEY 8"); // Debug code. Print "KEY 8" to show that button 8 was pressed break; // End of code for button 8 // Aux ON/OFF buton 1 case '9':{ // If the pressed key compares with "9" if (VirtalSwitch6 == false){ // check if the virtual switch (VirtalSwitch6) is OFF. If so, do the following VirtalSwitch6 = true; // set the new status of the virtual swich to ON send(msgV6.set(1)); // Sent "on" command to gateway for CHILD_ID_V6 } else { // If the virtual switch was not OFF, it must have been ON, so do the following VirtalSwitch6 = false; // set the new status of the virtual swich to OFF send(msgV6.set(0)); // Sent "off" command to gateway for CHILD_ID_V6 } } Serial.println("KEY 9"); // Debug code. Print "KEY 9" to show that button 9 was pressed break; // End of code for button 9 // On button for Wifi AP case 'A': // If the pressed key compares with "A" VirtalSwitch5 = true; // Change te state of boolean VirtalSwitch5 to true (on) send(msgV5.set(1)); // Sent "on" command to gateway for CHILD_ID_V5 Serial.println("KEY A"); // Debug code. Print "KEY A" to show that button A was pressed break; // End of code for button A // Off button for Wifi AP case 'B': // If the pressed key compares with "B" VirtalSwitch5 = false; // Change te state of boolean VirtalSwitch5 to false (off) send(msgV5.set(0)); // Sent "off" command to gateway for CHILD_ID_V5 Serial.println("KEY B"); // Debug code. Print "KEY B" to show that button B was pressed break; // End of code for button B // Aux ON/OFF buton 2 case 'C':{ // If the pressed key compares with "C" if (VirtalSwitch7 == false){ // check if the virtual switch (VirtalSwitch7) is OFF. If so, do the following VirtalSwitch7 = true; // set the new status of the virtual swich to ON send(msgV7.set(1)); // Sent "on" command to gateway for CHILD_ID_V7 } else { // If the virtual switch was not OFF, it must have been ON, so do the following VirtalSwitch7 = false; // set the new status of the virtual swich to OFF send(msgV7.set(0)); // Sent "off" command to gateway for CHILD_ID_V7 } } Serial.println("KEY C"); // Debug code. Print "KEY C" to show that button C was pressed break; // End of code for button C default: // If the pressed key does not match the cases above Serial.print(key); // Print the key that was pressed Serial.println(" was pressed but not recognized by the keypadcode. Something is wrong!"); // print warning break; // End of function } } // Force reading sensor, so it works also after sleep() dht.readSensor(true); // Get temperature from DHT library float temperature = dht.getTemperature(); if (isnan(temperature)) { Serial.println("Failed reading temperature from DHT!"); } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) { // Only send temperature if it changed since the last measurement or if we didn't send an update for n times lastTemp = temperature; if (!metric) { temperature = dht.toFahrenheit(temperature); } // Reset no updates counter nNoUpdatesTemp = 0; temperature += SENSOR_TEMP_OFFSET; send(msgTemp.set(temperature, 1)); #ifdef MY_DEBUG Serial.print("T: "); Serial.println(temperature); #endif } else { // Increase no update counter if the temperature stayed the same nNoUpdatesTemp++; } // Get humidity from DHT library float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) { // Only send humidity if it changed since the last measurement or if we didn't send an update for n times lastHum = humidity; // Reset no updates counter nNoUpdatesHum = 0; send(msgHum.set(humidity, 1)); #ifdef MY_DEBUG Serial.print("H: "); Serial.println(humidity); #endif } else { // Increase no update counter if the humidity stayed the same nNoUpdatesHum++; } // Sleep for a while to save energy //sleep(UPDATE_INTERVAL); } // ##### CODE FOR RECEIVING MYSENSORS MESSAGES FROM CONTROLLER ##### void receive(const MyMessage &message) { //start mysensor receiving code if (message.isAck()) { //Check for gateway acknowledgment Serial.println("This is an ack from gateway"); //Print debug code (serial print) to confirm received ack } // ----- Relay actors ----- // ----- Action taken for child ID 1: Currently set as V_LIGHT to switch relay on IoPin1 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID2) { //if message is V_LIGHT and the child ID is 2 state = message.getBool(); //guess this write the incomming boolean to state? digitalWrite(IoPin2, state?RELAY_ON:RELAY_OFF); //change the the arduino pin from "on" to "off" or other way around saveState(CHILD_ID2, state); //guess this saves the state if child ID 2 to EEPPROM Serial.print("Incoming change for sensor:"); //debug info text Serial.print(message.sensor); //write received child ID Serial.print(", New status: "); //debug info text Serial.println(message.getBool()); //write received boolean } // ----- Action taken for child ID 5: Currently set as V_LIGHT to switch relay on IoPin5 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID5) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin5, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID5, state); } // ----- Action taken for child ID 6: Currently set as V_LIGHT to switch relay on IoPin6 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID6) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin6, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID6, state); } // ----- Action taken for child ID 7: Currently set as V_LIGHT to switch relay on IoPin7 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID7) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin7, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID7, state); } // ----- Virtual switches ----- // ----- Action taken for CHILD_ID_V1: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch1) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V1) { //if message is V_LIGHT, the child ID is CHILD_ID_V1 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch1 = state; //copy the received boolean to VirtalSwitch1 saveState(CHILD_ID_V1, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } // ----- Action taken for CHILD_ID_V2: Currently set as V_LIGHT. ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V2 && state == 1) { //if message is V_LIGHT, the CHILD_ID_V2 and the message is 1 (on) VirtalSwitch2 = true; //set VirtalSwitch2 (heating) to 1 (on) VirtalSwitch3 = false; //set VirtalSwitch3 (anti frost) to 0. This prevents the anti frost and heating funtion being on at the same time. send(msgV3.set(0)); //sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion. saveState(CHILD_ID_V2, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } if (message.type == V_LIGHT && message.sensor == CHILD_ID_V2 && state == 0) { //if message is V_LIGHT, the CHILD_ID_V2 and the message is 0 (off) VirtalSwitch2 = false; //set VirtalSwitch2 (heating) to 0 (off) VirtalSwitch3 = false; //set VirtalSwitch3 (anti frost) to 0 ((off) send(msgV3.set(0)); //sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion. saveState(CHILD_ID_V2, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } // ----- Action taken for CHILD_ID_V3: Currently set as V_LIGHT. ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V3 && state == 1) { //if message is V_LIGHT, the CHILD_ID_V3 and the message is 1 (on) VirtalSwitch3 = true; //set VirtalSwitch3 (anti frost) to 1 (on) VirtalSwitch2 = false; //set VirtalSwitch2 (heating) to 0. This prevents the heating and anti frost funtion being on at the same time. send(msgV2.set(0)); //sent "off" command to gateway for CHILD_ID_V2. This is the heating funtion. saveState(CHILD_ID_V3, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } if (message.type == V_LIGHT && message.sensor == CHILD_ID_V3 && state == 0) { //if message is V_LIGHT, the CHILD_ID_V3 and the message is 0 (off) VirtalSwitch3 = false; //set VirtalSwitch3 (anti frost) to 0 ((off) VirtalSwitch2 = false; //set VirtalSwitch2 (heating) to 0 (off) send(msgV2.set(0)); //sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion. saveState(CHILD_ID_V3, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } // ----- Action taken for CHILD_ID_V4: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch4) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V4) { //if message is V_LIGHT, the child ID is CHILD_ID_V4 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch4 = state; //copy the received boolean to VirtalSwitch4 saveState(CHILD_ID_V4, state); //guess this saves the state if CHILD_ID_V4 to EEPPROM } // ----- Action taken for CHILD_ID_V5: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch5) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V5) { //if message is V_LIGHT, the child ID is CHILD_ID_V5 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch5 = state; //copy the received boolean to VirtalSwitch5 saveState(CHILD_ID_V5, state); //guess this saves the state if CHILD_ID_V5 to EEPPROM } // ----- Action taken for CHILD_ID_V6: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch6) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V6) { //if message is V_LIGHT, the child ID is CHILD_ID_V6 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch6 = state; //copy the received boolean to VirtalSwitch6 saveState(CHILD_ID_V6, state); //guess this saves the state if CHILD_ID_V6 to EEPPROM } // ----- Action taken for CHILD_ID_V7: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch7) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V7) { //if message is V_LIGHT, the child ID is CHILD_ID_V7 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch7 = state; //copy the received boolean to VirtalSwitch7 saveState(CHILD_ID_V7, state); //guess this saves the state if CHILD_ID_V6 to EEPPROM } }@SuperKris Yes sleep will power down your node so should not be used for nodes that are expecting to receive messages or are set up as a repeater. Have a look at this thread for the basic non blocking delay code.
-
Ok, next problem. I saw this one coming, but i cant figure it out by myself...
I added the DHT code for the temperature and humidity. I took the sketch that under the build section as example. It does compile and work, but the sleep in the sketch is a issue. I was surprised to find the sketch was still responding to messages from the gateway. Maybe i'm understanding sleep wrong, so that is my first question.
- Does sleep stop all code from running, or just the function that its in? In other words; My keypad code is in the loop function. The mysensor code for receiving messages is in another funtion outside the loop function (void receive). Does a sleep in the loop function also blocks void receive, or does it only block the loop part?
So both my keypad code and the DHT code are in the loop part of the sketch. This makes the keypad unresponsive. If i understand right this is caused because the code is sleeping most of the time. If i keep pressing the button until it wakes up for a a fraction of a second the key is registered.
So the easy way would be to disable sleep right.... I do not need to save any batteries, and i want the whole node to be as responsive as possible. Disabling the sleep function (with just a // ) seems to work, but its flooding (debug still enabled off course) the serial monitor "with Failed reading temperature from DHT! Failed reading humidity from DHT"
- So i guess this is just because of the way the DHT works, but i fear this may be slowing down the whole sketch and making the node less responsive. Is it a bad idea to just skip the sleep and keep the rest the same?
From what i learned from earlier experiments where i needed to time things but still needed it to be responsive to other input, i think the only solution is the millis function. I think such a function could be applied to only run the DHT code every 5 seconds. Unfortunately i'm way to much of a noob, and the DHT code is way to advanced to replace the sleep function with a millis function.
- Can anyone help me on my wat to replace the sleep funtion with the millies code?
My current code (its getting pretty big now) can be found below:
// ##### SET PROJECT NAME AND VERSION ##### #define ProjectName "Shed Controller" // Name that is vissible in controller #define ProjectVersion "0,3" // Version that is vissible in controller //#define MY_NODE_ID 10 // Manual Node ID. // ##### SET MYSENSOR SETTINGS BEFORE INCLUDIGN LIBRARY ##### #define MY_DEBUG // Enable debug prints to serial monitor // #define MY_DISABLED_SERIAL // Disable serial monitor so pins 0 and 1 can be used for the keypad. Disable this line with comment to use serial monitor so debug code works #define MY_RADIO_NRF24 // Enable and select radio type attached #define MY_REPEATER_FEATURE // Enabled repeater feature for this node // ##### INCLUDE LIBRARYS ##### #include <SPI.h> #include <MySensors.h> #include <Keypad.h> #include <DHT.h> // ##### DEFINE I/O PINS ##### //#define IoPin1 4 // Arduino Digital I/O pin number for I/O 1 #define IoPin2 3 // Arduino Digital I/O pin number for I/O 2 #define IoPin3 6 // Arduino Digital I/O pin number for I/O 3 #define IoPin4 5 // Arduino Digital I/O pin number for I/O 4 #define IoPin5 8 // Arduino Digital I/O pin number for I/O 5 #define IoPin6 7 // Arduino Digital I/O pin number for I/O 6 #define IoPin7 19 // Arduino Digital I/O pin number for I/O 7 // ##### DEFINE CHILD ID'S ##### #define CHILD_ID1 1 // ID for child 1 (I/O) #define CHILD_ID2 2 // ID for child 2 (I/O) used for relay //#define CHILD_ID4 4 // ID for child 4 (I/O) #define CHILD_ID5 5 // ID for child 5 (I/O) used for relay #define CHILD_ID6 6 // ID for child 6 (I/O) used for relay #define CHILD_ID7 7 // ID for child 7 (I/O) used for relay #define CHILD_ID_V1 10 // ID for child virtual switch 1. Used for Outside lighting button #define CHILD_ID_V2 11 // ID for child virtual switch 2. Used for Heater button #define CHILD_ID_V3 12 // ID for child virtual switch 3. Used for Anti Frost button #define CHILD_ID_V4 13 // ID for child virtual switch 4. Used for Party Lights button #define CHILD_ID_V5 14 // ID for child virtual switch 5. Used for Wifi AP button #define CHILD_ID_V6 15 // ID for child virtual switch 6. Used for Aux 1 button #define CHILD_ID_V7 16 // ID for child virtual switch 7. Used for Aux 2 button #define CHILD_ID_V8 17 // ID for child virtual switch 8. Used for 5 min button #define CHILD_ID_TEMP1 30 // ID for child 8 (I/O) used for humidity #define CHILD_ID_HUM1 31 // ID for child 3 (I/O) used for temperature // ##### TEMPERATURE SENSOR SETTINGS ##### #define SENSOR_TEMP_OFFSET 0 // Offset for temperatur sensor can be set here static const uint64_t UPDATE_INTERVAL = 10000; static const uint8_t FORCE_UPDATE_N_READS = 10; float lastTemp; float lastHum; uint8_t nNoUpdatesTemp; uint8_t nNoUpdatesHum; bool metric = true; DHT dht; // ##### RELAY SETTING ##### #define RELAY_ON 0 // Invert for some relay modules (currently inverted) #define RELAY_OFF 1 // Invert for some relay modules (currently inverted) // ##### OTHER VARIABLES ##### bool state; // Not realy sure what this exatly does. I guess temporary storage of received messages and loading from EEPROM // ##### BOOLEANS FOR VIRTUAL SWITCHES ##### bool VirtalSwitch1; // Boolean (status) for virtual switch 1 (controlled by keypad) bool VirtalSwitch2; // Boolean (status) for virtual switch 2 (controlled by keypad) bool VirtalSwitch3; // Boolean (status) for virtual switch 3 (controlled by keypad) bool VirtalSwitch4; // Boolean (status) for virtual switch 4 (controlled by keypad) bool VirtalSwitch5; // Boolean (status) for virtual switch 5 (controlled by keypad) bool VirtalSwitch6; // Boolean (status) for virtual switch 6 (controlled by keypad) bool VirtalSwitch7; // Boolean (status) for virtual switch 7 (controlled by keypad) // ##### DEFINE MYSENSORS MESSAGE CONTAINERS TO COMMUNICATE WITH GATEWAY ##### MyMessage msgTemp(CHILD_ID_TEMP1, V_TEMP); // msgTemp sends child ID CHILD_ID_TEMP1 as V_TEMP MyMessage msgHum(CHILD_ID_HUM1, V_HUM); // msgHum sends child ID CHILD_ID_HUM1 as V_HUM MyMessage msgV1(CHILD_ID_V1,S_LIGHT); // msgV1 sends child ID CHILD_ID_V1 as S_LIGHT MyMessage msgV2(CHILD_ID_V2,S_LIGHT); // msgV2 sends child ID CHILD_ID_V2 as S_LIGHT MyMessage msgV3(CHILD_ID_V3,S_LIGHT); // msgV3 sends child ID CHILD_ID_V3 as S_LIGHT MyMessage msgV4(CHILD_ID_V4,S_LIGHT); // msgV4 sends child ID CHILD_ID_V4 as S_LIGHT MyMessage msgV5(CHILD_ID_V5,S_LIGHT); // msgV5 sends child ID CHILD_ID_V5 as S_LIGHT MyMessage msgV6(CHILD_ID_V6,S_LIGHT); // msgV6 sends child ID CHILD_ID_V6 as S_LIGHT MyMessage msgV7(CHILD_ID_V7,S_LIGHT); // msgV7 sends child ID CHILD_ID_V7 as S_LIGHT MyMessage msgV8(CHILD_ID_V8,S_LIGHT); // msgV8 sends child ID CHILD_ID_V8 as S_LIGHT // ##### KEYPAD SETUP ##### const byte ROWS = 4; // Just settings for keypad library. Enter number of rows here const byte COLS = 3; // Just settings for keypad library. Enter number of columns here // Nameing of very key on the keypad. The output of keypad code will be the charaters used here. char keys[ROWS][COLS] = { {'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}, {'A', 'B', 'C'} }; byte rowPins[ROWS] = { A0, A1, A2, A3 }; // The pins the row wires are connected to (from left to right) byte colPins[COLS] = { A4, 1, 0 }; // The pins the column wires are connected to (from top to bottom) Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); // This creates the actual keypad based on specs above. void setup() { // ##### I/O SETUP FOR PHYSICAL I/O ON ARDUINO ##### // Setup I/O 2 pinMode(IoPin2, OUTPUT); // use I/O 2 as output for relay module digitalWrite(IoPin2, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID2); // Load last known state (using eeprom storage) digitalWrite(IoPin2, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 3 dht.setup(IoPin3); // set data pin of DHT sensor if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) { Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!"); } // Sleep for the time of the minimum sampling period to give the sensor time to power up // (otherwise, timeout errors might occure for the first reading) sleep(dht.getMinimumSamplingPeriod()); // Setup I/O 4 Not in use // pinMode(IoPin4, OUTPUT); // use I/O 4 as output for relay module // digitalWrite(IoPin4, RELAY_OFF); // and set switch relay output off // state = loadState(CHILD_ID4); // Load last known state (using eeprom storage) // digitalWrite(IoPin4, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 5 pinMode(IoPin5, OUTPUT); // use I/O 5 as output for relay module digitalWrite(IoPin5, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID5); // Load last known state (using eeprom storage) digitalWrite(IoPin5, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 6 pinMode(IoPin6, OUTPUT); // use I/O 6 as output for relay module digitalWrite(IoPin6, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID6); // Load last known state (using eeprom storage) digitalWrite(IoPin6, state?RELAY_ON:RELAY_OFF); // write last know state // Setup I/O 7 pinMode(IoPin7, OUTPUT); // use I/O 7 as output for relay module digitalWrite(IoPin7, RELAY_OFF); // and set switch relay output off state = loadState(CHILD_ID7); // Load last known state (using eeprom storage) digitalWrite(IoPin7, state?RELAY_ON:RELAY_OFF); // write last know state // ----- PIN SETUP (FOR TESTING ONLY ----- // pinMode(IoPin4, OUTPUT); //use I/O 4 as output for relay module // digitalWrite(IoPin4, HIGH);// and set is HIGH so relay stays off } // ###### PRESENT ALL ATTACHED SENSORS TO CONTROLLER ###### void presentation(){ // ----- Sent sketch info ----- sendSketchInfo(ProjectName, ProjectVersion); // Send the sketch version information to the gateway and Controller // ----- Physical I/O child IDs ----- //present(CHILD_ID1, XXXXXXX); //Register child ID 1 as NONE present(CHILD_ID2, S_LIGHT, "Outside lighting relay"); //Register CHILD_ID2 as S_LIGHT, and sent name to controller. //present(CHILD_ID4, XXXXXXX); //Register child ID 4 as NONE present(CHILD_ID5, S_LIGHT, "Switched outlet heater"); //Register CHILD_ID5 as S_LIGHT, and sent name to controller. present(CHILD_ID6, S_LIGHT, "Sw outlet party lights"); //Register CHILD_ID6 as S_LIGHT, and sent name to controller. present(CHILD_ID7, S_LIGHT, "Gate light relay"); //Register CHILD_ID7 as S_LIGHT, and sent name to controller. // ----- virtual switch child ID (keypad) present(CHILD_ID_V1, S_LIGHT, "Outside light switch"); //Register CHILD_ID_V1 as S_LIGHT, and sent name to controller present(CHILD_ID_V2, S_LIGHT, "Shed heater"); //Register CHILD_ID_V2 as S_LIGHT, and sent name to controller present(CHILD_ID_V3, S_LIGHT, "Anti frost mode"); //Register CHILD_ID_V3 as S_LIGHT, and sent name to controller present(CHILD_ID_V4, S_LIGHT, "Party lights"); //Register CHILD_ID_V4 as S_LIGHT, and sent name to controller present(CHILD_ID_V5, S_LIGHT, "Wifi AP"); //Register CHILD_ID_V5 as S_LIGHT, and sent name to controller present(CHILD_ID_V6, S_LIGHT, "Aux 1"); //Register CHILD_ID_V6 as S_LIGHT, and sent name to controller present(CHILD_ID_V7, S_LIGHT, "Aux 2"); //Register CHILD_ID_V7 as S_LIGHT, and sent name to controller present(CHILD_ID_V8, S_LIGHT, "5 min. button"); //Register CHILD_ID_V8 as S_LIGHT, and sent name to controller // ----- Sensor child ID's ----- present(CHILD_ID_TEMP1, S_TEMP, "Temp shed Inside"); //Register CHILD_ID_TEMP1 as S_TEMP, and sent name to controller present(CHILD_ID_HUM1, S_HUM, "Hum. shed Indide"); //Register CHILD_ID_HUM1 as S_HUM, and sent name to controller // ----- Aditional presentation setting ----- metric = getConfig().isMetric; //Not sure what this does, Its needed for DHT sensor } void loop() { // ##### KEYPAD CODE TO SET A ACTION FOR A PRESSED KEY ##### char key = kpd.getKey(); // Get key from keypad (if pressed) if (key) { // compare key (defined in keypad setup) switch (key) { // with multiple multiple options below // On button for outside light case '1': // If the pressed key compares with "1" VirtalSwitch1 = true; // Change te state of boolean VirtalSwitch1 to true (on) send(msgV1.set(1)); // Sent "on" command to gateway for CHILD_ID_V1 Serial.println("KEY 1"); // Debug code. Print "KEY 1" to show that button 1 was pressed break; // End of code for button 1 // Off button for outside light case '2': // If the pressed key compares with "2" VirtalSwitch1 = false; // Change te state of boolean VirtalSwitch1 to false (off) send(msgV1.set(0)); // Sent "off" command to gateway for CHILD_ID_V1 Serial.println("KEY 2"); // Debug code. Print "KEY 2" to show that button 2 was pressed break; // End of code for button 2 // 5 minute button case '3': // If the pressed key compares with "3" send(msgV8.set(1)); // Sent "on" command to gateway for CHILD_ID_V8 Serial.println("KEY 4"); // Debug code. Print "KEY 4" to show that button 4 was pressed break; // End of code for button 4 // On button for heating case '4': // If the pressed key compares with "4" VirtalSwitch2 = true; // Change te state of boolean VirtalSwitch2 to true (on). This is the heater VirtalSwitch3 = false; // Change te state of boolean VirtalSwitch3 to false (off). This is the anti frost funtion send(msgV2.set(1)); // Sent "on" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(0)); // Sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 4"); // Debug code. Print "KEY 4" to show that button 4 was pressed break; // End of code for button 4 // Off button for heating case '5': // If the pressed key compares with "5" VirtalSwitch2 = false; // Change te state of boolean VirtalSwitch2 to false (off). This is the heater VirtalSwitch3 = false; // Change te state of boolean VirtalSwitch3 to false (off). This is the anti frost funtion send(msgV2.set(0)); // Sent "off" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(0)); // Sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 5"); // Debug code. Print "KEY 5" to show that button 5 was pressed break; // End of code for button 5 // On button for anti frost case '6': // If the pressed key compares with "6" VirtalSwitch2 = false; // Change te state of boolean VirtalSwitch2 to false (off). This is the heater VirtalSwitch3 = true; // Change te state of boolean VirtalSwitch3 to true (on). This is the anti frost funtion send(msgV2.set(0)); // Sent "off" command to gateway for CHILD_ID_V2. This is the heater send(msgV3.set(1)); // Sent "on" command to gateway for CHILD_ID_V3. This is the anti frost funtion Serial.println("KEY 6"); // Debug code. Print "KEY 6" to show that button 6 was pressed break; // End of code for button 6 // On button for party lights case '7': // If the pressed key compares with "7" VirtalSwitch4 = true; // Change te state of boolean VirtalSwitch1 to true (on) send(msgV4.set(1)); // Sent "on" command to gateway for CHILD_ID_V4 Serial.println("KEY 7"); // Debug code. Print "KEY 7" to show that button 7 was pressed break; // End of code for button 7 // Off button for party lights case '8': // If the pressed key compares with "8" VirtalSwitch4 = false; // Change te state of boolean VirtalSwitch1 to false (off) send(msgV4.set(0)); // Sent "off" command to gateway for CHILD_ID_V4 Serial.println("KEY 8"); // Debug code. Print "KEY 8" to show that button 8 was pressed break; // End of code for button 8 // Aux ON/OFF buton 1 case '9':{ // If the pressed key compares with "9" if (VirtalSwitch6 == false){ // check if the virtual switch (VirtalSwitch6) is OFF. If so, do the following VirtalSwitch6 = true; // set the new status of the virtual swich to ON send(msgV6.set(1)); // Sent "on" command to gateway for CHILD_ID_V6 } else { // If the virtual switch was not OFF, it must have been ON, so do the following VirtalSwitch6 = false; // set the new status of the virtual swich to OFF send(msgV6.set(0)); // Sent "off" command to gateway for CHILD_ID_V6 } } Serial.println("KEY 9"); // Debug code. Print "KEY 9" to show that button 9 was pressed break; // End of code for button 9 // On button for Wifi AP case 'A': // If the pressed key compares with "A" VirtalSwitch5 = true; // Change te state of boolean VirtalSwitch5 to true (on) send(msgV5.set(1)); // Sent "on" command to gateway for CHILD_ID_V5 Serial.println("KEY A"); // Debug code. Print "KEY A" to show that button A was pressed break; // End of code for button A // Off button for Wifi AP case 'B': // If the pressed key compares with "B" VirtalSwitch5 = false; // Change te state of boolean VirtalSwitch5 to false (off) send(msgV5.set(0)); // Sent "off" command to gateway for CHILD_ID_V5 Serial.println("KEY B"); // Debug code. Print "KEY B" to show that button B was pressed break; // End of code for button B // Aux ON/OFF buton 2 case 'C':{ // If the pressed key compares with "C" if (VirtalSwitch7 == false){ // check if the virtual switch (VirtalSwitch7) is OFF. If so, do the following VirtalSwitch7 = true; // set the new status of the virtual swich to ON send(msgV7.set(1)); // Sent "on" command to gateway for CHILD_ID_V7 } else { // If the virtual switch was not OFF, it must have been ON, so do the following VirtalSwitch7 = false; // set the new status of the virtual swich to OFF send(msgV7.set(0)); // Sent "off" command to gateway for CHILD_ID_V7 } } Serial.println("KEY C"); // Debug code. Print "KEY C" to show that button C was pressed break; // End of code for button C default: // If the pressed key does not match the cases above Serial.print(key); // Print the key that was pressed Serial.println(" was pressed but not recognized by the keypadcode. Something is wrong!"); // print warning break; // End of function } } // Force reading sensor, so it works also after sleep() dht.readSensor(true); // Get temperature from DHT library float temperature = dht.getTemperature(); if (isnan(temperature)) { Serial.println("Failed reading temperature from DHT!"); } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) { // Only send temperature if it changed since the last measurement or if we didn't send an update for n times lastTemp = temperature; if (!metric) { temperature = dht.toFahrenheit(temperature); } // Reset no updates counter nNoUpdatesTemp = 0; temperature += SENSOR_TEMP_OFFSET; send(msgTemp.set(temperature, 1)); #ifdef MY_DEBUG Serial.print("T: "); Serial.println(temperature); #endif } else { // Increase no update counter if the temperature stayed the same nNoUpdatesTemp++; } // Get humidity from DHT library float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) { // Only send humidity if it changed since the last measurement or if we didn't send an update for n times lastHum = humidity; // Reset no updates counter nNoUpdatesHum = 0; send(msgHum.set(humidity, 1)); #ifdef MY_DEBUG Serial.print("H: "); Serial.println(humidity); #endif } else { // Increase no update counter if the humidity stayed the same nNoUpdatesHum++; } // Sleep for a while to save energy //sleep(UPDATE_INTERVAL); } // ##### CODE FOR RECEIVING MYSENSORS MESSAGES FROM CONTROLLER ##### void receive(const MyMessage &message) { //start mysensor receiving code if (message.isAck()) { //Check for gateway acknowledgment Serial.println("This is an ack from gateway"); //Print debug code (serial print) to confirm received ack } // ----- Relay actors ----- // ----- Action taken for child ID 1: Currently set as V_LIGHT to switch relay on IoPin1 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID2) { //if message is V_LIGHT and the child ID is 2 state = message.getBool(); //guess this write the incomming boolean to state? digitalWrite(IoPin2, state?RELAY_ON:RELAY_OFF); //change the the arduino pin from "on" to "off" or other way around saveState(CHILD_ID2, state); //guess this saves the state if child ID 2 to EEPPROM Serial.print("Incoming change for sensor:"); //debug info text Serial.print(message.sensor); //write received child ID Serial.print(", New status: "); //debug info text Serial.println(message.getBool()); //write received boolean } // ----- Action taken for child ID 5: Currently set as V_LIGHT to switch relay on IoPin5 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID5) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin5, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID5, state); } // ----- Action taken for child ID 6: Currently set as V_LIGHT to switch relay on IoPin6 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID6) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin6, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID6, state); } // ----- Action taken for child ID 7: Currently set as V_LIGHT to switch relay on IoPin7 ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID7) { //no further comments. See actions for child 2. Its the same state = message.getBool(); //also no debug code (serial print) written to save space digitalWrite(IoPin7, state?RELAY_ON:RELAY_OFF); saveState(CHILD_ID7, state); } // ----- Virtual switches ----- // ----- Action taken for CHILD_ID_V1: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch1) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V1) { //if message is V_LIGHT, the child ID is CHILD_ID_V1 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch1 = state; //copy the received boolean to VirtalSwitch1 saveState(CHILD_ID_V1, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } // ----- Action taken for CHILD_ID_V2: Currently set as V_LIGHT. ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V2 && state == 1) { //if message is V_LIGHT, the CHILD_ID_V2 and the message is 1 (on) VirtalSwitch2 = true; //set VirtalSwitch2 (heating) to 1 (on) VirtalSwitch3 = false; //set VirtalSwitch3 (anti frost) to 0. This prevents the anti frost and heating funtion being on at the same time. send(msgV3.set(0)); //sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion. saveState(CHILD_ID_V2, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } if (message.type == V_LIGHT && message.sensor == CHILD_ID_V2 && state == 0) { //if message is V_LIGHT, the CHILD_ID_V2 and the message is 0 (off) VirtalSwitch2 = false; //set VirtalSwitch2 (heating) to 0 (off) VirtalSwitch3 = false; //set VirtalSwitch3 (anti frost) to 0 ((off) send(msgV3.set(0)); //sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion. saveState(CHILD_ID_V2, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } // ----- Action taken for CHILD_ID_V3: Currently set as V_LIGHT. ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V3 && state == 1) { //if message is V_LIGHT, the CHILD_ID_V3 and the message is 1 (on) VirtalSwitch3 = true; //set VirtalSwitch3 (anti frost) to 1 (on) VirtalSwitch2 = false; //set VirtalSwitch2 (heating) to 0. This prevents the heating and anti frost funtion being on at the same time. send(msgV2.set(0)); //sent "off" command to gateway for CHILD_ID_V2. This is the heating funtion. saveState(CHILD_ID_V3, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } if (message.type == V_LIGHT && message.sensor == CHILD_ID_V3 && state == 0) { //if message is V_LIGHT, the CHILD_ID_V3 and the message is 0 (off) VirtalSwitch3 = false; //set VirtalSwitch3 (anti frost) to 0 ((off) VirtalSwitch2 = false; //set VirtalSwitch2 (heating) to 0 (off) send(msgV2.set(0)); //sent "off" command to gateway for CHILD_ID_V3. This is the anti frost funtion. saveState(CHILD_ID_V3, state); //guess this saves the state if CHILD_ID_V1 to EEPPROM } // ----- Action taken for CHILD_ID_V4: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch4) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V4) { //if message is V_LIGHT, the child ID is CHILD_ID_V4 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch4 = state; //copy the received boolean to VirtalSwitch4 saveState(CHILD_ID_V4, state); //guess this saves the state if CHILD_ID_V4 to EEPPROM } // ----- Action taken for CHILD_ID_V5: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch5) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V5) { //if message is V_LIGHT, the child ID is CHILD_ID_V5 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch5 = state; //copy the received boolean to VirtalSwitch5 saveState(CHILD_ID_V5, state); //guess this saves the state if CHILD_ID_V5 to EEPPROM } // ----- Action taken for CHILD_ID_V6: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch6) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V6) { //if message is V_LIGHT, the child ID is CHILD_ID_V6 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch6 = state; //copy the received boolean to VirtalSwitch6 saveState(CHILD_ID_V6, state); //guess this saves the state if CHILD_ID_V6 to EEPPROM } // ----- Action taken for CHILD_ID_V7: Currently set as V_LIGHT. Changes the boolean of virtual switch (VirtalSwitch7) ----- if (message.type == V_LIGHT && message.sensor == CHILD_ID_V7) { //if message is V_LIGHT, the child ID is CHILD_ID_V7 do the following state = message.getBool(); //guess this write the incomming boolean to state? VirtalSwitch7 = state; //copy the received boolean to VirtalSwitch7 saveState(CHILD_ID_V7, state); //guess this saves the state if CHILD_ID_V6 to EEPPROM } }Does sleep stop all code from running, or just the function that its in? In other words; My keypad code is in the loop function. The mysensor code for receiving messages is in another funtion outside the loop function (void receive). Does a sleep in the loop function also blocks void receive, or does it only block the loop part?
- sleep() stops all code. You should not use it in this environment.
- the receive() is declared outside loop() but runs inside loop(). This is done automatically by MySensors framework.
Disabling the sleep function (with just a // ) seems to work, but its flooding (debug still enabled off course) the serial monitor "with Failed reading temperature from DHT! Failed reading humidity from DHT
- you are right to disable sleep(), but .... the DHT Sensor is not as fast as your Arduino.
An excerpt of the DHT samplesketch:
// Sleep time between sensor updates (in milliseconds) // Must be >1000ms for DHT22 and >2000ms for DHT11 static const uint64_t UPDATE_INTERVAL = 60000; static const uint64_t MEASURING_INTERVAL = 30000; // Force sending an update of the temperature after n sensor reads, so a controller showing the // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that // the value didn't change since; // i.e. the sensor would force sending an update every MEASURING_INTERVAL*FORCE_UPDATE_N_READS [ms] static const uint8_t FORCE_UPDATE_N_READS = 10;Thus your code must result in more than 1 reading per 2 seconds, so the DHT Sensor is not ready and fails.
So as you expected, it boils down to enclose the DHT code into an millis() controlled if-Statement.
Basically it looks like this
static const uint64_t UPDATE_INTERVAL = 60000; static const uint64_t MEASURING_INTERVAL = 30000; // before setup() aka global variables unsigned long last_time = 0, actual_time = 0; ---------- // within loop() if ( (millis() - last_time) >= MEASURING_INTERVAL) { last_time = millis(); // Force reading sensor, so it works also after sleep() dht.readSensor(true); // rest of your DHT Code here } // don´t forget closing parenthesis (after Humidity is done)you will recognize the fragments, they originate form the DHT Example Sketch.
-
@SuperKris Yes sleep will power down your node so should not be used for nodes that are expecting to receive messages or are set up as a repeater. Have a look at this thread for the basic non blocking delay code.
@Boots33 said:
@SuperKris Yes sleep will power down your node so should not be used for nodes that are expecting to receive messages or are set up as a repeater. Have a look at this thread for the basic non blocking delay code.
Thanks. That is just what i was looking for, but i want not able to find it trough the search funtion!
There is just 1 thing i still dont understand about the sleep function. In the latest version of my sketch i use a sleep time of 5 seconds. If the arduino fully stops processing code while in sleep, i would not think it would be able to receive messages from the controller.
But i have no problem receiving messages from the controller. If i press a lightswitch in Domoticz the relay on the arduino switches without any noticeable delay. This should not be possible right? How is this possible?
@tboha said:
- sleep() stops all code. You should not use it in this environment.
- the receive() is declared outside loop() but runs inside loop(). This is done automatically by MySensors framework.
Thanks! I guess i still dont fully understand the whole structure of a arduino sketch. I see why sleep() would stop the keypad from working properly, but i dont really understand why receive() seems to be not affected by this.
- you are right to disable sleep(), but .... the DHT Sensor is not as fast as your Arduino.
I think i understand why i'm getting the errors from the DHT code. I'm just wondering if it would slow down other functions of the arduino, or the controller.
So as you expected, it boils down to enclose the DHT code into an millis() controlled if-Statement.
Basically it looks like this
static const uint64_t UPDATE_INTERVAL = 60000; static const uint64_t MEASURING_INTERVAL = 30000; // before setup() aka global variables unsigned long last_time = 0, actual_time = 0; ---------- // within loop() if ( (millis() - last_time) >= MEASURING_INTERVAL) { last_time = millis(); // Force reading sensor, so it works also after sleep() dht.readSensor(true); // rest of your DHT Code here } // don´t forget closing parenthesis (after Humidity is done)you will recognize the fragments, they originate form the DHT Example Sketch.
Thank, i'll try to work this within my sketch. It just seems a little hard because the DHT code is relatively complex compared to the other code i used in this sketch. I'm to much of a noob to understand if i can just copy the whole loop part into the if function with the millis.
I'll try adding the millis code tonight!
-
@Boots33 said:
@SuperKris Yes sleep will power down your node so should not be used for nodes that are expecting to receive messages or are set up as a repeater. Have a look at this thread for the basic non blocking delay code.
Thanks. That is just what i was looking for, but i want not able to find it trough the search funtion!
There is just 1 thing i still dont understand about the sleep function. In the latest version of my sketch i use a sleep time of 5 seconds. If the arduino fully stops processing code while in sleep, i would not think it would be able to receive messages from the controller.
But i have no problem receiving messages from the controller. If i press a lightswitch in Domoticz the relay on the arduino switches without any noticeable delay. This should not be possible right? How is this possible?
@tboha said:
- sleep() stops all code. You should not use it in this environment.
- the receive() is declared outside loop() but runs inside loop(). This is done automatically by MySensors framework.
Thanks! I guess i still dont fully understand the whole structure of a arduino sketch. I see why sleep() would stop the keypad from working properly, but i dont really understand why receive() seems to be not affected by this.
- you are right to disable sleep(), but .... the DHT Sensor is not as fast as your Arduino.
I think i understand why i'm getting the errors from the DHT code. I'm just wondering if it would slow down other functions of the arduino, or the controller.
So as you expected, it boils down to enclose the DHT code into an millis() controlled if-Statement.
Basically it looks like this
static const uint64_t UPDATE_INTERVAL = 60000; static const uint64_t MEASURING_INTERVAL = 30000; // before setup() aka global variables unsigned long last_time = 0, actual_time = 0; ---------- // within loop() if ( (millis() - last_time) >= MEASURING_INTERVAL) { last_time = millis(); // Force reading sensor, so it works also after sleep() dht.readSensor(true); // rest of your DHT Code here } // don´t forget closing parenthesis (after Humidity is done)you will recognize the fragments, they originate form the DHT Example Sketch.
Thank, i'll try to work this within my sketch. It just seems a little hard because the DHT code is relatively complex compared to the other code i used in this sketch. I'm to much of a noob to understand if i can just copy the whole loop part into the if function with the millis.
I'll try adding the millis code tonight!
@SuperKris
you already solved the problem with Pin0 and 1 (did you?). Here is possibly another solution (from 2.0 API):MY_DISABLED_SERIAL Disabled Enable this in sketch if you want to use TX(1), RX(0) as normal I/O pinso
#define MY_DISABLED_SERIALshould free Pin 0 and Pin 1.