My Slim 2AA Battery Node
-
Have you desoldered one radio to see if it's back alive again? What's your distance to Gateway? Maybe some filtering or antenna effect by your fingers and breadboard? What if you leave a working radio on the breadboard then just connect it with wires to PCB?
-
Have you desoldered one radio to see if it's back alive again? What's your distance to Gateway? Maybe some filtering or antenna effect by your fingers and breadboard? What if you leave a working radio on the breadboard then just connect it with wires to PCB?
@m26872
Distance is about 50cm. They are both on my desk. If testing then I do not tough the sensor. Just when trien pressing a radio an a non function radio.
I tried to de-solder the radio but did not succeed. Cut the pins, removed them and soldered wires to it. Connected to a new radio. Strange part is that the on very irregular basis message are received in MYSController. Also with a radio which is functioning well on the breadboard -
@m26872
Distance is about 50cm. They are both on my desk. If testing then I do not tough the sensor. Just when trien pressing a radio an a non function radio.
I tried to de-solder the radio but did not succeed. Cut the pins, removed them and soldered wires to it. Connected to a new radio. Strange part is that the on very irregular basis message are received in MYSController. Also with a radio which is functioning well on the breadboard@aneco - 50cm is a big problem for me! Its to close and the node - gw is having a hard time communicating for some reason. I wish I didnt set my gw up in the workplace where i build because every time im testing some node I have to go to the next room. Maybe you could try this?
-
@m26872 - I made this (but with the big motiondec, because my small ones didnt work so well due to clone/copy). Thanks for PCB, instructions and tutorials. Great work!
Node is running at 13uA without motiondetector attached and 90-95uA with the motion dec attached. Im happy with that and ill see how long the batteries last. When my small motion dec arrive I can just switch over.

