Keithley Bench Digital Multimeter - Review

Table of contents

RoadTest: Keithley Bench Digital Multimeter

Author: neuromodulator

Creation date:

Evaluation Type: Test Equipment

Did you receive all parts the manufacturer stated would be included in the package?: True

What other parts do you consider comparable to this product?:

What were the biggest problems encountered?:

Detailed Review:

1 Keithley Instruments

 

Keithley Instruments was founded in 1946 by Joseph F. Keithley after earning a Bachelor of Science and a Master of Science degree from the MIT. The company began its operations in a small workshop at the end of an alley in Cleveland, and hired its first employee, John Yeager in 1950. Throughout its history, the company has mainly focused on DC instruments, and made a reputation out of the high quality DMMs, SMUs, and sensitive instruments such as electrometers, picoammeters and nanovoltmeters. These days Keithley Instruments is part of Tektronix, which along with Fluke are part of Fortive, a diversified conglomerate that spun off from Danaher.

 

 

2 Keithley DMM6500

The digital multimeter (DMM) DMM6500 and the data acquisition system DAQ6510, introduced in the first half of 2018, are part of the ongoing effort of Keithley to modernize the user interface and experience of their test equipment. “Touch, test, invest” (TTI) is the name of Keithleys new line of touchscreen-based test equipment, which was launched in 2013 with the 2450 SMU, and is slowly replacing its previous VFD-based line. The DMM6500 and DAQ6510 come 3 years after the release of the first TTI DMM, the 7½ digits DMM7510.

 

 

2.1 Features

 

Compared to previous 6½ digits Keithley DMMs, the DMM6500 offers increased sensitivity and a wider range of measurements. The measurement capabilities of the instrument are:

 

• DC and AC true RMS voltage

• DC and AC current

• 2- and 4-wire resistance

• Continuity

• Capacitance

• Frequency and period

• Diode forward voltage drop

• Thermocouple, thermistor, 2-, 3- and 4-wire RTD temperature

• Voltage digitalization

• Current digitalization

 

The following table shows how the instrument compares to other Keithley DMMs.

 

image

Source: Tek/Keithley

 

 

The next image shows the measurement capabilities of the 3 TTI DMMs that have been launched so far:

 

image

Source: Tek/Keithley + edition

 

 

As it can be seen, the DMM6500 and the DAQ6510 have very similar measuring capabilities, with the maximum supported current being the only difference. This is because their main difference lies in the back of the instrument, whereas the DMM6500 has rear inputs, including a 10 A current input, the DAQ6500 does not, and uses the freed-up space for two plug-in card slots instead. The DMM6500 comes with a single plugin-in card slot, but does not support the same cards than the DAQ6510. As the DAQ6510 is meant to be used for data acquisition, it supports a greater variety of plug-in cards compared to the DMM6500.

 

One way to visualize the features that make the DMM6500 a modern instrument is to contrast it to what could be considered its VFD predecessor, the Keithley 2000.

 

image

Source: Tek/Keithley + edition

 

 

The table shows major improvement over the Keithley 2000 that go beyond just better specs. The new hybrid button + touchscreen interface increases productivity through faster and simpler access to the DMM functions, easier readability and graphing abilities. The addition of voltage and current waveform digitization with 7 million points of memory allow the study of transients. USB ports were added to either control the instrument remotely or store data, that does not fit in the internal memory, in a pen drive. The added LAN connectivity allows easy remote access to either control or program the instrument. LUA programmability was added to the instrument through the Test Script Processor (TSP) scripting language, which contains instrument-specific control commands that can be run directly on the instrument. TSP-enabled instruments can even operate connected to other TSP-enabled instruments as a tightly synchronized multi-instrument system.

 

 

2.2 User interface

 

The user interface is the space where the interaction between the operator and the machine occurs. An important goal of user interface design is to produce a user interface which is simple, intuitive and efficient to the user. Good interface design makes a huge difference in productivity, it reduces the interaction time, chances of making mistakes, and repetitive and tedious tasks.

 

The DMM6500 can be controlled directly by physical interaction, through its web server, the Kickstart application, remotely through SCPI or TSP commands and TSP scripts running directly on the instrument. In the next sections I will describe the different interfaces of the instrument.

 

 

2.2.1 Physical interface

 

Test equipment user interfaces have gone a long way since the early days. At the beginning instruments were analog, making measurements was very time consuming as it required reading the analog output, and then transcribing the values. The LED and LCD digital readout display based test equipment changed that, reading values became easier, and remote control of the instruments through interfaces such as GPIB or RS-232 removed the burden of transcribing data. VFD based test equipment improved the readability and the amount of information that could be presented in the display. Color LCD display instruments added greater displaying possibilities, instruments were able to plot graphs and integrate complex GUIs. The integration of the ethernet port allowed instruments to be controlled from a web browser. Finally, the integration of touchscreens simplified the instrument usage by allowing the user to interact directly with what is being displayed, making the control of the instrument a seamless process.

 

image

Source: Tek/Keithley

 

 

In the front panel of the instrument we can see that Keithley took a hybrid approach and integrated physical and virtual buttons in their TTI instruments; physical buttons have the advantage of giving physical feedback and being harder to press by mistake, virtual buttons have the advantage of being flexible and customizable to the current state of the instrument. Keithley implemented as physical buttons the buttons the user may want to press independent of the current state of the instrument. The touchscreen also supports gestures such as swiping, pinching and zooming. I found that the easiest way to use the touchscreen is with the fingers parallel to the screen, if they are perpendicular, non-tightly-trimmed fingernails could interfere with the touch detection.

 

In the rear panel we have two slots for plugin cards, one for communication and the other for multichannel measurements. We also have the LAN and USB remote control interface, input and output trigger terminals and an additional 10 A current connector.

 

image

Source: Tek/Keithley

 

 

The Keithley DMM6500 comes with a crisp 5” 800x480 screen with good color reproduction at wide viewing angles. When powered on it takes around 15 s to initialize to start and switch to the direct current voltage measurement screen. The measurement screen has three regions, a status, a measurement and tab region. The status region displays information of how the instrument is being accessed (locally or remotely), the active reading buffer, the running script, the triggering mode and the error log. The measurement region shows measurement related information and provides a button to select the measurement range. The tab region provides different tabs to perform a varied set of tasks.

 

