3 in 1 incl battery monitor
-
I'am trying to build some 3 in 1 ( motion / temp / hum ) incl. battery monitor .
At the moment i try to combine these sketches , as result#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 = 30000; // Sleep time between reads (in milliseconds) int oldBatteryPcnt = 0; MySensor gw; DHT dht; float lastTemp; float lastHum; 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; Serial.println(tripped); gw.send(msgMot.set(tripped?"1":"0")); // Send tripped value to gw delay(dht.getMinimumSamplingPeriod()); float temperature = dht.getTemperature(); 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); } float humidity = dht.getHumidity(); 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); } // Sleep until interrupt comes in on motion sensor. Send update every two minute. gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME); }Would this work ? ( sketch verification is okay :) )
I also moded the arduino pro mini 8 Mhz like : http://www.mysensors.org/build/battery
are there more (sketch) mod's possible to make it run as long as possible on 2 x AA -
Look here for more info about battery operations: http://forum.mysensors.org/topic/486/my-2aa-battery-sensor
-
I also moded the arduino pro mini 8 Mhz like : http://www.mysensors.org/build/battery
are there more (sketch) mod's possible to make it run as long as possible on 2 x AA@the-cosmic-gate What you can do is combine the radio actions (gw.send) in one burst at the end of the sketch. That way you avoid having the radio "on" during sensor reading. The sensebender sketch can be inspiring too.
-
@the-cosmic-gate What you can do is combine the radio actions (gw.send) in one burst at the end of the sketch. That way you avoid having the radio "on" during sensor reading. The sensebender sketch can be inspiring too.
@AWI
If i remove the (gw.send) action, the code would be#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 = 30000; // Sleep time between reads (in milliseconds) int oldBatteryPcnt = 0; MySensor gw; DHT dht; float lastTemp; float lastHum; 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 SketchInfo("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 BatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; } // Read digital motion value boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; Serial.println(tripped); (msgMot.set(tripped?"1":"0")); // Send tripped value to gw delay(dht.getMinimumSamplingPeriod()); float temperature = dht.getTemperature(); if (isnan(temperature)) { Serial.println("Failed reading temperature from DHT"); } else if (temperature != lastTemp) { lastTemp = temperature; if (!metric) { temperature = dht.toFahrenheit(temperature); } (msgTemp.set(temperature, 1)); Serial.print("T: "); Serial.println(temperature); } float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; (msgHum.set(humidity, 1)); Serial.print("H: "); Serial.println(humidity); } // Sleep until interrupt comes in on motion sensor. Send update every two minute. gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME); } -
@AWI
If i remove the (gw.send) action, the code would be#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 = 30000; // Sleep time between reads (in milliseconds) int oldBatteryPcnt = 0; MySensor gw; DHT dht; float lastTemp; float lastHum; 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 SketchInfo("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 BatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; } // Read digital motion value boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; Serial.println(tripped); (msgMot.set(tripped?"1":"0")); // Send tripped value to gw delay(dht.getMinimumSamplingPeriod()); float temperature = dht.getTemperature(); if (isnan(temperature)) { Serial.println("Failed reading temperature from DHT"); } else if (temperature != lastTemp) { lastTemp = temperature; if (!metric) { temperature = dht.toFahrenheit(temperature); } (msgTemp.set(temperature, 1)); Serial.print("T: "); Serial.println(temperature); } float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; (msgHum.set(humidity, 1)); Serial.print("H: "); Serial.println(humidity); } // Sleep until interrupt comes in on motion sensor. Send update every two minute. gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME); }@the-cosmic-gate That is true but you will lose the MySensors functionality ;-) which is probably not your intention.
What I meant is that you combine the gw.send actions in one "burst" or at least don't have the radio on while waiting for a (DHT) sensor to complete.like this part of code from the sensebender sketch
if (tx) { measureCount = 0; float temperature = (isMetric ? data.celsiusHundredths : data.fahrenheitHundredths) / 100.0; int humidity = data.humidityPercent; Serial.print("T: ");Serial.println(temperature); Serial.print("H: ");Serial.println(humidity); gw.send(msgTemp.set(temperature,1)); gw.send(msgHum.set(humidity)); lastTemperature = temperature; lastHumidity = humidity; } -
So the code "must" be
#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 = 30000; // Sleep time between reads (in milliseconds) int oldBatteryPcnt = 0; MySensor gw; DHT dht; float lastTemp; float lastHum; 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); 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) { } // Read digital motion value boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; Serial.println(tripped); delay(dht.getMinimumSamplingPeriod()); float temperature = dht.getTemperature(); if (isnan(temperature)) { Serial.println("Failed reading temperature from DHT"); } else if (temperature != lastTemp) { lastTemp = temperature; if (!metric) { temperature = dht.toFahrenheit(temperature); } Serial.print("T: "); Serial.println(temperature); } float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum) { lastHum = humidity; gw.send(msgHum.set(humidity, 1)); gw.send(msgMot.set(tripped?"1":"0")); gw.sendSketchInfo("Humidity/Motion", "1.0"); gw.sendBatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; Serial.print("H: "); Serial.println(humidity); gw.send(msgTemp.set(temperature, 1)); } // Sleep until interrupt comes in on motion sensor. Send update every two minute. gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME); } -
Dont know if im answring the question (or i understand it)...
Do you mean @AWI that if you put the gw.*** together?gw.begin(); dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 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);put all the gw. *** together it will not cause the radio be on during DHT setup and readings like:
dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input gw.begin(); // 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); -
Dont know if im answring the question (or i understand it)...
Do you mean @AWI that if you put the gw.*** together?gw.begin(); dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 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);put all the gw. *** together it will not cause the radio be on during DHT setup and readings like:
dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input gw.begin(); // 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);@sundberg84 said:
Dont know if im answring the question (or i understand it)...
Do you mean @AWI that if you put the gw.*** together?gw.begin(); dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 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);put all the gw. *** together it will not cause the radio be on during DHT setup and readings like:
dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input gw.begin(); // 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);Now I'am getting confused :)
The thing i want to do is to make this 3in1 sketch , an 4 in 1 where the 4th is the battery sensors.
When i copy and paste this sketches together, i want to arrange one sketch who can run als long as possible on 2xAA batteries.
So if there are some tricks to make this sketch more battery friendle, so it runs longer on this 2 AA then it try to arrange is.
So As @AWI said i'll removed all the gw.send instructions, which gives me the result that the mysensors function is gone.
Then i tried again and put all the gw.send instructions "together".
But when i read you're reactien @sundberg84 this is not okay, or are there even more options to combine rules to make the sketch more battery friendly ?Thnx for all the input
-
@sundberg84 said:
Dont know if im answring the question (or i understand it)...
Do you mean @AWI that if you put the gw.*** together?gw.begin(); dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 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);put all the gw. *** together it will not cause the radio be on during DHT setup and readings like:
dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input gw.begin(); // 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);Now I'am getting confused :)
The thing i want to do is to make this 3in1 sketch , an 4 in 1 where the 4th is the battery sensors.
When i copy and paste this sketches together, i want to arrange one sketch who can run als long as possible on 2xAA batteries.
So if there are some tricks to make this sketch more battery friendle, so it runs longer on this 2 AA then it try to arrange is.
So As @AWI said i'll removed all the gw.send instructions, which gives me the result that the mysensors function is gone.
Then i tried again and put all the gw.send instructions "together".
But when i read you're reactien @sundberg84 this is not okay, or are there even more options to combine rules to make the sketch more battery friendly ?Thnx for all the input
@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'am not getting this clear / working :(
Could somebody help me to complete this 3in1 incl battery monitoring sketch working? ThnxI 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; }``` -
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 ;-)?