Skip to content

EnergyTrace

Travis Goodspeed edited this page Oct 27, 2019 · 4 revisions

Profiling CC430 Power with EnergyTrace

Howdy y'all,

This quick little article explains how we perform power profiling, with greatest concern for the average power consumption case. The hardware used will be a recent (MSP430F5528-based) TI FET wired to a GoodWatch, and the software is energytrace-util from the Pluto Watch project.

--Travis KK4VCZ

Hardware and Wiring

To profile the GoodWatch, you need to wire its board to a JTAG FET that supports power profiling. I use the MSP-EXP430FR4133 kit, which can be had for $15 on Digikey. The actual target portion of the board is unused, and only the eZ-FET portion is active.

Remove the 0.1" jumpers to disconnect the old target board, then run four jumper wires to a GoodWatch. In addition to VCC and GND, run SBWTCK to TX and SBWTDIO to !RST.

Flashing Firmware

Like the BootStrapLoader, the SBW connection can be used to flash the firmware and read the kernel boot messages. To flash the firmware, use make sbwflash.

nuc16% make sbwflash
mspdebug tilib "prog goodwatch.elf" "load codeplug.hex"
MSPDebug version 0.25 - debugging tool for MSP430 MCUs
Copyright (C) 2009-2017 Daniel Beer <[email protected]>
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Chip info database from MSP430.dll v3.13.0.601 Copyright (C) 2013 TI, Inc.

Using new (SLAC460L+) API
MSP430_GetNumberOfUsbIfs
MSP430_GetNameOfUsbIf
Found FET: ttyACM1
MSP430_Initialize: ttyACM1
Firmware version is 31300601
MSP430_VCC: 3000 mV
MSP430_OpenDevice
MSP430_GetFoundDevice
Device: CC430F6147 (id = 0x00f5)
3 breakpoints available
MSP430_EEM_Init
Chip ID data:
  ver_id:         8135
  ver_sub_id:     0000
  revision:       10
  fab:            55
  self:           5555
  config:         10
  fuses:          55
Device: CC430F6147
Erasing...
Programming...
Writing 4096 bytes at 8000 [section: .text]...
Writing 4096 bytes at 9000 [section: .text]...
Writing 4096 bytes at a000 [section: .text]...
Writing 4096 bytes at b000 [section: .text]...
Writing 4096 bytes at c000 [section: .text]...
Writing 4096 bytes at d000 [section: .text]...
Writing 1286 bytes at e000 [section: .text]...
Writing 3926 bytes at e506 [section: .rodata]...
Writing   60 bytes at f45c [section: .data]...
Writing  128 bytes at ff80 [section: .vectors]...
Done, 29976 bytes total
Writing   60 bytes at 1800...
Done, 60 bytes total
MSP430_Run
MSP430_Close
nuc16% 

Dumping the kernel dmesg uses make sbwdmesg.

nuc16% make sbwdmesg
...
Device: CC430F6147
Done, 2048 bytes total
...
strings dmesg.bin
Zeroed buffer for bad magic.
----
RNG REF LCD rtc osc CC430F6147 Recognized
buzz cp rad This watch has a radio.
Beginning POST.
10 button entries are available for Jukebox.
key but Initializing UART Booted.
----
RNG REF LCD rtc osc CC430F6147 Recognized
buzz cp rad This watch has a radio.
Beginning POST.
key but Initializing UART Booted.
----
RNG REF LCD rtc osc CC430F6147 Recognized
buzz cp rad This watch has a radio.
Beginning POST.
key but Initializing UART Booted.
nuc16% 

Recording a Trace

On the software end, you need Daniel Beer's mspdebug utility to flash the watch and Lukas K's energytrace-util from the Pluto Watch to dump the consumption graph.

Run make energytrace.txt to flash the firmware then generate a 30 second trace, which ought to cover the early booting period and then also the stable period of the clock application ticking.