image

 

 

The measurement screen provides multiple buttons and swiping regions. Left or right tab switching can be done by either swiping the bottom region or pressing the “invisible” left and right buttons next to the middle dot of the middle region. The measurement region can be maximized through either swiping the middle region to the bottom or pressing either of the arrows in the middle region. At the top of the screen there are multiple regions that allow configuring the instrument or checking the system log.

 

image

 

 

There are 5 basic tabs, which can be expanded to 6 through scripts (or more when using a multichannel card). The statistics tab provides statistics of the data that has been captured. The secondary tab can be used to make a secondary measurement at the same time, on some measurement combinations this could cause continuous relay activity to quickly switch between the primary and secondary measurement. The function tab provides buttons to select between 15 different measurements. The settings tab provides measurement specific settings. The graph tab plots the data from the active reading buffer as measurements are made.

 

imageimageimageimageimage

 

 

The maximization of the primary measurement removes related measurement information and makes digits bigger and easier to read from the distance.

 

image

 

 

Multi-level menus are often tedious and confusing to navigate because of the complexity of their tree structure. Accessing a deep node in such systems may require multiple selections of child submenus or presses of the MORE soft-key, making the navigation very time consuming.

 

Keithley kept the menu navigation simple and efficient by providing a single level menu, making the access to the desired selection just a single icon press, similar to how its done on smartphones.

 

image

 

 

The captured data can be visualized in three different ways, as a graph, as a histogram or as a table of values. The graph plot can be panned and zoomed in or out through gestures or through manually entering the values. Analog to oscilloscopes, it also supports cursors that aid in making measurements. The histogram can be configured either automatically or manually and supports up to 700 bins as it can be seen in the screen capture. The table displays the content of the selected buffer as a table of values and also includes a plot that can be used to navigate the data.

 

imageimageimage

 

 

2.2.2 Web interface

 

The DMM6500 web interface can be used to check the instrument status, modify its settings (IP configuration, web password, and date/time), control it remotely through either the virtual front panel or through commands, and download buffer data as CSV files. The virtual front panel displays a real-time copy of the screen at a rate of ~3 refreshes/s and supports clicking/pushing and dragging/panning gestures. I found the virtual front panel particularly useful during development of TSP code as I could test the script without having to turn my head away from the computer screen. SCPI or TSP commands can be sent directly through the web interface and the command returned values read back as it can be seen in the screen capture.

 

imageimage

imageimage

 

 

2.2.3 KickStart

 

KickStart is a program sold by Keithley that simplifies data collection of their power supplies, SMUs, dataloggers and DMMs. KickStart can be used with the DMM6500 as a datalogger when a multi-channel card has been attached, or as a DMM. The DMM mode simplifies the process of setting the instrument up for data acquisition and allows real-time inspection of the captured data. Captured data can be inspected as a table of values or a graph, and can be exported as CSV, XLSX, or as a graph image.

 

imageimageimage

 

 

2.2.4 Remote commands

 

The most flexible (and eventually time consuming) way to control the instrument is through SCPI or TSP commands, or TSP scripts. Besides the web interface, remote commands can be sent through either Telnet (port 23), VXI-11 (port 1024) or raw sockets (port 5025). SCPI and TSP commands are roughly equivalent, but TSP supports scripts that can be executed from a stand-alone instrument. SCPI commands still have their niche, as the SCPI interface can emulate the Keithley 2000 or the Keysight 34401, making code developed for those DMMs compatible with the DMM6500.

 

TSP can be used in two different ways, as a series of commands sent by a computer, analog to how SCPI commands work on any other instrument, or as a script that runs in a stand-alone instrument. A TSP script can be loaded into the instrument from a remote computer or an USB drive. TSP commands can be function-based or attribute-based, function-based commands are commands that control actions or activities, attribute-based commands define characteristics of an instrument feature or operation.

 

An example of a short sequence of TSP commands that a computer could send to the instrument to make a 4-wire resistance measurement is shown below:

 

-- Reset the instrument settings to their default values
reset()

-- Set the measurement mode to 4 Wire resistance
dmm.measure.func = dmm.FUNC_4W_RESISTANCE

-- Make the measurement, concatenate the string to " Ohm" and print it
print(dmm.measure.read() .. " Ohm")

 

The command sequence produced the following output on my computer when tested on a 4.7K resistor:

 

4696.5598276 Ohm

 

And the following output on the DMM screen:

 

image

 

 

To load a script from a USB drive into the instrument, the script must be stored in the drive as text file with “tsp” as extension and then copied with the script manager into the instrument memory. A script can also be loaded remotely using the “loadscript” and “endscript” commands as shown in the example below:

 

-- Initial marker that tells the instrument that the next lines are part of a script called “DiodeVF”
loadscript DiodeVF

-- Reset the instrument settings to their default values
reset()

-- Set the measurement mode to 4 Wire resistance
dmm.measure.func = dmm.FUNC_DIODE

-- Set the bias level to 10 mA
dmm.measure.bias.level = 0.01

-- Make first measurement
vf0 = dmm.measure.read()

-- Switch to user tab 
display.changescreen(display.SCREEN_USER_SWIPE)

-- Print the first measurement as specified by the format in the first row of the user tab
display.settext(display.TEXT1, string.format("Vf0: %.3f V", vf0))

-- Wait 10 s
delay(10)

-- Make second measurement
vf1 = dmm.measure.read()

-- Print the second measurement as specified by the format in the second row of the user tab
display.settext(display.TEXT2,  string.format("Vf1: %.3f V", vf1))

-- Marker that tells the instrument that the script ends here
endscript

 

 

After remotely executing the previous sequence of commands, the code between "loadscript" and "endscript" is stored in a script called "DiodeVF". When the script button is pressed, a list of available scripts appears, a second press over the script immediately executes it. When execution begins the script button displays the name of the script next to a runner. The script example measures the forward voltage at 10 mA bias, keeps the LED on for 10 s at that bias and then makes a second measurement. The results are displayed in the user tab, which is a special tab that can be used by scripts to print results. I ran the example script with a white LED, and as expected the heating of the LED reduced the forward voltage drop.

 

