Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

Implementing EOI for pyVISA (\n and then what?)

According to the manual for a hardware I'm trying to automate using pyVISA, termination has to have LF and EOI (end or identify). However, how do I ensure EOI happens, and what exactly is EOI? 

 

From the manual:

astrocarbonate_0-1687280826499.png

What I have so far:

astrocarbonate_1-1687280939993.png

 

 

I'm doing this by following the Getting Started section of pyVISA, and hopefully, pyVISA will allow me to automate the triggering, receiving, and saving of a waveform of an oscilloscope which communicates with a pulser/reciever, sending the data to a computer/usb. Is this the right path to go on? Thanks so much.

0 Kudos
Message 1 of 6
(1,432 Views)

It's been years since I used PyVISA, but there's a manual that discusses these things... 

 

https://pyvisa.readthedocs.io/en/1.8/resources.html

 

write_termination - set the end of line termination character. (\r by default)

send_end - is BOOL for sending EOI.

 

Hope that helps.

Craig

0 Kudos
Message 2 of 6
(1,408 Views)

Thank you, that helps for the understanding a lot! However, how would I set that as the end of the read/write termination? I'm a function called read_raw() and it terminates when it sees \n. Since I want to only terminate at \n and EOI, how would I indicate EOI in a string, to be implemented in the code snippet from above?

0 Kudos
Message 3 of 6
(1,365 Views)

You don't have to do anything extra to send EOI.  Its managed by the bus, serial or GPIB protocol, as long as you have the EOI = TRUE which is the default.  So in your case changing the write_termination should be all you need to do. 

 

You might also consider setting the instrument/bus timeout to something long (3 or 10s) if you aren't getting all data.

 

If you need more help on this, post more details about the instrument, expected data and some code.

 

Cheers,

Craig

0 Kudos
Message 4 of 6
(1,345 Views)

Hi, thank you for your response! I appreciate it. 

 

I currently have the timeout set to 10 seconds, although I'm not sure if it's working. However, the program does wait before returning a timeout error, which is a good sign. 

 

I'm worried because when I use read_bytes() instead of read_raw() it will time out if I try to read 5 bytes, but not if I read 4. This confirms what I got with the read_raw() which also reads 4 bytes. However, as far as I know, read_bytes() does not stop at \n, unlike read_raw. When I print the four bytes, I am getting are this:  b'CH2\n'  . 

 

Specifically, I'm using the DPO/MSO 2000B series. I tried creating my own program to do this earlier, and have incorporated parts of that into the new code, but overall, that one only says that it's saving, but won't trigger. Also, even though the oscilloscope says it's saving, the other code never actually saved the data (I think it may be because I might not have provided the right type of file for the save to work).

 

Specifically, I have adapted a Python 2.7 and pyVISA 1.3 code from here: [https://github.com/tektronix/Programmatic-Control-Examples/blob/master/Examples/Oscilloscopes/BenchS...] to try and send a pulse, then save the data as a CSV. My goal is that whenever the code is executed, it immediately sends one pulse, waits for the signal to acquire for a bit, and then saves that one snapshot. I don't want it to run for an extended period of time: just one pulse and then save the data.

Specifically, I'm using the DPO/MSO 2000B series. I tried creating my own program to do this earlier, and have incorporated parts of that into the new code, but overall, that one only says that it's saving, but won't trigger. Also, even though the oscilloscope says it's saving, the other code never actually saved the data (I think it may be because I might not have provided the right type of file for the save to work).

 

I also tried adding a space, and adding more time to spots overall. For example, I made the code sleep for a while before trying to read, and I also increased the timeout. However, neither worked. I also tried implementing *OPC? but that also timed out, so I was not able to try that.

 

Here is the relevant code:

 

# Curve data captured and saved as CSV file
        if (logmode == 1 or logmode == 2) and scope.query("TRIGGER:STATE?") \
           != 'READY':
            for a, item in enumerate(channelson😞
                if channelson[a] == 1:
                    sleep(5)
                    scope.write("DATA:SOURCE CH" + str(a+1))
                    scope.write("CURVE?")
                    print(scope.write("DATa:SOUrce?"))
                    datac = scope.read_bytes(5)
                    print(len(datac))
                    print(datac)
                    #If FP not locked, settings may have changed
                    if LockFP == False:
                        recLen = scope.query("horizontal:recordlength?")
                        scope.write("data:start 1;stop " + recLen + \
                                    ";:data:encdg rpbinary;:DESE 1;:*ESE 1");
                        scope.write("wfmoutpre:bit_nr 8")
                        recLenNumBytes = len(recLen)
                        headerLen = 1 + 1 + recLenNumBytes;
                        xincr = float(scope.query("WFMInpre:xincr?"))
                        ymult = float(scope.query("WFMInpre:ymult?"))
                        yoff = float(scope.query("WFMInpre:yoff?"))
                        yzero = float(scope.query("WFMInpre:yzero?"))
                        if True:
                            Hscale = float(scope.query("HOR:SCA?"))
                            HDelay = float(scope.query("HORizontal:DELay:TIMe?"))
                            HPos = float(scope.query("HORIZONTAL:POSITION?"))
                       


                    # Strip the header
                    datac = datac[headerLen😞int(recLen)-1)]
                    # Convert to byte values
                    datac = unpack('%sB' % len(datac),datac)
                    # Convert bytes to voltage values
                    x = []
                    y = []
                    print("hello before ranges")
                    for i in range(len(datac)):
                        print("into the for loop 1")
                        x.append((i-(len(datac)*(HPos/100)))* xincr + HDelay)
                        y.append(((datac[i]-yoff) * ymult) + yzero)
                    #save curve data in .csv format
                    f2 = open(filepath + filename+str(filenumber)+ ' CH_' \
                              + str(a+1)+'.csv', 'w')
                    f2.write("s,Volts\n")
                    for i in range(len(datac)):
                        print("into the for loop 1")
                        f2.write(str(x[i]) + ',' + str(y[i])+ '\n')
                    f2.close()
                    print ("CH " + str(a+1) + " Waveform #" + str(filenumber) \
                          + " saved as " + filepath + filename + str(filenumber)\
                          + ' CH_' + str(a+1)+ '.csv' )
                    print ("     triggered at "+ ctime(triggertime) + '\n')
                    capturelog.append("CH " + str(a+1) + " Waveform #" \
                                      + str(filenumber)+ " saved as " \
                                      + filepath + filename + str(filenumber)\
                                      + ' CH_' + str(a+1)+ '.csv')
                    capturelog.append(" triggered at "+ ctime(triggertime) \
                                      + '\n')
 
The 0 bytes is probably coming after I strip off the header. Any assistance would be greatly helpful.

 

0 Kudos
Message 5 of 6
(1,336 Views)

If you are using termination characters, then use read_raw() and stop on the termination character...that's what they are for.  Then you don't need to know exactly how many bytes to read each time. 

 

I'm really not familiar with python anymore enough to debug this from text.  

 

But don't you make two queries here and only one read?  

                    scope.write("CURVE?")
                    print(scope.write("DATa:SOUrce?"))
 
Shouldn't you query or at least read twice after those queries?  You might be piling up data in the buffer that is not being read.  The example you point to does this to read the measurement..
scope.write("CURVE?")
datac = scope.read_raw()
 
As for the triggering settings, a pulsed measurement can be tricky to setup.  But, I don't see where you have the triggering setup at all here.  You will need to consult the manual for the instrument for the right SCPI commands to setup the measurement you want.
 
Craig
 
 
0 Kudos
Message 6 of 6
(1,298 Views)