How To: Make a Simple/Cheap Scene Controller (with video)
-
The 2.0 version code:
#define MY_DEBUG #define MY_RADIO_NRF24 #include <SPI.h> #include <MySensors.h> #include <Keypad.h> #define NODE_ID 14 // or set to AUTO if you want gw to assign a NODE_ID for you. #define SN "Scene Controller" #define SV "1.0" #define KEYPAD_CHILD_ID 95 MyMessage scene(KEYPAD_CHILD_ID, V_SCENE_ON); MyMessage scene2(KEYPAD_CHILD_ID, V_SCENE_OFF); const byte ROWS = 4; //four rows const byte COLS = 1; //three columns char keys[ROWS][COLS] = { {'1'}, {'2'}, {'3'}, {'4'} }; byte rowPins[ROWS] = {6, 7, 4, 5}; //connect to the row pinouts of the keypad byte colPins[COLS] = {8}; //connect to the column pinouts of the keypad Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); byte lastState; void setup() { sendSketchInfo(SN, SV); present(KEYPAD_CHILD_ID, S_SCENE_CONTROLLER); keypad.addEventListener(keypadEvent); } void loop() { char key = keypad.getKey(); } void keypadEvent(KeypadEvent key) { switch (keypad.getState()) { case PRESSED: lastState = 1; break; case HOLD: lastState = 2; break; case RELEASED: int keyInt = key - '0'; //Quick way to convert Char to Int so it can be sent to controller if (lastState == 2) { keyInt = keyInt + 4; //If button is held, add 4. If using more than 4 buttons this number will need to be changed } send(scene.set(keyInt)); break; } } -
@Łukasz-Kostrzewa said:
send(scene.set(keyInt));
Hi
After
send(scene.set(keyInt));
Add
send(scene2.set(keyInt));
Write this code to arduino (now You can OFF all the switches) Next delete code You added and write it to Arduino once again but now in Domoticz make modifications I writed couple post higher. When You do that You will be able to control 4 scenes and another 4 will bo halpefull to OFF the first4 (when You hold the buttons) -
Complete code version 2 with short press ON long press OFF.
#define MY_DEBUG #define MY_RADIO_NRF24 #include <SPI.h> #include <MySensors.h> #include <Keypad.h> #define NODE_ID AUTO // or set to AUTO if you want gw to assign a NODE_ID for you. #define SN "Scene Controller" #define SV "2.0" #define KEYPAD_CHILD_ID 95 MyMessage scene(KEYPAD_CHILD_ID, V_SCENE_ON); //scene ON MyMessage scene2(KEYPAD_CHILD_ID, V_SCENE_OFF); //scene OFF const byte ROWS = 4; //four rows const byte COLS = 1; //one column char keys[ROWS][COLS] = { {'1'}, {'2'}, {'3'}, {'4'} }; byte rowPins[ROWS] = {6, 7, 4, 5}; //connect to the row pinouts of the keypad byte colPins[COLS] = {8}; //connect to the column pinouts of the keypad Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); byte lastState; void setup() { sendSketchInfo(SN, SV); present(KEYPAD_CHILD_ID, S_SCENE_CONTROLLER); keypad.addEventListener(keypadEvent); } void loop() { char key = keypad.getKey(); } void keypadEvent(KeypadEvent key) { switch (keypad.getState()) { case PRESSED: lastState = 1; break; case HOLD: lastState = 2; break; case RELEASED: int keyInt = key - '0'; //Quick way to convert Char to Int so it can be sent to controller if (lastState == 2) { //keyInt = keyInt + 4; //If button is held, add 4. If using more than 4 buttons this number will need to be changed send(scene2.set(keyInt)); } else { send(scene.set(keyInt)); } //break; } }``` -
Hi rechin304
Thank You for Your code...It's working great!!!
Best regards -
Hi rechin304
Thank You for Your code...It's working great!!!
Best regards -
Hi Guys,
I'm so glad that have updated the sketch which i have now been able to compile and get running :-)
But this is the message I get in the serial monitor and I only get these messages when I press button 3?? I am using a single row of four buttons as in the original sketch.
Am I missing something here? I was assuming the message with either be a 1 for a short press and 0 for a long press? I would be really grateful if someone who knows more about this than me is able to help me figure out what's going on?
TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:3 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:3 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:3 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:3 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:3 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:3 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:3 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:3 -
Hi Guys,
I'm so glad that have updated the sketch which i have now been able to compile and get running :-)
But this is the message I get in the serial monitor and I only get these messages when I press button 3?? I am using a single row of four buttons as in the original sketch.
Am I missing something here? I was assuming the message with either be a 1 for a short press and 0 for a long press? I would be really grateful if someone who knows more about this than me is able to help me figure out what's going on?
TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:3 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:3 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:3 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:3 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:3 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:7 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:3 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:3 TSP:MSG:SEND 11-11-0-0 s=95,c=1,t=19,pt=2,l=2,sg=0,ft=0,st=ok:3@Matt-Pitts on 3 is short press and in code is scene on and on long press is 7 scene off
MyMessage scene(KEYPAD_CHILD_ID, V_SCENE_ON); //scene ON MyMessage scene2(KEYPAD_CHILD_ID, V_SCENE_OFF); //scene OFF send(scene2.set(keyInt)); } else { send(scene.set(keyInt));``` -
@rechin304 said:
@Matt-Pitts on 3 is short press and in code is scene on and on long press is 7 scene off
MyMessage scene(KEYPAD_CHILD_ID, V_SCENE_ON); //scene ON MyMessage scene2(KEYPAD_CHILD_ID, V_SCENE_OFF); //scene OFF send(scene2.set(keyInt)); } else { send(scene.set(keyInt));```Hi Not sure if that helps me, I'm struggling to understand how this actually works? as I said the only button doing anything is 3, do I need to modify the sketch to get the other buttons working?
-
@rechin304 said:
@Matt-Pitts on 3 is short press and in code is scene on and on long press is 7 scene off
MyMessage scene(KEYPAD_CHILD_ID, V_SCENE_ON); //scene ON MyMessage scene2(KEYPAD_CHILD_ID, V_SCENE_OFF); //scene OFF send(scene2.set(keyInt)); } else { send(scene.set(keyInt));```Hi Not sure if that helps me, I'm struggling to understand how this actually works? as I said the only button doing anything is 3, do I need to modify the sketch to get the other buttons working?
@Matt-Pitts then you need to check your conenction to all wires and if are correctly. Check first post as there is a picture.
-
Complete code version 2 with short press ON long press OFF.
#define MY_DEBUG #define MY_RADIO_NRF24 #include <SPI.h> #include <MySensors.h> #include <Keypad.h> #define NODE_ID AUTO // or set to AUTO if you want gw to assign a NODE_ID for you. #define SN "Scene Controller" #define SV "2.0" #define KEYPAD_CHILD_ID 95 MyMessage scene(KEYPAD_CHILD_ID, V_SCENE_ON); //scene ON MyMessage scene2(KEYPAD_CHILD_ID, V_SCENE_OFF); //scene OFF const byte ROWS = 4; //four rows const byte COLS = 1; //one column char keys[ROWS][COLS] = { {'1'}, {'2'}, {'3'}, {'4'} }; byte rowPins[ROWS] = {6, 7, 4, 5}; //connect to the row pinouts of the keypad byte colPins[COLS] = {8}; //connect to the column pinouts of the keypad Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); byte lastState; void setup() { sendSketchInfo(SN, SV); present(KEYPAD_CHILD_ID, S_SCENE_CONTROLLER); keypad.addEventListener(keypadEvent); } void loop() { char key = keypad.getKey(); } void keypadEvent(KeypadEvent key) { switch (keypad.getState()) { case PRESSED: lastState = 1; break; case HOLD: lastState = 2; break; case RELEASED: int keyInt = key - '0'; //Quick way to convert Char to Int so it can be sent to controller if (lastState == 2) { //keyInt = keyInt + 4; //If button is held, add 4. If using more than 4 buttons this number will need to be changed send(scene2.set(keyInt)); } else { send(scene.set(keyInt)); } //break; } }```Not getting the Hold on buttons working, everything else works. Any ideas why the long press doesn't work?
-
Never mind part of the code was commented out. I wasn't sure because I just started to use OTA. But it's all good now its working fine. Here it is:
#define MY_DEBUG #define MY_RADIO_NRF24 #define MY_OTA_FIRMWARE_FEATURE #include <SPI.h> #include <MySensors.h> #include <Keypad.h> #define NODE_ID AUTO // or set to AUTO if you want gw to assign a NODE_ID for you. #define SN "Scene Controller" #define SV "2.0" #define KEYPAD_CHILD_ID 95 MyMessage scene(KEYPAD_CHILD_ID, V_SCENE_ON); //scene ON MyMessage scene2(KEYPAD_CHILD_ID, V_SCENE_OFF); //scene OFF const byte ROWS = 4; //four rows const byte COLS = 1; //one column char keys[ROWS][COLS] = { {'1'}, {'2'}, {'3'}, {'4'} }; byte rowPins[ROWS] = {6, 7, 4, 5}; //connect to the row pinouts of the keypad byte colPins[COLS] = {8}; //connect to the column pinouts of the keypad Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); byte lastState; void setup() { sendSketchInfo(SN, SV); present(KEYPAD_CHILD_ID, S_SCENE_CONTROLLER); keypad.addEventListener(keypadEvent); } void loop() { char key = keypad.getKey(); } void keypadEvent(KeypadEvent key) { switch (keypad.getState()) { case PRESSED: lastState = 1; break; case HOLD: lastState = 2; break; case RELEASED: int keyInt = key - '0'; //Quick way to convert Char to Int so it can be sent to controller if (lastState == 2) { keyInt = keyInt + 4; //If button is held, add 4. If using more than 4 buttons this number will need to be changed send(scene2.set(keyInt)); } else { send(scene.set(keyInt)); } break; } } -
Never mind part of the code was commented out. I wasn't sure because I just started to use OTA. But it's all good now its working fine. Here it is:
#define MY_DEBUG #define MY_RADIO_NRF24 #define MY_OTA_FIRMWARE_FEATURE #include <SPI.h> #include <MySensors.h> #include <Keypad.h> #define NODE_ID AUTO // or set to AUTO if you want gw to assign a NODE_ID for you. #define SN "Scene Controller" #define SV "2.0" #define KEYPAD_CHILD_ID 95 MyMessage scene(KEYPAD_CHILD_ID, V_SCENE_ON); //scene ON MyMessage scene2(KEYPAD_CHILD_ID, V_SCENE_OFF); //scene OFF const byte ROWS = 4; //four rows const byte COLS = 1; //one column char keys[ROWS][COLS] = { {'1'}, {'2'}, {'3'}, {'4'} }; byte rowPins[ROWS] = {6, 7, 4, 5}; //connect to the row pinouts of the keypad byte colPins[COLS] = {8}; //connect to the column pinouts of the keypad Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); byte lastState; void setup() { sendSketchInfo(SN, SV); present(KEYPAD_CHILD_ID, S_SCENE_CONTROLLER); keypad.addEventListener(keypadEvent); } void loop() { char key = keypad.getKey(); } void keypadEvent(KeypadEvent key) { switch (keypad.getState()) { case PRESSED: lastState = 1; break; case HOLD: lastState = 2; break; case RELEASED: int keyInt = key - '0'; //Quick way to convert Char to Int so it can be sent to controller if (lastState == 2) { keyInt = keyInt + 4; //If button is held, add 4. If using more than 4 buttons this number will need to be changed send(scene2.set(keyInt)); } else { send(scene.set(keyInt)); } break; } } -
Hello,
Here an update of the original sketch with a small modif to add a buzzer for validating the keypress.
It will beep once for short key press and twice for the long one.
The buzzer is connected on D3 and the beep length can be adjusted in the function.
Your feedback and improvement ideas are welcome.
Best regards,
Jef
#define MY_DEBUG #define MY_RADIO_NRF24 // Set LOW transmit power level as default, if you have an amplified NRF-module and // power your radio separately with a good regulator you can turn up PA level. /* - RF24_PA_MIN = -18dBm * - RF24_PA_LOW = -12dBm * - RF24_PA_HIGH = -6dBm * - RF24_PA_MAX = 0dBm */ #define MY_RF24_PA_LEVEL RF24_PA_HIGH // Enabled repeater feature for this node #define MY_REPEATER_FEATURE // activate signal report // #define MY_SIGNAL_REPORT_ENABLED #include <SPI.h> #include <MySensors.h> #include <Keypad.h> #define NODE_ID AUTO // or set to AUTO if you want gw to assign a node id for you. #define SN "Keypad Scene Controller" #define SV "2.1" #define KEYPAD_CHILD_ID 95 MyMessage scene(KEYPAD_CHILD_ID, V_SCENE_ON); //scene ON MyMessage scene2(KEYPAD_CHILD_ID, V_SCENE_OFF); //scene OFF int buzzer = 3; // buzzer pin const byte ROWS = 4; //four rows const byte COLS = 1; //one column char keys[ROWS][COLS] = { {'1'}, {'2'}, {'3'}, {'4'} }; byte rowPins[ROWS] = {6, 7, 4, 5}; //connect to the row pinouts of the keypad byte colPins[COLS] = {8}; //connect to the column pinouts of the keypad Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); byte lastState; void setup() { sendSketchInfo(SN, SV); present(KEYPAD_CHILD_ID, S_SCENE_CONTROLLER); keypad.addEventListener(keypadEvent); pinMode(buzzer, OUTPUT); } /* * Declare the buzzer function. * Adjust the delay to fit your preferences */ void beep() { digitalWrite(buzzer, HIGH); delay(50); digitalWrite(buzzer, LOW); } void loop() { char key = keypad.getKey(); } void keypadEvent(KeypadEvent key) { switch (keypad.getState()) { case PRESSED: lastState = 1; beep(); break; case HOLD: lastState = 2; beep(); break; case RELEASED: int keyInt = key - '0'; //Quick way to convert Char to Int so it can be sent to controller if (lastState == 2) { //keyInt = keyInt + 4; //If button is held, add 4. If using more than 4 buttons this number will need to be changed send(scene2.set(keyInt)); } else { send(scene.set(keyInt)); } //break; } } -
I want to use this mysensors touch sensor to adjust a selector switch in domoticz, so if I select scene 1 the selector switch in Domoticz goes to 10%, and scene 2 to 20% and so on. Is that possible and how do I do that?