-
@aneco - 50cm is a big problem for me! Its to close and the node - gw is having a hard time communicating for some reason. I wish I didnt set my gw up in the workplace where i build because every time im testing some node I have to go to the next room. Maybe you could try this?
@sundberg84
The node on the breadboard is on the same desk and same distance to gateway. The same for my first sensor. And both are working well. Only issue with 4 sensors a soldered afterwords.Just remember now that I used for the first sensor other solder. But do not think that this is causing the issue or .....
-
@rollercontainer Your sleep looks good. Did you remove this piece of code?
// Activate internal pull-ups digitalWrite(PRIMARY_BUTTON_PIN, HIGH); digitalWrite(SECONDARY_BUTTON_PIN, HIGH);Take a look at this thread for a < 1 uA consumption...
@AWI said in My Slim 2AA Battery Node:
@rollercontainer Your sleep looks good. Did you remove this piece of code?
// Activate internal pull-ups digitalWrite(PRIMARY_BUTTON_PIN, HIGH); digitalWrite(SECONDARY_BUTTON_PIN, HIGH);Take a look at this thread for a < 1 uA consumption...
Hmm, I noticed, that I have to disable the internal pullups. But instead of removing the lines, I set them to LOW. I will test it without the lines and come back. Thank you @AWI.
-
Ok, just want to give you an update:
I have 3 sensors running in the moment, initially I planned to run a lot more, but I still have problems with freezing of the sensors. The Sensors ran 2 months now until they were not coummunicating anymore, 1 is still working. I restarted 1 of the freezed sensors and it just came back up and works fine again, I leave the other one "freezed" just to see if it would come up again...
It´s sad that they are not very reliable but I don´t get what makes them freeze after working quiet good for such a long time (they are reporting every 15 minutes 24/7 and whenever a window is opened/closed).
I don´t think it´s a temp thing, also power should be no problem, batteries are still about 80 % loaded...
-
Maybe there is something like a counter (variable++) which causes a overflow after two month?
-
No, not really, but if you want to you can check my code:
// Sensor Node Schlafzimmer mit HTU21D Temp/Hum Sensor, Fensterkontakte an Interrupt PINS Digital 5&6. Sleep Time 15 Minutwn, wake up wenn Fenster geöffnet/geschlossen wird. #define MY_RADIO_NRF24 //MySensor Library auf NRF24 Funkmodul einstellen, muss vor MySensor.h Initialisierung geschehen // Define Node ID #define MY_NODE_ID 1 #define MY_PARENT_NODE_ID 0 #define MY_PARENT_NODE_IS_STATIC //Batterysensor int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point int oldBatteryPcnt = 0; #define CHILD_ID_BATT 7 //Kontaktschalter //#include <Bounce2.h> #define CHILD1_ID 1 // Kontaktschalter 1 #define CHILD2_ID 2 // Kontaktschalter 2 #define BUTTON1_PIN 2 // Kontaktschalter 1 #define BUTTON2_PIN 3 // Kontaktschalter 2 int oldValueReed1=-1; int oldValueReed2=-1; //Tempsensor #include <SparkFunHTU21D.h> #include <Wire.h> #define CHILD_ID_HUM 3 #define CHILD_ID_TEMP 4 unsigned long SLEEP_TIME = 900000; // Sleep time between reads (in milliseconds) #include <MySensors.h> #include <SPI.h> //tempsensor HTU21D myHumidity; float lastTemp; float lastHum; //boolean metric = true; //Messages //Battery MyMessage msgbatt(CHILD_ID_BATT,V_VOLTAGE); // Kontaktschalter MyMessage msgReed1(CHILD1_ID,V_TRIPPED); // Kontaktschalter 1 MyMessage msgReed2(CHILD2_ID,V_TRIPPED); // Kontaktschalter 2 //TempMessage MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); //Presentation; present sensors to gateway! void presentation(){ // Send the sketch version information to the gateway and Controller sendSketchInfo("Schlafzimmer Messstation", "2.0"); // 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. present(CHILD1_ID, S_DOOR); present(CHILD2_ID, S_DOOR); //Tempsensor present(CHILD_ID_HUM, S_HUM); present(CHILD_ID_TEMP, S_TEMP); //metric = getConfig().isMetric; //Battery present(CHILD_ID_BATT,V_VOLTAGE); } //Setup void setup() { //Serial.begin(9600); Serial.println("Hello!"); //Batterysensor // use the 1.1 V internal reference #if defined(__AVR_ATmega2560__) analogReference(INTERNAL1V1); #else analogReference(INTERNAL); #endif //Tempsensor Serial.println("Setting up TempSensor..."); myHumidity.begin(); Serial.println("...done!"); // Setup Kontaktschalter 1 pinMode(BUTTON1_PIN,INPUT); // Activate internal pull-up digitalWrite(BUTTON1_PIN,HIGH); // Setup Kontaktschalter 2 pinMode(BUTTON2_PIN,INPUT); // Activate internal pull-up digitalWrite(BUTTON2_PIN,HIGH); } //Starte den Loop void loop() { //Batterysensor // get the battery Voltage delay(1000); int sensorValue = analogRead(BATTERY_SENSE_PIN); #ifdef DEBUG #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 sendBatteryLevel(batteryPcnt); send(msgbatt.set(batteryPcnt)); oldBatteryPcnt = batteryPcnt; } //Kontakstschalter 1 // Short delay to allow buttons to properly settle wait(10); // Get the update value int valueReed1 = digitalRead(BUTTON1_PIN); if (valueReed1 != oldValueReed1) { // Send in the new value send(msgReed1.set(valueReed1==HIGH ? 1 : 0)); Serial.println("Button 1 geschaltet"); oldValueReed1 = valueReed1; } //Kontakstschalter 2 // Get the update value int valueReed2 = digitalRead(BUTTON2_PIN); if (valueReed2 != oldValueReed2) { // Send in the new value send(msgReed2.set(valueReed2==HIGH ? 1 : 0)); Serial.println("Button 2 geschaltet"); oldValueReed2 = valueReed2; } //Tempsensor Serial.println("Starte Messung..."); float temp = myHumidity.readTemperature(); if (isnan(temp)) { Serial.println("Failed reading temperature from DHT"); } else if (temp != lastTemp) { lastTemp = temp; send(msgTemp.set(temp, 1)); Serial.print("T: "); Serial.println(temp); } float humd = myHumidity.readHumidity(); if (isnan(humd)) { Serial.println("Failed reading humidity from DHT"); } else if (humd != lastHum) { lastHum = humd; send(msgHum.set(humd, 1)); Serial.print("H: "); Serial.println(humd); } Serial.println("Sleep..."); sleep(BUTTON1_PIN - 2, CHANGE, BUTTON2_PIN - 2, CHANGE, SLEEP_TIME); //sleep a bit } -
@rollercontainer Your sleep looks good. Did you remove this piece of code?
// Activate internal pull-ups digitalWrite(PRIMARY_BUTTON_PIN, HIGH); digitalWrite(SECONDARY_BUTTON_PIN, HIGH);Take a look at this thread for a < 1 uA consumption...
@AWI: I am down to 1,3 µA :+1:
my code:
//#define MY_DEBUG #define MY_RADIO_NRF24 #define MY_NODE_ID 66 #define MY_PARENT_NODE_ID 0 #define MY_PARENT_NODE_IS_STATIC #include <MySensors.h> #include "Vcc.h" #define SKETCH_NAME "MySlim2aaBatteryNode" #define PRIMARY_CHILD_ID 3 #define PRIMARY_BUTTON_PIN 3 MyMessage msg(PRIMARY_CHILD_ID, V_TRIPPED); const float VccMin = 1.7; // Minimum expected Vcc level, in Volts. const float VccMax = 3.3; // Maximum expected Vcc level, in Volts. const float VccCorrection = 3.496 / 3.572; // Measured Vcc by multimeter divided by reported Vcc const int32_t report_interval = 8640000; // 1day -> h * m * s * ms NOTICE: milliseconds, not microseconds! Vcc vcc(VccCorrection); #ifdef MY_DEBUG void before(){ Serial.begin(9600); } #endif void setup() { pinMode(PRIMARY_BUTTON_PIN, INPUT); } void presentation() { sendSketchInfo(SKETCH_NAME, __DATE__); present(PRIMARY_CHILD_ID, S_DOOR, "Reed Contact"); } void loop() { int32_t timestamp = millis(); uint8_t reedState; static uint8_t lastReedState = 2; static int32_t lastBatteryReport = -report_interval; // for inital report sleep(5); // Short delay to allow buttons to properly settle reedState = digitalRead(PRIMARY_BUTTON_PIN); if ( (timestamp-lastBatteryReport) >= report_interval ) { uint8_t batteryPercent = (uint8_t)vcc.Read_Perc(VccMin, VccMax); sendBatteryLevel(batteryPercent); lastBatteryReport = timestamp; } if (reedState != lastReedState) { // Value has changed from last transmission, send the updated reedState send(msg.set(reedState==HIGH)); lastReedState = reedState; } sleep(PRIMARY_BUTTON_PIN-2, CHANGE, 0); } -
No, not really, but if you want to you can check my code:
// Sensor Node Schlafzimmer mit HTU21D Temp/Hum Sensor, Fensterkontakte an Interrupt PINS Digital 5&6. Sleep Time 15 Minutwn, wake up wenn Fenster geöffnet/geschlossen wird. #define MY_RADIO_NRF24 //MySensor Library auf NRF24 Funkmodul einstellen, muss vor MySensor.h Initialisierung geschehen // Define Node ID #define MY_NODE_ID 1 #define MY_PARENT_NODE_ID 0 #define MY_PARENT_NODE_IS_STATIC //Batterysensor int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point int oldBatteryPcnt = 0; #define CHILD_ID_BATT 7 //Kontaktschalter //#include <Bounce2.h> #define CHILD1_ID 1 // Kontaktschalter 1 #define CHILD2_ID 2 // Kontaktschalter 2 #define BUTTON1_PIN 2 // Kontaktschalter 1 #define BUTTON2_PIN 3 // Kontaktschalter 2 int oldValueReed1=-1; int oldValueReed2=-1; //Tempsensor #include <SparkFunHTU21D.h> #include <Wire.h> #define CHILD_ID_HUM 3 #define CHILD_ID_TEMP 4 unsigned long SLEEP_TIME = 900000; // Sleep time between reads (in milliseconds) #include <MySensors.h> #include <SPI.h> //tempsensor HTU21D myHumidity; float lastTemp; float lastHum; //boolean metric = true; //Messages //Battery MyMessage msgbatt(CHILD_ID_BATT,V_VOLTAGE); // Kontaktschalter MyMessage msgReed1(CHILD1_ID,V_TRIPPED); // Kontaktschalter 1 MyMessage msgReed2(CHILD2_ID,V_TRIPPED); // Kontaktschalter 2 //TempMessage MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); //Presentation; present sensors to gateway! void presentation(){ // Send the sketch version information to the gateway and Controller sendSketchInfo("Schlafzimmer Messstation", "2.0"); // 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. present(CHILD1_ID, S_DOOR); present(CHILD2_ID, S_DOOR); //Tempsensor present(CHILD_ID_HUM, S_HUM); present(CHILD_ID_TEMP, S_TEMP); //metric = getConfig().isMetric; //Battery present(CHILD_ID_BATT,V_VOLTAGE); } //Setup void setup() { //Serial.begin(9600); Serial.println("Hello!"); //Batterysensor // use the 1.1 V internal reference #if defined(__AVR_ATmega2560__) analogReference(INTERNAL1V1); #else analogReference(INTERNAL); #endif //Tempsensor Serial.println("Setting up TempSensor..."); myHumidity.begin(); Serial.println("...done!"); // Setup Kontaktschalter 1 pinMode(BUTTON1_PIN,INPUT); // Activate internal pull-up digitalWrite(BUTTON1_PIN,HIGH); // Setup Kontaktschalter 2 pinMode(BUTTON2_PIN,INPUT); // Activate internal pull-up digitalWrite(BUTTON2_PIN,HIGH); } //Starte den Loop void loop() { //Batterysensor // get the battery Voltage delay(1000); int sensorValue = analogRead(BATTERY_SENSE_PIN); #ifdef DEBUG #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 sendBatteryLevel(batteryPcnt); send(msgbatt.set(batteryPcnt)); oldBatteryPcnt = batteryPcnt; } //Kontakstschalter 1 // Short delay to allow buttons to properly settle wait(10); // Get the update value int valueReed1 = digitalRead(BUTTON1_PIN); if (valueReed1 != oldValueReed1) { // Send in the new value send(msgReed1.set(valueReed1==HIGH ? 1 : 0)); Serial.println("Button 1 geschaltet"); oldValueReed1 = valueReed1; } //Kontakstschalter 2 // Get the update value int valueReed2 = digitalRead(BUTTON2_PIN); if (valueReed2 != oldValueReed2) { // Send in the new value send(msgReed2.set(valueReed2==HIGH ? 1 : 0)); Serial.println("Button 2 geschaltet"); oldValueReed2 = valueReed2; } //Tempsensor Serial.println("Starte Messung..."); float temp = myHumidity.readTemperature(); if (isnan(temp)) { Serial.println("Failed reading temperature from DHT"); } else if (temp != lastTemp) { lastTemp = temp; send(msgTemp.set(temp, 1)); Serial.print("T: "); Serial.println(temp); } float humd = myHumidity.readHumidity(); if (isnan(humd)) { Serial.println("Failed reading humidity from DHT"); } else if (humd != lastHum) { lastHum = humd; send(msgHum.set(humd, 1)); Serial.print("H: "); Serial.println(humd); } Serial.println("Sleep..."); sleep(BUTTON1_PIN - 2, CHANGE, BUTTON2_PIN - 2, CHANGE, SLEEP_TIME); //sleep a bit }@siod
Gateway issue? Other sensors working or all down at same time? Do you have a sniffer or listen-only gateway, or heartbeat LED attached to each sensor?What's the purpose of the delay(1000)? It usually safer to use wait() or sleep() and perhaps also to deal with the interrupt results first. You could also try level interrupt instead of "change". You're not using indefinite sleep so it shouldn't be a problem, but try anyway..
-
@AWI: I am down to 1,3 µA :+1:
my code:
//#define MY_DEBUG #define MY_RADIO_NRF24 #define MY_NODE_ID 66 #define MY_PARENT_NODE_ID 0 #define MY_PARENT_NODE_IS_STATIC #include <MySensors.h> #include "Vcc.h" #define SKETCH_NAME "MySlim2aaBatteryNode" #define PRIMARY_CHILD_ID 3 #define PRIMARY_BUTTON_PIN 3 MyMessage msg(PRIMARY_CHILD_ID, V_TRIPPED); const float VccMin = 1.7; // Minimum expected Vcc level, in Volts. const float VccMax = 3.3; // Maximum expected Vcc level, in Volts. const float VccCorrection = 3.496 / 3.572; // Measured Vcc by multimeter divided by reported Vcc const int32_t report_interval = 8640000; // 1day -> h * m * s * ms NOTICE: milliseconds, not microseconds! Vcc vcc(VccCorrection); #ifdef MY_DEBUG void before(){ Serial.begin(9600); } #endif void setup() { pinMode(PRIMARY_BUTTON_PIN, INPUT); } void presentation() { sendSketchInfo(SKETCH_NAME, __DATE__); present(PRIMARY_CHILD_ID, S_DOOR, "Reed Contact"); } void loop() { int32_t timestamp = millis(); uint8_t reedState; static uint8_t lastReedState = 2; static int32_t lastBatteryReport = -report_interval; // for inital report sleep(5); // Short delay to allow buttons to properly settle reedState = digitalRead(PRIMARY_BUTTON_PIN); if ( (timestamp-lastBatteryReport) >= report_interval ) { uint8_t batteryPercent = (uint8_t)vcc.Read_Perc(VccMin, VccMax); sendBatteryLevel(batteryPercent); lastBatteryReport = timestamp; } if (reedState != lastReedState) { // Value has changed from last transmission, send the updated reedState send(msg.set(reedState==HIGH)); lastReedState = reedState; } sleep(PRIMARY_BUTTON_PIN-2, CHANGE, 0); }@Tim-Abels :+1: that is how you do it
Be aware that the timer (millis()) is not running during sleep.
-
@AWI: I am down to 1,3 µA :+1:
my code:
//#define MY_DEBUG #define MY_RADIO_NRF24 #define MY_NODE_ID 66 #define MY_PARENT_NODE_ID 0 #define MY_PARENT_NODE_IS_STATIC #include <MySensors.h> #include "Vcc.h" #define SKETCH_NAME "MySlim2aaBatteryNode" #define PRIMARY_CHILD_ID 3 #define PRIMARY_BUTTON_PIN 3 MyMessage msg(PRIMARY_CHILD_ID, V_TRIPPED); const float VccMin = 1.7; // Minimum expected Vcc level, in Volts. const float VccMax = 3.3; // Maximum expected Vcc level, in Volts. const float VccCorrection = 3.496 / 3.572; // Measured Vcc by multimeter divided by reported Vcc const int32_t report_interval = 8640000; // 1day -> h * m * s * ms NOTICE: milliseconds, not microseconds! Vcc vcc(VccCorrection); #ifdef MY_DEBUG void before(){ Serial.begin(9600); } #endif void setup() { pinMode(PRIMARY_BUTTON_PIN, INPUT); } void presentation() { sendSketchInfo(SKETCH_NAME, __DATE__); present(PRIMARY_CHILD_ID, S_DOOR, "Reed Contact"); } void loop() { int32_t timestamp = millis(); uint8_t reedState; static uint8_t lastReedState = 2; static int32_t lastBatteryReport = -report_interval; // for inital report sleep(5); // Short delay to allow buttons to properly settle reedState = digitalRead(PRIMARY_BUTTON_PIN); if ( (timestamp-lastBatteryReport) >= report_interval ) { uint8_t batteryPercent = (uint8_t)vcc.Read_Perc(VccMin, VccMax); sendBatteryLevel(batteryPercent); lastBatteryReport = timestamp; } if (reedState != lastReedState) { // Value has changed from last transmission, send the updated reedState send(msg.set(reedState==HIGH)); lastReedState = reedState; } sleep(PRIMARY_BUTTON_PIN-2, CHANGE, 0); }@Tim-Abels
1.3uA is nice!
A question about your sketch: Is millis() working because it's an interrupt-only sleep() or have I missed something else? As I recall it millis() stops working when using sleep().
Edit: Haha. @AWI got it before me! :smile: -
@Tim-Abels :+1: that is how you do it
Be aware that the timer (millis()) is not running during sleep.
@AWI one step forward, two steps back... Thanks for the hint.
I guess, I should send battery percentage every 10 interrupts or so. Even if the contact doesn't trigger for a while, I can force it by showing my neighbours my ocd on doors ^^ (knock, knock, knock - Penny!)
What do you think?