Extending the life of a cell connected IoT device

Extending the life of a cell connected IoT device

How do we maximize the useful lifetime of our battery powered, cell connected, IoT device? The obvious answer is to sleep and conserve power as much as possible but there are a few ways of doing this when dealing with M2M networks, like NB-IoT and LTE Cat M1, each with its own advantages and trade-offs.

To get a clearer picture under real-world conditions, tests were performed by combining a Pycom GPy, a custom extension board to host the module–manage the LiPo battery, provide peripherals like GPS, etc–and an LTE-M connection from Bell Canada.

The testing, considerations and conclusions are all demoed and summarized in this video:

and here I’ll expand on a few key points.

The M2M networks

The two flavours available for specifically for connecting IoT devices through cellular are Narrowband IoT and LTE Cat M1. Both are part of the same 3GPP standard, with each being optimized for different uses.

LTE Cat M1 is faster–it will deliver higher throughput and cross over to a different network cell during travel efficiently much like a regular cell phone. It’s great if you want to transfer a lot of data or do OTA updates.

NB-IoT, aka LTE Cat NB1, is slower than Cat M1 and will require more work when switching cell towers so it’s more geared towards static sensors, but it is very low power and the signal can penetrate further indoors or underground.

Some chipsets, like that used in the GPy, support both LPWAN technologies–but whether both are available in your location is up to providers.

IoT Connection States

A cell connected IoT device can be in either of three states:


When you first power up a GPy, even with the SIM card inserted, it is detached: the network is unaware of its existence and the LTE hardware is powered down. This is the least power-hungry state but you obviously don’t have any benefits related to network access.


When you want to talk to the outside world, the first step is to attach to the cell network. Under the hood, this process is somewhat involved

but most modems/SDKs, like that on the GPy, will hide these details. The main things we care about is how long this takes and how much energy it requires.

For the GPy, attaching basically means doing something like:

    lte = network.LTE() # get the LTE object
    lte.attach() # start the attachment process
    while not lte.isattached():
        time.sleep(0.2) # waiting

During testing, I found that the GPy would usually attach within a few seconds (4-6 seconds) but, on occasion, this could take upwards of 25 seconds. Not so great.


While you’re attached, the device is active on the cell network but, until it’s connected, it’s still lacking the setup needed to use the I.P. layer and talk to the internet at large.

To get a connection up and running, you must be attached to the network first. Then, on the GPy, the process is then similar to that for attaching, i.e.

    lte.connect() # start the connection process
    while not lte.isconnected():
        time.sleep(0.2) # waiting for conn

Once attached, the GPy connection usually happened quickly (about 1.5 seconds) but would also, on occasion, be much slower. So the average was estimated to be around 2.5 seconds.

The fact that connecting and attaching are distinct operations will help us down the line, as we decide how to best go to sleep.

Power Usage

While completely detached, the device under test would eat up about 130 mA when powered from battery but, when actually connected to the internet, this consumption becomes higher and more erratic.

Though the power needs during active use are important, and we want to strive to minimize the time we spend in this state, it’s pretty much a constant we just have to live with.

Where we can have the most effect is in deciding on the best way to go to sleep. Our choices for sleeping are the same as described above–detached, attached or connected–and the ideal selection will depend on the trade-offs we want to make.

Obviously, you’re dead to the network when sleeping detached but this also provides the most energy savings. On the GPy with the extension board, we get down to below half a milliamp when sleeping deep in this manner.

Biggest downside–other than dropping any incoming SMSes and such–is that getting back into connected state from fully detached takes the longest amount of time. So if you plan to wake up often and transmit over the cell network this can quickly become more expensive than other sleep methods.

Sleeping while disconnected but attached is a good middle ground: the connection process is much faster and you can receive SMS messages, but the cost is higher sleep current. In my tests, this hovered below 1.5mA most of the time, but the occasional spikes up to 40 or 50 mA eventually add up and make it so the average consumed sleep current is closer to 4 or 5 mA.

Finally, sleeping while connected might let you receive (and wake from) push notifications from a server and is the quickest to re-establish data exchanges but, in the tests run here, this was wildly expensive compared to the other options. The baseline sleep current in this case was above 20mA and it kept spiking around, sometimes into the hundred mA range meaning you’ll need a very hefty battery to keep this up for any amount of time.

Comparing approaches to sleep

Since the final amount of charge we’re going to suck out of the battery is partially dependent on

  • the current required during sleep; and
  • the amount of sleep we get to do

and that amount of sleep will depend on:

  • the number of times we wake and communicate over the network;
  • how long it takes us to get work done while we’re awake; and
  • how long we need to wait to re-establish connectivity

the best trade-off will depend on how many updates we intend to make in a given period. As demonstrated in the video, the actual numbers and transition points will change according to how long we spend awake working at whatever our task is, but we can use some reasonable values to investigate the question more concretely.

In the graph below, we’re estimating 5 seconds of work time when awake at an average current of 175mA. The graph shows the differences between the amount of charge required in a day depending on the number of wake/update cycles we intend to do, for each of the three sleep scenarios.

The difference in connection setup time between being fully detached and sleeping while attached makes it such that it becomes more efficient to sleep attached–even with the extra sleep current implied–if we start waking and transmitting more often than every 4 minutes or so (i.e. ~350 updates per day).

As we increase the number of wakes and connections, the added delay of having to reconnect eventually becomes more energy hungry than simply staying connected (when sending updates every 30 seconds, or less).

If we can lower the work-time power requirements, say to an average of 75mA, then the total energy expenditure is lower and the initial attach time has even greater weight, thereby increasing the range where staying attached (but disconnected) is the best option (anything between updates every 2 minutes to updates every 16 seconds).


Caveats and notes

These graphs and comparisons assume all these connection events are the same and evenly spaced throughout the day.

Adding some intelligence to the system can really help and modulate the best approach to sleep.

For instance, you may be able to wake only every ten minutes so long as there’s no motion–accelerometer, change in GPS, whatever–and only send an update once an hour. In this case, the best option is to sleep completely detached and only connect as needed.

Then, when things start happening (coordinates change, the accel is going wild…), we keep an eye on the situation and update frequently.  Maybe that means staying connected for a bit and going back to deep sleep after things calm down.

Short version: adapting to the actual needs and use case is paramount.

Happy experimenting, may all your devices endure years in the field.