imageimageimage

 

 

Keithley provides two tools to send remote commands to the instrument, the Keithley Test Script Builder (TSB), and the Keithley Communicator. The TSB is an Eclipse-based IDE with syntax highlight and debugging capabilities. The Communicator is a lightweight tool that lacks syntax highlight and debugging.

 

imageimage

 

 

3 Experiments

 

In the next experiments I will show how the instrument can be used to perform more realistic tasks. None of these experiments are meant to be taken as examples of how to perform precise measurements (as that would require a far greater effort), the focus of this section is to explore how to use the different instrument features.

 

 

3.1 Diode characterization

 

A diode is a two-terminal electronic device that facilitates current conduction in one direction and blocks it in the opposite direction. There are many different types of diodes with different electrical characteristics. One way to characterize them is through their I-V curve, which describes the relationship between the current and the voltage of a device. An I-V curve can be traced easily with an SMU, such as a the Keithley 2450, but here I’ll show how the DMM6500 could be used to get a crude trace of the first I-V quadrant of a diode, without the need of any other instrument.

 

To make good measurements some key parameters of the instrument must be set, the autozero, the autodelay, the aperture and the filter. Autozero reduces the instrument measurement drift by making it automatically check the reference measurements whenever a signal measurement is made. Autodelay adds a delay period at the end of a measure-related setting change to allow cables or internal circuitry to settle for best measurement accuracy. The aperture (amount of time the signal is measured) affects the time required to make the measurement, the level of noise, and the amount of drift (as seen in the figure) of the measurements. The filter reduces noise by averaging multiple measurements.

 

image

Source: Tek/Keithley

 

 

The diodes were measured with autozero and autodelay enabled and the filter disabled. To avoid heating the LEDs and at the same time get good accuracy, the aperture was set to 1 PLC (power line cycle) which is 20 ms where I live. The measurements were performed at 4 current levels: 10 μA, 100 μA, 1 mA and 10 mA. The used script is shown below:

 

-- Switch to user swipe screen and clear it
display.changescreen(display.SCREEN_USER_SWIPE)
display.clear()

-- Set the diode function parameters
dmm.measure.func = dmm.FUNC_DIODE
dmm.measure.autozero.enable = dmm.ON
dmm.measure.autodelay = dmm.DELAY_ON
dmm.measure.nplc = 1
dmm.measure.filter.enable = dmm.OFF

-- Measure diode at 10 mA and print results on screen
dmm.measure.bias.level = 1e-2
v2 = dmm.measure.read()
text2 = string.format("V2: %.3f", v2)
display.settext(display.TEXT2, text2)

-- Measure diode at 1 mA and print results on screen
dmm.measure.bias.level = 1e-3
v3 = dmm.measure.read()
text2 = string.format("V3: %.3f, ", v3) .. text2
display.settext(display.TEXT2, text2)

-- Measure diode at 100 uA and print results on screen
dmm.measure.bias.level = 1e-4
v4 = dmm.measure.read()
text1 = string.format("V4: %.3f", v4)
display.settext(display.TEXT1, text1)

-- Measure diode at 10 uA and print results on screen
dmm.measure.bias.level = 1e-5
v5 = dmm.measure.read()
text1 = string.format("V5: %.3f, ", v5) .. text1
display.settext(display.TEXT1, text1)

-- Return all measured values to the Python program
print(v5)
print(v4)
print(v3)
print(v2)

 

 

The script execution was controlled by a python program that communicated to the instrument through the PyVisa library. The program first loads the previous script into the instrument and names is “DiodeIV”. Every time the user presses Enter, the program executing the “DiodeIV” script and then stores the results in a list. Pressing the Esc key saves the list in a file and exits the program.

 

import visa
import numpy
import time
import keyboard

# Connect to the instrument, set the timeout and clear the buffer
keithley = visa.ResourceManager().open_resource('TCPIP0::192.168.0.30::inst0::INSTR')
keithley.timeout = 30000
keithley.clear()

# Delete script if it script exists, then load the script from the file
keithley.write('reset()')
keithley.write('script.delete("DiodeIV")')
keithley.write('loadscript DiodeIV')
with open("DiodeIV.tsp") as file:
    keithley.write(file.read())
keithley.write('endscript')

# Set initial values for the measurement list, and the last time a measurement was made
iv = []
lastProbe = 0

while True:
    # if Enter is pressed and more than 1 second has passed since the last time we made a measurement
    if keyboard.is_pressed('enter') and (time.time() - lastProbe > 1.):
        # Execute the script, read values and append them to the measurement list
        keithley.write('DiodeIV()')
        v5 = float(keithley.read())
        v4 = float(keithley.read())
        v3 = float(keithley.read())
        v2 = float(keithley.read())
        iv.append([v5, v4, v3, v2])

        # print the forward voltages
        print("Vfs: %.4f, %.4f, %.4f, %.4f" %(v5, v4, v3, v2))

        # Save the last time that a measurement was made
        lastProbe = time.time()
    
    # If Esc is pressed save data and quit
    if keyboard.is_pressed('esc'):
        numpy.save("Data.npy", iv)
        keithley.close()
        quit()

 

 

8 Different LEDs were tested and their I-V curves were plotted in a semi-log graph. As expected, in most cases the diode curves looked very close to a straight line, with the exception of the green LED, which at at higher currents "bends" likely due to its high series resistance.

 

imageimage

 

 

To show why diode I-V curve looks like straight line in a semi-log graph we will need the Shockley diode equation, which defines the relationship between current and voltage across a diode:

 

image

 

Where:

I is the diode current.

Is is the reverse bias saturation current.

V is the voltage across the diode.

n is the quality factor.

VT is the thermal voltage (~25.7 mV at 25 ºC).

 

 

The thermal voltage is defined as:

 

image

Where:

k is the the Boltzmann (1.38064852×1023 J/K).

T is the absolute temperature of the p-n junction.

q is the magnitude of the electrical charge on the electron (1.6021766208×1019 C).

 

 

Usually the LEDs will be driven at voltages where:

 

image

 

 

So we can rewrite the Shockley equation as:

 

image

 

 

If we apply a logarithm to the previous approximation we get:

 

