My 2AA battery sensor
-
The news is that my Vera Lite gave up (soft-wise) after all hacking, plug-ins and un-clean factory resets, so I gave up on her (and Z-wave too, at least for a while). We've been fighting with each other for too long, so I'd say the divorce was welcome.
Instead, in the controller jungle I decided to try Fhem, aware of the challanges as I'm not German- (nor Perl) speaking. I'm still in the sens-but-no-control-phase and have a few test nodes running, including "the" node 105. (Very easy transition btw, just one press at reset button then a node is in production with a new controller.)
Back home today after 2w holiday I think it's looking good. The only problem now is of course that my trending is broken. If anyone knows how to merge the old trend data with the new, you're very welcome? Or just on how to rescue the Datamine data (from NAS)? If possible? I haven't researched anything yet.

-
Just an idea... I'm not sure if someone mentioned it:
If sending consumes so much power... what about collecting sensor data every 5 minutes and then send the data (array) once per hour? Of course there would be some time calculating before logging in the controller (fhem), but this way, I can save power... What do you think? -
Just an idea... I'm not sure if someone mentioned it:
If sending consumes so much power... what about collecting sensor data every 5 minutes and then send the data (array) once per hour? Of course there would be some time calculating before logging in the controller (fhem), but this way, I can save power... What do you think?@Meister_Petz Kind of what I already do in the test nodes 105/106 if you look at code above. Update frequencey and battery life time is a balance that can be adjusted just as you wish. Right now these node send update every 15 min and take sample for calculation 5 min before, which is about what I need. If you and your application is more interested in trending, history and data collection, I think your suggestion is excellent. If you need a fast response or action from your automation system it's not.
But, what I think is most unneseccary with my test nodes 105/106 is that they check battery level every 15 min and send update if it has changed. Since the level typically is unstable right after the first transmission, it will generate a lot of useless transmissions. The only reason for me not to update code in node 105/106 is to keep it as an untouched study case. In my new nodes I usually set a fixed battery check/update frequency (1/week) which also works as a heartbeat signal for less active nodes.
-
Not sure if any one has had the same question. But the other day I stumbled on this little thing ;)
https://www.adafruit.com/product/1572 It's a really small rechargeable battery. Now I don't no much about batteries. But I know that my LiOn powerd handdrill is very strong. The batteries of my handdril hardly lose power over time.So I was wondering if this could be used to power an Arduino and some sensors and how long it will take for the battery te become empty. It would make my 3.3V Sensors really small. I could almost install them in a small matchbox. Which I think is really cool!
-
Not sure if any one has had the same question. But the other day I stumbled on this little thing ;)
https://www.adafruit.com/product/1572 It's a really small rechargeable battery. Now I don't no much about batteries. But I know that my LiOn powerd handdrill is very strong. The batteries of my handdril hardly lose power over time.So I was wondering if this could be used to power an Arduino and some sensors and how long it will take for the battery te become empty. It would make my 3.3V Sensors really small. I could almost install them in a small matchbox. Which I think is really cool!
-
Ok, another thing: why not sending everything at once?
As I understand you are using FHEM which allows a lot of coding on the controller side. So you could send batteryLevel, humidity and temperature in one go.
Something like (this is no real code, just an idea):
theValues = "battlvl:hum:temp"
gw.send(msgAll.set(theValues, 1));and in fhem you split it at ":"
So you have just one instead of 3 transmits.
-
Ok, another thing: why not sending everything at once?
As I understand you are using FHEM which allows a lot of coding on the controller side. So you could send batteryLevel, humidity and temperature in one go.
Something like (this is no real code, just an idea):
theValues = "battlvl:hum:temp"
gw.send(msgAll.set(theValues, 1));and in fhem you split it at ":"
So you have just one instead of 3 transmits.
@Meister_Petz I think it's a very good idea! It would be a nice option to have. Parsing with Perl should be simple even for a beginner like me, but to change the Mysensors core and fhem plugin is far beyond what I can. If you can do it, just go ahead and plz share.
-
ok, I did some testing and succeeded:
This is the important part of the Arduino code:
String allSens = String(sensor1) + " " + String(sensor2); gw.send(msg1.set(allSens.c_str()));This is the FHEM code:
define Sensor MYSENSORS_DEVICE 20 attr Sensor IODev MSGateway attr Sensor mapReading_brightness1 1 brightness attr Sensor mode node attr Sensor version 1.5 attr Sensor userReadings Bat Deg # split and copy to userReadings define Sensor.copy at +*00:02:00 {my $a = ReadingsVal("Sensor","brightness1",1);; my @b = split(/\ /,$a);; fhem("setreading Sensor Bat $b[0]");; fhem("setreading Sensor Grad $b[1]");;}P.S.: when I had this in fhem.cfg I had to use @@ instead of only one @
This is my complete Arduino code for a Battery Sensor with Dallas Temp:
#include <MySensor.h> #include <SPI.h> #define SketchName "Sensor-send-all" #define SketchVer "1.2" #define NodeID 20 unsigned long SleepTime = 828523; // 55234 = 1 Minute --- 828523 = 15 Minuten MySensor gw; // this is the one which sends everything #define SENSOR1_ID 1 // Sensor 1 - allAtOnceMessage //------------------------------------------------ // Sensor PINS #define SENSOR1_PIN A0 // BattLevel #define SENSOR2_PIN 6 // Dallas // MyMessage V_TEMP, V_LIGHT_LEVEL, ... depending on Sensor Type MyMessage msg1(SENSOR1_ID,V_LIGHT_LEVEL); // Sensor 5 - allAtOnceMessage //------------------------------------------------ // Dallas Temp #include <OneWire.h> #include <DallasTemperature.h> OneWire oneWire(SENSOR2_PIN); DallasTemperature sensors(&oneWire); boolean receivedConfig = false; float firstRun = 1; boolean metric = true; void setup() { // use the 1.1 V internal reference analogReference(INTERNAL); delay(500); // Allow time for radio if power used as reset <<<<<<<<<<<<<< Experimented with good result gw.begin(NULL, NodeID, false); // Send the sketch version information to the gateway and Controller gw.sendSketchInfo(SketchName, SketchVer); // present all Sensors to Gateway - S_TEMP, S_LIGHT_LEVEL,... depending an SENSOR type gw.present(SENSOR1_ID, S_LIGHT_LEVEL); sensors.begin(); } void loop() { gw.process(); // wait some time to get all parts powered up if (firstRun == 1){ delay(5000); firstRun = 0; } else { delay(1000); } //---------------------- // Sensor1 - Battery Voltage - Part 1 int sensorRead10 = analogRead(SENSOR1_PIN); //---------------------- // Sensor2 - DAL sensors.requestTemperatures(); int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution()); gw.sleep(conversionTime); float sensorRead2 = static_cast<float>(static_cast<int>((metric?sensors.getTempCByIndex(0):sensors.getTempFByIndex(0)) * 10.)) / 10.; //---------------------- // Sensor1 - Battery Voltage - Part 2 int sensorRead11 = analogRead(SENSOR1_PIN); //Volt der Battery float sensorRead1 = (sensorRead10 + sensorRead11 + sensorRead12) / 3 * 0.0033; // should be 0.003363075 my Batteries are different float test = sensorRead10; //---------------------- // send all to fhem String allComb = String(sensorRead1) + " " + String(sensorRead2); gw.send(msg1.set(allComb.c_str())); gw.sleep(SleepTime); } -
ok, I did some testing and succeeded:
This is the important part of the Arduino code:
String allSens = String(sensor1) + " " + String(sensor2); gw.send(msg1.set(allSens.c_str()));This is the FHEM code:
define Sensor MYSENSORS_DEVICE 20 attr Sensor IODev MSGateway attr Sensor mapReading_brightness1 1 brightness attr Sensor mode node attr Sensor version 1.5 attr Sensor userReadings Bat Deg # split and copy to userReadings define Sensor.copy at +*00:02:00 {my $a = ReadingsVal("Sensor","brightness1",1);; my @b = split(/\ /,$a);; fhem("setreading Sensor Bat $b[0]");; fhem("setreading Sensor Grad $b[1]");;}P.S.: when I had this in fhem.cfg I had to use @@ instead of only one @
This is my complete Arduino code for a Battery Sensor with Dallas Temp:
#include <MySensor.h> #include <SPI.h> #define SketchName "Sensor-send-all" #define SketchVer "1.2" #define NodeID 20 unsigned long SleepTime = 828523; // 55234 = 1 Minute --- 828523 = 15 Minuten MySensor gw; // this is the one which sends everything #define SENSOR1_ID 1 // Sensor 1 - allAtOnceMessage //------------------------------------------------ // Sensor PINS #define SENSOR1_PIN A0 // BattLevel #define SENSOR2_PIN 6 // Dallas // MyMessage V_TEMP, V_LIGHT_LEVEL, ... depending on Sensor Type MyMessage msg1(SENSOR1_ID,V_LIGHT_LEVEL); // Sensor 5 - allAtOnceMessage //------------------------------------------------ // Dallas Temp #include <OneWire.h> #include <DallasTemperature.h> OneWire oneWire(SENSOR2_PIN); DallasTemperature sensors(&oneWire); boolean receivedConfig = false; float firstRun = 1; boolean metric = true; void setup() { // use the 1.1 V internal reference analogReference(INTERNAL); delay(500); // Allow time for radio if power used as reset <<<<<<<<<<<<<< Experimented with good result gw.begin(NULL, NodeID, false); // Send the sketch version information to the gateway and Controller gw.sendSketchInfo(SketchName, SketchVer); // present all Sensors to Gateway - S_TEMP, S_LIGHT_LEVEL,... depending an SENSOR type gw.present(SENSOR1_ID, S_LIGHT_LEVEL); sensors.begin(); } void loop() { gw.process(); // wait some time to get all parts powered up if (firstRun == 1){ delay(5000); firstRun = 0; } else { delay(1000); } //---------------------- // Sensor1 - Battery Voltage - Part 1 int sensorRead10 = analogRead(SENSOR1_PIN); //---------------------- // Sensor2 - DAL sensors.requestTemperatures(); int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution()); gw.sleep(conversionTime); float sensorRead2 = static_cast<float>(static_cast<int>((metric?sensors.getTempCByIndex(0):sensors.getTempFByIndex(0)) * 10.)) / 10.; //---------------------- // Sensor1 - Battery Voltage - Part 2 int sensorRead11 = analogRead(SENSOR1_PIN); //Volt der Battery float sensorRead1 = (sensorRead10 + sensorRead11 + sensorRead12) / 3 * 0.0033; // should be 0.003363075 my Batteries are different float test = sensorRead10; //---------------------- // send all to fhem String allComb = String(sensorRead1) + " " + String(sensorRead2); gw.send(msg1.set(allComb.c_str())); gw.sleep(SleepTime); }@Meister_Petz Wow! Well done! I think this can be very useful.
In theory some power should be saved. Estimation from here is that a 250kbit/s transmission of a maximum size (32 byte) packet is >1.5ms. I think at around 20mA. Massage header is 7 byte, but a normal massage just a few bytes, i.e. just 30% of a message. Startup time for radio is fast (140us), so that shouldn't be an issue. (A side note here is that wake up atmega328p from sleep takes long (6ms?).)Is there a reason that you wrote the Fhem sonsor.copy macro as an "at" and not a "notify" ? The intuitive way would be to copy upon a new reading.
-
@Meister_Petz Wow! Well done! I think this can be very useful.
In theory some power should be saved. Estimation from here is that a 250kbit/s transmission of a maximum size (32 byte) packet is >1.5ms. I think at around 20mA. Massage header is 7 byte, but a normal massage just a few bytes, i.e. just 30% of a message. Startup time for radio is fast (140us), so that shouldn't be an issue. (A side note here is that wake up atmega328p from sleep takes long (6ms?).)Is there a reason that you wrote the Fhem sonsor.copy macro as an "at" and not a "notify" ? The intuitive way would be to copy upon a new reading.
@m26872 there is no special reason for "at"... I think I got it from some where and it worked ;-)
-
Soon 11 months of production including a fair amount of too frequent battery uppdates. Most exciting is wheter the initially used batteries in 106 will make it 12 months or not.


