Close

Power consumption tuning and other

A project log for Wireless solar-powered sensor node

A solar-powered node that stores energy in a supercapacitor, wakes-up regularly, measures different parameters, and sends them to a gateway

strangerandstrange.rand 11/01/2020 at 11:050 Comments

Since I'm still waiting for PCBs and components decided to play a bit with software for the node to optimize power consumption.

Initial values:

First of all, seems I mixed up the power consumption of RFM69W and nRF24L01+ (some time ago I tried to use this transceiver, but then switched to the current one), so now the peak current is around 45 mA, a bit bigger than I initially thought. It's not a big deal, but it should be taken into account.

Measured 4 uA during deep sleep is okay as for me, I use a regular multimeter with 1 uA precision and (0.8% + 1) accuracy so it isn't really precise value. I won't tune power consumption during the transmission part, though it can be easily decreased with decreasing transmission power. And now only one candidate is left - idle mode.

To program ATmega328P, PlatformIO and Arduino framework are used. By default, in this framework, all periphery is enabled and consumes power, let's try to switch something off. There are two cases: some modules are not needed at all (timers 1 & 2, UART), some required only during a short period of time (SPI, TWI, ADC, etc.).

Due to the microcontroller limitations, I cannot specify a deep sleep period greater than 8 seconds, so every 8 seconds it wakes up to increase a counter and check if the overall sleep duration is greater than required value or no. If yes - it runs the main job, if not - goes to sleep again. During that time all peripheral modules are not needed and should be turned off.

#include <avr/power.h>

ADCSRA = 0; // turn ADC off
power_adc_disable();
power_spi_disable();
power_timer0_disable();
power_timer1_disable();
power_timer2_disable();
power_twi_disable();
power_usart0_disable();

The code above reduces power consumption from 2.65 mA to 2.26 mA, not much, but it is for free.

According to the microcontroller datasheet, all unused pins should be in output mode with a pull-up/down resistor. I already tried this trick to reduce deep sleep power consumption with no effect, but it helps when MCU is working.

#include <Arduino.h>

const uint8_t pins[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 15, 16, 17};
for (uint8_t i = 0; i < sizeof(pins); i++)
{
  pinMode(pins[i], OUTPUT);
  digitalWrite(pins[i], LOW);
}

 This code reduces power consumption to 1.95 mA.

We could save a bit more power disabling modules right after using them, e.g.:

  1. turn on all required modules
  2. read power supply voltage
  3. disable ADC
  4. read sensors data
  5. disable TWI
  6. send data to a gateway
  7. disable rest of modules

I would say that it looks like over optimization, but it is possible and not really hard. The final node's software will be open source and will be published on my GitHub closer to the final stages of the project.

An additional experiment

A few days ago Tomáš asked a good question about supercap's ESR and max current. Initially, I thought that ~25 mA in a peak shouldn't be a problem, but then ~25 mA were transformed into ~45 mA, and I decided to check.

The chart above shows the voltage on the supercapacitor during the data transmission. There are three series:

As you can see, transmission takes about 6 ms, and without an additional capacitor voltage drops by ~0.5V. Surprisingly, when supercapacitor is discharged to 1.8V the node is still functional and sends data. I suspect that transmission power at those stages could be lower, so currently, I'm collecting RSSI for each data package to prove or disprove this (with less power RSSI should be smaller).

That's all for now.

Discussions