On a LiPo battery!

This tutorial illustrates how to optimize the energy when the TeensyWiNo is powered by a LiPo battery.

Connecting a LiPo battery

The TeensyWiNo can be powered by a LiPo battery via the battery connector. It embeds a LiPo charger to recharge any LiPo battery. Do not connect another battery type on this connector. When the LiPo battery is connected, the TeensyWiNo acts as a charger as soon as the USB is powered. When the charger is on, the dedicated red LED automatically turned on (no control by software). When the LiPo battery is full, this LED is turned off.

The TeensyWiNo battery connector LiPo charger active: charger LED on

Theoretical energy consumption

The two mains energy consumers on TeensyWiNo are the MCU (Teensy) and the transceiver (RFM22b). When designing an application, remember that:

  • The higher the MCU frequency, the higher the energy consumption,
  • the transceiver consumes energy even in reception and idle modes.

The following table summarizes the power consumption of the MCU (Teensy: Freescale MK20DX256 VLH7) and the transceiver (HopeRF RFM22b) (source: datasheets).

Compoment State/frequency Power
Teensy Working, 96MHz 129mW
Teensy Working, 72MHz 103mW
Teensy Working, 48MHz 88.8mW
Teensy Working, 24MHz 55.5mW
Teensy Working, 16MHz 32.9mW
Teensy Working, 8MHz 22,2mW
Teensy Working, 4MHz 14.8mW
Teensy Working, 2MHz 5.18mW
Teensy Sleep, any freq, LPTMR wake 2mW
Teensy Deepsleep, any freq, LPTMR wake 650μW
Teensy Hibernate, any freq, LPTMR wake <30μW
Transceiver Transmit (10dBm) 76mW
Transceiver Receive 57mW
Transceiver Idle 26mW
Transceiver Sleep <5μW

Enabling sleep states on the MCU and transceiver

The best way to save the battery is enabling sleep states on both MCU and transceiver.

On the transceiver

With RadioHead, enable the RFM22b sleep mode with:

1
  rf22.sleep();

The transceiver enters in sleep mode just after calling the sleep() method; it then consumes less than 5µW and does not receive messages anymore until waking-up. Wake the transceiver by calling recv(), send()… as indicated in the RadioHead documentation.

On the MCU

Enabling the sleep states (sleep, deepsleep and hibernate) of the Teensy is easy using the Snooze library. The examples sketches work out-of-the-box on the TeensyWiNo.

Note that the USB Serial is lost when the Teensy enters sleep mode.

Benchmarking!

The lifetime on battery depends heavily on actions on the MCU and the transceiver. Here is an example of a simple code that:

  1. Get the temperature using the BMP085,
  2. Get the voltage and charge of the LiPo battery,
  3. Send these data on radio in an ASCII JSON string,
  4. Wait 50ms for nothing,
  5. Turns the transceiver on sleep mode,
  6. Turns the MCU on sleep mode for 10 seconds.

and can be used to evaluate the lifetime of a TeensyWiNo on a battery.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <MAX17043.h>
#include <Snooze.h>
#include <RH_RF22.h>
 
#define LED_BLUE_PIN 6
 
MAX17043 batteryMonitor;
Adafruit_BMP085 bmp;
RH_RF22 rf22(SS,9);
 
SnoozeBlock config;
uint8_t rfbuf[RH_RF22_MAX_MESSAGE_LEN];
uint8_t rflen = sizeof(rfbuf);
 
 
void setup()
{ 
  pinMode(LED_BLUE_PIN, OUTPUT);
  SPI.setSCK(14);
 
  if (!rf22.init()) while(1);
  if (!bmp.begin()) while(1);
 
  // Configure PHY layer
  rf22.setTxPower(5);
  rf22.setModemConfig(RH_RF22::GFSK_Rb125Fd125);
  rf22.setFrequency(433.7, 0.05); &nbsp;
 
  // start LiPo gauge sensor
  batteryMonitor.reset();
  batteryMonitor.quickStart();
 
  config.setTimer(10000); // milliseconds
}
 
 
void loop()
{
  // Get information from sensors
  float temperature = bmp.readTemperature();
  float cellVoltage = batteryMonitor.getVCell();
  float stateOfCharge = batteryMonitor.getSoC();
 
  // LED_ON, make and send the message, than LED OFF
  digitalWrite(LED_BLUE_PIN, HIGH);
  sprintf((char*)rfbuf, "{\"temp\":%.1f,\"bat\":%.1f,\"volt\":%.2f}", 
          temperature, stateOfCharge, cellVoltage);
  rf22.send(rfbuf, strlen((char*)rfbuf));
  rf22.waitPacketSent();
  digitalWrite(LED_BLUE_PIN, LOW);
 
  // Sleep mode for transceiver, than for the MCU
  rf22.sleep();
  Snooze.hibernate(config);
}