-
Soon 11 months of production including a fair amount of too frequent battery uppdates. Most exciting is wheter the initially used batteries in 106 will make it 12 months or not.


@m26872 perhaps you could reduce the redundant updates by filtering. If the current sample is lower than the "next" sample ignore it. If your node does not support charging, it will never really truly read an increase in battery voltage.
-
@m26872 perhaps you could reduce the redundant updates by filtering. If the current sample is lower than the "next" sample ignore it. If your node does not support charging, it will never really truly read an increase in battery voltage.
@Anticimex Yes, but in this particular case its double. Conclusion from above was that frequency and magnitude of the "low spikes" gives you information of how near the end you are. On the other hand I would never run like this if it wasn't for keeping the experiment "untouched". I think my thought for future sensors is to preserve that information, but save battery, just by reducing the number of samples.
I'm still not sure of the best filter/algorithm to predict battery end of life from present and historic data. It will probably differ a lot wheter there's a step-up or a nicer load.
-
@Anticimex Yes, but in this particular case its double. Conclusion from above was that frequency and magnitude of the "low spikes" gives you information of how near the end you are. On the other hand I would never run like this if it wasn't for keeping the experiment "untouched". I think my thought for future sensors is to preserve that information, but save battery, just by reducing the number of samples.
I'm still not sure of the best filter/algorithm to predict battery end of life from present and historic data. It will probably differ a lot wheter there's a step-up or a nicer load.
@m26872 Just a suggestion: once the node dies you could take the raw data and run some filtering on it like @Anticimex suggested.
It'll give you a quick way to experiment with different filter settings.
Once you find an optimal filter you can implement it in the node(s). -
@m26872 Just a suggestion: once the node dies you could take the raw data and run some filtering on it like @Anticimex suggested.
It'll give you a quick way to experiment with different filter settings.
Once you find an optimal filter you can implement it in the node(s). -
i think it would be better to open a new thread for this, instead to discuss two topics in one thread....the 2xaa battery sensor is very interesting ;)
-
I declare the 6 months criteria easily passed. And the chinese step up regulator to be good value for money. Next target; 12 months.

The 12 months target was done a few days ago. Today's status 105: 63% and 106: 27%
I had a thought to celebrate their birthday by retrieve old Vera data and make nice plot, but that has to wait. Next, 18 months.Just to clarify that these are no "sleeping" nodes; they transmit 100-150 messages each every day.