Very DeepSleep and energy saving on ESP8266 – Part 2: Sending data with HTTP

In an earlier post,  I showed how to  try and do some major energy saving in case you are using a battery. I gave a working framework sketch, that did all but actually read data or send data as it just focussed on the energy saving.

Though it isn’t hard to add that to the program, as I indicated where you could add a ‘read sensor’ and ‘senddata’ procedure, I realize that that may still cause some obstacles for a beginner, so I will show how to add some code to send the data somewhere.

Though MQTT is a popular way to send data, in this example I have chosen to send data to a MySQL database (in fact I am using MariaDB, but that works the same).

As there is no reason to reinvent the wheel, for setting up the database and the needed  php files, I refer to the randomnerdstutorial website that has 2 excellent tutorials about this. We will use their server-side code (database and php files) to send the data to.

We will use the BME280 to gather the data.

Since the BME280 is used as I2C device, we need to inlude the Wire library. As we will use the Adafruit library to read the data, we will actually need two  more libraries, that we add in the global section of the program. We will also declare the object:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h> //defaults to 0x77, change that if yr BME is 0x76
Adafruit_BME280 bme;

In the Setup() section, we have to initialize the library.  The library defaults to the BME having an I2C address of 0x76, but if you happen to have a 0x77 module, here is where you can change the default.
We then do am optional check to see if the BME280 is detected and in principle you are good to go. However, in my previous article I mentioned you could put the BME280 to sleep in between readings and that is what we will do. Therefore for now I only added a jump to a procedure that i call ‘BMEsetup’. We will fill it in later

//bme.begin() will return True if the sensor was found, and False if not. If you get a False value back, check your wiring!
status = bme.begin(); //bme.begin(address) 0x76 or 0x77
if (!status) {
Serial.println("no BME detected");
BMEsetup(); // set weathermonitormode

So now we have to do 2 things: we have to read the sensor  and send those in an HTTP request.

As we are using Forced Mode we have to wake the sensor and tell it it has to take a new measurement:


We can read the sensor and  build  our HTTP request string in one go like so:

// Prepare your HTTP POST request data

httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName
+ "&location=" + sensorLocation + "&value1=" + String(bme.readTemperature())
+ "&value2=" + String(bme.readPressure() / 100.0F) + "&value3=" + String(bme.readHumidity())+ "";

Sadly, the Adafruit library is extremely inefficient in reading the data. The datasheet advises a ‘burst read’ of the data, both for speed and to prevent mix-up of data. The adafruit library has chosen to do separate register readings, but to make matters worse, it precedes the pressure and humidity readings each with a temperature reading first, which is then discarded. So 3 measurements become 5 which adds at least 4 ms to the total. As we are reading the temperature first in our httprequest string, we could opt to remove the extra reads from the Adafruit library. The Sparkfun library does not have these extra reads.

The total conversion time of the 3 measurements comes to 13msec and it is better to do that while the radio is still off, especially when the library adds anothe 4 msecs

As I plan to send the http request in a seperate procedure (to keep it all clear and transparent), we have to define the String variable httpRequestData as a global variable (by adding it in the global section of the program), like so:

String httpRequestData;

Then it is time to Switch the WiFi on like described before and make our http request.

void sql() {
//Check WiFi connection status
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;

// Your Domain name with URL path or IP address with path
http.begin(serverName);// deprecated.

// Specify content-type header
http.addHeader("Content-Type", "application/x-www-form-urlencoded");

// Send the request and collect the response
int httpResponseCode = http.POST(httpRequestData);

if (httpResponseCode > 0) {
Serial.print("HTTP Response code: ");
else {
Serial.print("Error code: ");
// Free resources
else {
Serial.println("WiFi Disconnected");

The http.begin(serverName); command, is or will be deprecated in near future. I understand the proper command then will be: http.begin(client,serverName);. Current code is working.

Now we only have to define the BMEsetup routine that we called earlier. Thats an easy one:

// weather monitoring
void BMEsetup() {
Serial.println("-- Weather Station Scenario --");
Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
Serial.println("filter off");
Adafruit_BME280::SAMPLING_X1, // temperature
Adafruit_BME280::SAMPLING_X1, // pressure
Adafruit_BME280::SAMPLING_X1, // humidity
Adafruit_BME280::FILTER_OFF );

Download the entire file here.  After you got it working feel free to delete the print statements.

A word on voltage monitoring
In my previous article I mentioned that voltage monitoring -a popular thing to do when using a battery- needs a voltage divider that can be a considerable, constant drain on on the battery.
If you are using a LiPobattery that can be as high as 4.2Volts, a 320k over 1ook voltage divider is a decent choice, but still adds to a discharge of the batteries. From that aspect, measuring the internal Vcc is an interesting alternative.
Sure, if you use a stabiliser to get the battery voltage down to 3.3 Volt, initially you have no info on the battery voltage, but you will know when it gets critical.
Presume you have an HT7833 that has a voltage drop og 360 mV. Suppose the output is a rock solid 3.3Volt, then the only thing you know is that your battery is still OK, i.e >3.63 Volt. The moment your Vcc drops below 3.3Volt you know yr battery is dropping below its nominal 3.7 Volt, while there still is plenty of juice to feed your ESP.
If you want to monitor the internal Vcc, then just add.


to the declaration section and read the voltage with


Adding fields
Should you want to add a field, e.g. for the battery voltage, then there are several things to do:

    1. add  String(ESP.getVcc()/1023.0F) to the httpRequest string
    2. add a field to the database. you can do that with
      ALTER TABLE yourtable ADD newfieldname VARCHAR() after fieldname

      but it is better to use your own specific database management system. (I use webmin)

    3. Adapt the post-esp-data.php file to collect and store data, to cater for an extra field. Go ahead, try, it is simple
    4. Do the same for the esp_data.php file

The best board to use would be an ESP12F:

In a follow up article I will show how to implement MQTT with this deep sleep example

Part 1 -DeepSleep General
Part 2 -DeepSleep HTTP publishing
Part 3 -DeepSleep MQTT Publishing
Part 4 -DeepSleep MQTT Subscribing
Part 5 -Deepsleep ESP-NOW
Part 6 -Power Down

11 thoughts on “Very DeepSleep and energy saving on ESP8266 – Part 2: Sending data with HTTP”

  1. Very in depth blog post! Liking it, what is the total on time and average current consumed in wake and sleep? I would think shaving of a few ms doesn’t really matter since the HTTP request takes hundreds probably.

    1. Thank you for your kind words Bart. I am not sure exactly what i measured at that tim in sleep, i seem to recall it was around 6uA but that with a regular multimeter so i am not sure to what extend it is correct. Might have been lower, even around the level of spontaneous decharge of batteries. Awake it just followed the regular energy consumption of the 8266 but i only measured the average, not the peaks, which was 60mA as i recall. I can’t remeasure as i only used it for testing. My main interest was see how i could minimize it as much as possible in several ways. The main save is by trying to keep the sleep as long as possible, which might be different from project to project.
      Advanced merry christmas and stay safe

  2. I’m trying to adopt this for HTU21 and SR-HC04 but I wasn’t able to compile the code on GitLab >> ‘calculateCRC32’ and ‘BMESetup’ was not declared in this scope. I’m using VSC with PlatformIO. Not sure this makes any difference. Is this an interim code version?

    1. Sorry to hear that. It is not an interim version and should compile fine. I am not usinv VSC so i do not know of any intricacies there that could cause this. I will try to compile the code myself later when i get home

    2. Thomas. I downloaded the code and compiled in the IDE (I do not use VSC/Platformio) compiles without problems. Sadly i do not know enough about the setup of VSC/PlatformIO to suggest where the problem lies. Only thing I can say is that the code is OK

      1. Ok thanks for checking. I managed to get it to compile but had to move ‘calculateCRC32’ and ‘BMESetup’ and ‘sql’ further up in the code – before the setup() function. Weird that the platform would make that difference

      2. That indeed is peculiar. I do know that e.g. in older versions of the IDE you had to declare your functions/procedures, maybe Platformio expects that too.

  3. So I was able to successfully adopt your code (thanks) and I can write to the database. However I need to set the endpoint to ‘http’ as opposed to ‘https’ which I’d prefer. Have you done any work as part of your DeepSleep project on ‘https’?

    1. I am a bit confused about what you are asking. The endpoint is http and not https.
      I have not done work on https as part of deepsleep but i have used it in some other projects in here such as upload to GoogleSheet and Telegram. Using it with DeepSleep should not propose any additional pronlems

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.