Christopher-
I noticed your branch a few days ago. Looks like you've been
putting in a lot of work. Thanks!
The identify example is basically just a sanity check to make sure
that the communication to the instrument is working correctly and
that the new driver can be correctly instantiated. Actually, if
there are any major issues, the 'import ivi' call or the initialize
call will most likely fail. There are a few additional examples way
down at the bottom of the readme, but these are by no means
comprehensive and are mainly just an indication of how you can use
Python IVI to control instruments.
You mentioned an example for screenshots; there is one in the
readme, but it really isn't much to look at:
png = mso.display.fetch_screenshot()
with open('screenshot.png', 'wb') as f:
f.write(png)
I have a couple of scripts that use Python IVI to control a couple
of instruments that I can pass along to you if you are interested,
but there really isn't much to how they use Python IVI that you
can't glean from the examples in the readme.
In terms of individual parameters, I don't think there is one good
simple example. The way I develop drivers is I just go through the
parameters one at a time and I make sure changes to each parameter
are reflected correctly on the instrument.
Implementing the trigger type? If you set the trigger.type
parameter to 'edge', the scope should switch to edge trigger mode.
However, for trigger modes, things may be a little bit complicated.
I would suggest taking a look at the IVI spec. The documentation in
the code is probably sufficient, but the spec is a little better
formatted. Basically, in most of the scopes that I have looked at,
the mapping between IVI trigger types and the scope's supported
trigger types is not quite 1:1. For example, IVI has an 'edge'
trigger and an 'ac_line' trigger. However, to get AC line
triggering on my MSO7104, you need to set it to edge trigger and
then set the source to 'line'. And on the same scope the 'glitch'
and 'width' types both correspond to what the scope calls 'glitch'
triggering, just with different qualifiers. So implementing trigger
types in accordance with the IVI spec requires a little bit of extra
bookkeeping as the IVI trigger type has to be determined from
looking at the scope's trigger type, trigger source, and glitch
qualifier settings.
The bottom line is that you need to check that every parameter works
correctly with your instrument. The easiest way to do this is check
them one at a time by setting them to a sensible value and making
sure the instrument responds appropriately.
Also, if your instrument supports parameters and modes that are not
in the base classes, go ahead and implement them. If there are
already similar instruments included in Python IVI, it would be a
good idea to take a look at those and see if any of them might have
added a similar function, perhaps with a slightly different name.
For example, most instruments support *SAV and *RCL commands to save
and restore the setup to internal memories. For all of the drivers
currently in the repo for instruments that support this, this
functionality is accessed through memory.save and memory.recall.
This isn't an IVI standard, but it is essentially a Python IVI de
facto standard.
The way the IVI spec defines the scope's horizontal timebase is
actually a little bit wonky and I am still mulling over the right
way to implement it. Basically, the idea is that you set the start
time (relative to the trigger) and the range. A setting of 0 for
the start time means that the first point out of fetch_waveform
corresponds to the trigger event. However, on most scopes, you set
the trigger position on the display relative to the center. On my
MSO7104, the start of the trace just ends up on the left-hand edge
of the display, and the offset between the left-hand edge and the
center changes with the horizontal scale, necessitating calculating
and subtracting off that offset. However, on the DSA91304, the
scope seems to like taking 1k points even if it can't display all 1k
points on the screen, so the start of the acquisition actually ends
up quite a ways off the left hand side of the display for sweep
times around 2ns per division or less. I have not thought of a
good, reliable solution for dealing with this yet, so I went ahead
and exposed the timebase.position, timebase.range, and
timebase.scale properties. Yes, they aren't in the IVI spec, but
they correspond nicely with the available commands for most scopes.
(This is a very recent addition and was not present in the version
of the agilentBaseScope file that you copied for the lecroy
scopes).
Alex Forencich