I am trying to set up Labview as an instrument, responding to commands from a remote controller. My vi runs a while loop. It needs to check to see if a command has been received. If not, it performs other tasks in the loop. If a command is received, it has to be able to either send a reply or not send a reply, according to the command.
One non-controller.vi example I found uses RcvRespMsg. The problem here is that RcvRespMsg waits until data is received. I tried adding GPIB Status with a LACS & !ATN test, but once data was received I have to do a send to reset the LACS status.
Another non-controller.vi example uses VISA with a GPIB Listener event. I tried reducing the timeout for the wait for event, but ran into delays when I did not follow a receive with a send.
The common problem seems to be how to get out of listener state without doing a send.
Do you think using a GPIB Read function would work? You could then use the timeout error as the event to cause LabVIEW to carry out the rest of your code. All you'd have to do is find out the number for the timeout error and set your VI to search for that error. Once that error is recieved, you can clear the error and carry out the remaining code.
My code (attached) is based on the non-controller example from http://zone.ni.com/devzone/cda/epd/p/id/3508. It uses RcvRespMsg instead of Read, but the situation is similar. I made it work by setting a short (10 ms) GPIB timeout prior to entering RcvRespMsg, but that seems like a work-around rather than a real fix.
Upon first starting the vi and initializing GPIB, the status bits set are TACS, REM, and CMPL. I use GPIB Status and only call RcvRespMsg when LACS is set, meaning that a message has arrived. Status bits are now LACS, REM, and CMPL. I send a reply and the status reverts to TACS, REM, and CMPL. If I don’t send a reply, LACS remains set. Now, every call to GPIB Status indicates that there is received data (LCAS set) even though there is nothing new. Is there a way for the non-controller to reset listener mode if there is no transmitted reply?
It appears there isn't a way to clear the status. If you want to switch to TACS, you will need to use a write command. The LACS status light simply tells you that it is in a listening mode and it will stay in listening mode until it writes.
May I ask why you are wanting to clear this status?
Reason to clear is so GPIB Status will know there is nothing to read, thereby not calling and waiting for RcvRespMsg to time out. I got around this by setting a short timeout for RcvRespMsg -- it works good enough now.
Thanks for the help.
I would look at using a queue for the recieving commands. This would be a better way to ensure that you respond to all command even under heavy load. I recommend looking at a producer comsumer approach.
Thanks for the tip. I was not familiar with the producer/consumer approach. Looks like it might be useful if I run into problems with lost commands.
Let me describe my application a little better in case there are other ways of dealing with the root problem. The Labview box is acting as a data logger instrument. I communicate with it over gpib as I might with an Agilent meter.
I receive "*IDN?" and respond with "Labview Data logger"
Next, I receive the command "CONF:VOLTS 10 (@1)" to set the range of an input channel, but I do not reply to the controller on this command. Because I did not send, GPIB Status still shows LACS set. Since I use GPIB Status to test for LACS, I go back into RcvRespMsg to receive until it times out (timeout is set to 10ms) with an error. This poll repeats in the main loop until I receive a "READ? (@1)" command and reply with the voltage. This resets LACS and sets TACS.
Perhaps there is a better way to poll for newly received commands? Each complete listener command could be enqueued cleanly and independently of what is going on with the talker.
We are getting into the design of a communication protocol here. One of my first questions is there a need for error checking the comminication protocol? I alway do this just for the piece of mind. For example in you ConF:Volt 10 (@1) command you might consider returning a checksum or some sort of ack.
I don't fully understand your app, what exactly are you looking for? Have you taken a look at the VISA and NI488.2 manuals. If not here are some links
I'm trying to create an instrument with the app. Compare it, for example, to communicating with a 34401A multimeter using the NI488.2 Communicator in M&E. If I send *IDN? as a query, I get a reply. If I send CONF:VOLTC 10 as a query, I get an iberr=EABO because the meter does not reply to that command. So, I just write the command. If I send a bogus command, the meter gives an error beep, but doesn't reply until I separately query SYST:ERR?. In my Labview instrument, I likewise want to receive commands (that I will error check) but for which a reply is not made. With the Labview functions I tried, I couldn't process a receive only without getting a timeout error. The GPIB status wants to continue listening (and timing out) until I send something.
The links to the manuals are helpful. I'll dig further there.