Low-Power Operation

The uC/OS-II library shipped with the

On-Chip Software Development Kit

has been customized to ensure low-power operation. While the customization does not affect the way your application interacts with it, it does ensure that the

LTC5800

chip is automatically put into low-power state when no task is executing.

Your application is not aware of these optimizations. In particular, your application does not have to do anything for the chip to go into low-power state, since this is handled entirely by the uC/OS-II library.

Your application has access to all devices and peripherals on the 

LTC5800

 chip, and controls the 

SmartMesh network stack

. This means that it has a major influence on the energy consumed by the device.

What follows are some "best practice" tips for keeping that consumption as low as possible.

Packets Size and Frequency

Very often, your application will collect small samples from sensors, possibly only a handful of bytes for each sample.

Recommendation

For applications collecting data frequently, we recommend that several sensor readings be grouped into larger packets (which you send infrequently) if at all possible. Sending packets into the network as infrequently as possible will minimize the amount of power used.

For example, if your application collects a 2-byte reading from a flow sensor every second, we recommend you cache those readings, and send a packet with 80 bytes of application payload every 40 seconds, rather than sending one packet with 2 bytes of application payload every second.

The reason is that wireless communication accounts for most of the energy budget of your device. Sending large packets infrequently has the following advantages over sending small packets frequently:

  • Apart from your application payload, all packets contain header bytes to ensure correct and secure delivery of your data. The overhead associated with sending and receiving those bytes is the same whether you send a small or large number of payload bytes. If therefore makes sense to send as small a number of packets as possible.
  • Similarly, sending a packet involves starting up the radio's RF chain on both the transmitter and the receiver, and exchanging an acknowledgment packet for the receiver to indicate successful reception.
  • This overhead is all the more important that your device can be located multiple hops from its destination. No data aggregation is done in the network, so if you send 5 packets, 5 separate packets will be traveling along the multi-hop route between your device and the destination. This means that the overhead associated with sending many small packets is accounted for at each wireless hop.

Services and Actual Data Rate

After joining, your application requests a service, which can be seen as a data "pipe" your device can send data through. When requesting the service, your application indicates the value of the service. For a service of type "bandwidth", this corresponds to the number of milliseconds between any two consecutive packets. If a 

SmartMesh mote

 requests a service with value 10000ms, it is indicating to the 

SmartMesh manager

 that it plans on sending one data packet every 10 seconds. In the analogy above, the value of the service is equivalent to the thickness of the data pipe.

Once your application requests this service, the 

SmartMesh manager

 installs and maintains enough resources to satisfy this request, along the multi-hop route between your device and the destination. These resources are links in the communication schedule. The 

SmartMesh manager

 will not monitor how much data traffic your application actually sends through this data pipe. If your application requests a service of value 10000ms, and only sends one packet every 30s, this will result in energy being wasted. The reason is that, even if your application does not send a packet, the devices along this packet will listen for possible data.

Recommendation

We recommend that your application requests services which match the interval that data will actually be sent.

Busy-waiting/Polling

When your application is waiting for an event to happen, it is possible to implement a busy wait. In addition to being energy-inefficient, this approach prevents lower priority tasks from executing and may result in erroneous operation. 

For example, if your application is waiting for a pin to go high, you could, in one of your application's tasks, read the value of that pin in a loop, and exit the loop when the value read indicates that the pin is high. This is called busy-waiting since the micro-controller is continuously busy (in this case reading a GPIO pin), while waiting. 

A better way for waiting for a pin to transition is to enable the pin's notifications at the driver level. Your application can then sleep while waiting for a callback function to be called by the GPIO driver.

Another example is synchronization between tasks in your application. If task A is waiting for task B to do some operation, you could have both tasks share some variable, and have task A continuously read the value of that variable while waiting for task B to set it. Apart from obvious concurrency issues, this also results in wasted energy.

A more optimal way to synchronize between different tasks in your application is to use a uC/OS-II synchronization primitive such as a semaphore. In this case, your task A can pend on a shared semaphore, which task B posts whenever ready. The uC/OS-II scheduler then handles the synchronization in a way that does not involve busy-waiting.

Use driver notifications and uC/OS-II task synchronization primitives instead of busy-waiting.

Battery Load Resistors

To assess the depletion level of your battery, your application can enable internal battery load resistors before measuring the supply voltage. This is detailed in the 

SmartMesh On-Chip API html documentation

. When enabled, current flows through those resistors. While this is needed for evaluating the depletion level of some batteries (by measuring their internal resistance), your application should disable those load resistors directly after the measurement is done.

Enable the battery load resistors only when needed.