Binary sensor expanded help
-
Wow. It's been two years since I've visited this. At any rate. I'm trying to update to the latest mysensors version and am running into an issue. I've used the binary sensor as a base but I'm pretty sure that I'm doing something wrong. Here's the code I'm trying to use:
#include <MySensor.h> #include <SPI.h> #include <Bounce2.h> #define ZONE_1 3 // Arduino Digital I/O pin for button/reed switch #define NUMBER_OF_ZONES 6 MySensor gw; Bounce debouncer_1 = Bounce(); Bounce debouncer_2 = Bounce(); Bounce debouncer_3 = Bounce(); Bounce debouncer_4 = Bounce(); Bounce debouncer_5 = Bounce(); Bounce debouncer_6 = Bounce(); int oldValue_1 =-1; int oldValue_2 =-1; int oldValue_3 =-1; int oldValue_4 =-1; int oldValue_5 =-1; int oldValue_6 =-1; void setup() { gw.begin(); for (int i=0; i<NUMBER_OF_ZONES;i++) { // Setup the button pinMode(ZONE_1+i,INPUT); // Activate internal pull-up digitalWrite(ZONE_1+i,HIGH); MyMessage msg(ZONE_1+i,V_TRIPPED); // After setting up the button, setup debouncer switch (1+i) { case 1: debouncer_1.attach(ZONE_1); debouncer_1.interval(5); break; case 2: debouncer_2.attach(ZONE_1+i); debouncer_2.interval(5); break; case 3: debouncer_3.attach(ZONE_1+i); debouncer_3.interval(5); break; case 4: debouncer_4.attach(ZONE_1+i); debouncer_4.interval(5); break; case 5: debouncer_5.attach(ZONE_1+i); debouncer_5.interval(5); break; } // Register binary input sensor to gw (they will be created as child devices) // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. // If S_LIGHT is used, remember to update variable type you send in. See "msg" above. gw.present(ZONE_1+i, S_DOOR); delay(1000); } } // Check if digital input has changed and send in new value void loop() { for (int i=0; i<NUMBER_OF_ZONES;i++) { int num = 1+i; // Get the update value switch (num) { case 1: { debouncer_1.update(); int value_1 = debouncer_1.read(); if (value_1 != oldValue_1) { // Send in the new value gw.send(msg.setSensor(ZONE_1+i).set(value_1==HIGH ? 1 : 0)); oldValue_1 = value_1; } break; } case 2: { debouncer_2.update(); int value_2 = debouncer_2.read(); if (value_2 != oldValue_2) { // Send in the new value gw.send(msg.setSensor(ZONE_1+i).set(value_2==HIGH ? 1 : 0)); oldValue_2 = value_2; } break; } case 3: { debouncer_3.update(); int value_3 = debouncer_3.read(); if (value_3 != oldValue_3) { // Send in the new value gw.send(msg.setSensor(ZONE_1+i).set(value_3==HIGH ? 1 : 0)); oldValue_3 = value_3; } break; } case 4: { debouncer_4.update(); int value_4 = debouncer_4.read(); if (value_4 != oldValue_4) { // Send in the new value gw.send(msg.setSensor(ZONE_1+i).set(value_4==HIGH ? 1 : 0)); oldValue_4 = value_4; } break; } case 5: { debouncer_5.update(); int value_5 = debouncer_5.read(); if (value_5 != oldValue_5) { // Send in the new value gw.send(msg.setSensor(ZONE_1+i).set(value_5==HIGH ? 1 : 0)); oldValue_5 = value_5; } break; } case 6: { debouncer_6.update(); int value_6 = debouncer_6.read(); if (value_6 != oldValue_6) { // Send in the new value gw.send(msg.setSensor(ZONE_1+i).set(value_6==HIGH ? 1 : 0)); oldValue_6 = value_6; } break; } } } }When I try to compile I get this error:
Arduino: 1.6.6 (Windows 7), Board: "Arduino/Genuino Uno" Warning: platform.txt from core 'MySensors AVR based boards' contains deprecated recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{build.path}/{archive_file}" "{object_file}", automatically converted to recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}". Consider upgrading this core. WARNING: Category '' in library UIPEthernet is not valid. Setting to 'Uncategorized' C:\Users\User\Documents\Arduino\alarm\alarm.ino: In function 'void loop()': alarm:118: error: 'msg' was not declared in this scope gw.send(msg.setSensor(ZONE_1+i).set(value_1==HIGH ? 1 : 0)); ^ alarm:129: error: 'msg' was not declared in this scope gw.send(msg.setSensor(ZONE_1+i).set(value_2==HIGH ? 1 : 0)); ^ alarm:140: error: 'msg' was not declared in this scope gw.send(msg.setSensor(ZONE_1+i).set(value_3==HIGH ? 1 : 0)); ^ alarm:151: error: 'msg' was not declared in this scope gw.send(msg.setSensor(ZONE_1+i).set(value_4==HIGH ? 1 : 0)); ^ alarm:162: error: 'msg' was not declared in this scope gw.send(msg.setSensor(ZONE_1+i).set(value_5==HIGH ? 1 : 0)); ^ alarm:173: error: 'msg' was not declared in this scope gw.send(msg.setSensor(ZONE_1+i).set(value_6==HIGH ? 1 : 0)); ^ exit status 1 'msg' was not declared in this scopeI'm guessing it's a syntax error but I'm having trouble trying to format it correctly. I'm a hacker not a programmer so any help would be most appreciated! Thanks
-
Hi,
I think that your problem is that you are using a "variable" (msg) that you never declare.
C++ requires that every variable used MUST have a type and be declared in advance.
Inserting a declaration:MyMessage msg;
should fix your problem. Let us know.
Ciao
-
Thanks for the advice. I did have the variable declared as:
MyMessage msg(ZONE_1+i,V_TRIPPED);but it's quite possible that I'm doing that wrong. I tried changing it to your version and I get the same error.
I'm very excited to get this working but am so in the dark when it comes to actual programming. I appreciate any help you guys can give to get this thing running finally.
-
You are declaring msg inside a for loop. It will not live outside the scope of that for loop. You need to declare it globally (=outside any function) to make it available inside the loop() and setup() functions.
Since you are using multiple messages, an array makes sense. See line 20 in this code
for an example.
You can convert the debouncer_Ns and oldvalue_Ns to arrays in a similar manner, making your code much neater (no need for the long switch statement for example). -
Thank you for taking the time to help. Unfortunately I'm more of hacker than a programmer. I understand what you are saying about making the message a global, but I don't know exactly how to accomplish it. I tried to just force it like this:
MyMessage msg(1,V_TRIPPED); MyMessage msg(2,V_TRIPPED); MyMessage msg(3,V_TRIPPED); MyMessage msg(4,V_TRIPPED); MyMessage msg(5,V_TRIPPED); MyMessage msg(6,V_TRIPPED);but that did not work. Also, I do understand using an array would clean things up a bit but I'd like to get it working in this basic format first then work on refining it. Thanks again.
-
Thanks for the help again. I think I have something working. Could definitely use some help cleaning it up though:
#include <SPI.h> #include <MySensor.h> #include <Bounce2.h> #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) #define SLEEP_TIME 600000 // Sleep time between reads (in milliseconds) #define STABILIZATION_TIME 500 // Let the sensor stabilize 0.5 seconds before reading const int SENSORS[] = {3,4,5,6,7,8}; // Remove the pins that you don't want to use #define N_ELEMENTS(array) (sizeof(array)/sizeof((array)[0])) MySensor gw; Bounce debouncer_1 = Bounce(); Bounce debouncer_2 = Bounce(); Bounce debouncer_3 = Bounce(); Bounce debouncer_4 = Bounce(); Bounce debouncer_5 = Bounce(); Bounce debouncer_6 = Bounce(); int oldValue_1 =-1; int oldValue_2 =-1; int oldValue_3 =-1; int oldValue_4 =-1; int oldValue_5 =-1; int oldValue_6 =-1; MyMessage button_messages[N_ELEMENTS(SENSORS)]; void setup() { gw.begin(); for (int sensor = 0; sensor < N_ELEMENTS(SENSORS); sensor++) { button_messages[sensor].sensor = sensor + 1; // Battery uses child ID 0 so sensors start at 1 button_messages[sensor].type = V_TRIPPED; delay(250); gw.present(sensor + 1, S_DOOR); } for (int i = 0; i < N_ELEMENTS(SENSORS); i++) { pinMode(SENSORS[i], INPUT); digitalWrite(SENSORS[i], HIGH); switch (1+i) { case 1: debouncer_1.attach(SENSORS[i]); debouncer_1.interval(5); break; case 2: debouncer_2.attach(SENSORS[i]); debouncer_2.interval(5); break; case 3: debouncer_3.attach(SENSORS[i]); debouncer_3.interval(5); break; case 4: debouncer_4.attach(SENSORS[i]); debouncer_4.interval(5); break; case 5: debouncer_5.attach(SENSORS[i]); debouncer_5.interval(5); break; case 6: debouncer_6.attach(SENSORS[i]); debouncer_6.interval(5); break; } } } void loop() { for (int sensor = 0; sensor < N_ELEMENTS(SENSORS); sensor++) { int num = 1+sensor; // Get the update value switch (num) { case 1: { debouncer_1.update(); int value_1 = debouncer_1.read(); if (value_1 != oldValue_1) { // Send in the new value gw.send(button_messages[sensor].set(value_1==HIGH ? 1 : 0)); Serial.print("Switch 1="); Serial.println(value_1); oldValue_1 = value_1; } break; } case 2: { debouncer_2.update(); int value_2 = debouncer_2.read(); if (value_2 != oldValue_2) { // Send in the new value gw.send(button_messages[sensor].set(value_2==HIGH ? 1 : 0)); Serial.print("Switch 2="); Serial.println(value_2); oldValue_2 = value_2; } break; } case 3: { debouncer_3.update(); int value_3 = debouncer_3.read(); if (value_3 != oldValue_3) { // Send in the new value gw.send(button_messages[sensor].set(value_3==HIGH ? 1 : 0)); Serial.print("Switch 3="); Serial.println(value_3); oldValue_3 = value_3; } break; } case 4: { debouncer_4.update(); int value_4 = debouncer_4.read(); if (value_4 != oldValue_4) { // Send in the new value gw.send(button_messages[sensor].set(value_4==HIGH ? 1 : 0)); Serial.print("Switch 4="); Serial.println(value_4); oldValue_4 = value_4; } break; } case 5: { debouncer_5.update(); int value_5 = debouncer_5.read(); if (value_5 != oldValue_5) { // Send in the new value gw.send(button_messages[sensor].set(value_5==HIGH ? 1 : 0)); Serial.print("Switch 5="); Serial.println(value_5); oldValue_5 = value_5; } break; } case 6: { debouncer_6.update(); int value_6 = debouncer_6.read(); if (value_6 != oldValue_6) { // Send in the new value gw.send(button_messages[sensor].set(value_6==HIGH ? 1 : 0)); Serial.print("Switch 6="); Serial.println(value_6); oldValue_6 = value_6; } break; } } } } -
That would be great. Thanks for the push in the right direction.. I'm about to connect it to the alarm wires!
-
Something like this should work. Note: I haven't tested the code, but it compiles and I think it does the same as your old code.
#include <SPI.h> #include <MySensor.h> #include <Bounce2.h> #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) const int SENSORS[] = {3, 4, 5, 6, 7, 8}; // Remove the pins that you don't want to use #define N_ELEMENTS(array) (sizeof(array)/sizeof((array)[0])) MySensor gw; Bounce debouncers[N_ELEMENTS(SENSORS)]; int oldValues[N_ELEMENTS(SENSORS)]; MyMessage button_messages[N_ELEMENTS(SENSORS)]; void setup() { gw.begin(); for (int sensor = 0; sensor < N_ELEMENTS(SENSORS); sensor++) { debouncers[sensor] = Bounce(); oldValues[sensor] = -1; button_messages[sensor].sensor = sensor + 1; // Battery uses child ID 0 so sensors start at 1 button_messages[sensor].type = V_TRIPPED; delay(250); gw.present(sensor + 1, S_DOOR); pinMode(SENSORS[sensor], INPUT); digitalWrite(SENSORS[sensor], HIGH); debouncers[sensor].attach(SENSORS[sensor]); debouncers[sensor].interval(5); } } void loop() { for (int sensor = 0; sensor < N_ELEMENTS(SENSORS); sensor++) { int num = 1 + sensor; debouncers[num].update(); int value = debouncers[num].read(); if (value != oldValues[num]) { // Send in the new value gw.send(button_messages[sensor].set(value == HIGH ? 1 : 0)); Serial.print("Switch "); Serial.print(num); Serial.print(" ="); Serial.println(value); oldValues[num] = value; } } } -
Much cleaner! I'll give it a go soon. Thanks for all the help!