IoT 201: Power Management, Part 2

In IoT 201: Power Management, Part 1 we built a data-logging power meter based on an ARTIK 5. Now let’s use it to increase the battery life of our IoT designs.

Let’s get right to it. Here’s what you’ll need for today’s tutorial:

Configure the code

Get the power_datalogger.ino from GitHub and copy it to your Arduino development environment. If you clone or fork the repository, you’ll copy the code from your local repo into the proper Arduino directory, then copy it back to the repo if you’ve modified it. (At least I haven’t seen a way to check out files into the Arduino IDE.)

Look through the code; it’s not very complicated. At the top of the file is a set of constants that tailor the code to your purposes. Here’s the list of options and their defaults:

• char logFile [160] = "/usr/local/etc/logfile"; // This is the file we’ll write when we’re just playing.

• const char logPath [80] = "/usr/tmp/"; // When we’re in run mode we’ll generate unique filenames and place log files at this location.

Tip: for long data runs and associated large files, mount an SD card and point to the mount point here.

• const int logTest = 1; // Set to 0 to build unique file name for each logging run, otherwise use default.

• const char deLimit []="|"; // We generate character-delimited data files. This is the delimiting character.

• const int voltPin = A0; // ARTIK input pin for power supply voltage

• const int ampPin = A1; // ARTIK input pin for power supply current

• const int trigger = 5; // Pull this GPIO pin down to start logging

• const int lowDi = 6; // Status input includes all GPIO pins from here (LSB)...

• const int highDi = 9; // ... to here.

• const long period = 200; // How many ms between samples.

There’s one more modification you may want to make. In the loop code find these two lines:

while (digitalRead(trigger) == LOW){ // this for one-shot
// if (digitalRead(trigger) == LOW){ // this allows start, pause, restart under trigger control

The default while structure begins logging when the trigger pin is pulled low then stops and remains stopped when it goes high. Changing to the if structure allows the logger to start, pause, and start again depending on trigger state.

Connect and test

Enough talk, let’s connect everything to the ARTIK 5 (or 10) and run the code.

Step 1

  • Connect the wiper on the voltage divider pot to A0 or whatever pin you set for voltage input.
  • Connect the wiper on the other pot to A1 or other current input pin. (Just temporary while we make sure everything’s working.)
  • Use a jumper to pull down at least one of the designated status GPIO pins.
  • Prepare a jumper to pull down the trigger GPIO pin.

Step 2

Compile and load the sketch.

Confirm the Arduino IDE reports the sketch successfully started.

Step 3

Confirm proper function of the setup code. Find and open the file /usr/local/etc/logfile and you should see a header that looks something like this:

Log file header shows file location, start time (in UCT), and field headers.

If you use an editor to view the file, remember to close the editor before proceeding.

Step 4

Confirm proper function of the loop code.

Now’s the moment of truth! Use a jumper wire to pull down the trigger pin, wait a few seconds, then remove the jumper.

Open the log file again and you should see something like this:

Each record includes a timestamp in milliseconds since the program started.

Column 1 is the number of milliseconds since this sketch launched. If you want to know the real time at which events occur during the sensing period, use this as an offset to the UCT timestamp at the top of the file.

Step 5

Move the jumper from A1 (current input) to pick up the signal from the current sensor. Re-run the test and confirm the current sensor is working.


Before we get into calibration, let’s remember the goal of the instrument. We don’t much care about the absolute value of consumed power: we’re not building a utility meter here. We just need to reliably compare the power consumed in one time period to the power consumed in another time period. If the relationships are accurate and repeatable, the absolute magnitude can be off by 5% or even 10% without impacting our ability to design the most battery-sipping device possible.

Therefore what matters most is zero offset (since power = V * I) and stability.

Calibrate voltage input

Zero offset is not a problem with a resistor network. As long as we set the resistor ratio such that the max sensed voltage is about 90% full scale value we’re fine. Stability may be an issue, though, especially with a cheap single-turn pot. More about that when we discuss taking the design off the breadboard and into the lab.

Calibrate current input

There are two trim pots on the current sensing board. Here’s how to set them:

  • Short out the IP+ and IP- pins so zero current flows through the sensor.
  • Using a voltmeter, set the output to about 0.18 V (10% full-scale voltage, or FSV) using the “offset” trim pot.
  • Run the test software and record about 100 samples. Average the current readings: that’s your Zero Offset. Save the dataset; we’ll refer to it later.
  • Unshort the IP+ and IP- pins so current flows through the sensor.
  • Using a voltmeter, set the output to about 0.9 V (50% FSV). That leaves plenty of headroom to record power surges.
  • Run the test software and confirm you’re reading about 50% FSV.

From breadboard to lab

That’s it! Well, almost. If you plan to use the data logger to refine your IoT design, you’ll want to move it off the breadboard to a more robust structure. You could go all the way and design, etch, and build a custom circuit board, but you don’t have to go that far for a piece of lab equipment. You can easily translate your prototype from breadboard to a soldered perfboard like the Perma Proto boards from Adafruit.

However you plan to implement your final instrument, here are a few modifications you may want to consider:

  • Replace the voltage divider pot with two precision resistors; they’ll be much more stable. If you need the pots because your voltage sources vary (maybe you haven’t decided how many batteries you need) at least use a multi-turn model designed for calibration.
  • Speaking of single-turn pots, those trimmers on the low current breakout board are problematic. They’re fine for single test runs, but if you want to compare today’s test results to a measurement taken last week or last month you may be out of luck. Remember that set of 100 readings we took during the zero offset calibration? Load that dataset into a spreadsheet and calculate the standard deviation to get an idea of how much noise you have in the system. Editable schematic and board layout docs are available on GitHub if you want to swap out the pots.
  • If you’re going to modify the current sensor, consider replacing the Hall-effect chip with a shunt resistor. I chose Hall effect because it provides zero insertion loss and therefore provides visibility all the way to the end of battery life. If that doesn’t matter to you, pass the current through a precision resistor to generate 10 mV or so, then amplify the signal with an op amp.

Power saving tips

Now that we have an instrument to measure the power consumption of our current IoT design, how do we improve it? Here are a few tips:

  • Log an entire day’s power consumption for your device in a typical application. Load the dataset in a spread sheet and calculate power consumed (V * I). Look for power consumed by status to relate it back to what your software was doing at the time. Also look for periods of peak power use regardless of status. The power pig you didn’t expect is the best one to tackle.
  • Slow down. This datalogger can record upwards of 200 samples per second. But if I’d slow it down if I was running on batteries. Same goes for your sample rates.
  • Keep quiet until you have something useful to say. Radio communication consumes a lot of power, so be stingy in using it.
  • Speak clearly by considering your antenna design. Inefficient antennas require more radio power.
  • Think outside your node by considering the radio with which you’re communicating. If you’re a spoke in a hub-and-spoke topology, directional antennas at the hub could save you a lot of power.
  • Delegate power-consuming tasks to the cloud. If you’re a control node, you may need to implement basic control algorithms in case of network loss, but delegate the heavy computations when possible.

Explore the IoT 101 series: Connectivity, Networks, Sensors, Security, Power Supplies (Part 1, Part 2), Power Management (Part 1)

About the author: Kevin Sharp has been an engineer since long before he got his engineering degree, and has extensive experience in data acquisition and control networks in industrial, retail, and supply chain environments. He’s currently a freelance writer based in Tucson, Arizona.