image

 

 

As we can see, the right side of the equation is a line equation with slope of 1/(nVt) and an intercept of log(Is). With that in mind with 2 points we can solve the slope and intercept, and from those 2, also solve the "n" and the "Is":

 

image

 

image

 

 

I computed the the Is and n values out of the 10 μA and 10 mA points and then computed the voltage and current of the points at 100 μA and 1 mA.

 

When using the voltage to compute the current, the error was:

 

11.6% at the 100 μA measurement

10.5% at the 1 mA measurement

 

When using the current to compute the voltage, the error was:

 

0.467% at the 100 μA measurement

0.388% at the 1 mA measurement

 

And here we can see the plot in a log and non-log current scale:

 

imageimage

 

Of course there are many other ways to fit a curve, for instance the curve could have been fitted with a linear regression taking into account all 4 measurements, or the curve could be a piecewise function where Is and n could be computed for each of the 3 intervals, or the non-approximated Shockley equation could also have been fitted to the measurements through the use of numerical methods.


3.2 Audio characterization

 

Human hearing has a high dynamic range and is capable of sensing sounds that go from roughly 20 to 20,000 Hz. To characterize analog audio signals, we ideally need an instrument with high dynamic range, but not necessarily high bandwidth.

 

As shown previously, the instrument can digitize voltage or current at a resolution of 16 bit and a sampling rate that goes from 1 k/s to 1 MS/s. The digitized data can be stored in the internal memory of 7 MS or, depending on the sampling frequency, streamed to a computer. Kickstart is especially useful for digitization, but not as flexible TSP scripting, which is what I will show next.

There are many different tests that can be performed to characterize audio equipment, let’s see how we can use TSP scripts and Python code to record the signal for analysis.

 

On my first audio experiment I wanted to compare two audio signal sources, a sound card and a 14-bit DDS function generator and see which of the two generates the purest 1 kHz sine wave. I used the Python “sounddevice” library to play a 1 kHz sine wave on the sound card (if required), ran a TSP script to capture the data, and then downloaded the data as 32-bit floating-point numbers (Single-precision IEEE Std 754) from the instrument. The TSP script and Python program are shown below:

 

-- The Python program replaces the format specifiers with values before uploading the script to the instrument
sampleRate = %i
time = %f
range = %i
count = math.ceil(sampleRate * time)

-- Reset the instrument
reset()

-- Switch to user swipe screen and inform that we are "digitizing"
display.changescreen(display.SCREEN_USER_SWIPE)
display.clear()
display.settext(display.TEXT1, "Digitizing...")

-- Make as much memory available as possible by setting the default buffers to their minimum size, then create the audio buffer
defbuffer1.capacity = 10
defbuffer2.capacity = 10
audioBuffer = buffer.make(count)

-- Set the digitizer parameters
dmm.digitize.func = dmm.FUNC_DIGITIZE_VOLTAGE
dmm.digitize.range = range
dmm.digitize.samplerate = sampleRate
dmm.digitize.count = count

-- Begin digitization
dmm.digitize.read(audioBuffer)

-- Inform the Python program that we are ready to upload data, and display that on the screen
print("U")
display.settext(display.TEXT1, "Uploading...")

-- Set data format and upload data
format.data = format.REAL32
format.byteorder = format.LITTLEENDIAN
printbuffer(1, audioBuffer.n, audioBuffer.readings)

-- Inform that execution is "complete"
display.settext(display.TEXT1, "Complete!")

 

import time
import visa
import numpy
import sounddevice

# play audio?
playAudio = True

if playAudio:
    # Wave parameters
    rate = 192000
    freq = 1000
    duration = 90

    # Generate the the sine wave
    t = numpy.arange(0, duration, 1. / rate)
    f = numpy.sin(2. * numpy.pi * freq * t).transpose()

# Connect to the instrument, set the timeout and clear the buffer
keithley = visa.ResourceManager().open_resource('TCPIP0::192.168.0.30::inst0::INSTR')
keithley.timeout = 90000
keithley.clear()

if playAudio:
    # Begin playing the generated wave without blocking the execution and wait 3 seconds to make sure the playback has began
    sounddevice.play(f, rate)
    time.sleep(3)

# Delete script if it script exists, then load the script from the file and set the "sampleRate", "time" and "range" variables
keithley.write('script.delete("Digitizer")')
keithley.write('loadscript Digitizer')
with open('Digitizer.tsp') as file:
    keithley.write(file.read() % (20000, 60, 10))
keithley.write('endscript')

# Execute the script
keithley.write('Digitizer()')
print('Digitizing...')

# Digest the 'U' script output, which indicates that the instrument is ready to upload
keithley.read()
if playAudio:
    # Stop playback
    sounddevice.stop()

# Download data as a numpy.array
print('Downloading...')
v = keithley.read_binary_values(datatype = 'f', is_big_endian = False, container= numpy.array)

# Save data    
print('Complete!')
numpy.save('Data.npy', v)
keithley.close()

 

 

Then I estimated the power spectral density (PSD) with Welch’s method:

 

image

 

 

The plot shows that the sound card has a lower and flat noise floor while the function generator appears to show 1/f noise. The harmonics, an indicator of linearity, shows again that the sound card performed better than the function generator.

 

On my second experiment I wanted to see how an amplifier affects an input signal, but instead of probing the effect of the amplifier in a single frequency I probed it in the whole human hearing spectrum. I performed a linear 20 to 20,000 Hz sweep with a function generator that was synchronized to the DMM6500 through the triggering port. Triggers on the DMM6500 can be set and used either directly or in conjunction with the trigger model. Direct usage usually requires fewer lines of code (unless trigger model templates are used). On the other, the trigger model, which a small program that runs on a separate processor and coordinates triggers and measurements, gives greater flexibility and tighter control, but usually at higher programming complexity.

 

The used TSP script and Python code are shown below:

 

-- Reset the instrument
reset()

-- The Python program replaces the format specifiers with values before uploading the script to the instrument
sampleRate = %i
time = %f
range = %i
count = math.ceil(sampleRate * time)

-- Switch to user swipe screen and inform that we are "waiting" for the trigger
display.changescreen(display.SCREEN_USER_SWIPE)
display.clear()
display.settext(display.TEXT1, "Waiting...")

