Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

Responding to messages with NI-Device

I am implementing GPIB device behavior with NI-Device, and am having difficulty implemeting _asynchronous_ message handling behavior.

A typical _synchronous_ GPIB message sequence is
END_MSG_RECEIVED (my device receives a message)

QueryDetected() (inform NI-Device that response message is available)
QueueResponseMsg()
AcknowledgeEndOfMessage()
EnableInputQueue(); <- no new gpib messages can be received until this point

However, I want to be able to receive additional GPIB messages while I am processing messages (which may take a while), so I do this:
thread 1:
END_MSG_RECEIVED (my device receives a message)

QueryDetected() (inform NI-Device that message is available)
AcknowledgeEndOfMessage()
EnableInputQueue();
thread 2:

QueueResponseMsg()

Unfortunately, NI-Device does not allow me to place response messages in the output queue (QueueResponseMsg()) more than once unless a new input message arrives.
I've tried calling QueryDetected() before posting additional response messages, but that does not work.
Is there any way to post additional response messages to NI-Device without requiring a a new input message?

Thanks,
- Ian
0 Kudos
Message 1 of 5
(3,224 Views)
Sorry, but my last post is missing some lines.
Here is the corrected version:


I am implementing GPIB device behavior with NI-Device, and am having difficulty implemeting _asynchronous_ message handling behavior.

A typical _synchronous_ GPIB message sequence is
END_MSG_RECEIVED (my device receives a message)
_process message
QueryDetected() (inform NI-Device that response message is available)
QueueResponseMsg()
AcknowledgeEndOfMessage()
EnableInputQueue(); <- no new gpib messages can be received until this point

However, I want to be able to receive additional GPIB messages while I am processing messages (which may take a while), so I do this:
thread 1:
END_MSG_RECEIVED (my device receives a message)
_add message to queue
QueryDetected() (inform NI-Device that message is available)
AcknowledgeEndOfMessage()
EnableInputQueue();
thread 2:
_process message on queue
QueueResponseMsg()

Unfortunately, NI-Device does not allow me to place response messages in the output queue (QueueResponseMsg()) more than once unless a new input message arrives.
I've tried calling QueryDetected() before posting additional response messages, but that does not work.
Is there any way to post additional response messages to NI-Device without requiring a a new input message?

Thanks,
- Ian
0 Kudos
Message 2 of 5
(3,225 Views)
Could we step back just a little? Which state machine are you trying to follow? The Message Exchange Protocol State Machine or the Unterminated State Machine. It looks like it's the Message Exchange Protocol State Machine, but I just want to verify.

NI-Device Help

Logan S.
0 Kudos
Message 3 of 5
(3,211 Views)
Yes, I am asking about the Message Exchange Protocol.
I found a function called EnableRelaxedOutputMode(), which appears to do what I want it to do.
- Ian
0 Kudos
Message 4 of 5
(3,199 Views)

@ianchan1970 wrote:
Unfortunately, NI-Device does not allow me to place response messages in the output queue (QueueResponseMsg()) more than once unless a new input message arrives.
I've tried calling QueryDetected() before posting additional response messages, but that does not work.
Is there any way to post additional response messages to NI-Device without requiring a a new input message?

Thanks,
- Ian



NI-Device does allow you to queue multiple messages (one at a time) using QueueResponseMsg() for a single input message, but only the last one can have the "SendEnd" parameter set to true (which causes the transition from Response->Done in the state machine). (Essentially, you can send a single response message in pieces).

IEEE 488.2 specifically restricts multiple responses (where each response has END) for a single query. It also states that the entire response to a query must be read by the controller before the controller can send you another message to be parsed (transition from Response->Read via MSG_INTERRUPTED). However, you can do some of what you are trying to do with IEEE 488.2 by sending a "compound message". The offiical term from IEEE 488.2 is "The [semicolon] separates sequential [command] elements from one another within a [compound message]." Essentially, you can send the command "DoSomething;DoSomethingElse". By putting a semicolon between the two, the device can receive two messages at once and act on them. If they both generate responses, they must be responded to in order, but both responses are generated and separated by commas.

Relaxed mode, as you have determined, skips most of this IEEE 488.2 restrictions and is probably what you are looking for, but I did want to give you some official background.
0 Kudos
Message 5 of 5
(3,187 Views)