element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Test & Tools
  • Technologies
  • More
Test & Tools
Blog Keithley DMM6500: Measure Amp-Hours of a microcontroller with a µCurrent
  • Blog
  • Forum
  • Documents
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Test & Tools to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 19 Jan 2019 10:58 PM Date Created
  • Views 2253 views
  • Likes 7 likes
  • Comments 1 comment
  • RoadTest
  • amphour
  • dmm6500
  • rt
  • keithley
  • max32660
  • maxim
  • µcurrent
  • eevblog
Related
Recommended

Keithley DMM6500: Measure Amp-Hours of a microcontroller with a µCurrent

Jan Cumps
Jan Cumps
19 Jan 2019

I'm road testing the  Keithley Bench Digital Multimeter DMM6500.

In this blog, I presents a script that measures a microcontoller power consumption using an EEVblog µCurrent.

image

Knowing the amp hours your application consumes, helps to predict battery life.

Battery capacity is given in this unit. With modern switching converters, you can squeeze almost all capacity out of a battery. Knowing how much runtime all that capacity gives you is useful.

 

Why a µCurrent?

 

The DMM6500 can read low currents very well. However, the Burden voltage is not low enough for certain measurements.

With the device I'm checking here, a MAX32660 microcontroller, the device does not get enough voltage when I add the DMM6500 in series.

The µCurrent fills this niche. A small lab tool that allows you to measure current with a lower Burden voltage than most meters.

In this case, it makes the difference between the microcontroller working and not.

image

You put the µCurrent in series with the device under test. It translates the current into a voltage. This voltage can be measured by the DMM6500.

 

image

image source: EEVblog product page

 

The instrument has 3 ranges that you can set with a sliding switch: 1 mV / nA,  1 mV / µA and 1 mV / mA.

In the script that I'm describing in this post, you can select on-screen what µCurrent setting you are using.

The script then does the calculation for you.

Here's the selection screen :

 

image

 

Measuring Amp Hours

 

If you want to know how long your device can run on a battery, it's useful to know its power consumption.

Batteries state their capacity in amp hours. They usually have a graph showing the voltage after a certain amount of amp hour delivered.

If you know how much volts your gizmo needs, and how many amp hours it consumes, you can extrapolate the autonomy of your design.

With a good DC converter and a low voltage design, you can also drop voltage when the battery is new and boost the voltage when the battery has dropped below your minimum.

You extend your device's lifespan, and this script + µCurrent can help you predict how long it will stay up.

 

A second reason for measuring the amp hours is to validate how much you lowered power consumption after a design optimisation.

If you run this script before the exercise, then run it again after you improved the power profile of your design, you have a figure that indicates your saving.

 

Measurement Setup

 

The setup is straightforward. The device under test (DUT)  is a MAX32660 microcontroller evaluation board.

It's powered by a 1.8 V PSU. The debugger of that device delivers that voltage.

 

image

 

The µCurrent is in series with the microcontroller.

To do that, I removed the voltage jumper JP1, and put the µCurrent's + input to that jumper's 1.8 V pin.

The - input of the µCurrent goes to the right upper breakout pi, named VDDIO.

If you look at the schematic of the MAX32660 evaluation system, you'll see that this effectively puts the µCurrent in series with the microcontroller design.

image

 

The DMM6500 is connected to the outputs of the µCurrent. It will read the mV coming out of that device. And those mV are a direct function of the current running through DUT.

We'll read that voltage in our script and convert that into the amp hours consumed by the MAX32660, under different power profiles.

 

How Can You Use the Script?

 

You can save the script at the end of this blog to a USB stick, with a *tsp extension, then plug that stick into the DMM6500 and run it.

You'll get a series of menu options:

 

 

1: do you want to report Amp hours or Watt hours?

