Basic RigolWFM Usage
Scott Prahl
August 2021
This notebook contains a short overview of the RigolWFM parser for waveform .wfm
files created by Rigol oscilloscopes.
Script to print out description about .wfm file
import RigolWFM.wfm as rigol
model = "DS1102E'
filename = "localfile.wfm"
scope_data = rigol.Wfm.from_file(filename, model)
description = scope_data.describe()
print(description)
Script to put the values of the channels in numpy arrays
import RigolWFM.wfm as rigol
filename = 'wfm/DS2072A-1.wfm'
scope = 'DS2072A'
scope_data = rigol.Wfm.from_file(filename, scope)
# at this point all the data is in scope_data.channels[0] etc.
for ch in scope_data.channels:
print("Channel ", ch.name)
for i in range(5):
print("%d %g %g" % (i, ch.times[i], ch.volts[i]))
Script to create comma-separated values
import RigolWFM.wfm as rigol
filename = 'wfm/DS2072A-1.wfm'
scope = 'DS2072A'
scope_data = rigol.Wfm.from_file(filename, scope)
description = scope_data.describe()
print(description)
s = scope_data.csv()
# just show the first few entries
rows = s.split('\n')
for i in range(5):
print(rows[i])
Script to plot .wfm file
import matplotlib.pyplot as plt
import RigolWFM.wfm as rigol
model = "DS1102E'
filename = "localfile.wfm"
scope_data = rigol.Wfm.from_file(filename, model)
for ch in scope_data.channels:
plt.plot(ch.times, ch.volts, label=ch.name)
plt.legend()
plt.show()
[1]:
#!pip install --user RigolWFM
[2]:
import numpy as np
import matplotlib.pyplot as plt
try:
import RigolWFM.wfm as rigol
except ModuleNotFoundError:
print('RigolWFM not installed. To install, uncomment and run the cell above.')
print('Once installation is successful, rerun this cell again.')
repo = "https://github.com/scottprahl/RigolWFM/raw/master/wfm/"
Motivation
The .wfm
format offers a few nice advantages
saving onto a USB drive on the scope is fast
uploading the
.wfm
file back to the scope is (sometimes) possibleno need to interface to a computer
the files are small (one byte per point)
all the settings are contained in the file header
The disadvantage are that different scopes (and often different firmware version) have different formats. Worse, documentation from Rigol on these formats is sparse at best. Finally, the Rigol software to support reading these files is klunky.
Possible Scope Models
This program currently covers six classes of scopes.
DS1000C untested
Support for these models is in the program, but parsing is completely untested.
Handy Abbreviations: C
, 1000C
, DS1000C
Specific Models: DS1000CD
, DS1000C
, DS1000MD
, DS1000M
, DS1302CA
, DS1202CA
, DS1102CA
, DS1062CA
DS1000E validated
Handy Abbreviations: D
, 1000D
, DS1000D
Specific Models: DS1102D
, DS1052D
Handy Abbreviations: E
, 1000E
, DS1000E
Specific Models: DS1000E
, DS1102E
, DS1052E
DS1000Z tested, incorrect voltages
Handy Abbreviations: Z
, 1000Z
, DS1000Z
,
Specific Models: DS1202Z
, DS1074Z
, DS1104Z
, DS1074Z-S
, DS1104Z-S
, MSO1054Z
, DS1054Z
, MSO1074Z
, MSO1104Z
, DS1104Z
DS2000 tested
Handy Abbreviations: 2
, 2000
, DS2000
,
Specific Models: DS2102A
, MSO2102A
, MSO2102A-S
, DS2202A
, MSO2202A
, MSO2202A-S
, DS2302A
, MSO2302A
, MSO2302A-S
DS4000 validated
Handy Abbreviations: 4
, 4000
, DS4000
,
Specific Models: DS4054
, DS4052
, DS4034
, DS4032
, DS4024
, DS4022
, DS4014
, DS4012
, MSO4054
, MSO4052
, MSO4034
, MSO4032
, MSO4024
, MSO4022
, MSO4014
, MSO4012
]
DS6000 untested
Support for these models is in the program, but parsing is completely untested.
Handy Abbreviations: 6
, 6000
, DS6000
Specific Models: DS6062
, DS6064
, DS6102
, DS6104
The Wfm
class
This is a class with two basic methods to create objects from files and urls:
Wfm.from_file(file_name, model)
Wfm.from_url(url, model)
where model
describes the scope.
It also has a methods to manipulate the data.
Wfm.describe()
Wfm.csv()
Wfm.plot()
The first two return strings. The third produces a basic matplotlib.pyplot.plt
object.
Example for a remote file
First let’s have look at the description of the internal file structure. We see that only channel 1 has been enabled.
[3]:
# raw=true is needed because this is a binary file
wfm_url = repo + "DS1102E-D.wfm" + "?raw=true"
w = rigol.Wfm.from_url(wfm_url, 'E')
downloading 'https://github.com/scottprahl/RigolWFM/raw/master/wfm/DS1102E-D.wfm?raw=true'
Sample description
[4]:
description = w.describe()
print(description)
General:
File Model = wfm1000e
User Model = E
Parser Model = wfm1000e
Firmware = unknown
Filename = DS1102E-D.wfm
Channels = [1, 2]
Channel 1:
Coupling = unknown
Scale = 2.00 V/div
Offset = 2.40 V
Probe = 1X
Inverted = False
Time Base = 100.000 µs/div
Offset = 0.000 s
Delta = 400.000 ns/point
Points = 8188
Count = [ 1, 2, 3 ... 8187, 8188]
Raw = [ 41, 41, 41 ... 110, 110]
Times = [-1.638 ms,-1.637 ms,-1.637 ms ... 1.637 ms, 1.638 ms]
Volts = [ 4.48 V, 4.48 V, 4.48 V ... -1.04 V, -1.04 V]
Channel 2:
Coupling = unknown
Scale = 5.00 V/div
Offset = -15.80 V
Probe = 1X
Inverted = False
Time Base = 100.000 µs/div
Offset = 0.000 s
Delta = 400.000 ns/point
Points = 8188
Count = [ 1, 2, 3 ... 8187, 8188]
Raw = [ 204, 204, 204 ... 178, 178]
Times = [-1.638 ms,-1.637 ms,-1.637 ms ... 1.637 ms, 1.638 ms]
Volts = [400.00 mV,400.00 mV,400.00 mV ... 5.60 V, 5.60 V]
Sample Plot
[5]:
w.plot()
plt.show()
Sample .csv
file
[6]:
s = w.csv()
# just show the first few entries
rows = s.split('\n')
for i in range(5):
print(rows[i])
X,CH 1,CH 2,Start,Increment
µs, V, V,-6.000000e-04,1.000000e-06
-1637.600000,4.48,0.40
-1637.199951,4.48,0.40
-1636.799902,4.48,0.40
Example for a local file
You will need to adjust the path and filename for your computer
[7]:
path = "../wfm/"
filename = "DS1102E-D.wfm"
wfm_name = path + filename
w = rigol.Wfm.from_file(wfm_name, 'E')
description = w.describe()
print(description)
General:
File Model = wfm1000e
User Model = E
Parser Model = wfm1000e
Firmware = unknown
Filename = DS1102E-D.wfm
Channels = [1, 2]
Channel 1:
Coupling = unknown
Scale = 2.00 V/div
Offset = 2.40 V
Probe = 1X
Inverted = False
Time Base = 100.000 µs/div
Offset = 0.000 s
Delta = 400.000 ns/point
Points = 8188
Count = [ 1, 2, 3 ... 8187, 8188]
Raw = [ 41, 41, 41 ... 110, 110]
Times = [-1.638 ms,-1.637 ms,-1.637 ms ... 1.637 ms, 1.638 ms]
Volts = [ 4.48 V, 4.48 V, 4.48 V ... -1.04 V, -1.04 V]
Channel 2:
Coupling = unknown
Scale = 5.00 V/div
Offset = -15.80 V
Probe = 1X
Inverted = False
Time Base = 100.000 µs/div
Offset = 0.000 s
Delta = 400.000 ns/point
Points = 8188
Count = [ 1, 2, 3 ... 8187, 8188]
Raw = [ 204, 204, 204 ... 178, 178]
Times = [-1.638 ms,-1.637 ms,-1.637 ms ... 1.637 ms, 1.638 ms]
Volts = [400.00 mV,400.00 mV,400.00 mV ... 5.60 V, 5.60 V]
[ ]: