Tektronix Technical Forums are maintained by community involvement. Feel free to post questions or respond to questions by other members. Should you require a time-sensitive answer, please contact your local Tektronix support center here.

get SRQ on ACQUIRE:STATE ON, TDS-820, linux-gpib, python

Post Reply
doobs.
Posts: 4
Joined: July 16th, 2017, 8:53 pm
Country: Australia

get SRQ on ACQUIRE:STATE ON, TDS-820, linux-gpib, python

Post by doobs. » December 3rd, 2017, 5:35 am

Hi,
the problem I am having is that after setting:

Code: Select all

DESE 1  # Enable the OPC bit in DESE enable register
*ESE 1   # Enable the OPC bit in ESE enable register
*SRE 32   # Enable SRQs (bit 5) in the SRE enable register

ACQUIRE:MODE AVERAGE
ACQUIRE:STOPAFTER SEQUENCE
ACQUIRE.NUMAVG 512
when I submit the commands:

Code: Select all

ACQUIRE:STATE 1
*OPC
-at that point, the GPIB board gets an SRQI almost immediately, even though the scope is still accumulating data.
I assume that this is because the device/scope has asserted the SRQ line.

The scope is connected to an Agilent 82357B USB/GPIB connector.
The PC is running linux-gpib-4.0.4rc2 .
Python2.7 loads the gpib module without issues and by and large communicates with the TDS-820 without any other issues.

The actual offending bit of code is this:

Code: Select all

import threading
import Queue as queue   # for message parsing to thread

CMPL   = (1<<8) # 0x1000
RQS   = (1<<11) # 0x1000
SRQI   = (1<<12) # 0x1000
END    = (1<<13)
TIMO   = (1<<14) # 0x4000
ERR    = (1<<15) # 0x8000

Mutex = threading.Lock() # put a lock on the gpib communications


# write command and wait for service request
class SRQIThread (threading.Thread):
    # initialize class
    def __init__(self, name, bus, inst, inputQ):
      threading.Thread.__init__(self)
      self.name = name      # thread name
      self.bus = bus            # this is the python gpib object 
      self.inst = inst            # this is my  wrapper around the gpib object
      self.device = inst.inst  # and this is whatever is returned by gpib.find(device)
      self.board = 0             # gpib id of the Agilent 82357B controller board
      self.queue = inputQ
      self.running = True

    # gets called when thread is started with .start()
    def run(self):
        while self.running:
          if not self.queue.empty():
            command, callback = self.queue.get(block=True)
            Mutex.acquire()
            try:
              self.bus.write(self.device, command) # submit command
              self.bus.write(self.device, "*OPC\n" ) # submit command
            finally:
               Mutex.release()
            count = 0
            while True:
              try:
                #MASK = TIMO | END | CMPL | RQS | SRQI
                MASK = TIMO | SRQI
                self.bus.wait(self.board, MASK)# Wait SRQI or TIMeOut
                sta = self.bus.ibsta()           # Get status
                if (sta & TIMO) != 0:
                  #print"Timed out"
                  continue
                if (sta & ERR) == 0:    # yep, no errors, all going to plan
                  count = count + 1
                  if count > 1:            # this was just in case there was a lingering SRQ already there??
                    callback(sta)       # this is called way to prematurely!!!!
                  else:
                    print "try again..."
                    continue
                #else an error?
                break
              except gpib.GpibError as e:
                print e
                break

          time.sleep(0.1)
          

    def die(self):
      self.running = False          

The way it works is that a (command-string, callback-func) tuple is submitted into the queue. When the SRQIThread gets an opportunity, it reads the command and the callback from the queue, gets a lock on the GPIB interface, sends the "ACQUIRE:STATE ON" command, followed closely by the "*OPC" command and then runs gpib.wait() - checking for the SRQI status of the board (not SRQ on the scope??).

But the callback is always called immediately with SRQI asserted by the board. And I don't know enough about GPIB to guess whats going wrong.

Thanks for any info.

doobs.
Posts: 4
Joined: July 16th, 2017, 8:53 pm
Country: Australia

Re: get SRQ on ACQUIRE:STATE ON, TDS-820, linux-gpib, python

Post by doobs. » December 11th, 2017, 4:43 am

So anyway, the following code seems to work:

Code: Select all

    # gets called when thread is started with .start()
    def run(self):
        while self.running:
          if not self.queue.empty():
            command, callback = self.queue.get(block=True)
            Mutex.acquire()
            try:
              self.bus.write(self.device,"*ESR?\n")
              tmp = self.bus.read(self.device, 256) # read/clear register
              self.bus.write(self.device, command) # submit command
              self.bus.write(self.device, "*OPC\n" ) # submit command
            finally:
               Mutex.release()
            while True:
              try:
                MASK = TIMO | SRQI
                sta = self.bus.wait(self.board, MASK)# Wait SRQI or TIMeOut
                #print "waited.. ",bin(sta)
                if (sta & TIMO) != 0:
                  #print"Timed out"
                  time.sleep(0.01) # give other thread a chance?
                  continue
                if (sta & ERR) == 0:
                  #print "not an error  so poll"
                  # woke from wait for a good reason...
                  ista = 0
                  Mutex.acquire() # this will block
                  try:
                    ista =self.bus.serial_poll(self.device)
                    print "polled: ", bin(ista), ista & (1<<5)
                  except Exception as e:
                    print e
                    print "----", command
                  finally:
                    Mutex.release()
                  if (ista & (1<<5)):
                    # SRQ! Woke from wait for the right reason...
                    # print "success!"
                    callback(sta)
                  else:
                    # Woke from wait for the wrong reason...
                    #print "try again...", bin(ista)
                    continue
                #else an error?
                break
              except gpib.GpibError as e:
                print e
                break

          time.sleep(0.1)
So there were several important issues. gpib.wait(device, MASK) can function in two different modes depending on the configuration of
gpib.IbcAUTOPOLL. When autopolling is switched on, in principle you say gpib.wait(oscilloscopeID, TIMO | RQS) and the library automatically polls the oscilloscope when any service request is detected from any instrument on the bus. I couldn't get this mode to work.

With autopolling switched off, the default, then when the service request arrives, YOU need to check that is came from the instrument on the bus that you care about - hence the gpib.serial_poll(oscilloscopeID).

But apparently when more than one thread is hammering the gpib interface, then that bus traffic also causes the blocking wait() to return. So YOU need to check that status returned by the serial_poll() actually corresponds to the SRQ event (1<<5) that you are waiting on. Surprisingly, it does actually turn up when the acquisition is complete!

Post Reply

Return to “Programming Support”

Who is online

Users browsing this forum: No registered users and 5 guests