-- Make as much memory available as possible by setting the default buffers to their minimum size, then create the audio buffer
defbuffer1.capacity = 10
defbuffer2.capacity = 10
audioBuffer = buffer.make(count)

-- Set the digitizer parameters
dmm.digitize.func = dmm.FUNC_DIGITIZE_VOLTAGE
dmm.digitize.range = range
dmm.digitize.samplerate = sampleRate
dmm.digitize.count = count

-- Set the external trigger and wait until the rising edge gets detected or function times out
trigger.extin.edge = trigger.EDGE_RISING
trigger.extin.clear()
triggered = trigger.extin.wait(time)

if triggered then
    -- A rising edge was detected, inform the Python that we are digitizing
    print("D")
    display.settext(display.TEXT1, "Digitizing...")
    dmm.digitize.read(audioBuffer)

    -- Inform the Python program that we are ready to upload data, and display that on the screen
    print("U")
    display.settext(display.TEXT1, "Uploading...")

    -- Set data format and upload data
    format.data = format.REAL32
    format.byteorder = format.LITTLEENDIAN
    printbuffer(1, audioBuffer.n, audioBuffer.readings)

    -- Inform that execution is "complete"
    display.settext(display.TEXT1, "Complete!")

else
    -- No riding edge was detected, inform the Python program and display error on the screen
    print("E")
    display.settext(display.TEXT1, "No trigger detected!")
end

 

import visa
import numpy

# Connect to the instrument, set the timeout and clear the buffer
keithley = visa.ResourceManager().open_resource('TCPIP0::192.168.0.30::inst0::INSTR')
keithley.timeout = 90000
keithley.clear()

# Delete script if it script exists, then load the script from the file and set the "sampleRate", "time" and "range" variables
keithley.write('script.delete("TriggerDigitizer")')
keithley.write('loadscript TriggerDigitizer')
with open("TriggerDigitizer.tsp") as file:
    keithley.write(file.read() % (100000, 30, 10))
keithley.write('endscript')

# Execute the script
keithley.write('TriggerDigitizer()')
print("Waiting...")    

# if the script outputs 'D', digitization has begun
if (keithley.read() == 'D\n'):
    print("Digitizing...")    

    # Digest the 'U' script output, which indicates that the instrument is ready to upload
    keithley.read()

    # Download data as a numpy.array
    print("Downloading...")
    v = keithley.read_binary_values(datatype = 'f', is_big_endian = False, container= numpy.array)

    # Save data    
    print("Complete!")
    numpy.save('Data.npy', v)

else:
    # the script outputted 'E\n' (error), which means that the instrument did not detect a rising edge
    print("No trigger detected!")

keithley.close()

 

 

I then computed the spectrogram and PSD of the of the input and output (speaker ouput) amplifier signals:

         imageimage

 

 

By comparing the input and output spectrograms it can be observed that even though the input signal contains harmonic components, the amplifier increases them. Its also noticeable that the amplifier also increases the overall noise. When looking at the PSD plot, it can be seen that the amplifier does a fairly good job at reproducing the input frequency response.

 

To see the effect that the tone control knobs have on the signal I recorded multiple sweeps on different conditions: with tone defeat button on or off and with the bass and treble knobs moved to the minimum or maximum:

 

imageimageimage

 

 

The tone defeat button allows the signal to bypass the tone control circuitry, but in practical terms, every time I tested the button (with music), I could not sense any difference between its active and non-active state (with the bass and treble at their neutral position). The PSD on the other side clearly shows that the frequency response of the activation of the tone defeat is much closer to the input signal than when it is turned off. The last plot shows that the bass and treble knobs mostly affect what is below or above 1 kHz.

 

 

3.3 IoT current consumption

 

One common challenge of internet of things (IoT) devices is to reduce its power consumption so that they can make the best use of their limited available energy. Many microcontrollers and sensor support different operating modes to reduce power consumption. One way microcontrollers can reduce the consumption is by staying in sleep mode most of the time and only briefly waking up to perform their programmed tasks such as acquiring sensor data, processing it and transmitting it wirelessly. Here I will show how to use the DMM6500 programmatically to profile the current consumption of an ESP32 battery-powered microcontroller board.

image

 

The ESP32 is a low-cost 240 MHz dual-core microcontroller with integrated WIFI and Bluetooth support. My ESP32 board also comes with a 128x64 organic LED (OLED) screen, an 18650-battery holder, USB-bridge and battery charging integrated circuits (ICs) and LEDs.

 

There are many different approaches to reduce the ESP32 power consumption (clock speed reduction, wireless usage minimization, ultra-low power (ULP) coprocessor usage, etc.), but I will only explore the sleeping modes of the microcontroller. The ESP32 provides two sleeping modes, light and deep sleep. Light sleep keeps the current state of the microcontroller and allows it to continue the execution from where it went to sleep, Deep sleep, on the other hand, requires the reinitialization of the microcontroller.

 

To measure the current consumption, I wrote a simple ESP32 program that sets pin 21 high 5 ms before and after doing any of the following tasks:

 

  • Deep sleep for 0 ms.
  • Deep sleep for 100 ms.
  • Light sleep for 0 ms.
  • Light sleep for 100 ms.
  • Idle.
  • Integer and floating-point computation for 100 ms.

 

The purpose of sleeping for 0 ms is to compute the time and consumption overhead of each sleeping mode. The program is shown below:

 

#include <arduino.h>
#include "esp_sleep.h"

const uint8_t ledPin     = 16;
const uint8_t triggerOut = 21;
const int separation     = 5;
const int modeDuration   = 100;
const int uploadDuration = 15000;

RTC_DATA_ATTR unsigned restart = 0;

auto begin() -> void
{
    digitalWrite(triggerOut, 1);
    delay(separation);
}

auto end() -> void
{
    delay(separation);
    digitalWrite(triggerOut, 0);
}

