This post is a relic. The initial draft dates back in January 19, 2013. And was left as draft ever since. Past couple of days I was busy — among other things — learning a new programming language, C#. 🙂
Ok, here’s the deal: my scope (KeysightAgilent DSO-X 2002A) is SCPI–compliant device. If you remember, the reason behind this OS X driver project was an attempt to control my KeysightAgilent DSO-X 2002A scope from my MacBook. Unfortunately, KeysightAgilent does not provide SCPI libraries for Mac, neither do they provide any OS X drivers, although they have SCPI/ VISA libraries for Windows (IO Libraries Suite) and a nice app for Windows, named Command Expert; the app can be used to control the instrument.
SCPI stands for Standard Commands for Programmable Instruments. This defines a standard for syntax and commands to use in controlling programmable test and measurement devices. Basically, it is a set of standardised command set that anyone can implement to automate control of measurement instruments like multimeters, oscilloscopes etc. SCPI is pure software standard. SCPI syntax is ASCII text, and therefore can be attached to any computer test language, such as BASIC, C, or C++. For example, this is the scope setup method I wrote in my program (C#):
/** * Sets the scope parameters * */ public void scopeSetup() { string strResults; double fResult; // set labels myDSOX.myScope.Transport.Command.Invoke(":DISPlay:LABel ON"); myDSOX.myScope.SCPI.CHANnel.LABel.Command(1, "Meas.Ch."); myDSOX.myScope.SCPI.CHANnel.LABel.Command(2, "Ref.Ch."); // set scope trigger mode myDSOX.myScope.SCPI.TRIGger.MODE.Command("EDGE"); myDSOX.myScope.SCPI.TRIGger.MODE.Query(out strResults); Console.WriteLine("Trigger Mode: {0}", strResults); // set EDGE trigger source; channel 1 --> yellow; channel 2 --> green myDSOX.myScope.SCPI.TRIGger.EDGE.SOURce.Command("CHANnel2"); myDSOX.myScope.SCPI.TRIGger.EDGE.SOURce.Query(out strResults); Console.WriteLine("Trigger edge source: {0}", strResults); // set EDGE trigger level myDSOX.myScope.SCPI.TRIGger.EDGE.LEVel.Command(1.5, "CHANnel2"); myDSOX.myScope.SCPI.TRIGger.EDGE.LEVel.Query("CHANnel2", out fResult); Console.WriteLine("Trigger edge level: {0:F2}", fResult); // set EDGE trigger slope type myDSOX.myScope.SCPI.TRIGger.EDGE.SLOPe.Command("POSitive"); myDSOX.myScope.SCPI.TRIGger.EDGE.SLOPe.Query(out strResults); Console.WriteLine("Trigger edge slope: {0}", strResults); // set acquisition type myDSOX.myScope.SCPI.ACQuire.TYPE.Command("AVERage"); myDSOX.myScope.SCPI.ACQuire.COUNt.Command(8); myDSOX.myScope.SCPI.ACQuire.TYPE.Query(out strResults); Console.WriteLine("Acquire mode: {0}", strResults); // save scope configuration string[] strScopeConfigurationArray; myDSOX.myScope.SCPI.SYSTem.SETup.Query(out strScopeConfigurationArray); }// end private static scopeSetup()
SCPI can also be used with Test Application Environments such as LabWindows/CVI, LabVIEW, MATLAB, Microsoft Visual Studio, or Agilent VEE. SCPI is hardware-independent. SCPI strings can be sent over any instrument interface. It works equally well over GPIB, RS-232, VXIbus or LAN networks. More informations in the links under further reading section (below).
Since the OS X driver is still on my drawing board (did not have time to complete the libraries part), I decided it is a very good opportunity to give C# a try. Yes C# as for Microsoft C# stuff. And — starting from scratch and for just / less two days of work — I dare say I have managed to impress myself:
Considering the fact that is my FIRST C# attempt with a total of 12 hours of work on the project (during evenings, after my daily job chores), I think I managed pretty well. And, honestly, I understand now why so many rave about C#. It is ideal to quickly create working, simple, useful, visual apps. What this application does is to connect to the Agilent scope, set up the device (with some predefined parameters) and perform some measurements, at a touch of a software button. Results are stored in a volatile collection and displayed in a line chart. The scope setup is pictured in the image below:
Unfortunately one [major] shortcoming of the KeysightAgilent DSO-X 2002A — which, I believe, is true for the entire 2000–series — is the fact that the scope input are high–Z, which makes mandatory the use of 50Ω cable terminators. However, for programming purposes, it does not matter too much. For example, this is how a frequency sweep from 1 MHz to 20 MHz looks like for voltages measured across 10 μH inductor:
The Chart class is superb. I wish Apple could do something like this. I mean, aside of all those bells and whistles and so on damn, Apple, is it so difficult to enhance XCode with a chart object ? Or possibly with a serial connection object ? Or, even sexier, with an USB connection object ? I mean, how difficult is to allow us, poor developers, to use a predefined class with a simple isLogarithmic
boolean property (for example) that automatically sets a NSView–based chart as it suggests ? Yeah, yeah, I know, we can do it. You provide developers with flexibility. But stilll, sometimes I prefer a bit more rigid approach…
What I am trying to achieve is to increase my instrumentation capabilities draining the last drop of functionality from my KeysightAgilent scope. For example, I want to leverage the availability and usefulness of the embedded wave generator which is able to go up to 20 MHz and can provide AM, FM, phase and FSK modulation. Basically, the scope does not have a sweep function, but this can be easily achieved via SCPI integration and C# coding. For example, considering three variables: a frequency for sweep start (lowFrequency
), a frequency for end sweep (highFrequency
) and a frequency increment step (stepFrequency
), the C# routine could be:
int i = 0; while (lowFrequency <= highFrequency) { Thread.Sleep(100); // set start sweep frequency to low freq value freqSweep.startSweep(lowFrequency); // add each measured point to the collection listDataSource.Add(new Record(i, lowFrequency, freqSweep.measureResults(channel))); // end adding data lowFrequency += stepFrequency; // report progress if needed //bw.ReportProgress(i); ++i; }
where the freqSweep.measureResults(channel)
is the method that actually does the measurement, on scope channel, channel
; the method is implemented inside the class freqSweep
; the actual measurement and variable assignment are performed on highlighted lines:
/** * Perform the measurement on specified scope channel */ public double measureResults(string channel) { double fResult; myDSOX.myScope.SCPI.MEASure.SOURce.Command(channel, null); myDSOX.myScope.SCPI.MEASure.VAMPlitude.Query(channel, out fResult); Console.WriteLine("Amplitude : {0:F4}", fResult); if (fResult > 1000) return 0.0; else return fResult; }// end public double measureResults
Ok, that’s it for today. There is a tremendous amount of improvement for this small project, from my point of view notwithstanding the results are impressive. I was able to create a fully-functional app in less than two days, starting from scratch. True, the very abrupt learning curve is probably due to my prior programming knowledge. Nevertheless. I might fall in love with this C# so more to come on the topic. Hm… Microsoft, mon amour ? 😀
Further reading
- SCPI on Wikipedia; a good place to start. SCPI overview, some background, rationale, command syntax (high–level topics), arguments, abbreviations; not too in–depth, but enough for starters;
- SCPI Consortium; included in the IVI Foundation website; SCPI Consortium was engulfed by IVI Foundation in 2002 and finally merged with in 2003; IVI Foundation is now the official responsible for SCPI specification.
- National Instruments’ LabWindows/CVI;
- LabView, MATLAB
- MS Visual Studio
- Keysight
AgilentVEE - Open Source SCPI device library/ SCPI parser library — Not sure what is this useful for; nightmarish C–oriented framework; to be explored and — possibly — exploited 😉
About KeysightAgilent libraries for VISA (Virtual Instrument Software Architecture) and SCPI: Starting with IO Libraries Suite 15.5, all of the KeysightAgilent I/O Libraries are available for use in both 32-bit and 64-bit systems. You can find specific information on how to use the libraries on 64-bit systems by searching the IO Libraries Suite 15.5 Help file for the topic “64-bit”. Available information:
- FAQ documentation
- Keysight
Agilentforum home - Keysight
AgilentVISA User’s Guide - Virtual Instrument Software Architecture page on Wikipedia
- VISA Specification on IVI website
- Search results for “VISA” keyword on Agilent website
- Software I/O Layers – VISA, VISA COM, SICL, Agilent 488
- “Programming Considerations for Using VISA with Visual Basic 6” — application note (pdf document)
- Learn to control instruments with Visual Basic
- Keysight
AgilentIO Libraries Suite 16 Data Sheet (pdf) - Building Hybrid Test Systems (pdf) — excellent additional literature @ end of document.
Your class interface is interesting. Do you have any code snippets to post?
Hi, Mark. Thanks for your comment and appreciation. I am not quite sure what snippets are you talking about. 🙂 Could you, please, let me know ?
Regards,
AP