Need some help with a Multi-Sensor Node
-
Hi,
I'm working on making a multi-sensornode (PIR, Light, Temp and V_LIGHT (for night-light)), as well as a repeater node. So far though, I am having problems with the system reporting all the variables every second, instead of on change/every 10 seconds like I have in my sketch. I'm not sure where I am going wrong,. I need the device to only report changes, specifically on motion when it is detected, as well as to receive the V_STATUS message. Would someone please look over this and point me in the right direction? I've been looking at this off and on for a while now and I can't find anything that is majorly wrong.
/** * The MySensors Arduino library handles the wireless radio link and protocol * between your home built sensors/actuators and HA controller of choice. * The sensors forms a self healing radio network with optional repeaters. Each * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * * Created by Henrik Ekblad <henrik.ekblad@mysensors.org> * Copyright (C) 2013-2015 Sensnology AB * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors * * Documentation: http://www.mysensors.org * Support Forum: http://forum.mysensors.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * ******************************* * * REVISION HISTORY * Version 1.0 - Derrick Rockwell (@Drock1985) * * DESCRIPTION * * */ // Enable debug prints #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 #define MY_NODE_ID 21 #include <SPI.h> #include <MySensors.h> #include <DallasTemperature.h> #include <OneWire.h> #include <BH1750.h> #include <Wire.h> unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds) #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No #define ONE_WIRE_BUS 4 // Pin where dallase sensor is connected #define LED_ARRAY_1 5 // Pin that controls the LED Light array (does not need to be a PWM pin) #define LED_ARRAY_2 6 #define MAX_ATTACHED_DS18B20 2 // #define MY_REPEATER_FEATURE //Enables Repeater feature for non-battery powered nodes. OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. int lastTemperature = 0; int numSensors=0; boolean receivedConfig = false; boolean metric = true; #define CHILD_ID_MOTION 1 // ID of the sensor child #define CHILD_ID_TEMP 2 // ID of Temperature Sensor #define CHILD_ID_LUX 3 // ID of Lux Sensor #define CHILD_ID_LIGHT 4 // ID of LED light array #define LIGHT_ON 1 #define LIGHT_OFF 0 BH1750 lightSensor; // Initialize messages MyMessage msgMotion(CHILD_ID_MOTION, V_TRIPPED); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); MyMessage msgLux(CHILD_ID_LUX, V_LEVEL); //Sets up custom units (this case LUX for Light) MyMessage msgPrefix(CHILD_ID_LUX, V_UNIT_PREFIX); // Sends controller the LUX value instead of % MyMessage msgLight(CHILD_ID_LIGHT, V_STATUS); uint16_t lastlux = 0; int compareMotion = LOW; bool stateLight = 0; // Place holders for the loop function to register nodes in Home-Assistant bool initialValueSentLight = 0; void setup() { pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input pinMode(LED_ARRAY_1, OUTPUT); // sets the LED Array as an output pinMode(LED_ARRAY_2, OUTPUT); // sets the LED Array as an output lightSensor.begin(); // Startup up the OneWire library sensors.begin(); // requestTemperatures() will not block current thread sensors.setWaitForConversion(false); send(msgPrefix.set("lux")); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("LuxMotionTempSensor", "1.0"); // Register all sensors to gw (they will be created as child devices) present(CHILD_ID_MOTION, S_MOTION); wait(150); present(CHILD_ID_TEMP, S_TEMP); wait(150); present(CHILD_ID_LUX, S_LIGHT_LEVEL); wait(150); present(CHILD_ID_LIGHT, S_LIGHT); } void loop() { if (!initialValueSentLight) { Serial.println("Sending initial value"); send(msgLight.set(stateLight?LIGHT_ON:LIGHT_OFF)); Serial.println("Requesting initial value from controller"); request(CHILD_ID_LIGHT, V_STATUS); wait(2000, C_SET, V_STATUS); } { uint16_t lux = lightSensor.readLightLevel();// Get Lux value if (lux != lastlux) { Serial.println(lux); Serial.println("Sending lux value"); send(msgLux.set(lux)); send(msgPrefix.set("lux")); lastlux = lux; } } // Fetch temperatures from Dallas sensors sensors.requestTemperatures(); // Fetch and round temperature to one decimal int temperature = (((sensors.getTempCByIndex(0)) * 10.)) / 10.; if (lastTemperature != temperature && temperature != -127.00 && temperature != 85.00) Serial.println(temperature); Serial.println("Sending temperature");{ // Send in the new temperature send(msgTemp.set(temperature)); // Save new temperatures for next compare lastTemperature = temperature; } // Read digital motion value boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; // if (compareMotion != tripped) { Serial.println("Sending motion status"); Serial.println(tripped); send(msgMotion.set(tripped?"1":"0")); // Send tripped value to gw // compareMotion = tripped; // } // sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME); } void receive(const MyMessage &message) { if (message.isAck()) { Serial.println("This is an ack from gateway"); } if (message.type == V_STATUS && message.sensor == CHILD_ID_LIGHT) { if (!initialValueSentLight) { Serial.println("Receiving initial value from controller"); initialValueSentLight = true; } // Change relay state stateLight = (bool)message.getInt(); digitalWrite(LED_ARRAY_1, stateLight?LIGHT_ON:LIGHT_OFF); digitalWrite(LED_ARRAY_2, stateLight?LIGHT_ON:LIGHT_OFF); send(msgLight.set(stateLight?LIGHT_ON:LIGHT_OFF)); } }Thanks,
-
Hi,
I'm working on making a multi-sensornode (PIR, Light, Temp and V_LIGHT (for night-light)), as well as a repeater node. So far though, I am having problems with the system reporting all the variables every second, instead of on change/every 10 seconds like I have in my sketch. I'm not sure where I am going wrong,. I need the device to only report changes, specifically on motion when it is detected, as well as to receive the V_STATUS message. Would someone please look over this and point me in the right direction? I've been looking at this off and on for a while now and I can't find anything that is majorly wrong.
/** * The MySensors Arduino library handles the wireless radio link and protocol * between your home built sensors/actuators and HA controller of choice. * The sensors forms a self healing radio network with optional repeaters. Each * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * * Created by Henrik Ekblad <henrik.ekblad@mysensors.org> * Copyright (C) 2013-2015 Sensnology AB * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors * * Documentation: http://www.mysensors.org * Support Forum: http://forum.mysensors.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * ******************************* * * REVISION HISTORY * Version 1.0 - Derrick Rockwell (@Drock1985) * * DESCRIPTION * * */ // Enable debug prints #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 #define MY_NODE_ID 21 #include <SPI.h> #include <MySensors.h> #include <DallasTemperature.h> #include <OneWire.h> #include <BH1750.h> #include <Wire.h> unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds) #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No #define ONE_WIRE_BUS 4 // Pin where dallase sensor is connected #define LED_ARRAY_1 5 // Pin that controls the LED Light array (does not need to be a PWM pin) #define LED_ARRAY_2 6 #define MAX_ATTACHED_DS18B20 2 // #define MY_REPEATER_FEATURE //Enables Repeater feature for non-battery powered nodes. OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. int lastTemperature = 0; int numSensors=0; boolean receivedConfig = false; boolean metric = true; #define CHILD_ID_MOTION 1 // ID of the sensor child #define CHILD_ID_TEMP 2 // ID of Temperature Sensor #define CHILD_ID_LUX 3 // ID of Lux Sensor #define CHILD_ID_LIGHT 4 // ID of LED light array #define LIGHT_ON 1 #define LIGHT_OFF 0 BH1750 lightSensor; // Initialize messages MyMessage msgMotion(CHILD_ID_MOTION, V_TRIPPED); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); MyMessage msgLux(CHILD_ID_LUX, V_LEVEL); //Sets up custom units (this case LUX for Light) MyMessage msgPrefix(CHILD_ID_LUX, V_UNIT_PREFIX); // Sends controller the LUX value instead of % MyMessage msgLight(CHILD_ID_LIGHT, V_STATUS); uint16_t lastlux = 0; int compareMotion = LOW; bool stateLight = 0; // Place holders for the loop function to register nodes in Home-Assistant bool initialValueSentLight = 0; void setup() { pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input pinMode(LED_ARRAY_1, OUTPUT); // sets the LED Array as an output pinMode(LED_ARRAY_2, OUTPUT); // sets the LED Array as an output lightSensor.begin(); // Startup up the OneWire library sensors.begin(); // requestTemperatures() will not block current thread sensors.setWaitForConversion(false); send(msgPrefix.set("lux")); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("LuxMotionTempSensor", "1.0"); // Register all sensors to gw (they will be created as child devices) present(CHILD_ID_MOTION, S_MOTION); wait(150); present(CHILD_ID_TEMP, S_TEMP); wait(150); present(CHILD_ID_LUX, S_LIGHT_LEVEL); wait(150); present(CHILD_ID_LIGHT, S_LIGHT); } void loop() { if (!initialValueSentLight) { Serial.println("Sending initial value"); send(msgLight.set(stateLight?LIGHT_ON:LIGHT_OFF)); Serial.println("Requesting initial value from controller"); request(CHILD_ID_LIGHT, V_STATUS); wait(2000, C_SET, V_STATUS); } { uint16_t lux = lightSensor.readLightLevel();// Get Lux value if (lux != lastlux) { Serial.println(lux); Serial.println("Sending lux value"); send(msgLux.set(lux)); send(msgPrefix.set("lux")); lastlux = lux; } } // Fetch temperatures from Dallas sensors sensors.requestTemperatures(); // Fetch and round temperature to one decimal int temperature = (((sensors.getTempCByIndex(0)) * 10.)) / 10.; if (lastTemperature != temperature && temperature != -127.00 && temperature != 85.00) Serial.println(temperature); Serial.println("Sending temperature");{ // Send in the new temperature send(msgTemp.set(temperature)); // Save new temperatures for next compare lastTemperature = temperature; } // Read digital motion value boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; // if (compareMotion != tripped) { Serial.println("Sending motion status"); Serial.println(tripped); send(msgMotion.set(tripped?"1":"0")); // Send tripped value to gw // compareMotion = tripped; // } // sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME); } void receive(const MyMessage &message) { if (message.isAck()) { Serial.println("This is an ack from gateway"); } if (message.type == V_STATUS && message.sensor == CHILD_ID_LIGHT) { if (!initialValueSentLight) { Serial.println("Receiving initial value from controller"); initialValueSentLight = true; } // Change relay state stateLight = (bool)message.getInt(); digitalWrite(LED_ARRAY_1, stateLight?LIGHT_ON:LIGHT_OFF); digitalWrite(LED_ARRAY_2, stateLight?LIGHT_ON:LIGHT_OFF); send(msgLight.set(stateLight?LIGHT_ON:LIGHT_OFF)); } }Thanks,