Designing Battery/Solar Support for a Deep Sleep System with ESP8266

I have a project designed to wake every two hours, gather data, and send it to Firebase or ThingSpeak. This system is supported by both a solar panel and a 750mAh LiPo battery using a power path load-sharing setup. The sensors include a few DS18B20s, set to operate on 8 bits to speed them up. I use a bare ESP8266-12F soldered on a support plate, without an FTDI chip. The goal is to see how long this would remain active. The project box was closed and put in the sun on May 1, 2024. Software updates were done by on-demand self updating OTA1. Here’s an overview of the energy consumption:

Energy Consumption Overview

  • 150mA for 0.5 seconds: When WiFi is active.
  • 50mA for 0.5 seconds: When the ESP8266 is awake but WiFi is off (sensor reading phase).
  • 7μA for the remaining time: During deep sleep.

Over a period of 2 hours, the energy consumption is as follows:

  • Deep Sleep: 7μA * 2 hours = 14μAh
  • WiFi Active: 150mA * 0.5s = 75mAs
  • Sensor Reading: 50mA * 0.5s = 25mAs

Total energy used in 2 hours:

  • 100mAs + 14μAh = 0.014mAh
  • 100mAs = 100/3600 = 0.0278mAh
  • Total: 0.0418mAh or 41.8μAh in 2 hours

With a 500mAh battery, the theoretical duration would be:

  • 500mAh / 41.8μAh = 11962 periods of 2 hours
  • 23924 hours = 998 days ≈ 2 years 8 months 12 days

Considering inefficiencies, if we can use only half the battery capacity:

  • 1 year 4 months 1 week

Solar Panel Contribution

  • Solar Panel Specs: 6V, 2W (i.e. 333mA)
  • Effective Sunlight: Estimated at 500 hours/year due to fixed position.

During these 500 hours, the panel charges the battery and powers the ESP8266. This could extend the battery life by roughly an additional 21 days, leading to an estimated total lifespan of about 1 year and 9 months. This estimate feels optimistic, so practical testing is necessary.
So, is adding a solar panel useful? A typical amateur project will contain a cheap panel, a TP4056 battery charger, and a LiPo battery. Ideally, that setup requires a load-sharing power path. This prevents the battery from being charged by the solar panel while it is also discharging by feeding the ESP8266.

TP4056 Specifications
  ParameterValue
Voltage Supply (Vs)4V0 ~ 8V0
Charge Voltage termination (accuracy)4.2V(1.5%)
Supply current (Rprog=1.2k: 1A chrg)150uA (typ)
Supply current (Chrg ended/ shutdown)55uA (typ)
Ibat (Rprog=1.2k: 1A chrg )1050mA (max)
Ibat (Stand by mode; Vbat = 4.2V)-6uA (max)
Vtrckl(Rprog=1.2k: Vbat:rising)2.9V (typ)
Itrckl (Rprog=1.2k: Vbat<Vtrckl )140mA max)
Vtrhsy(Rprog=1.2k)80mV (typ)
Operating temperature-40°C ~ 85°C
[trckl = Trickle charge, trhsy = Trickle Charge Hysteresis]

          

A load-sharing power path switches between using the solar panel to feed the ESP8266 and charge the battery when there is enough sunshine and switching to the battery for feeding the ESP8266 when there is not enough sunshine. Such a ‘switch’ basically uses two Schottky diodes (though one can be replaced by a pFET), one in the solar panel line and one in the output of the battery (through the TP4056). These Schottky diodes do have a voltage drop.

For example, say you have an LDO voltage regulator with a voltage drop of 100mV and a Schottky diode with a voltage drop of 200mV. You are losing 0.3V of your battery voltage. The minimum voltage for stable operation is 2.5V, but if you already lose 0.3V, the minimum battery voltage at which the ESP8266 will stop working is 2.8V. This might not be a big issue, as ideally, you should not discharge your batteries below 3.3V anyway. Modern TP4056 modules have discharge protection (through a DW01 FET), but that cuts off at 2.5V. This may be okay for some 18650 batteries but not for most LiPo batteries. (More about powerpaths here). The added protection by the FET’s is limited since the TP4056:

  • Stops discharging at voltages below 2.9V; Here trickle charge activates.
     As the DW01A threshold is ~ 2.4V, it will never activate.
  • Stops charging at voltages above 4.2V.
     As the DW01A threshold is  ~ 4.3V, it will never activate.

The only function that will operate is the over current protection and short circuit protection (or fail safe if the TP4056 chip fails – fairly unlikely). These FETs will activate at around 3A

A standard TP4056 module is preprogrammed for a 1Amp current through the usual 1.2kOhm resistor. Obviously that is a bit too much to deliver for the 333mA solar panel and it’s voltage may drop, so we may want to jack it up to a 4 k resistor, giving only a 300mA charge.
Rprog on the breakout board is R3.

Rprog (kΩ)IBAT (mA) (calculated values)
10130 (120)
5250 (240)
4300
3400
2580 (600)
1.66690 (723)
1.5780 (800)
1.33900
1.21000
Program resistor vs charge current2

