HowTo: Reduce sensor’s WiFi communication to use 300 times less power

The Problem

Many devices with sensors spend the majority of time in deep sleep, wake up, take a measurement, communicate it over WiFi and go back to sleep.

WiFi communication is typically the step that takes the longest and consumes the most battery power.

How do we optimize our code to spend less time being connected to and communicating over WiFi?

Solution

Don’t communicate the measurement unless it is a certain percentage larger or smaller than the previously reported measurement.

Results

This algorithm change resulted in my sensor/Wemos D1 Mini combo consuming three hundred (300!) times less power over same time period.

You can find a simple Lua code sample that illustrates this solution below the following details.

Details

I have a battery powered moisture sensor that takes a measurement roughly every 15 minutes. I worked on optimizing its deep sleep and was able to do that, but then I wanted to focus on the meatier part of its power consumption.

Now I take the measurement and before connecting to WiFi to communicate the value to my MQTT broker I read the last communicated value stored in a file.

If the value is within 5% of the latest reading I simply go back to sleep and skip the entire WiFi step. If there is no previously communicated value or it has changed enough, then send over MQTT and update the value stored in the file.

Of course, the magnitude of improvement that this optimization will deliver to your project depends on how volatile your measurements are or how granular your reporting needs are.

If your values change a lot between readings or you need to know about every slightest change, this is not for you.

In the case of my moisture sensor though it was a dramatic improvement. The sensor communicated once every 5 hours on average instead of 4 times/hour.

Using a Wemos D1 Mini + moisture sensor’s average WiFi connected consumption of about 85mA vs non-WiFi 30mA we can do some math:

Default way: (4 times / hour) * (6 seconds of connecting and communicating / time) * 5 hours = 120 seconds. Which is about 120 / 3600 * 85 = 3mA.

Optimized way: (4 times / hour) * (0.5 seconds / time) * 5 hours = 10 seconds. Which works out to 10 / 3600 * 30 = < 0.01mA.

In my case, that’s 300 times less power consumed in the same amount of time! Incredible, considering the ease of implementation.

Sample Code

I’m using Lua programming language in my ESP8266 projects but this can be easily translated to any other language of your liking.

local last_reading_file_name = 'last_reading.txt'
local reading = nil

local get_last_reported_value = function()
  if file.open(last_reading_file_name, 'r') then
    local last_val = tonumber(file.read(100))
    file.close()
    return last_val
  end

  return nil
end

local save_last_reported_value = function()
  if file.open(last_reading_file_name, 'w') then
    file.write(reading)
    file.close()
  end
end

local read_value = function()
  reading = adc.read(0)

  local last_value = get_last_reported_value()
  local percent_change = (math.abs((last_value or 0) - reading) / reading) * 100

  if last_value == nil or percent_change > 5 then
    connect_to_wifi_and_publish_to_mqtt("your_topic", message, qos, retain, sleep_function)
  else
    sleep_function("Skipping reporting over WiFi, change: " .. percent_change .. "%")
  end
end

read_value()

sleep_function and connect_to_wifi_and_publish_to_mqtt are outside of this post’s scope and will be very specific to your project.

Please let me know if this was helpful to you and if wanted me to expand on anything in this post.


Posted

in

by

Comments

2 responses to “HowTo: Reduce sensor’s WiFi communication to use 300 times less power”

  1. Michal Avatar
    Michal

    As you said, it’s not applicable everywhere, but it’s a good hint to think about your code while programming esp.

    1. Alex Avatar
      Alex

      Exactly, it’s not a silver bullet but good to keep in mind and could be an incredible strategy in many situations. Especially considering how easy it is to implement.

Leave a Reply

Your email address will not be published. Required fields are marked *