How to communicate with non-SCPI instruments?

What is the preferred way to communicate with non-SCPI instruments (R2D2) and “strange” serial protocols?
As I understand the Instrument class doesn’t provide “low-level” VISA I/O methods?

If the instrument is VISA based you can leverage the ScpiIO class to see how we implement VISA:

If it is serial, I’d just recommend using one of the C# Serial libraries for example, this is what we did for a barcode scanner:

For serial devices I think it is a must to use some external libraries since most serial devices doesnt speak SCPI and it’s not(?) possible to control baudrate, parity etc.
Room for improvement?

1 Like

So far, people have gotten by with the 3rd party libraries, but I could see an open source DUT plugin base class existing. Sounds like you would find that useful as well?

Yes, and exposing more of the underlaying VISA properties so baudrate etc. can be set/get. I think it’s a big advantage if as much as possible of I/O can be done using OpenTAP’s I/O layer

1 Like

Found out, the hard way, ScpiInstrument always sends some commands in Open:
image
ViClear can be disabled in Settings but not the rest (*IDN?, *CLS and ReadSTB)
This makes it impossible to use OpenTAP’s I/O layer for non-SCPI (actually non-488.2 compatible) devices incl most serial devices and old GPIB instruments.

I think ScpiInstrument class settings need more granularity. Like a non-SCPI/488.2 mode (in addition to be able to set/get serial settings).
Alternatively expand the Instrument class to include basic and low-level VISA functionality.

1 Like

The original intention of that exposing that class was SPCI based instruments that had some non-standard read/write commands. It would be possible to have a custom class that used the IScpi2 interface similar to ScpiInstrument. You would then be able to customize the Open method which is where those commands are called:

In general, I understand your point on the serial settings. However, I think ultimately, this would make most sense as a separate class, not an extension of the ScpiInstrument. I’ll submit an issue on it, but in the meantime if you come up with something, I think would be something really valuable that could be contributed back if interested.

Hi @GoranJohnsson

for serial comms I use ScipiInstrument as the base class. The instrument then looks like all other instruments. The address will also use the standard SCPI format, selectable from the address dropdown. In this example, I haven’t exposed any other serial comms parameters thought.
Simply create a SerialComms class to use instead of the usual Scpi calls. Initially I wasn’t going to use ScpiInstrument but it made address selection easy.

… use in your instrument like this.

    public override void Open()
    {
        SerialComms = new SerialComms();
        SerialComms.Open(VisaAddress);
        IsConnected = true;            
    }

… comms class.

    public SerialComms()
    {
        _serialPort = new SerialPort()
        {
            BaudRate = 9600,
            Parity = Parity.None,
            DataBits = 8,
            StopBits = StopBits.One,
            Handshake = Handshake.None,
            ReadTimeout = 500,
            WriteTimeout = 500,
            Encoding = Encoding.ASCII
        };
    }

    private SerialPort _serialPort;

    public void Open(string port)
    {

        _serialPort.PortName = port;
        _serialPort.Open();

    }

    public void Close()
    {
        _serialPort.Close();
    }

    public string Read()
    {
        return _serialPort.ReadExisting();
    }

    public byte[] ReadBytes()
    {
        var byteBuffer = new byte[6];
        _serialPort.Read(byteBuffer, 0, 6);

        return byteBuffer;
    }

    public void Send(string msg)
    {
        _serialPort.WriteLine(msg);
    }

    public void SendBytes(byte[] byteBuffer)
    {
        _serialPort.Write(byteBuffer, 0, 6);
    }

    public string QueryInstrument(string message)
    {

        this.Send(message);
        TapThread.Sleep(300);
        var answer = this.Read();

        return answer;

    }

    public byte[] QueryInstrument(byte[] bytes)
    {
        SendBytes(bytes);
        TapThread.Sleep(300);
        var answer = ReadBytes();
        return answer;

    }
}
2 Likes

Good solution! Agree, you really want it to “look” like all other instruments. Key point is to avoid/remove ScpiInstrument base.Open() I guess. There are no side-effects of not using base.Open()?

1 Like

No side-effect at all.

1 Like

I assume you use System.IO.Ports? Can you use a VisaAddress as PortName?

Yeah System.IO.Ports, sorry, missed that. VisaAddress works fine but I may use COM3 in the dropdown. Not infront of my system so I can’t confirn this.

Back in the lab, so I can now confirm I use COM3 and not the visa ASRL3:INSTR address.

2 Likes

Yes, no surprise. I guess you convert ASRLx to COMx? So what was the reason to use ScpiInstrument as base and not Instrument? (since none of the VISA/SCPI Bench settings are used or can be used)

1 Like

I have phased out GPIB connections, so all instruments will communicate using LXI, USB or serial now. In this case, it was a temperature chamber and serial was the only other interface available. It was some time ago now so I probably just left it in for convenience. Now you’ve reminded me, I’ll look at getting rid of it now.

3 Likes