Any other charge current can be set by changing Rprog according to the formula:

So say you wanted a Charge current of 750mA that would need Rprog​≈1600 Ω (1599,96 Ω to be precise).

There is some discussion on the internet whether a solar panel can be used with the TP4056 module. Andreas Spiess, in a youtube video claims it can, while others say it can’t as the TP4056 “only knows 5 Volt or 0 Volt and nothing in between”. That might be so, but my experience is that it can be used and will charge your battery, but obviously it will only work in bright sunshine, when 5 Volt will come off of your solarpanel.

One thing is clear: a small solar cell may ideally add 3 weeks to the operational period by relieving the battery from its function, but it is difficult to calculate how much it will actually add by putting charge into the battery. Regardless, it may be more beneficial to just add a battery than to use a solar panel.

Monitoring Battery Voltage

Direct Measurement

One common method is using a voltage divider (e.g., 420kΩ over 100kΩ) to connect the battery to the A0 pin of the ESP8266. This approach, however, results in a continuous current draw, increasing energy consumption by about 25%. An alternative is using a FET as a high-side switch to reduce this loss.

Indirect Measurement

Another option is monitoring the supply line voltage using ADC_MODE(ADC_VCC) and ESP.getVcc(), which gives a 10-bit reading of the rail voltage. Since the ESP8266 is powered through a voltage regulator, this voltage should always be 3.3V unless the battery voltage drops below 3.3V plus the regulator’s drop voltage (typically 90-300mV). This method provides an early warning when the battery is not giving adequate power, but one might miss the gradual change preceding it.
An interesting thing i did see here is that the reading of the Vcc was a solid 3.3 Volt, but that each time after a self-update of the firmware, the read voltage would show a dip to 3.01 Volt.

Considerations for Accuracy

The ESP8266’s ADC is not highly accurate, even with 10-bit resolution. Multiple readings can improve accuracy but at the cost of prolonged awake time. It’s more reliable when WiFi is off, which suits deep sleep projects. Note that ADC_MODE(ADC_VCC) is only viable if nothing is connected to the ADC pin. On boards like Wemos and NodeMCU, a voltage divider between A0 and the ADC pin further reduces accuracy.

In conclusion, while the theoretical calculations provide a promising outlook for battery life, I will need to do practical testing to see what is the best solution and to see if some of my assumptions were valid.

Heat

Given that a solar project is bound to be in the sun, heat can become a problem. When the ESP8266 is in rest, heat can come from different sources:

  • direct sunlight on the solarpanel
  • heat generation in the TP4056 as it is charging the battery at (standard) 1 amp and has to dissipate that over a voltage drop of about 1 Volt.3

The image below shows the increase in temperature in a small project box exposed to sunlight (not seldomly going up to 65 degrees celsius, but for now without any ill effects). The only effect that i noticed upon a temperature rise was that the sleep period was getting slightly longer, say 4-6 min on 2 hrs. let’s call it the ESP8266’s siesta. However point of concern remains that 6o degrees is not an ideal temperature to charge a LiPo battery and it is of course under the same circumstances that cause the high temperature, the battery will receive most of it’s charge.

Having a separate solar-panel with a wire going to the box that keeps your electronics and keeping that in the shade, might be an option

Using energy guzzlers

I am only using DS18B20 sensors, but in any given project, some elements may be constant energy users and drain your battery. An example for instance is a voltage divider that is used to check on battery status. Usually those are 420k, leading to an extra load of some 8-10uA. It becomes worse if perhaps you are reading several resistive soil humidity sensors (and of course using an ADS11115 or similar). Often these add about 20 kOhm per channel, which easily adds 840uA for the voltage dividers+150uA for the ADS1115 (though the latter will be reduced to 0.5uA in ‘one shot mode’ which is what you would typically need in a deepsleep application). This can be avoided by feeding those elements from one of the I/O pins of the ESP8266 which can deliver 12mA. It is important then to use a pin that is LOW in sleep state (eg GPIO15).

If for whatever reason you need to use peripherals that need more than 12 mA, it is best to give those a separate regulator with an enable pin, such as the RT9013, the SPX3819, the ME6211 A &H, or XC6204. Obviously those will need 2 capacitors (input and output). usually around 10hf. These will need 0.5 mSec (500microsec) to charge and will need 15.125 nanowatt-hours (nWh) to charge from 0 to 3V3. a good quality capacitor will keep that charge for a while though

  1. This means that I put new software on a server and the ESP8266 on wake up checks to see if there is new software to download. ↩︎
  2. Obviously the datasheet table seems not totally correct: 1.5k gives 800mA, 1.66k gives 723mA, 2k gives 600mA, 5 k gives 240 and 10K 120mA ↩︎
  3. For illustration: In a confined space of 9x5x3 cm (135 cm3), presuming there is no energy loss, one Watt of energy can heat up the air in that box with 6 degrees per second ↩︎