nuc16% head -n 30 energytrace.txt
#Initializing the interface: #MSP430_Initialize(portNumber=TIUSB, version=31300601) returns 0
#Setting the device Vcc: #MSP430_VCC(3300) returns 0
#Opening the device: #MSP430_OpenDevice() returns 0
#MSP430_GetFoundDevice() returns 0
# device.id: 58
# device.string: CC430F6137
# device.mainStart: 0x8000
# device.infoStart: 0x1800
# device.ramEnd: 0x2bff
# device.nBreakpoints: 3
# device.emulation: 5
# device.clockControl: 2
# device.lcdStart: 0x0000
# device.lcdEnd: 0x0000
# device.vccMinOp: 1800
# device.vccMaxOp: 3600
# device.hasTestVpp: 1
#MSP430_EnableEnergyTrace=0
#MSP430_ResetEnergyTrace=0
1.318000e-03 0.000000e+00 3.280000e+00 2.500000e-06
1.531000e-03 0.000000e+00 3.296000e+00 2.900000e-06
1.800000e-03 0.000000e+00 3.293000e+00 3.200000e-06
2.012000e-03 0.000000e+00 3.289000e+00 3.400000e-06
2.225000e-03 0.000000e+00 3.292000e+00 3.600000e-06
2.635000e-03 0.000000e+00 3.290000e+00 3.800000e-06
2.848000e-03 0.000000e+00 3.293000e+00 4.300000e-06
3.061000e-03 0.000000e+00 3.293000e+00 4.500000e-06
3.331000e-03 0.000000e+00 3.291000e+00 5.000000e-06
3.544000e-03 0.000000e+00 3.290000e+00 5.000000e-06
3.954000e-03 0.000000e+00 3.291000e+00 5.400000e-06
...
3.012178e+01 6.600000e-06 3.292000e+00 3.430800e-03
3.012205e+01 6.600000e-06 3.291000e+00 3.430800e-03
3.012226e+01 6.600000e-06 3.291000e+00 3.430800e-03
3.012248e+01 6.600000e-06 3.291000e+00 3.430800e-03
3.012289e+01 6.600000e-06 3.291000e+00 3.430800e-03
3.012316e+01 6.600000e-06 3.291000e+00 3.430800e-03
3.012337e+01 6.600000e-06 3.291000e+00 3.430800e-03

The columns of this file are the time, current, voltage, and energy, respectively.

Plotting a Trace

Once energytrace.txt has been generated, you can graph it to a PNG with gnuplot energytrace.gnuplot.

You can also run gnuplot energytrace-txt.gnuplot to give a record of the current consumption on the console.

                               GoodWatch Current Consumption                   
                                                                               
         1e-05 +-----------------------------------------------------------+   
               |           +           +           +           +           |   
               |                                 "energytrace.txt" ******* |   
         8e-06 |-+    **********                                         +-|   
               |      *        *                                           |   
               |      *        *                                          *|   
               |*******        *                *******************       *|   
         6e-06 |-+             **********       *                 *      +*|   
               |                        *********                 *       *|   
               |                                                  *       *|   
         4e-06 |-+                                                *********|   
               |                                                           |   
               |                                                           |   
               |                                                           |   
         2e-06 |-+                                                       +-|   
               |                                                           |   
               |           +           +           +           +           |   
             0 +-----------------------------------------------------------+   
               20          21          22          23          24          25  
                                          Seconds                            

Predicting Battery Life

While graphs are great to get a sense of high-power features, we generally just want to know how long the Clock applet can tick before the battery needs to be replaced. For this, we simply average the current consumption after boot and then see how long that would take to burn though the battery's capacity.

#!/usr/bin/python3

## This is a quick little python script that takes the output of
## energytrace-util, averages the current consumption for all samples
## after ten seconds, and then predicts battery life from a 100mAH
## CR2016 battery.

## Usage: et 60 | python3 batterylife.py


import sys;

capacity=100 #mAH

ampsum=0.0;
ampcount=0;

#Ugly shotgun parser to ignore comments and early records.
for line in sys.stdin:
    if line[0]=='#':
        pass;
    else:
        words=line.split();
        time=float(words[0]);
        amps=float(words[1]);
        milliamps=amps*1000.0;

        #We only count after the first 10 seconds, as booting takes 5 seconds.
        if time>10.0:
            ampcount=ampcount+1;
            ampsum=ampsum+amps;

if ampcount>0:
    ampavg=ampsum/(ampcount*1.0);
    milliamp=ampavg*1000.0;
    microamp=ampavg*1000000.0;
    print("%f µA average consumption"%microamp);
    hours=100/milliamp;
    days=hours/24.0;
    years=days/365.2425;
    months=years*12.0;
    print("%f months of CR2016 battery life."%months);

You can pipe energytrace-util directly into this script to run a test over a longer period of time, in case you need to quantitatively compare changes to the codebase.

nuc16% et 600 | ./batterylife.py 
6.106727 µA average consumption
22.417138 months of CR2016 battery life.
nuc16% 

Some Quick Notes

As of 29 August 2018, the Clock applet idles at roughly 7µA, the radio idles at 1.5mA, and the radio trapped in a Morse transmission pulls 16mA.

Clone this wiki locally