Managing Power Consumption for Data Rate and Range
Design Constraints
There are two main constraints when designing an efficient power management scheme for wirelessly powered devices.
Average Power
The WISP is powered by converting RF energy into DC voltage. However, the available RF power decreases with the square of distance from the RFID reader. So, in order to maximize data rate, we need to perform work efficiently so as to minimize the average power consumption. This in turn will allow us to maximize our data rate. Lets look at an example:
Our wireless distance is 2 meters and we have roughly 100 uW available on average. In one second, we have 100 uW *1 second = 100 uJ
Algorithm 1 takes 1 ms to execute. Our energy to excecute the algorithm is 1 mA * 1.8V * 1ms = 1.8 uJ. So, we can excecute 100/1.8 = 55 times per second.
Algorithm 2 takes 2 ms to execute. Using the same algebra, we can execute half as fast, or 27 times per second.
Here are some tips on writing power efficient algorithms:
a. Uses registers to keep cycles per instruction low
b. Uses timers instead of while/for loops to perform timing
c. Utilizes low power sleep modes when waiting on external input
Operating Voltage
Operating Voltage
The MSP430 microcontroller (MCU) draws approximately 1 mA running at full speed (200 uA per MHz). This would limit wireless range to under 0.5 meter if the MCU were run continuously. To overcome this limitation, the MCU waits in a low power sleep mode, accumulating stored energy in a capacitor. When sufficient energy is available, the MCU powers on and performs some computation, sensing and/or communication. Note that because our instaneous power consumption is higher than the average incoming RF power available, the voltage stored on the capacitor is drained down. Thus, there must be some time limitation on the time we can spend doing computation.
WISP stores up energy in a capacitor much like storing water in a water tank. The rectifier pump energy into the capacitor, just like pumping water into the water tank. The MCU consumes energy from the storage capacitor, just like dispensing water from the water tank. The electrical models are relatively simple:
The energy stored in the capacitor, E = 0.5 C * V * V, where C = 10uF and V = volts on the capacitor
The rate of capacitor discharge, or current consumption, I = C dV / dT, where again C = 10uF and dV = change in voltage and dT = time duration
Keeping in mind that the MCU needs 1.8 V to operate, if we charge the storage capacitor to 2 V, and our MCU draws 1 mA, we can run for 2 ms before needing to recharge the capacitor. Note that the MCU consumes relatively constant energy per instruction regardless of clock rate, so there is little benefit to reducing clock rate in order to decrease power consumption. The exception to this rule is if the MCU is consuming clock cycles without performing computation, such as a for loop to create a time delay.
[ TODO: insert figure from scope showing dv / dt during query & ack from dev page. Possibly compare / contrast purple to red dv /dt. I = 10uf * dv/dt = 420 uA versus 580 uA]
Design Methods
We need to accumulate voltage to do a task. The fastest way to accumulate voltage is in sleep mode. However, in sleep mode we have only the hardware supervisor to generate an external interrupt to wake us (at ~1.9V). To wait for more voltage, we need to set up periodic polling. This is done by using the analog voltage sampling module. Both are described below:
Hardware supervisor
The voltage supervisor (SV) is connected to P2.4, or VOLTAGE_SV_PIN on Port 2.
The voltage supervisor allows the WISP to wait in LPM4 (very low power mode) until we have enough stored energy to some some useful task.
We don't need to poll when we use the HW SV because the SV generates a hardware interrupt, which will automagically wake the MCU.
Analog Voltage Sampling
This requires active polling; there is no hardware interrupt
Sleep current is increased slightly using the VLO or 32kHz crystal oscillators as clock sources.
Vout ranges from 0 to 5.5V. It is divided by 3 in the analog domain before reaching the ADC. This scales the input down to 0 to ~1.8V.
The ADC reference voltages are 0 and vdd (1.8V). The ADC output code = 1024 * V(in) / 1.8V
So: Vout = 3 * 1.8V * [output code] / 1024.
Multiply and divide are expensive operations in the MCU. Since we have a linear transfer function, we can do some approximations or precompute the analog voltages you need as #defines. This is used in blinky.c in WISP code examples
For a live example utilizing both mechanisms, see the blinky.c code (WISP code examples)