auto setup() -> void
{
    restart++;

    delay(separation);
    pinMode(triggerOut, OUTPUT);

    digitalWrite(triggerOut, 1);
    delay(1);
    digitalWrite(triggerOut, 0);

    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin, 1);

    Serial.begin(115200);

    if (restart == 1)
    {
        for (int i = 0; i < 10; i++)
        {
            digitalWrite(ledPin, 0);
            delay(500);
            digitalWrite(ledPin, 1);
            delay(500);
        }
    }
    else
        delay(uploadDuration);

    if (restart == 1)
    {
        Serial.print("\n\nDeep sleep (no delay)...\n");
        Serial.flush();

        esp_sleep_enable_timer_wakeup(0);

        begin();
        esp_deep_sleep_start();
    }

    if (restart == 2)
    {
        Serial.print("\n\nDeep sleep (delayed)...\n\n\n");
        Serial.flush();        

        esp_sleep_enable_timer_wakeup(1000 * modeDuration);

        begin();
        esp_deep_sleep_start();
    }

    if (restart > 2)
        for (int mode = 0; mode < 4; mode++)
        {
            if (mode == 0)
            {
                Serial.print("Light Sleep (no delay)...\n");
                Serial.flush();

                esp_sleep_enable_timer_wakeup(0);

                begin();
                esp_light_sleep_start();
                end();
            }
            if (mode == 1)
            {
                Serial.print("Light Sleep (delayed)...\n");
                Serial.flush();

                esp_sleep_enable_timer_wakeup(1000 * modeDuration);

                begin();
                esp_light_sleep_start();
                end();
            }
            else if (mode == 2)
            {
                Serial.print("Idle...\n");

                begin();
                delay(modeDuration);
                end();
            }
            else if (mode == 3)
            {
                Serial.print("Computation...\n");

                volatile int i0 = 1234567890;
                volatile int i1 = 12345;
                volatile int iv;
                volatile float f0 = 1/3;
                volatile float f1 = 2/3;
                volatile float fv;
                volatile double d0 = 1/3;
                volatile double d1 = 2/3;
                volatile double dv;

                begin();
                auto t0 = millis();
                while (true)
                {
                    for (int i = 0; i < 50; i++)
                        iv = i0 + i1;
                        iv = i0 - i1;
                        iv = i0 * i1;
                        iv = i0 / i1;
                        fv = f0 + f1;
                        fv = f0 - f1;
                        fv = f0 * f1;
                        fv = f0 / f1;
                        fv = std::pow(f0, f1);
                        dv = std::sin(d0);
                        dv = d0 + d1;
                        dv = d0 - d1;
                        dv = d0 * d1;
                        dv = d0 / d1;
                        dv = std::pow(d0, d1);
                        dv = std::sin(d0);

                    if (millis() - t0 > modeDuration)
                        break;
                }
                end();
            }

            delay(uploadDuration);
        }

    Serial.print("Restarting...\n");
    delay(5000);
    esp_restart();
}

void loop() 
{
}

 

 

I used a power supply at 3.7 V to power the microcontroller battery connectors with the DMM6500 in series to measure the current. Instead of manually waiting for the trigger to detect a rising edge, as in the previous audio experiment, I used the trigger through a trigger model. A trigger model is program that run on a separate processor and coordinates measurements and trigger inputs and outputs. A trigger model can be built either through the instruments interface or programmatically. My trigger model begins measuring current as soon as it detects a rising edge at pin 21 of the ESP32. The code to build the trigger model and its graphical representation are shown below:

 

trigger.model.setblock(1, trigger.BLOCK_BUFFER_CLEAR, currentBuffer)
trigger.model.setblock(2, trigger.BLOCK_WAIT, trigger.EVENT_EXTERNAL, trigger.CLEAR_ENTER)
trigger.model.setblock(3, trigger.BLOCK_MEASURE_DIGITIZE, currentBuffer, trigger.COUNT_AUTO)

 

image

 

 

A trigger model always begins with an Idle block at position 0. The execution of the model stays at the Idle block until the model is initialized, and just then it moves to the next block at position 1. In my model, the position 1 block clears the buffer. The wait block clears any previously detected external trigger input signal and waits for a new external trigger input signal. The external trigger input is configured outside of the trigger model to detect raising edges, and whenever one is detected, a signal is sent to the trigger model processor, which will move execution to the next block. The block 3 begins the digitization of the current until the buffer gets filled. The execution then moves back to the Idle block and and stays there until the model is reinitialized.

 

The TSP code was divided into two parts, the first part initializes the environment, by setting the buffer, the current digitizer, the trigger, the trigger model and the data upload format. The second part initializes the trigger model, uploads the results to the Python program and displays information on the instruments screen. By dividing the TSP code in two parts, only the second part is called every time a new digitization is required.

 

-- The Python program replaces the format specifiers with values before uploading the script to the instrument
sampleRate = %i
time = %f
range = %i
count = math.ceil(sampleRate * time)

-- Reset the instrument
reset()

-- Make as much memory available as possible by setting the default buffers to their minimum size, then create the current buffer
defbuffer1.capacity = 10
defbuffer2.capacity = 10
currentBuffer = buffer.make(count)

-- Set the digitizer parameters
dmm.digitize.func = dmm.FUNC_DIGITIZE_CURRENT
dmm.digitize.range = range
dmm.digitize.samplerate = sampleRate
dmm.digitize.count = count

-- Set the external trigger to detect rising edges
trigger.extin.edge = trigger.EDGE_RISING

-- Create trigger model
trigger.model.setblock(1, trigger.BLOCK_BUFFER_CLEAR, currentBuffer)
trigger.model.setblock(2, trigger.BLOCK_WAIT, trigger.EVENT_EXTERNAL, trigger.CLEAR_ENTER)
trigger.model.setblock(3, trigger.BLOCK_MEASURE_DIGITIZE, currentBuffer, trigger.COUNT_AUTO)

-- Set data format
format.data = format.REAL32
format.byteorder = format.LITTLEENDIAN

 

-- Switch to user swipe screen and inform that we are running the trigger model
display.changescreen(display.SCREEN_USER_SWIPE)
display.clear()
display.settext(display.TEXT1, "Running model...")

-- Initiate trigger model and wait until it finishes
trigger.model.initiate()
waitcomplete()

-- Inform the Python program that we are ready to upload data, and display that on the screen
print("U")
display.settext(display.TEXT1, "Uploading...")

-- Upload the data
printbuffer(1, currentBuffer.n, currentBuffer.readings)

-- Inform that the upload is complete
display.settext(display.TEXT1, "Complete!")

 

import time
import visa
import numpy

# Time of the beginning of the execution
t0 = time.time()

# Print message with timestamp
def log(s):
    print('[%.1f] %s' % (time.time() - t0, s))

# Connect to the instrument, set the timeout and clear the buffer
keithley = visa.ResourceManager().open_resource('TCPIP0::192.168.0.30::inst0::INSTR')
keithley.timeout = 90000
keithley.clear()

# Setup the instrument with the specified sampling rate, digitizing time, and current range. Then create the "currentDigitizer" script.
with open("currentDigitizerSetup.tsp") as file:
    keithley.write(file.read() % (1000000, 0.3, 1))
keithley.write('script.delete("currentDigitizer")')
keithley.write('loadscript currentDigitizer')
with open("currentDigitizerBegin.tsp") as file:
    keithley.write(file.read())
keithley.write('endscript')

# Digitize current of ESP32 operating modes
m = []
for i in range(6):
    # Execute the script
    keithley.write('currentDigitizer()')
    log("Running trigger model...")

    # Digest the 'U' script output, which indicates that the instrument is ready to upload
    keithley.read()

    # Download data as a numpy.array and append it to the list
    log("Downloading...")
    i = keithley.read_binary_values(datatype = 'f', is_big_endian = False, container= numpy.array)
    m.append(i)

# Save data    
numpy.save('MCU.npy', numpy.array(m).transpose())
log("Complete!")
keithley.close()

 

 

Measurements were repeated 16 times, averaged and decimated to reduce the effect of current spikes in the plot:

image

 

 

The results show that deep sleep consumes the least amount of current (15.1 mA), followed by light sleep (17.4 mA), Idle (80.2 mA) and computation (115.3 mA). It is interesting to note that there is an important difference in the time overhead between the light sleep (0.6 ms) and deep sleep (168.4 ms).

 

To measure the charge overhead to entering and leaving a sleep mode I measured  the consumed charge for  0 ms deep and light sleep modes:

 



image

 

The plot shows that the net charge overhead compared to idling is almost negligible for both sleeping modes. With these measurements we can calculate when each of the sleeping modes should be used. For my specific board and test firmware I found that for periods shorter than 1100 ms, light sleep consumes less charge than deep sleep, past that threshold deep sleep consumes less than light sleep.

 

4. Summary

 

Multimeters have come a long way since the early days, they have become more precise and have been modernized in every aspect. They have turned into very flexible instruments, able to perform many different types of measurements either directly or remotely. Keithley has gone one step further by adding LUA scripting support and touchscreen interface to their TTI instrument line.

 

The DMM6500 is a great 6.5 digits DMM that supports a wide variety of measurement functions, including the ability to digitize voltage or current at 1 MS/s with 16 bits of resolution. It uses a modern touchscreen-based GUI and supports programming either through remote SCPI or TSP commands, or TSP scripts running directly on the instrument.

 

Basic usage of the instrument is intuitive enough to not require the reading of the user manual. The GUI is responsive and the navigation between menus, quick and efficient. Programming the instrument is relatively simple, but some concepts require extra effort to understand, such as the triggering system. The documentation is extensive and good, the user and reference manuals are 107 and 1257 pages long respectively, but I felt that a few complex programming topics could have been introduced in a way that is easier to follow. Kickstart and TSB worked fine without any issues. Kickstart can get you very quick results, but you can not beat the flexibility of using the instrument through TSP scripts, so I barely used Kickstart. TSB on the other hand was very useful to debug code before implementing it on my Python code and I used it extensively. I found a few non-serious firmware bugs in the firmware, but we know Keithley is serious about fixing bugs, so this should not be a deal breaker. My overall experience with the instrument was very good and at the instruments price range it offers greater flexibility than any other alternative.

 

Finally, I would like to thank those that made this review possible, Element14 and Keithley, and especially to Randall (Element14) for his support and to Bradley (Keithley) for responding my emails with useful information.

