Super-zoomable graphs
One of the nice features of the Rigol is "Long Memory" - instead of downloading the 600-point trace that appears on the screen, you can record and access a high-resolution trace of 1 million points. In this hack, I show how you can display this data with Python, giving you a picture that you can easily zoom into with the mouse.The following screenshot shows the data collected by hooking the oscilloscope up to an IR sensor. In the above picture, the sensor is the three-pin device below the screen. Since I've developed an IR library for Arduino, my examples focus on IR, but any sort of signal could be used. By enabling Long Memory, we can download not just the data on the screen, but 1 million data points, allowing us to zoom way, way in. The graph below shows what it sent when you press a button on the TV remote - the selected button transmits a code, followed by a periodic repeat signal as long as the button is held down.
To use this script, first enable Long Memory by going to Acquire: MemDepth. Next, set the trigger sweep to Single. Capture the desired waveform on the oscilloscope. Then run the Python script to upload the data to your computer, which will display a plot using matplotlib
. To zoom, click the "+" icon at the bottom of the screen. This lets you pan back and forth through the data by holding down the left mouse button. You can zoom in and out by holding the right mouse button down and moving the mouse right or left. The magnifying glass icon lets you select a zoom rectangle with the mouse. You can zoom on your oscilloscope too, of course, but using a mouse and having labeled axes can be much more convenient.
A few things to notice about the code. The first few lines get the list of instruments connected to VISA and open the USB instrument (i.e. your oscilloscope). The timeout and chunk size need to be increased from the defaults to download the large amount of data without timeouts.
Next, ask_for_values
gets various scale values from the oscilloscope so the axes can be labeled properly. By setting the mode to RAW
we download the full dataset, not just what is visible on the screen. We get the raw data from channel 1 with :WAV:DATA? CHAN1
. The first 10 bytes are a header and should be discarded. Next, the raw bytes are converted to numeric values with Mahto's formulas. Finally, matplotlib
plots the data.
There are a couple "gotchas" with Long Memory. First, it only works reliably if you capture a single trace by setting the trigger sweep to "single". Second, downloading all this data over USB takes 10 seconds or so, which can be inconveniently slow.
Analyze an IR signal
Once we can download a signal from the oscilloscope, we can do more than just plot it - we can process and analyze it. In this hack, I decode the IR signal and print the corresponding hex value. Since it takes 10 seconds to download the signal, this isn't a practical way of using an IR remote for control. The point is to illustrate how you can perform logic analysis on the oscilloscope trace by using Python.
This code shows how the Python script can wait for the oscilloscope to be triggered and enter the STOP
state. It also shows how you can use Python to initialize the oscilloscope to a desired configuration. The oscilloscope gets confused if you send too many commands at once, so I put a short delay between the commands.
Generate a spectrogram
Another experiment I did was using Python libraries to generate a spectrogram of a signal recorded by the oscilloscope. I simply hooked a microphone to the oscilloscope, spoke a few words, and used the script below to analyze the signal. The spectrogram shows low frequencies at the bottom, high frequencies at the top, and time progresses left to right. This is basically a FFT swept through time.
Dump data to a .wav file
You might want to analyze the oscilloscope trace with other tools, such as Audacity. By dumping the oscilloscope data into a WAV file, it can easily be read into other software. Or you can play the data and hear how it sounds.
To use this script, enable Long Memory as described above, capture the signal, and run the script. A file channel1.wav
will be created.
How to install the necessary libraries
Before connecting your oscilloscope to your Windows computer, there are several software packages you'll need.- I assume you have Python already installed - I'm using 2.7.3.
- Install NI-VISA Run-Time Engine 5.2. This is National Instruments Virtual Instrument Software Architecture, providing an interface to hardware test equipment.
- Install PyVISA, the Python interface to VISA.
- If you want to run the graphical programs, install Numpy and matplotlib.
VI_WARN_CONFIG_NLOADED
errors. If you've already installed Ultrascope, you'll probably need to uninstall and reinstall NI_VISA.
If you're using Linux instead of Windows, see Mehta's article.
How to control and program the oscilloscope
Once the software is installed (below), connect the oscilloscope to the computer's USB port. Use the USB port on the back of the oscilloscope, not the flash drive port on the front panel.
Hopefully the code examples above are clear.
First, the Python program must get the list of connected instruments from pyVisa and open the USB instrument, which will have a name like USB0::0x1AB1::0x0588::DS1ED141904883
. Once the oscilloscope connection is open, you can use scope.write()
to send a command to the oscilloscope, scope.ask()
to send a command and read a result string, and scope.ask_for_values()
to send a command and read a float back from the oscilloscope.
When the oscilloscope is under computer control, the screen shows Rmt and the front panel is non-responsive. The "Force" button will restore local control. Software can release the oscilloscope by sending the corresponding ":KEY:FORCE" command.
Error handling in pyVisa is minimal. If you send a bad command, it will hang and eventually timeout with VisaIOError: VI_ERROR_TMO: Timeout expired before operation completed.
The API to the oscilloscope is specified in the DS1000D/E Programming Guide. If you do any Rigol hacking, you'll definitely want to read this. Make sure you use the right programming guide for your oscilloscope model - other models have slightly different commands that seem plausible, but they will timeout if you try them.
I really enjoyed this post. You always expose new and awesome information. Thank you for sharing your work so much!
ReplyDeleteKen
ReplyDeleteI also have a Rigol and would like to try this out on Windows. Do you know of any tool to interface with it on windows?. Is it a custom USB i/F or serial?
If you have a moment have a look at our AnalysIR project on Indiegogo. (see below for details). We would be happy to offer you a copy if the project is successful. We would also appreciate any suggestions for features & new protocols to support. We should have 20 protocols supported by the time it is released.
BTW: Thanks for all of the work on IR over the years, it has been truly inspirational.
As Part of our project we also plan to release a method for recording IR signals & modulation frequency on Arduino (simultaneously). We will be exhibiting this method at the Dublin Mini Maker Faire on July 27th
========
For anyone interested in IR protocols – we have just launched a project on IndieGoGo for AnalysIR – IR Decoder & Analyzer (Arduino & Raspberry Pi). Currently we support 17 IR protocols and are looking for more to add as part of the campaign. Suggestions Welcome!
You can find out more about the Project on http://bit.ly/1b7oZXH or Screenshot via www.AnalysIR.com
Sorry
ReplyDeleteI assumed when I saw Python it was running on linux. After clicking the link I see it supports windows. We will have lots of fun with this after Maker Faire :) tnx again.
Thanks for the great article with the helpful code. I was wondering what you might suggest for fixing the 'Bad instrument list' error. Could it be because I'm running Python 3.x? Thanks!
ReplyDeleteHi Norse! The most likely problem is incompatibility between Python 3 and PyVISA; according to the github page, PyVISA doesn't support Python 3 yet. Also, try printing the raw instrument list to see what you're getting. Finally, make sure you have the NI-VISA I specify above.
ReplyDeleteThanks Ken, 2.7 worked! Also, In case anyone runs into this problem, NI-VISA 5.2 wound up giving me errors on Python 2.7. I updated to NI-VISA 5.3, installed Enthought (free version) for numpy and matplotlib, and installed the linked version of PyVISA and everything worked well together. Thanks again for the great article and help!
ReplyDeleteKen, looks like the code assoiciated with the "create .wav" section is for the spectagraph rather than for creating .wav files.
ReplyDeleteKen,
ReplyDeleteAny chance of giving me a pointer to a solution?
I have just bought a Rigol DS1102E scope from Amazon and would like to access it with Python on OSX 10.9 Maverick.
The problem is that when I plug in the USB cable, OSX does not recognise the USB port: i.e.
ls /dev/tty.* does not show anything.
I have no trouble seeing when another USB cable is plugged in - say an Arduino.
On the Riogol, selecting computer or Pictbridge under Utilities does not make a difference.
I guess I could use RS232 but would lim ego get the USB working.
Any ideas?
Thanks,
Mike Alport
I just got this to work on Mac Os X Mavericks.
ReplyDeleteMike,
Follow the instructions on
http://www.rau-deaver.org/Mac-PyVISA.html
I grabbed the NI-VISA-Runtime-5.4.0 from Labviews web page.
Download and install the PyVisa according to the instructions.
Modify Kens script with adding
from pyvisa.vpp43 import visa_library
visa_library.load_library("/Library/Frameworks/Visa.framework/VISA")
before
import visa
That is all.
Hello
ReplyDeletefrom my PC running windows 7 I want to control my function generator DG1022 RIGOL with its USB HOST interface as I am not a developer this are 2 questions:
1) After installing python, visa, pyvisa is it necessary to install other usb interfaces as openusb, libusb, USBTMC? .. )
2) Has anyone ever done this driving of a 1000 Series RIGOL?
Thank you for your information
Daniel de Paris in France
[email protected]
Just looking at the first example and I couldn't change it to read channel 2. It needs:-
ReplyDeletescope.write(":WAV:SOUR CHAN2")
scope.write(":WAV:POIN:MODE RAW")
rawdata = scope.ask(":WAV:DATA? CHAN2")[10:]
On Windows: C:/Windows/System32/visa32.dll
ReplyDeleteKen,
ReplyDeleteI am trying to pull voltage / any information from a tattoo needle machine as the tattoo is being done, so I can generate a nice spectrogram and other images from the data. Do you think this would be a good setup to do that?
Thank,
Maxwell
Maxamust: your tattoo application sounds interesting. One thing to keep in mind is the oscilloscope captures the data and then transfers it to the computer, so you're getting blocks of data rather than "real time" data. That's probably okay for your application - I don't know exactly what you're doing - but I wanted to mention it. Let me know how it works out, since it sounds like an interesting project.
ReplyDeleteKen really good post. I did not even think of using Rigol scope for generating spectrogram ;-D For those who are interested in controlling Rigol instruments from C have look at this tutorial Rigol oscilloscope remote control with NI-Visa
ReplyDeleteYou could maybe use Ethernet transport like I do here: http://luhasoft.github.io/scopeio/
ReplyDeleteAt least it seems easier than the USB problems reported in this page.
And your computer can be wireless then if you have wireless and wired networks connected. But for such big data you may need to increase vxi11 buffer even more than I do in the small patch and binary data needs special handling in the C program part.
Ken,
ReplyDeleteDoes your code control the amount of data that is taken? Basically I am writing a code that needs to be able to run for x amount of triggers over whatever duration of time... Does your code do that, or is there a simple way to program that type of function with your code?
Thanks so much,
Zak
I am interfacing RIGOL DS1052 with computer using USB cable. I am acquiring data of two channels in normal mode (600 data points). I have constructed wave forms, but what I am interested in is measuring the phase difference between two waveforms, this is possible only if RIGOL provides me data of channel1 and channel2 at same time intant i.e first sample of ch1 is at t=t0 and first sample value of ch2 is also at t=t0. Kindly tell me in what format is RIGOL transfers data. I am acquiring databy sending WAV:DATA:CHAN1 command, after getting the result I ask for data of channel2.
ReplyDeleteHello.
ReplyDeleteI have used your example code and made a fork to work with my MSO1104 and Python35 + PyVISA1.8.
It can be found here:
https://gist.github.com/StevanxDK/3d1001eb817fdf4cc7384d388b989c99
Hi! Thanks for the great tutorial. Some of the code was a little out of date, so I updated it here: https://gist.github.com/samclane/c0fb90219214361cb963674b3bc82848
ReplyDeleteI'm using:
RIGOL DS1052E
Python 3.6.2
PyVisa 1.9.1
numpy 1.14.2