Using Python for Test and Measurement Setups

advertisement
Using Python for Test and Measurement Setups
Stephan Nigg,MSc. Dipl. El. Ing FH
Abstract—The article shows how a test and measurement
installation can be set-up in a few simple steps with the popular high-level programming language python. A simple design
approach for the automation of such setups will be introduced.
It will also be shown that even sophisticated setups can be
addressed with the same simple approach keeping the over all
complexity low. At last the problematic of delayed communication
is discussed and a possible solution using multithreading is
presented.
Index Terms—Computer Society, Python, IVI, VXI-11, LXI,
Ethernet, USBTMC, Multi-Threading, GPIB
I. I NTRODUCTION
Test and measurement setups (TMS) are part of an engineers
and scientists daily business. Figure 1 shows an example
of a simple temperature logging scenario. The device under
test (DUT) is powered with a power supply (PSU) and the
temperature is measured by a digital multi meter (DMM). The
DMM is connected via USB or Ethernet to a PC and where
a piece of software reads out the temperature periodically and
writes it to a file. This piece of software can we written in
any language. This paper shows how python can be used for
such setups.
Pythons design philosophy emphasizes code readability.
This is especially beneficial for people not constantly writing
code as is often the case with engineers outside information
technology. It is available for free, is Open Source and
runs on almost any CPU architecture and operating system.
Python offers a huge and still increasing amount of powerful
libraries (modules) especially but not exclusive in the area of
mathematics and science [1], [2]. With python the data can be
acquired and analyzed in the same development environment.
Often setups get much more complex than just simply
logging one parameter. In such advanced setups, automation
has an even greater relevance, as it can save a lot of time
conducting extensive parameter combinations. The number
of measurements increase exponentially with the count of
different parameters. As an automated measurement setup can
be rerun, its results are reproducible. If post processing raises
questions on the validity of some data, the setup can be rerun
for double-checking.
Figure 2 shows an example of a more complex TMS.
The PSU is controllable and delivers information on the
power consumption. The DUT is stimulated or controlled with
defined data sets. Instead of only recording one parameter with
a DMM, we have a digital storage oscilloscope (DSO) capable
of recording what we here call events. These events are short
time series showing a fast process instead of just a single
value. An example would be the measurement of the slope of
a rising edge or the timing of a communication process such
as SPI.
First we take a look how to tackle the simple temperature
logging example of Figure 1 with python including some
programming hints in Section II. In section III the example
is extended towards the more advanced setup from Figure 2.
In this paper the ivi module by Alex Forencich is used to
access ivi-compliant instruments. It is a python implementation of the Interchangeable Virtual Instrument standard. The
module depends on communication modules such as VXI11 for ethernet, USBTMC for USB or pySerial for RS232
communication [3], [4], [5]. The installation is straight forward
and not covered here. Section IV covers methods to implement
generic instruments. The method is shown by seamlessly
extend the approach used in Sections II and III with a fixedperiod measurement instrument.
Fig. 1. Simple Temperature logging.
II. S IMPLE S ETUP
The piece of software to control the setup shown in Figure 1
opens a communication channel to the instrument, polls values
in a 10 seconds interval and stores them in a file. This is done
in 7 lines of code (see Listing 1). Compared to C or Java
it is very short and clean providing excellent readability. As
python can be used in interactive mode, a setup can be created
or tested step by step in the command line. This is a huge
advantage compared to compiled languages.
Line 3 creates an object of the digital multimeter (DMM)
of the type Agilent34410A. If the exact type is not available
(check the ivi documentation [6]), a similar type that is
available can be tried. In most cases basic functions will work.
The first part of the connection string on line 3 indicates
the connection method being TCP/IP. To establish TCP/IP
connection the ivi module will load the vxi-11 communication
module in the background. Line 4 opens the log-file for
writing. More precisely it is in appendage mode, meaning that
if it does not exist it is created otherwise data is appended
without loosing its prior content. This seemingly little detail
is essential in TMS. If a script is rerun by accident or intention
without saving the data of the last run, the is lost and even
with data forensics almost impossible to retrieve.
Line 5 defines an infinite loop. Infinite may seem strange at
first but is actually a feasible method to run a function without
predetermined length. Python’s garbage collector always does
a clean up upon termination. The infinite measurement-loop
can be stopped at any time by triggering a keyboard interrupt
with Ctrl-D. Beware that operating systems use writing buffers
to optimize IO performance. This has the side effect that data
written to a file is not written to disk immediately. If the file
had to be read during the measurement, a log.flush() after the
write operation would be necessary. If the data is extremely
precious this needs to be done anyway to ensure the datas
safety in case of a system failure. The premature flushing may
have a performance penalty.
1
2
3
4
5
6
7
import i v i
import t i m e
dmm = i v i . a g i l e n t . a g i l e n t 3 4 4 1 0 A ( ” TCPIP
: : 1 0 . 1 . 1 . 2 : : INSTR” )
l o g = open ( ” l o g . t x t ” , ” a ” )
while True :
l o g . w r i t e ( ” %0.4 f ◦C\n ” % dmm . m e a s u r e m e n t .
read (0) )
time . sleep (10)
Listing 1. VXI-11 connection example
III. A DVANCED S ETUP
Now lets examine the advanced example of Figure 2.
Suppose the DUT is a mobile device. As such devices are
normally powered by a single lithium polymer cell, the supply
range we need to verify is from 3.6 to 4.4Volt. The DUT has
a communication interface with four signals where we need
to verify the timing. The interface can be configured with
different driver strength between 20mA to 50mA at different
speed from 100 to 800 kHz. Suppose we want to verify the
interface timing at 5 voltage levels, 4 driver settings and 4
different speeds. This results in 80 measurements to capture
and analyze. Manually going through all these combinations
is tedious. In this example the temperature shall be recorded at
each setting. This increases the amount of time considerably.
Due to the long temperature settling time of 60 seconds, the
measurement takes more than 80 minutes.
Listing 2 shows one possible approach to get the expected
results. It uses three nested for loops one for each parameter
space. The correct timing is achieved with simple sleeps. To
control the DUT a module named myDUT is imported. All
we need to know for this example is that it talks to the DUT.
On line 19 and 20 the supply voltage and communication
parameters are set. Line 21 informs the user about the current
status. Line 23 could be replaced with a for-loop printing a dot
or a ’z’ every 5 seconds have something similar to a progress
bar. After the thermal settling time the trigger on the DSO
is set for a single shot on line 24. After getting the current
the DUT consumes and temperature on line 25 and 26, the
script waits for 5 seconds to be sure the trigger has fired.
After the waveform data is retrieved from the four observed
channels. At this point all the data needed for a timing analysis
is collected. Line 30 to 34 demonstrate how easy it is, to fetch
a scope image and save it to the local disk. Such scope snapshots are useful for engineers to get a quick overview of the a
measurement. As post-processing is not covered in this article,
the analysis and storage of the result is only indicated by line
35.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import i v i
from t i m e import s l e e p
import myDUT
sup volt =[3.6 , 3.8 , 4.0 , 4.2 , 4.4]
d r i v c u r = [ 20 e −3, 30 e −3, 40 e −3, 50 e −3]
speed =[100 ,200 ,400 ,800]
dmm= i v i . a g i l e n t . a g i l e n t 3 4 4 1 0 A ( ” TCPIP
: : 1 0 . 1 . 1 . 2 : : INSTR” )
d s o = i v i . l e c r o y . lecroyWR62XIA ( ” TCPIP
: : 1 0 . 1 . 1 . 3 : : INSTR” )
p s u = i v i . a g i l e n t . a g i l e n t E 3 6 4 9 A ( ” TCPIP
: : 1 0 . 1 . 1 . 4 : : INSTR” )
d u t =myDUT . i n i t ( )
c h a n = range ( 4 )
psu . o u t p u t s [ 0 ] . v o l t a g e l e v e l = s u p v o l t [ 0 ]
psu . o u t p u t s [ 0 ] . e n a b l e d =True
for sv in s u p v o l t :
f o r dc i n d r i v c u r :
for sp in speed :
psu . o u t p u t s [ 0 ] . v o l t a g e l e v e l =sv
d u t . s e t ( d r i v e r =dc , s p e e d = s p )
p r i n t ” Wait a t %.1fV , %imA , %ikHz ” %
( sv , dc ∗ 1 0 0 0 , s p )
dut . s t a r t t x ( )
sleep (55)
d s o . t r i g g e r . mode=single
s y s i =psu . o u t p u t s [ 0 ] . g e t c u r r e n t ( )
s y s t =dmm . m e a s u r e m e n t . r e a d ( 0 )
sleep (5)
f o r c i n range ( 4 ) :
chan [ c ]= dso . c h a n n e l s [ c ] . measurement
. fetch waveform ( )
png= d s o . d i s p l a y . f e t c h s c r e e n s h o t ( )
p i c n a m e =” r u n %.1 fV %imA %ikHz . png ” %
( sv , dc ∗ 1 0 0 0 , s p )
f =open ( pic name , wb )
f . w r i t e ( png )
f . close ()
p r o c s a v e ( sv , dc , sp , chan , s y s i , s y s t )
Listing 2. VXI-11 connection example
Fig. 2. Advanced Test and Measurement Setup.
IV. I NTEGRATING G ENERIC D EVICES
The instruments used so far are controlled via the Standard
Commands for Programmable Instrumentation (SCPI). This
communication standard originating from GPIB (IEEE-488)
devices, use the requestresponse principle (see Figure 3(a)).
Hence, to get a value a request is sent to the instrument and
an answer comes back accordingly. This may lead to a short
delay, but we can request a value at any time.
There are other instruments offering a computer interface
not supporting the requestresponse method. One popular representative of that device class are low-range digital multimeter. Such devices send measurement values periodically over
RS232, USB or Bluetooth (see Figure 3(b)). This raises a
problem. When opening such a port, the input buffer has to be
read periodically for proper operation. Directly using such a
device in Listing 1 might be possible due to the periodic nature
but it certainly does not fit into Listing 2. Suppose we extend a
perfectly working setup with such a device, rewriting the hole
code using dummy reads and inner loops completely conflicts
with our paradigm of clean an simple code. In a situations like
this, multithreading should be considered.
A. Multithreading
The multithreading functionality in python is very easy to
use. While generally considered an advanced programming
technique, a multithreaded approach can keep a TMS simple.
The idea is to spawn a thread for the DMM object, that
independently takes care of the device communication. The
thread-object updates an externally accessible variable with
the most recent value.
Listing 3 shows a crude example of such a thread-object.
This example works for a device sending a string like ”5.234
V\n” every second. Line 1 imports the serial module pyserial
[4]. The threading module is part of pythons standard library.
Line 8 is called when we first create the object. It opens the
requested com port. Line 9 reads 100 bytes without using
them. It ensures empty buffers. Calling the start-function of a
thread-object as seen in line 3 of Listing 4 causes the runfunction of that object to run independently. In Listing 3 at line
10 we see the definition of the loop reading the measurement
values that once started will run forever.
While Listing 3 serves demonstration only, lets focus on
one nasty detail. In line 13 of Listing 3 we try to convert the
first 6 characters (0 to 5 as the 6th is not included in the slice)
of the string to a floating point number. This is a process very
prone to errors. If for some reason the measurement range
on the instrument changes and we get a whitespace inside the
cropped string, the float-command will fail with an error. Such
a conversion has to be done in a robust way. Python offers
plenty of possible approaches depending on the exact use case.
For example a try-catch enclosure or regular expression to
name a few. In the given example at the very least a test for
the presence of the line-break symbol should be implemented.
1
2
3
4
5
6
7
8
9
10
11
12
import s e r i a l
from t h r e a d i n g import T h r e a d
from t i m e import s l e e p
c l a s s PeriodicDMM ( T h r e a d ) :
value = 0
def
init
( self , device ) :
s e l f . com= s e r i a l . S e r i a l ( d e v i c e , 9 6 0 0 ,
timeout =.1)
n i l = s e l f . port . read (100)
def run ( s e l f ) :
while True :
res = s e l f . port . read (10)
(a) SCPI based communication.
(b) Periodic communication.
Fig. 3. Sequence Diagram (UML style).
13
14
15
16
s e l f . value= f l o a t ( res [ 0 : 6 ] )
sleep (0.8)
def get value ( s e l f ) :
return s e l f . value
Listing 3. Multithreading Instrument Object.
1
2
3
4
5
import p e r i o d i c d m m
dmm= p e r i o d i c d m m . PeriodicDMM ( ” / dev / ttyUSB0 ” )
dmm . s t a r t ( )
...
p r i n t dmm . g e t v a l u e ( )
Listing 4. Using the Multithreading Object.
B. Integration of Slow Instruments
There is an other type of issue where multithreading can be
beneficial. As a consequence of the requestresponse principle
there is a delay reading a value. The code execution is blocked
until the instruments response is correctly received. In Figure
3(a) this time is visible between the GET arrow and the RES
arrow on the dashed time line. While this delay for most cases
is negligible, even for very fast devices the delay can be in
the range of 10 milliseconds.
Suppose we have a setup with 3 slow instruments (A, B
and C). Instrument B is known to have an additional unpredictable response delay due to internal calculations. Using
these instruments in the simple loop-setup seen in Section
II and III can lead to timing violations (see Figure 4(a)).
Since reading a single value from a variable updated by a
thread-object is considerably faster, the multithread approach
can be used to have device objects with a so called nonblocking interface. The request to the instrument can either be
generated internally or initiated via a function call. But instead
of initiating the request and then wait for the answer, code
execution is continued right away and the response can then
be read when available. This way the delays are not combined
to one very long delay but only the single longest delay has
to be considered as depicted in Figure 4(b).
Listing 5 shows an exemplary code snippet on how the setup
from Figure 4(b) could be handled. To stress the issue the
sampling period only is 200 milliseconds (line 9).
(a) Slow instruments handled in main thread.
(b) Slow instruments in a multi threading setup.
Fig. 4. Setup with very slow measurement instruments.
1
2
3
4
5
6
7
8
9
10
dmmA=slowdmm . SlowDMM( ” / dev / ttyUSB0 ” )
dmmB=slowdmm . SlowDMM( ” / dev / ttyUSB1 ” )
dmmC=slowdmm . SlowDMM( ” / dev / ttyUSB2 ” )
# init ()
dmmA. s t a r t ( )
dmmB . s t a r t ( )
dmmC . s t a r t ( )
while True :
sleep (0.2)
s a v e R e s (dmmA. g e t ( ) ,dmmB . g e t ( ) ,dmmC . g e t ( ) )
Listing 5. Multithreading Approach for Slow Devices.
V. C ONCLUSION
The first two sections showed that test and measurement
setups can be developed with few lines of python code,
keeping the essence of the approach clear to the reader. The
trivial loop-approach can be used for both simple and complex
use cases. Even spacial cases such as fixed periodic transfers
and long communication delays can be handled by using
multithreading.
While already in heavy use for data analysis, this paper
demonstrated how simple data acquisition can be with python.
ACKNOWLEDGMENT
The authors would like to thank Beat Bolli for his encouragement to get involved with python and Alex Forencich for
his work on PythonIVI, Python VXI-11 and Python USBTMC.
Further thanks go to Peter Schlachter for his support on
setting up the necessary python environment in the Institute
of Microelectronics.
R EFERENCES
[1] Numpy: Base n-dimensional array package. [Online]. Available:
http://www.numpy.org
[2] Scipy: Fundamental library for scientific computing. [Online]. Available:
http://www.scipy.org
[3] Python vxi-11 driver for controlling instruments over ethernet. [Online].
Available: https://pypi.python.org/pypi/python-vxi11
[4] (2015) Serial port access-module for pyhton. [Online]. Available:
http://pyserial.sourceforge.net
[5] (2015) Usbtmc driver for controlling instruments over usb. [Online].
Available: https://github.com/python-ivi/python-usbtmc
[6] (2015, Feb) Python implementation of the interchangeable virtual
instrument standard. [Online]. Available: https://github.com/pythonivi/python-ivi
Download