3 in 1 incl battery monitor
-
@the-cosmic-gate The reason to group all the "gw.send" instructions together (at the end of the sketch) is that the radio can "sleep" during the temperature and humidity readings. There are many ways (other than HW) to save battery power, like: only send values when a certain threshold is exceeded, decrease update frequency etc.
Just an example for a sensor which uses 11 uA in idle and sends updates only when needed (including a once in a hour 'heartbeat' of all sensors).
/* PROJECT: MySensors / Small battery sensor low power 1 mhz PROGRAMMER: AWI DATE: november 4, 2015/ last update: december 4, 2015 FILE: AWI small THM.ino LICENSE: Public domain Hardware: ATMega328p board w/ NRF24l01 and MySensors 1.6 (Development) Special: program with Arduino Pro 3.3V 1Mhz!!! Summary: low power (battery) HTU21 Temp/Hum & Motion (interrupt) voltage meter for battery (internal) Remarks: Fixed node-id Change log: 20151204 - made it universal with respect to node id, only change first 2 lines */ // Enable debug prints to serial monitor #define MY_NODE_ID 19 #define NODE_TXT "THM 19" // Text to add to sensor name #define MY_DEBUG #define MY_RADIO_NRF24 // Enable and select radio type attached #include <SPI.h> #include <MySensor.h> #include <Wire.h> // I2C #include <HTU21D.h> // temperature / humidity (i2c, HTU21D, SHT21) #include <Vcc.h> // library for internal reference Vcc reading #undef MY_DEBUG // turns of MySensors Serial debug (default on) // Reference values for ADC and Battery measurements const float VccMin = 1.0*2.5 ; // Minimum expected Vcc level, in Volts. Example for 1 rechargeable lithium-ion. const float VccMax = 1.0*3.0 ; // Maximum expected Vcc level, in Volts. //const float VccMin = 2.0*0.6 ; // Minimum expected Vcc level, in Volts. for 2xAA Alkaline. //const float VccMax = 2.0*1.5 ; // Maximum expected Vcc level, in Volts.for 2xAA Alkaline. const float VccCorrection = 3.30/3.42 ; // Measured Vcc by multimeter divided by reported Vcc Vcc vcc(VccCorrection); // instantiate internal voltage measurement lib const float tempThreshold = 0.02 ; // send only if change > treshold (Celcius) const float humThreshold = 0.05 ; // send only if change > treshold (% RG) const float voltageThreshold = 0.01 ; // send only if change > treshold (Volt) #define MOTION_CHILD_ID 1 #define TEMP_CHILD_ID 3 #define HUM_CHILD_ID 4 #define VOLTAGE_CHILD_ID 7 #define DIGITAL_INPUT_SENSOR 3 // motion sensor. (Only 2 and 3 generates interrupt!) #define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 HTU21D SHT21; // Hum/Temp (SHT12) const unsigned long SLEEP_TIME = 60000UL; // 60 sec sleep time between reads (seconds * 1000 milliseconds) const int heartbeat = 60 ; // heartbeat every hour (x times SLEEP_TIME) unsigned long lastHeartbeat = 0 ; float lastHumidity = 0 ; float lastTemperature = 0 ; float lastVoltage = 0 ; boolean lastTripped = false ; // flags to indicate if transmission is needed, heartbeat and/or changes > treshold boolean txHumidity = true ; // flags to indicate if transmit is needed (time & change driven) boolean txTemperature = true ; boolean txVoltage = true ; boolean txTripped = true ; // standard messages MyMessage temperatureMsg(TEMP_CHILD_ID, V_TEMP); // SHT temp MyMessage humidityMsg(HUM_CHILD_ID, V_HUM); // SHT hum MyMessage voltageMsg(VOLTAGE_CHILD_ID, V_VOLTAGE); // Node voltage MyMessage motionMsg(MOTION_CHILD_ID, V_TRIPPED); // Motion/ door contact void setup() { analogReference(INTERNAL); // use the 1.1 V internal reference for voltage measurement //begin(NULL, nodeId); // fixed node Serial.begin(9600); // reset baud rate for 1 mhz clock rate // Send the sketch version information to the gateway and Controller sendSketchInfo("AWI small " NODE_TXT, "1.0"); present(TEMP_CHILD_ID, S_TEMP, "Temperature SHT " NODE_TXT); present(HUM_CHILD_ID, S_HUM, "Humidity SHT " NODE_TXT); present(VOLTAGE_CHILD_ID, S_MULTIMETER, "Battery " NODE_TXT); present(MOTION_CHILD_ID, S_MOTION, "Motion " NODE_TXT); pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input Wire.begin(); // init I2C SHT21.begin(); // initialize temp/hum } void loop() { // first read all sensors before possible transmission (save battery) readTempHum(); // Read digital motion value boolean tripped = false ;//digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; if (lastTripped != tripped){ lastTripped = tripped ; txTripped = true ; } // read battery Voltage float voltage = vcc.Read_Volts() ; if ( abs(voltage - lastVoltage) >= voltageThreshold ){ // update only if threshold exceeded lastVoltage = voltage ; txVoltage = true ; } sendSensors() ; // send sensors (== radio) at the end sleep(INTERRUPT, CHANGE , SLEEP_TIME ); // sleep and wait for time and motion } void readTempHum(void) { // SHT2x sensor // Temperature and Humidity float humidity = SHT21.readHumidity(); float temperature = SHT21.readTemperature(); // save battery by sending changes only & reading SHT first (>50ms) if ( abs(humidity - lastHumidity) >= humThreshold ){ // update only if threshold exceeded lastHumidity = humidity ; txHumidity = true ; } if ( abs(temperature - lastTemperature) >= tempThreshold ){ lastTemperature = temperature ; txTemperature = true ; } // Serial.print("SHT_ temp: "); // Serial.print(temperatureSHT); // Serial.print(" SHT_ hum: "); // Serial.println(humidity); } // send to gateway depending on tx.. settings void sendSensors() { lastHeartbeat++ ; // update Heartbeatcount every call if ( lastHeartbeat > heartbeat) { // if heartbeat update all sensors & battery status txTemperature = txHumidity = txVoltage = true ; sendBatteryLevel(vcc.Read_Perc(VccMin, VccMax, true)); lastHeartbeat = 0 ; } if (txTemperature){ send(temperatureMsg.set(lastTemperature, 2)); // Send in deg C txTemperature = false ; } if (txHumidity){ send(humidityMsg.set(lastHumidity, 2)); // Send in %RH txHumidity = false ; } if (txVoltage){ send(voltageMsg.set(lastVoltage,2)); //send battery in Volt txVoltage = false ; } if (txTripped){ send(motionMsg.set(lastTripped?"1":"0")); // Send tripped value to gw txTripped = false ; } }
-
I'am not getting this clear / working
Could somebody help me to complete this 3in1 incl battery monitoring sketch working? Thnx
-
What does your serial or error log tell you when you upload the sketch you have? And which sketch/code do you use at this point?
-
I changed your original sketch a little. It now includes a conditional send for the "tripped" values and groups the conditional sends for all values.
I was not able to test as I'm using a different library for the DHT.
Have fun..
#include <SPI.h> #include <MySensor.h> #include <DHT.h> int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point #define CHILD_ID_HUM 0 #define CHILD_ID_TEMP 1 #define CHILD_ID_MOT 2 // Id of the sensor child #define HUMIDITY_SENSOR_DIGITAL_PIN 4 #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) #define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway) unsigned long SLEEP_TIME = 30000UL; // Sleep time between reads (in milliseconds) int oldBatteryPcnt = 0; MySensor gw; DHT dht; float lastTemp = 0 ; float lastHum = 0 ; boolean lastTripped = false ; boolean metric = true; MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); MyMessage msgMot(CHILD_ID_MOT, V_TRIPPED); void setup() { // use the 1.1 V internal reference #if defined(__AVR_ATmega2560__) analogReference(INTERNAL1V1); #else analogReference(INTERNAL); #endif gw.begin(); dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN. DHT22); // Send the Sketch Version Information to the Gateway gw.sendSketchInfo("Humidity/Motion", "1.0"); pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input // Register all sensors to gw (they will be created as child devices) gw.present(CHILD_ID_HUM, S_HUM); gw.present(CHILD_ID_TEMP, S_TEMP); gw.present(CHILD_ID_MOT, S_MOTION); metric = gw.getConfig().isMetric; } void loop() { // get the battery Voltage int sensorValue = analogRead(BATTERY_SENSE_PIN); #ifdef DEBUG Serial.println(sensorValue); #endif // 1M, 470K divider across battery and using internal ADC ref of 1.1V // Sense point is bypassed with 0.1 uF cap to reduce noise at that point // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts // 3.44/1023 = Volts per bit = 0.003363075 float batteryV = sensorValue * 0.003363075; int batteryPcnt = sensorValue / 10; #ifdef DEBUG Serial.print("Battery Voltage: "); Serial.print(batteryV); Serial.println(" V"); Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %"); #endif if (oldBatteryPcnt != batteryPcnt) { // Power up radio after sleep gw.sendBatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; } // Read digital motion value boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; if (tripped != lastTripped ) { Serial.println(tripped); gw.send(msgMot.set(tripped?"1":"0")); // Send tripped value to gw } delay(dht.getMinimumSamplingPeriod()); float temperature = dht.getTemperature(); float humidity = dht.getHumidity(); if (isnan(temperature)) { Serial.println("Failed reading temperature from DHT"); } else if (temperature != lastTemp) { lastTemp = temperature; if (!metric) { temperature = dht.toFahrenheit(temperature); } gw.send(msgTemp.set(temperature, 1)); Serial.print("T: "); Serial.println(temperature); } if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; gw.send(msgHum.set(humidity, 1)); Serial.print("H: "); Serial.println(humidity); } if (oldBatteryPcnt != batteryPcnt) { // Power up radio after sleep gw.sendBatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; } // Sleep until interrupt comes in on motion sensor. Send update every two minute. gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME); }
-
Thnx a lot @AWI
there was 1 verification error,dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN. DHT22);
changed it, to :
#include <SPI.h> #include <MySensor.h> #include <DHT.h> int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point #define CHILD_ID_HUM 0 #define CHILD_ID_TEMP 1 #define CHILD_ID_MOT 2 // Id of the sensor child #define HUMIDITY_SENSOR_DIGITAL_PIN 4 #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) #define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway) unsigned long SLEEP_TIME = 30000UL; // Sleep time between reads (in milliseconds) int oldBatteryPcnt = 0; MySensor gw; DHT dht; float lastTemp = 0 ; float lastHum = 0 ; boolean lastTripped = false ; boolean metric = true; MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); MyMessage msgMot(CHILD_ID_MOT, V_TRIPPED); void setup() { // use the 1.1 V internal reference #if defined(__AVR_ATmega2560__) analogReference(INTERNAL1V1); #else analogReference(INTERNAL); #endif gw.begin(); dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); // Send the Sketch Version Information to the Gateway gw.sendSketchInfo("Humidity/Motion", "1.0"); pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input // Register all sensors to gw (they will be created as child devices) gw.present(CHILD_ID_HUM, S_HUM); gw.present(CHILD_ID_TEMP, S_TEMP); gw.present(CHILD_ID_MOT, S_MOTION); metric = gw.getConfig().isMetric; } void loop() { // get the battery Voltage int sensorValue = analogRead(BATTERY_SENSE_PIN); #ifdef DEBUG Serial.println(sensorValue); #endif // 1M, 470K divider across battery and using internal ADC ref of 1.1V // Sense point is bypassed with 0.1 uF cap to reduce noise at that point // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts // 3.44/1023 = Volts per bit = 0.003363075 float batteryV = sensorValue * 0.003363075; int batteryPcnt = sensorValue / 10; #ifdef DEBUG Serial.print("Battery Voltage: "); Serial.print(batteryV); Serial.println(" V"); Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %"); #endif if (oldBatteryPcnt != batteryPcnt) { // Power up radio after sleep gw.sendBatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; } // Read digital motion value boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; if (tripped != lastTripped ) { Serial.println(tripped); gw.send(msgMot.set(tripped?"1":"0")); // Send tripped value to gw } delay(dht.getMinimumSamplingPeriod()); float temperature = dht.getTemperature(); float humidity = dht.getHumidity(); if (isnan(temperature)) { Serial.println("Failed reading temperature from DHT"); } else if (temperature != lastTemp) { lastTemp = temperature; if (!metric) { temperature = dht.toFahrenheit(temperature); } gw.send(msgTemp.set(temperature, 1)); Serial.print("T: "); Serial.println(temperature); } if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; gw.send(msgHum.set(humidity, 1)); Serial.print("H: "); Serial.println(humidity); } if (oldBatteryPcnt != batteryPcnt) { // Power up radio after sleep gw.sendBatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; } // Sleep until interrupt comes in on motion sensor. Send update every two minute. gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME); }
uploading now
-
working nice for 2 day's now !
Thnx a lot @AWI !!!
-
Something strange: when I look in the IDE console the battery % is displayed. But using Domoticz there's no battery % display / selectable ? What's wrong , or do I forget something ?
-
In Domoticz you can see the battery level in Setup->Devices.
If you would like to see on a chart, you have to send the battery level or voltage to the controller as a sensor value too. After it, you can see as this:
-
Hi, I'm a newbee just started with MySensors. I built the first temp/hum sensor, and I'm trying to plot the battery level in a graph too. In this discussion you mention that I need to send the battery level to the controller as sensor value. Can you please share with me the code which I should use? Thanks a lot.
Marco
-
Yes, I can.
This is the definition of message for battery level:
// Battery sensor (A0) #define CHILD_ID_BATTERY 199 #define BATTERY_SENSOR_ANALOG_PIN 0 MyMessage msgBattery(CHILD_ID_BATTERY, V_VOLTAGE);
And this is the sender function:
// 1M, 470K divider across battery and using internal ADC ref of 1.1V // Sense point is bypassed with 0.1 uF cap to reduce noise at that point // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts // 3.44/1023 = Volts per bit = 0.003363075 #define VBAT_PER_BITS 0.003363075 #define VMIN 1.9 // Battery monitor lower level. Vmin_radio=1.9V #define VMAX 3.00 // Vmin<Vmax<=3.44 #define VCC_CORRECTION (3.4 / 3.33) int lastBatteryLevel; bool sendBatteryLevel(bool force = false) { int value = analogRead(BATTERY_SENSOR_ANALOG_PIN); float batVoltage = value * VBAT_PER_BITS / VCC_CORRECTION; int batLevel = static_cast<int>(((batVoltage-VMIN)/(VMAX-VMIN))*100.); if (batLevel != lastBatteryLevel || force) { gw.sendBatteryLevel(batLevel); gw.send(msgBattery.set(batVoltage, 2)); lastBatteryLevel = batLevel; } return true; }```
-
Great, thanks for your quick response. Implementing now. Looks good.
-
Running the sketch for 1 Monty (+-), and the AA batteries are dead empty ?
I did all the "possible" mods on the arduino ( cut the LED an V ) , what can i do to make this sketch run langer on this 2AA batteries ?
Something in the sketch , some fine tuning or something else ?
When read the arduino hardware tweaking topics on different forums they dat that running for 1 year ( and more) is possible but how ;-)?
-
Hello,
Did you measured the current of your circuit ?
What motion sensor are you using ? This component may consume a lot of current. Did you check this post ?If you wake-up the arduino every 30 seconds for measurement it's a problem. Every 5 minutes is the minimum I think. I have connected the Vcc pin of the DHT sensors and the Vcc of the LDR to a digital pin of the arduino and when a measurement is done I set the PIN to the HIGH state.
First measurement of my sensor gives an IDLE current consumption close to 5uA which is really correct according to elements connected to the arduino (RFM69HW, DHT22 and LDR).
David.
-
Yes as Carlierd writes, it's important that the Arduino are controlling the voltage to the external components, like DHT.
I might have overlooked, but which component are you using for motion sensing? maybe this component is also power-hungry
-
@the-cosmic-gate Now I measured my dev circuit (Arduino Nano from China (cutted power led and desoldered regulator) + DHT22 + PIR + Battery measure resistor divider) and in gw.sleep (with 1 interrupt for PIR) the power comsumption is ~90uA.
It wakes up every minutes, measuring and sending (~100ms and 5 - 20mA).
So 100ms with 20mA and 59900ms with 0.09mA. The average current is 120uA and with 2 AA battery it is about 2 years.
-
@icebob,
whats that app you are using to do the battery calculations?
-
@icebob
100ms for measurement and transmission seems very small ! I am at approximately 1500ms.
Give me your secret now !!
-
@ericvdb http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2680&dDocName=en545243. It's specified for PIC, but I select SLEEP mode in every cycle, so I can use for any uC.
@carlierd: I have no extra secret. If I measure 3-4 sensor and every values is changed, the loop time is 100ms. Best case is 10-20ms (if every sensors is unchanged). I'm not using delay in the loop.
-
@icebob: It's true that as I used signing feature, transmission is longer ! and in order to increase a little bit more I send every measure even if they not changed. I will probably upgrade my sketch to add a one-hour message at minimum and do not transfer mesure without change !
-
@carlierd said:
Hello,
Did you measured the current of your circuit ?
What motion sensor are you using ? This component may consume a lot of current. Did you check this post ?If you wake-up the arduino every 30 seconds for measurement it's a problem. Every 5 minutes is the minimum I think. I have connected the Vcc pin of the DHT sensors and the Vcc of the LDR to a digital pin of the arduino and when a measurement is done I set the PIN to the HIGH state.
First measurement of my sensor gives an IDLE current consumption close to 5uA which is really correct according to elements connected to the arduino (RFM69HW, DHT22 and LDR).
David.
Hello David,
I tried to meassure , but didn't have the right stuff to do this good enough.
The parts i use for this "project": DHT-22 (connected to D4), HC-SR501 (connected to D3)and connected to the 3.3V pin post , the VVC is connected to the VVC of the arduino pro mini 8 Mhz /3.3 V .
And use the sketch as above:#include <SPI.h> #include <MySensor.h> #include <DHT.h> int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point #define CHILD_ID_HUM 0 #define CHILD_ID_TEMP 1 #define CHILD_ID_MOT 2 // Id of the sensor child #define HUMIDITY_SENSOR_DIGITAL_PIN 4 #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) #define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway) unsigned long SLEEP_TIME = 30000UL; // Sleep time between reads (in milliseconds) int oldBatteryPcnt = 0; MySensor gw; DHT dht; float lastTemp = 0 ; float lastHum = 0 ; boolean lastTripped = false ; boolean metric = true; MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); MyMessage msgMot(CHILD_ID_MOT, V_TRIPPED); void setup() { // use the 1.1 V internal reference #if defined(__AVR_ATmega2560__) analogReference(INTERNAL1V1); #else analogReference(INTERNAL); #endif gw.begin(); dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); // Send the Sketch Version Information to the Gateway gw.sendSketchInfo("Humidity/Motion", "1.0"); pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input // Register all sensors to gw (they will be created as child devices) gw.present(CHILD_ID_HUM, S_HUM); gw.present(CHILD_ID_TEMP, S_TEMP); gw.present(CHILD_ID_MOT, S_MOTION); metric = gw.getConfig().isMetric; } void loop() { // get the battery Voltage int sensorValue = analogRead(BATTERY_SENSE_PIN); #ifdef DEBUG Serial.println(sensorValue); #endif // 1M, 470K divider across battery and using internal ADC ref of 1.1V // Sense point is bypassed with 0.1 uF cap to reduce noise at that point // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts // 3.44/1023 = Volts per bit = 0.003363075 float batteryV = sensorValue * 0.003363075; int batteryPcnt = sensorValue / 10; #ifdef DEBUG Serial.print("Battery Voltage: "); Serial.print(batteryV); Serial.println(" V"); Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %"); #endif if (oldBatteryPcnt != batteryPcnt) { // Power up radio after sleep gw.sendBatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; } // Read digital motion value boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; if (tripped != lastTripped ) { Serial.println(tripped); gw.send(msgMot.set(tripped?"1":"0")); // Send tripped value to gw } delay(dht.getMinimumSamplingPeriod()); float temperature = dht.getTemperature(); float humidity = dht.getHumidity(); if (isnan(temperature)) { Serial.println("Failed reading temperature from DHT"); } else if (temperature != lastTemp) { lastTemp = temperature; if (!metric) { temperature = dht.toFahrenheit(temperature); } gw.send(msgTemp.set(temperature, 1)); Serial.print("T: "); Serial.println(temperature); } if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; gw.send(msgHum.set(humidity, 1)); Serial.print("H: "); Serial.println(humidity); } if (oldBatteryPcnt != batteryPcnt) { // Power up radio after sleep gw.sendBatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; } // Sleep until interrupt comes in on motion sensor. Send update every two minute. gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME); }
So how do you connect the DHT / SR501 to the digital pin, and what's the sketch you're using ?
-
Hello,
You need to power the motion sensor all time as you want to detect any mouvement and not only every 2 minutes.
Caution, in your sketch, the battery level is sent at the beginning and at the end.
Did you tweak the motion sensor ?? Not tested yet but it seems that modification could (must ?) be done to reduce power consumption (LINK).
Why do you wake-up the arduino every 30 seconds ? For temperature, every 5 or 15 minutes is enough.
-
@icebob: is you motion sensor often triggered ? I mean, is the sensor placed somewhere where there is a lot of mouvement ? I tried to do such sensor some months ago but my sensors was very often triggered on finally the time is sleep was small and my battery decreased very quickly !
-
Currently I'm developing my boards, so there is no live device/sensor in my home. But in the future I plan to make a custom controller, and it will turn on/off the PIR sensors on the nodes, depending on the house is armed or not. So if I'm at home, PIR sensor won't watching. (It's just a plan for the present)
-
I am new in this forum so may be what I will tell here is posted already somewhere else.
Firstly I would measure the battery voltage at the end after sending some values to see the voltage after some stress. Often it is the case for a nearly empty battery that it shows a relaxed high voltage after a long sleep and the break down on some stress. I think it is better to measure the lower level.
Secondly for a motion sensor I would implement a wakeup on a pin change interrupt. As a stand-alone sensor this would be optimal for battery life time. In combination the other components you can use a large cycle time for getting temperature humidity and so on and for the motion sensor you get an intermediate interrupt on demand. If those event are too often for your desire, you can check it against time or count of last event and go back to sleep without sending.
-
@carlierd said:
Hello,
You need to power the motion sensor all time as you want to detect any mouvement and not only every 2 minutes.
Caution, in your sketch, the battery level is sent at the beginning and at the end.
Did you tweak the motion sensor ?? Not tested yet but it seems that modification could (must ?) be done to reduce power consumption (LINK).
Why do you wake-up the arduino every 30 seconds ? For temperature, every 5 or 15 minutes is enough.
Sure i modded the motion sensor as shown in the hyperlink , modded it this way :
I don't know why i wake-up this arduino every 30 seconds, the sketch was fabricated by combine 2 or 3 other sketches to this one ( with help from @AWI )
So if there are some tweaking thing to do, do not hesitate and change the sketch as you think it must be@icebob what's the sketch you using /testing ?
-
@the-cosmic-gate No specific reason to have a 30 second interval. You can just change the SLEEP_TIME to whatever eg. 5 minutes == 300000UL. The pin change interrupt is present in the code..
gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME);
-
@icebob could you share us you're code ?
-
@the-cosmic-gate sorry, I'm working a big complex sketch, I can't share my code currently.
-
@icebob said:
@the-cosmic-gate sorry, I'm working a big complex sketch, I can't share my code currently.
Big and complex sounds interesting
Could you maybe share us a sneak peak
-
@the-cosmic-gate Nothing special. I made a big sketch, which contains 7-8 sensors (DHT, Si7021, MQ-2/9, PIR, Door magnet, Light, battery) reading code because I would like to upload the same sketch to all nodes and configurate it on controller side, which sensors is on the node and need to read.
But currently I reached the limit with I2C includes, so I need to think over this solution.
-
@the-cosmic-gate Did you solved your power consumption issue ?
-
@carlierd said:
@the-cosmic-gate Did you solved your power consumption issue ?
Not yet, this because we moved to oneother house and didn't have the time now .
Also i had to disconnect and reconect all te sensors and domotica in this new house
-
I just finished my first motion sensor node and the power consumption in idle is about 75uA. Could be better but not too bad
The only thing is that the range is a little bit low for good detection. It's between 1 and 3 meters ...David.
-
@carlierd said:
I just finished my first motion sensor node and the power consumption in idle is about 75uA. Could be better but not too bad
The only thing is that the range is a little bit low for good detection. It's between 1 and 3 meters ...David.
Hello David
Could you share what and how ?
Thnx
-
And how is this sensor acting?
This is what i am looking for..
How lang can this sensor work? [ i wil try this with a 9Volt battery with a nano ]
What battery do you use?
-
Hello,
This is the code I use but it's not perfect especially with the battery report.
The principle is as follow when the sensor start:
- node in sleep mode with interrupt enable
- if a move is detected, the detection is reported to the gateway
- the node then go in sleep mode WITHOUT interrupt for 5 minutes
- then the node return to sleep mode with interrupt enable
This is to avoid having many report (and power consumption) to the gateway.
The code (not perfect ! I have to rework on it but it's ok for the moment):
/** * 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. * */ /**************************************************************************************/ /* Motion sensor. */ /* */ /* Version : 1.1.5 */ /* Date : 30/01/2016 */ /* Modified by : David Carlier */ /**************************************************************************************/ /* --------------- */ /* RST | | A5 */ /* RX | | A4 */ /* TX | ARDUINO | A3 */ /* RFM69 (DIO0) --------- D2 | UNO | A2 */ /* Motion --------- D3 | | A1 */ /* Power --------- D4 | ATMEGA 328p | A0 */ /* +3v --------- VCC | | GND --------- GND */ /* GND --------- GND | 8MHz int. | REF */ /* OSC | | VCC --------- +3v */ /* OSC | | D13 --------- RFM69 (SCK) */ /* D5 | | D12 --------- RFM69 (MISO) */ /* D6 | | D11 --------- RFM69 (MOSI) */ /* D7 | | D10 --------- RFM69 (NSS) */ /* D8 | | D9 */ /* --------------- */ /* */ /* +3v = 2*AA */ /* */ /**************************************************************************************/ #include <SPI.h> #include <MySensor.h> #include <MyTransportRFM69.h> #include <MySigningAtsha204Soft.h> //Constants #define SKETCH_NAME "Motion Sensor" #define SKETCH_VERSION "1.1.5" #define CHILD_ID 0 #define CHILD_ID_VOLTAGE 1 #define DIGITAL_INPUT_SENSOR 3 #define BATTERY_REPORT_CYCLE 4 //Report each hour (4 * 15') //Misc. variables uint8_t switchState = 2; unsigned long SLEEP_TIME = 820000; // Sleep time between reads (in milliseconds) (close to 15') unsigned long SLEEP_TIME2 = 275000; // Sleep time after int. (in milliseconds) (close to 5') uint8_t cycleInProgress = 0; uint8_t firstReportDone = 0; uint8_t firstReportWithZeroDone = 0; //Construct MySensors library MySigningAtsha204Soft signer; MyHwATMega328 hw; MyTransportRFM69 transport; MySensor node(transport, hw, signer); MyMessage msgSwitch(CHILD_ID, V_TRIPPED); MyMessage msgVolt(CHILD_ID_VOLTAGE, V_VOLTAGE); /**************************************************************************************/ /* Initialization */ /**************************************************************************************/ void setup() { //Get time (for setup duration) #ifdef DEBUG unsigned long startTime = millis(); #endif //Start MySensors and send the Sketch Version Information to the Gateway node.begin(); node.sendSketchInfo(SKETCH_NAME, SKETCH_VERSION); //Setup the button pinMode(DIGITAL_INPUT_SENSOR, INPUT); //Register all sensors node.present(CHILD_ID, S_MOTION); node.present(CHILD_ID_VOLTAGE, S_MULTIMETER); //Print setup debug #ifdef DEBUG int duration = millis() - startTime; Serial.print("[Setup duration: "); Serial.print(duration, DEC); Serial.println(" ms]"); #endif } /**************************************************************************************/ /* Main loop */ /**************************************************************************************/ void loop() { //Get time (for a complete loop) #ifdef DEBUG unsigned long startTime = millis(); #endif //Read digital motion value uint8_t value = digitalRead(DIGITAL_INPUT_SENSOR); //Get voltage for battery capacity report (add 0.1v to the read value) float realVoltage = (getVoltage() / 100.0) + 0.1; int batteryPcnt = realVoltage * 100 / 3.0; if (batteryPcnt > 100) {batteryPcnt = 100;} //Check is state change if (value != switchState) { //Report result if not first loop if (firstReportDone != 0) { node.send(msgSwitch.set(value==HIGH ? 1 : 0)); } //Store result switchState = value; } //Report data to the gateway each hour if (cycleInProgress >= BATTERY_REPORT_CYCLE || firstReportDone == 0) { node.send(msgSwitch.set(value==HIGH ? 1 : 0)); node.send(msgVolt.set(realVoltage, 2)); node.sendBatteryLevel(batteryPcnt); cycleInProgress = 0; firstReportDone = 1; } //Change cycle number cycleInProgress++; //Print debug #ifdef DEBUG Serial.print("Value is "); Serial.print(value, 1); Serial.print(" "); Serial.print("Cycle is "); Serial.print(cycleInProgress, 1); Serial.print(" "); Serial.print(realVoltage); Serial.print(" v"); int duration = millis() - startTime; Serial.print(" "); Serial.print("["); Serial.print(duration, DEC); Serial.println(" ms]"); Serial.flush(); #endif //Check if the motion was triggered and if it's not the first report if (switchState == 0 && firstReportWithZeroDone == 1) { //Sleep 5' without interrupt node.sleep(SLEEP_TIME2); } //Check if it's the first loop if (switchState == 0 && firstReportWithZeroDone == 0) { firstReportWithZeroDone = 1; } //Sleep until something happens with the sensor node.sleep(DIGITAL_INPUT_SENSOR-2, CHANGE, SLEEP_TIME); } /**************************************************************************************/ /* Allows to get the real Vcc (return value * 100). */ /**************************************************************************************/ int getVoltage() { const long InternalReferenceVoltage = 1056L; ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0); delay(50); // Let mux settle a little to get a more stable A/D conversion //Start a conversion ADCSRA |= _BV( ADSC ); //Wait for it to complete while (((ADCSRA & (1<<ADSC)) != 0)); //Scale the value int result = (((InternalReferenceVoltage * 1023L) / ADC) + 5L) / 10L; return result; }
On one sensor I tweak the PIR (remove regulator and diode) but on a second one, I just plug the 3 v to the H pin (see other topic on the forum).
Working correctly for the moment (one month) but it depends on the presence in the house.
David.
-
@ Carlied,
What code is better that one of you or the one from cosmi gate?
What are the different thing? Is your code check'the battery status?
And i get a error:
no matching function for call to 'MySensor::MySensor(MyTransportRFM69&, MyHwATMega328&, MySigningAtsha204Soft&)'
-
The error is because I enable the signing function !
Remove the following line:MySigningAtsha204Soft signer;
And replace
MySensor node(transport, hw, signer);
by
MySensor node(transport, hw);
I don't know who had the best sketch.
I measure internal battery status using the 1.1 reference.David.
-
When i put this sketch in to a nano..
With a 9volt battery....
How long do think this working?Or how long is this acting on your 3 volt battery's?
-
It depends on the activity close to the sensor so not possible to say but some people reach several month without problem.
In my house it's very fresh so I have not a lot of feedback to give.David.
-
5 days.... on a 9volt block
The sketch on a nano
On my toilet.... so not a very busy roomIs there some one that live longer, with this sketch......?
-
@icebob said:
@the-cosmic-gate Nothing special. I made a big sketch, which contains 7-8 sensors (DHT, Si7021, MQ-2/9, PIR, Door magnet, Light, battery) reading code because I would like to upload the same sketch to all nodes and configurate it on controller side, which sensors is on the node and need to read.
But currently I reached the limit with I2C includes, so I need to think over this solution.Dear..
Did you finish your big code....
-
Hello,
9v means that you are using a voltage regulator which probably consumes a lot of power.
Why not using AA or AAA battery directly connected to Vcc ?David
-
@carlierd said:
Hello,
9v means that you are using a voltage regulator which probably consumes a lot of power.
Why not using AA or AAA battery directly connected to Vcc ?David
Motion and DHT needed 5volt i wash thinking..?
So 9 @ the vcc should be strong enough i was thinking.
And i do have @ the same time 3.5 for the radioAre the extern step up better than the step down on a nano?
-
The motion can be adapt to run on 3v easily (connect the Vcc to the H pad if available. You can find information on the forum). The DHT could also run on 3v. I have several nodes like that. No problem.
Can't reply for the step-up because I don't use it.David.
-
@carlierd said:
The motion can be adapt to run on 3v easily (connect the Vcc to the H pad if available. You can find information on the forum). The DHT could also run on 3v. I have several nodes like that. No problem.
Can't reply for the step-up because I don't use it.David.
@ David
How long is the 3v battery running whit this option?
-
@Dylano : My nodes are really new so difficult to say exactly but for the moment the oldest node was started one month ago (04/02) and battery still at 3.32v.
David.
-
i'am back in business after the "big move" and going to try again to get this 4:1 sensor working for a long time uning 2 x AA batteries.
If someone has some new input, please let me know and feel free to change the sketch
-
@the-cosmic-gate
Hello,
Motion nodes are still working correctly. The oldest node started the 4 of February is still at 3,29v. My other nodes (temp / humidity / light) are also working correctly but I will replace DHT22 for another sensor.David.
-
Hey @carlierd Just curious if you are still using a DHT22 with your sketch? Have you modified the code much from the above? I am looking at implementing something similiar ( identical actually ) and was wondering if much has changed for you over the last few months?
Thanks!
-
Hello,
All nodes are still working correctly but I still want to replace DHT22. But nothing done for the moment. Not at top position on my todo list
David.
Suggested Topics
-
Welcome
Announcements • • hek