Anonymous
  • I'm sure we all have our own ideas on how to roadtest a product. Our application proposal should reflect that, so that the company can select the proposal that better fits what they would like to see in a roadtest.

  • Gerald,

     

    Here's the proposal that I submitted for this instrument: (scroll down to This is the all in the open part of my application for the Keithley Bench Digital Multimeter  Road Test)

    How I Enroll for a RoadTest - Part 7: Case for Some Other Road Tests

    What do you think of it? I explicitly mentioned that I would not validate the meter against the specs but focus on particular functions - the software and automation part.

  • Hi neuromodulator 

     

    Hello Gerald,

    I didn't post my own photos of the instrument because I didn't think they would add much value to the review, and the photos of the brochure were good enough. Just like in scientific papers my approach was to post images only when they would actually help understand something, I suppose this made the report a bit sterile, but this is not a paper, so if people like images, I'll provide them.

     

     

    Well, I certainly did not want to disturb or even split the spirit of the road test.

    The road test and the review was fulfilled, without question, your visit is excellent and very accurate.

    I understood everything and also tracked your tests.

    Also I compared that with the manuals.

     

    - >>

     

    The experimental section was mostly focused on how to use the instrument to perform certain measurements with a combination of TSP scripts and Python code, than an actual evaluation of any particular DUT and that is what I proposed I would do on my Roadtest entry. For a moment I thought maybe I could add more details about the DUT, measurement data, etc, but then I thought it would be better to stick to the instrument as that is what I'm evaluating. For that reason you probably noticed that the code was well commented to make it evident how it works. Again if people actually want more detailed information on the process downstream the measurements, I can provide that.

     

    When you talk about "tolerances, mistakes, "runaways", problems", what are you referring to?

     

    Let's say for the time being:

    After all, a road test is a product test, not just showing the features of the product, but also showing where the product's strengths and weaknesses are.

    That's what I first understand. - The manufacturer gives us a great thing to test in the hand, and we ... !!, we are allowed to throw this thing on the ground and see when it breaks; and that not even the product warranty is lost!

    Well, that's something.

    Of course, we will not immediately throw this great Keithley Multimeter on the ground. image

    But we can test the properties down to their device limits.

    Of course, taking into account your personal options. You do not have to have a super great lab to do a great roadtest.

     

    An example of what I always test on such devices is, in software-controlled devices: the collaboration between software and hardware.

    This is exactly the spirit of the manufacturer when he "gives away" a product to the road test.

     

     

    The equations were posted because I proposed in the application that I would use them to fit to the diode measurements. The way I decided to perform the fitting is of my own, that is why I posted how I solved the n and the Is. Numerical methods would have got a closer solution, but I thought it would be more elegant to solve an approximation of the equation directly. And just because I love math, the equations were entered as latex, not as an image.

    An example:

    Last year, some of us were allowed to test the Keysight multi-channel bench power supply E36312A, so I was allowed to join.

    After a few clicks on the keys to test the software, the power supply suddenly crashed with the software, AND it kept its outputs fully live, instead of turning off the outputs.

    That can be very fatal for the modules attached to the power supply and its voltage can suddenly not be turned off.

    I had to disconnect the power supply from the connection and restart completely.

     

    After this road test within a month, we were able to download a new firmware from Keysight.

    That's what the manufacturers want.

    Now, today before writing this post, I see that there is again a new firmware, namely AC_inputs during operation, or abnormal states in the inhibit latched function.

     

    Therefore, I also thought of your tests, whether you see it that way.

     

    The same thing happened, for example, for the spectrum analyzer from R & S FPC1500, which I was also allowed to test last year.
    Again, the software crashed when I switched between the functions; "Blue Screen".
    A month later there was a new firmware here.
    And also a new PC app, which also worked better with the FPC1500. There were also problems with the USB port, which R & S did with a virtual LAN bridge as the connection to the software from the device as a solution.

     

    For me, two sides I consider important:
    The power supply, product and human safety!
    Meter, in case if it is not properly connected, then the product or the measuring instrument to be measured can be broken.

    For example, you will certainly know the analogue multimeter with pointer instrument from analogue times at that time, or ok, later on digital multimeters that did not yet have automatic range switching.
    It was essential to switch off the power supply before switching to the other measuring range. Then you could switch the meter, or change, and after switching on the new measurement.

    Or you certainly know the return current that acts on the output of the upstream device from the input module, if it has its own power supply, if this is not switched on.
    For example, if a meter is turned on, it may also impress and potentially destroy the current on a module that is to be measured but switched off; CMOS components.
    Sounds unlikely, but I see, read again and again in application notes: "be careful that no flowing currents flow at the output". From experience, I also repeatedly say that drivers are kapput because of these currents, tensions.

     

    And, as I see above, you have now reduced the score from 60 to 58. image

     

    No, I really do not want to refer you to something, everyone does their own roadtest, and these are all very good, as far as I've read.

    I am not a!!! Examiner of anybody, certainly not a standard, I'm just a simple citizen, hm ... Roadtester.


    At Keithley, what about the software?
    How does the soft / hardware work with your device?

     

    Sorry, for my above objection, finding.

     

    Best Regards

    Gerald

    ---

  •   wrote:

     

    Here's a picture of mine - doing a useful measurement over 100 seconds period at 2k samples per second to establish the average current drawn by a gas sensor. The average and other stats are shown on the screen - and you can set this up with no programming at all.

    ....

     

     

    image

     

    MK

     

    This Keithley script allows you to take the Amp Hours over long time (hours, days).

    I've tested it (and adapted it for a related exercise).

  • Is that because it's user friendly ?

     

    MK

  •   wrote:

     

    .... and that, in common with other Keithley instruments in this style of case, the rubber front panel surround droops in the middle !

    ....

     

    MK

    It's smiling image

  • Fine if you can improve it - but - I liked your (sufficiently detailed) description of some actual useful stuff that you did.

     

    @Gerald

     

    I certainly don't expect a road test to include checks of calibration or performance of high end gear like this.

    (The Road tester would need a full calibration lab !)

     

    And I was really pleased not to see any pictures of the cardboard box it came in !

     

    Here's a picture of mine - doing a useful measurement over 100 seconds period at 2k samples per second to establish the average current drawn by a gas sensor. The average and other stats are shown on the screen - and you can set this up with no programing at all.

    The picture also conveniently illustrates that the meter is very long (a bit too long for my shelf) and that, in common with other Keithley instruments in this style of case, the rubber front panel surround droops in the middle !

    I have managed to get it to hang once, but I can't reproduce it - basically it's worked well since I had it.

     

     

    image

     

    MK

  • Thanks Jan, I'm glad you noticed that there was work behind, I was afraid that the result didn't show that... Gerald still has a point, the review may be a bit boring/sterile, so I'll try to improve it...

  • Hello Gerald,

    I didn't post my own photos of the instrument because I didn't think they would add much value to the review, and the photos of the brochure were good enough. Just like in scientific papers my approach was to post images only when they would actually help understand something, I suppose this made the report a bit sterile, but this is not a paper, so if people like images, I'll provide them.

    The experimental section was mostly focused on how to use the instrument to perform certain measurements with a combination of TSP scripts and Python code, than an actual evaluation of any particular DUT and that is what I proposed I would do on my Roadtest entry. For a moment I thought maybe I could add more details about the DUT, measurement data, etc, but then I thought it would be better to stick to the instrument as that is what I'm evaluating. For that reason you probably noticed that the code was well commented to make it evident how it works. Again if people actually want more detailed information on the process downstream the measurements, I can provide that.

    When you talk about "tolerances, mistakes, "runaways", problems", what are you referring to?

    The equations were posted because I proposed in the application that I would use them to fit to the diode measurements. The way I decided to perform the fitting is of my own, that is why I posted how I solved the n and the Is. Numerical methods would have got a closer solution, but I thought it would be more elegant to solve an approximation of the equation directly. And just because I love math, the equations were entered as latex, not as an image.









  • , I’d say that this report is done in the spirit of road test. Showing the results of hands-on experience with the instrument.

    While it does not show tables, it shows the graphic representation as curves.

     

    For the diodes, there is no test circuit involved. You just connect the diode. The script used to control the instrument for this measurement, and how the data was retrieved, is also shown.

    I’m impressed by the work done here.