This is a single wake from deep-sleep event in the Arduino environment.
Reset pin is pulsed, ESP wakes up, collects data, WiFi connects, sends data by UDP, then back to deep-sleep.
The greyed area starts with the ESP reset pin being activated and ends when the ESP goes back to sleep, in this case (above pic) it takes about 280ms so it is not completely unrealistic to use ESP8266 devices on batteries (many people do). Between 269 and 274ms is fairly typical for me on my home network. Here is 12-hours of connect-times graph The times are NOT by using millis() as the internal timebase does not start till some time after the reset.
The low-power item before the ESP-reset is a companion-processor (ATtiny1614) that does a bunch of background stuff. It is responsible for waking the ESP and handing over its collected data for transmission. It also handles the DS18B20 for temperature because the ESP is not awake for long enough.
At the bottom of the image, the blue logic trace is the actual Arduino sketch-active time. 1st instruction in sketch sets it high, goes low after initiating the UDP transmission.
There is no RF-Cal on wake so startup is quicker. In my use, every 100th wake, an RF-cal is included.
From reset to start of sketch is (in this case) 113ms. This is dead-time for the user while the ESP is initialised up to the point where the boot process hands over to the user sketch. WiFi becomes connected just after the second-last current peak, so from sketch start to that point, do stuff!
By the time your WiFi connection is active your data should be all packaged-up and ready to send. There is about 160ms of actual usable sketch time available before WiFi is connected. Use it wisely!
With everything sleeping (ESP8266 and ATtiny1614) the standby current is about 78uA. Still a bit high. Now I have my Nordic PPK2 I can try and optimise this so as I modify the software I can actually see the difference.
11-Feb-22: After a bit of tweaking, standby is now down to 22uA. Not bad for an ESP and ATtiny together (and support circuitry).
Since getting my hands on a Nordic PPK2 (power profiler) I have been able to accurately measure the operational and standby/sleep performance of my ESP8266 systems that use batteries. One of my boards I’ve investigated contains the following: 1 x ESP12S 1 x ATTINY1614 1 x MPU6050 module 1 x DS18B20 plus a few capacitors and resistors. This is powered from 2 x 600mAh LiFePo4 cells in parallel.
The board is set up to wake up every 5-min, send data, go back to deep-sleep. I like to use the ESP12S in compact designs because it requires no external resistors. The relevant pull-up/down resistors are built in to the module so if its been programmed, all you need is to supply power (and a VCC decoupling cap). The MPU6050 module is a common version found on ebay. It has a small regulator (5V to 3.3V), a few caps and resistors and a power LED. To minimise the power consumption I remove both the power LED and the regulator from the MPU6050 module. Not using a regulator avoids the parasitic drain or voltage drop that would normally be involved.
The charge/discharge voltage profile for this type of cell means that no regulator is required for the electronics.
From the ESP data sheet, operating voltage is from 2.5 to 3.6V. MPU data says 2.375 to 3.46 ATtiny is 1.8V to 5.5V
By using the Nordic power profiler I obtained the following data for a 5-min wake/sleep cycle
The highlighted grey-section contains a complete 5-min cycle (well.., 4:57.9). (For an actual wakeup event, see here)
This shows max current (when the ESP transmits), average current and the charge used. (25.95 milli-Coulombs) To translate Coulombs to mA/h is a simple divide by 3.6 which produces 0.00720833mAh for the 5-min cycle. So 1 hour takes that figure up to 0.0865mAh, 1 day is 2.076mAh, 30 days uses 62.28mAh. Theoretically with 1200mAh of battery this allows for 13872 hours of operation. Or 578 days (19.2 months!). Mmm… was not expecting that. Seems a bit optimistic, maybe got my sums wrong somewhere. But even if its correct, its never going to be that good. Not even close.
This battery chemistry has a self-discharge rate of around 5% a month. Some sources say 3% but 5% seems the most common figure so lets go with 5%. This equates to 60mAh a month just vanishing. Nothing you can do about it. The electronics actually uses 62.28mAh/month and the battery looses another 60 in self-discharge. This brings the new monthly ‘consumption’ figure to 122.28mAh so the theoretical run-time changes from 19.2 months to 9.8 months. But wait, there’s more!
The battery capacity figures given by manufacturers are from full charged to fully discharged. If you read lots of stuff about LiFePo4 batteries, charging/discharging, what constitutes fully charged seems to vary. Some advocate charging as high as 4.2V which packs in an extra percent, others say fully charged is 3.65V (seems to be common). If you charge to 3.65V then stop, take it out the charger and next day measure the voltage it has settled to a more friendly (for my purposes) 3.4-ish V. (Some very good info about charge voltages and percentage capacity at powerstream) The minimum voltage for LiFePo4 cells is often given as 2.5V. I don’t let mine get that far down. I shut-down at 2.9V which probably looses maybe 8% of the available capacity so the 1200mAh battery is actually 1200-8% so 1104. Only charging to 3.4V can loose another 3%, so instead of 1200-8%, make that 1200-11% so now only 1068mAh
At last the numbers should be usable. 1068mAh/122.28 = 8.7 months which I’m hoping is a bit more realistic. Disappointingly different from the first number of 19.2 months (I’d got a bit excited!) but after thinking about it a bit, and reading more, I realised it just was not going to be. Theoretical-maximum and realism can be very different.
The style of usage has quite an effect on the usable capacity. If I was discharging at 0.5C then I should get close to the theoretical capacity as the self-discharge is not a factor. By using low discharge rates over a long period, the self-discharge of the battery becomes very significant. In my case, almost half the energy is lost in self-discharge. I have not managed to find any information about LiFePo4 cell very low discharge rates. 0.1C was the lowest test discharge I found. Although I’m not sure if this qualifies as low, perhaps pulsed is a better description. It does have high current pulses (~230mA), but of very short duration and 5-min apart to allow for ‘recovery’. It probably makes a difference and in a beneficial way to the user but I’m just guessing here.
Since the self-discharge has such a large effect on my battery life I looked at using 2 AA alkaline cells in series, no regulator. So lets look at some numbers here..
Capacity of a AA alkaline cell seems to be from 1700 to 2850mAh depending on the manufacturer so 2000mAh seems reasonable to use. Self discharge for alkaline cells is 2-3% a year, so 3%/12 gives 0.25% per month, or 5mAh per month loss. The ESP8266 needs 2.5V minimum so each cell only gets down to 1.25V which means only about 35% of its 2000mAh is available for use, so 700mAh Monthly use is 62.28mAh for the electronics plus 5mAh self discharge = 67.28mAh 700mAh/67.28 = 10.4 months. An extra 1.7 months than the rechargeable cells and starting with a lower available mAh. The self-discharge makes the difference.
Its not quite that simple. The circuit would need more capacitance because as the internal resistance in the cells rises (as its discharged), the high current peaks for the ESP transmission need the energy reservoir of the caps to source it. (Excellent article here with measurements and examples) There is also a degree of waste involved. The AA batteries still have 65% charge left. Maybe OK for a TV remote? The rechargeables are, well, rechargeable. 1000 charge cycles for the LiFePo4 batteries seems quite reasonable, but the alkaline cells probably go in the bin. Or modify the circuit to have a very efficient micropower boost regulator so much more energy can be extracted from the alkaline cells. I have not looked into this, I’m going for low component count and simplicity. Ease of building at home.
The figures above (apart from the actual measurements) are gathered (and interpreted) from the dreaded internet so don’t take it all as rigorously defined. It should however be ball-park enough to be useful and food for thought.
So how long would a simple configuration last running on batteries…
Only one way to find out.
The circuit is very basic. An ESP12 module on a carrier, the required pull up/down resistors, and a HTU21D humidity/temperature sensor. Power source is 2 alkaline C-cells. No regulator, just powered direct from the batteries.
The two C-cells measured about 3.15V to start and the ESP data sheet says it runs down to 2.5V. Data is read from the sensor every 3-min then posted by UDP packet to a local Influx-DB on a Raspberry-Pi. UDP because its fast and the occasional lost packet is not an issue for this function.
This is the 1st (nearly) 6-months.
The steps at 1,2,3 were because when the ESP wakes up from sleep and tries to connect, on these occasions the local WiFi was missing so instead of just going back to sleep, it kept trying to connect. This had a significant impact on the battery. I found it interesting that after the battery takes a bigger discharge-hit, it recovers somewhat in the time after. This can be over several days or a week or more.
4 was when i decided to tweak the software and fix the constant-retries issue but then I discovered that a breaking-change happened when I upgraded from ESP (arduino) 2.74 to 3.02.
Now WiFi defaults to WiFi OFF at the start of a sketch so every connect takes longer. Another battery-hit from that one! Till I found the fix to change behaviour back to the old-method of WiFi ON at startup.
The green spikes are WiFi connect time. These vary considerably. This is a closer view of number 4 above.
Some connect times (in the early days) are over 10-sec which is a terrible waste of battery power. This is now changed so if no connection by 2.5-sec, it just goes back to sleep. No more retries if it fails (1,2,3 above), it now just shuts-down and tries again later. 2.5-sec is probably still too high as the green spikes for connect times are about 1.2-sec. It looks like if its not connected by 1.5-sec then its not going to happen is a sensible timescale.
This is 24hrs at the head of the graph. Almost all of the connect times are 253ms. This is slightly longer after the V3.02 changes. 247ms was the V2.74 baseline. Sometimes a 1.2-sec connection but the vast majority are pretty fast. Some gaps due to missing packets which could be because its UDP (and not a great environment), or possibly >2.5-sec WiFi timeouts. The time is measured from when millis() starts counting (prior to the user sketch beginning) till just before the UDP post.
Now the constant-retries has been fixed, and the attempt-connect time reduced to 2.5-sec it seems believable that I might get a year from this set of batteries. Battery voltage is now down to 2.85V from the starting 3.15V.
The early discharge rate was quite steep due to a combination of software (constant retries) and the initial discharge behaviour of the batteries but this has flattened out now. The major step (1) in the first graph probably lost a month or more of runtime.
Apart from my dodgy software, its doing a lot better than I thought it would. Running a WiFi sensor from batteries had never seemed that practical to me but it looks like it is more realistic than I had initially thought. Maybe it will manage a year, maybe not. Time will tell.