(in case of Watt hours, it'll ask for the supplied voltage, in this case 1.8 V)

image

2: What's the sample rate? How many measurements do you want to take per second?

image

3: What's the expected maximum current pulled by the device under test?

image

4: To what value have you set the µCurrent? This will be used to calculate the right current.

image

Immediately after this selection, the script starts to execute.

You can run it as long as you want. You can always get the results by using the rule of 3  to recalculate the measurement time to one hour.

The longer you run it, the preciser your result.

Pushing the Trigger button ends the process.

 

Example Runs

 

I'm showing the script with the MAX32660 running two different designs.

 

The first one is the device in its highest power use.

It's constantly running in active mode and flashes a led 50% of the time.

It's MAX32660 Hello_World example, with the printf() commands removed.

The µCurrent is set to 1 mV / 1 mA and I ran the test for 1 minute.

The graph shows the amp hour evolving calculation during the last few seconds of the execution.

imageimage

The User screen shows the average current during the run, and the amount of amp hours consumed during the minute.

If  I extrapolate the value for one hour, I get 0.00010160 AH * 60 = 6.096 mAH

 

The second example is the device switching between its power modes.

It's the LP demo program. The MAX32660 is 2/5 of its time in high power mode, 3/5 of the time in the lower power modes. No LEDs are flashed.

After a minute:

imageimage

The same design after half an hour:

imageimage

After 1 minute, the consumption extrapolates to 3.84606 mAH. After 30 minutes, we get the advantage of a longer run and we would expect 3.42800 mAH.

For an example like this, where the controller is doing the same loop all the time, you get a fair estimate after a short run.

If you have slow runners, it's best to run long enough to have a real life sample

 

The Script

 

It's not mine. I took it from a Keithley application note Data Logging of Power Profiles from Wireless IoT and Other Low-Power Devices.

That script uses the DMM6500 in it's natural habitat, as a current meter.

I adapted it so that it to operate in volt mode (the µCurrent output is a voltage) but log the amp hours as a current anyway.

 

What I changed:

  • instrument mode from DC CURRENT to DC VOLTAGE.
  • add a screen to ask the user to input the µCurrent's switch setting.
  • a calculation to convert the measured volts to amps, based on the user selection.

 

image

You can find the script below. For the original version, check the end of the application note linked in above.

 

-- create functions
function setup_DMM6500_buffer(BufSize)
dciBuffer = buffer.make(BufSize, buffer.STYLE_STANDARD)
dciBuffer.clear()
buffer.clearstats(dciBuffer)
dciBuffer.capacity = 1 * BufSize
dciBuffer.fillmode = buffer.FILL_CONTINUOUS
end -- function


function setup_DMM6500_measure(sampleRate, measRange)
-- setup our refilling buffer
setup_DMM6500_buffer(sampleRate) -- BufSize = sampleRate = 1 second of buffering
opc()
-- setup measure type, ranges, etc.
dmm.digitize.func = dmm.FUNC_DIGITIZE_VOLTAGE
opc()
dmm.digitize.range = measRange
dmm.digitize.samplerate = sampleRate
dmm.digitize.aperture = dmm.APERTURE_AUTO
--Changing count is optional. The reading buffer capacity is the determining factor
dmm.digitize.count = 1 -- CANNOT be zero; 1 to 55Million
-- control the swipe screen
display.clear()
display.changescreen(display.SCREEN_USER_SWIPE)
-- clear any existing trigger blocks
trigger.clear()
trigger.model.load("Empty")
opc()
--Define a trigger model that will capture until we push front panel trigger button
trigger.model.setblock(1, trigger.BLOCK_BUFFER_CLEAR, dciBuffer)
trigger.model.setblock(2, trigger.BLOCK_DELAY_CONSTANT, 0)
trigger.model.setblock(3, trigger.BLOCK_DIGITIZE, dciBuffer, trigger.COUNT_INFINITE)
trigger.model.setblock(4, trigger.BLOCK_WAIT, trigger.EVENT_DISPLAY) 
-- wait until the TRIGGER key is pressed
trigger.model.setblock(5, trigger.BLOCK_DIGITIZE, dciBuffer, trigger.COUNT_STOP) 
-- stop making digitized measurements
opc()
end -- function


function my_dmm6500_waitcomplete(useWattHrs, dcvVal, microcurrentrange)
local i = 1
local cbIndex = 1
local tempVal = 0
-- check trigger model state on Amp-Hr meter (DMM6500)
present_state, n = trigger.model.state() -- state, present block number
--STATE_RUNNING, IDLE, WAITING, EMPTY, FAILED, ABORTING, ABORTED, BUILDING
while present_state == (trigger.STATE_WAITING or trigger.STATE_RUNNING) do
reading_stats = buffer.getstats(dciBuffer)
i_avg = reading_stats.mean * microcurrentrange
runtime = dciBuffer.relativetimestamps[dciBuffer.n]
AmpHrs = i_avg * runtime/3600
if useWattHrs == 0 then
display.settext(display.TEXT1, string.format("Amp-Hrs: %.4e", AmpHrs));
display.settext(display.TEXT2, string.format("Avg. I: %.6e A", i_avg));
tempVal = AmpHrs
buffer.write.reading(ampHrsBuffer, tempVal, runtime)
else
WattHrs = AmpHrs * dcvVal
display.settext(display.TEXT1, string.format("Watt-Hrs: %.4e", WattHrs));
display.settext(display.TEXT2, string.format("Avg. I: %.6e A", i_avg));
tempVal = WattHrs
buffer.write.reading(wattHrsBuffer, tempVal, runtime)
end
delay(1)
i = i + 1
present_state, n = trigger.model.state() --update the trigger model state var
end -- while loop
end -- function


function get_amphrs(microcurrentrange)
present_state, n = trigger.model.state()
reading_stats = buffer.getstats(defbuffer1)
runtime = defbuffer1.relativetimestamps[defbuffer1.n]
i_avg = reading_stats.mean * microcurrentrange
AmpHrs = i_avg * runtime/3600
end --function


function set_dci_range()
optionID = display.input.option("Select current range", "1A", "100mA", "10mA", "1mA",
"100uA", "10uA")
if optionID == display.BUTTON_OPTION1 then -- 1A
return 1.0
elseif optionID == display.BUTTON_OPTION2 then -- 100mA
return 100e-3
elseif optionID == display.BUTTON_OPTION3 then -- 10mA
return 10e-3
elseif optionID == display.BUTTON_OPTION4 then -- 1mA
return 1e-3
elseif optionID == display.BUTTON_OPTION5 then -- 100uA
return 100e-6
elseif optionID == display.BUTTON_OPTION6 then -- 10uA
return 10e-6
end
end


function set_output_hrs_format()
optionID = display.input.option("Select Computation Option", "Amp-Hours", "Watt-Hours")
if optionID == display.BUTTON_OPTION1 then -- Amp-Hrs
return 0
elseif optionID == display.BUTTON_OPTION2 then -- Watt-Hrs
return 1
end
end -- function


function set_microcurrent_range()
optionID = display.input.option("Select uCurrent range", "mA", "uA", "nA")
if optionID == display.BUTTON_OPTION1 then -- mA
return 1.0
elseif optionID == display.BUTTON_OPTION2 then -- uA
return 1e-3
elseif optionID == display.BUTTON_OPTION3 then -- nA
return 1e-6
end
end


function get_user_sample_rate()
return display.input.number("Sample Rate", display.NFORMAT_INTEGER, 50000, 1000, 125000)
end -- function


function get_user_dcv_value()
-- for the watt-hours, have the user input the applied voltage to their device
return display.input.number("DCV Level Applied", display.NFORMAT_DECIMAL, 3.25, 0.0, 24.0)
end -- function


-- ************************* MAIN PROGRAM **************************
reset() --reset the DMM6500
eventlog.clear()
-- set default sample_rate and current_range
local sample_rate = 15e3
local DMMcurrentMeasRange = 0.01
local microcurrentrange = 1.0
local dcvVal = 0.0
-- downsize the default buffers to ensure room for the new ones
defbuffer1.capacity = 10
defbuffer2.capacity = 10
-- let us size this for 1 sample per second for up to 30 days: 60*60*24*30 = 2,592,000
local hrsFormat = set_output_hrs_format()
if hrsFormat == 0 then -- provide semi-acceptable units to be visible on the graph and in the reading table
ampHrsBuffer = buffer.make(2592000, buffer.STYLE_WRITABLE)
buffer.write.format(ampHrsBuffer, buffer.UNIT_AMP, buffer.DIGITS_6_5)
else
wattHrsBuffer = buffer.make(2592000, buffer.STYLE_WRITABLE)
buffer.write.format(wattHrsBuffer, buffer.UNIT_WATT, buffer.DIGITS_6_5)
end
if hrsFormat == 1 then
dcvVal = get_user_dcv_value()
end
dmm.digitize.func = dmm.FUNC_DIGITIZE_VOLTAGE
dmm.digitize.range = DMMcurrentMeasRange
sample_rate = get_user_sample_rate()-- let the user select the sample rate to use
DMMcurrentMeasRange = set_dci_range()-- let the user select the current range to use
microcurrentrange = set_microcurrent_range()-- let the user select the microcurrent switch setting
setup_DMM6500_measure(sample_rate, DMMcurrentMeasRange)
-- start our DMM6500 High Speed Digitizing
trigger.model.initiate()
delay(0.5) -- allow some data to accumulate....
-- start the DMM6500 Amp-Hr status reporting loop
-- Press TRIGGER button to exit the loop
my_dmm6500_waitcomplete(hrsFormat, dcvVal, microcurrentrange)
-- clean up DMM6500 (Amp-Hr)
trigger.model.abort()

 

 

I hope that this post helps you when dealing with specifying low power designs.

It's my first script change. There may be bugs. Help and testing are welcome.

Related Blog
Keithley Bench Digital Multimeter - Review
Software Control Options Pt 1 - TSP Script Builder, LabVIEW, Web Interface
TSP Script Example - Measure Power
How to Create a Bitmap for a Custom App
Verify a µCurrent Manually
Verify a µCurrent in an Automated Setup
Measure Amp-Hours of a microcontroller with a µCurrent
Trigger from External Trigger Input
Trigger from External Trigger Input in LabVIEW
Software Control Options Pt 2 - Test Commands with Communicator
App to Hold Measurements

Store Multiple Measurements Manually

Script Example - Externally Triggered Measurements
  • Sign in to reply
  • Jan Cumps
    Jan Cumps over 6 years ago

    note: if you have a power supply with voltage sense wires, Burden voltage drop is a lesser issue.

    Your power supply will compensate the voltage drop over the Ahmmeter.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube