11-04-2009 11:59 AM
The instrument driver that I developed continually yields the result 0xBFFF0015 (VI_ERROR_TMO) when any query is sent to the instrument. The returned value was obtained by running NI Spy in parallel with my program.
I followed the example given in the NI-VISA User Manual, Appendix A, Example 7-1, as shown in the following excerpt from part of my driver:
longRet& = viEnableEvent(vi1&, VI_EVENT_SERVICE_REQ, VI_QUEUE, VI_NULL)
writeBuf$ = "ERR?" & Chr$(13) & Chr$(10)
longRet& = viWrite(vi1&, writeBuf$, Len(writeBuf$), 6)
longRet& = viWaitOnEvent(vi1&, VI_EVENT_SERVICE_REQ, 3000, eventType&, viEvent&)
longRet& = viReadSTB(vi1&, lclSTBret%)
longRet& = viClose(viEvent&)
longRet& = viDisableEvent(vi1&, VI_ALL_ENABLED_EVENTS, VI_ALL_MECH)
Is there any explanation as to why an error is always encountered for the viWaitOnEvent call (see pasted line from NI Spy file below)? The fact that this error is returned does not seem to affect the successful operation of my driver.
Thanks, in advance, for any and all suggestions.
> 12. viWaitOnEvent (GPIB0::3::INSTR (0x038B0550), SERVICE_REQ, 3000, 0, 0x00000000)
> Process ID: 0x00000660 Thread ID: 0x00000578
> Start Time: 17:00:42.662 Call Duration 00:00:03.005
> Status: 0xBFFF0015 (VI_ERROR_TMO)
11-04-2009 01:16 PM
What, if anything, have you done to make the instrument generate a service request? An SRQ is not automatic and for the ERR? query, would not be required anyway. All that you have to is a viRead after the viWrite.
Have a look at this tutorial.
11-04-2009 03:57 PM
I believe that I've set the *ESE & *SRE correctly, based on what I expect to monitor from the instrument(s), which is(are) Newport series laser diode controllers. Specifically, in the initialization routine, I have the following:
writeBuf$ = "*ESE 191" & Chr$(13) & Chr$(10)
longRet& = viWrite(vi1&, writeBuf$, Len(writeBuf$), 6) 'enable event status registry
' bit 0 = 1 -> Operation complete YES
' bit 1 = 2 -> GPIB parser is idle YES
' bit 2 = 4 -> Query error YES
' bit 3 = 8 -> Device dependent error YES
' bit 4 = 16 -> Execution error YES
' bit 5 = 32 -> Command error YES
' bit 6 = 64 -> N/A YES
' bit 7 = 128 -> Power on YES
and
writeBuf$ = "*SRE 191" & Chr$(13) & Chr$(10)
longRet& = viWrite(vi1&, writeBuf$, Len(writeBuf$), 6)
' bit 0 = 1 -> TEC event summary YES
' bit 1 = 2 -> TEC condition summary YES
' bit 2 = 4 -> Laser event summary YES
' bit 3 = 8 -> Laser condition summary YES
' bit 4 = 16 -> Message available YES
' bit 5 = 32 -> Event status summary YES
' bit 6 = 64 -> Request service/Master status summary NO
' bit 7 = 128 -> Error message available YES
The reason for not setting bit 6 high in the SRE mask is due to the fact that it seems to be locked-out. In other words, if I send *SRE 255 to the instrument & then queried the instrument with *SRE?, it always returns 191. Thus, I assmumed that it could not be enabled/disabled by the user.
So, based on my understanding of the GPIB service request structure, I decided to try having the instrument generate an SRQ whenever its output queue was filled following the execution of a query. I wanted to try this approach after initially implementing loops with finite timeouts while continually reading the MAV bit in the status byte & waiting for it to be set high before attempting to retrieve the instrument's expected reply. Unfortunately, I would encounter errors every once in a while. My ultimate goal is to have a significantly more robust instrument driver than the currently used one that is prone to errors.
Am I missing something w.r.t. my understanding of the GPIB service request structure?
11-04-2009 07:25 PM
11-05-2009 10:48 AM
I appreciate your suggestion that my attempt to have the instrument set the SRQ bit for all queries might be overdoing it a bit. Unfortunately, based on my experience w/product FW and instrument automation, I'm just not very comfortable with assuming that since a command was sent to an instrument/device-under-test that it was actually implemented correctly.
Is there an industry-accepted method for verifying such actions without querying the instrument for the recently-issued "set" command? I'm open to any suggestions.
The fact that I'm using the err? query in my example is due to the fact that this instrument is available in a 16 channel model, by which there are 16 slots in the rear that can be populated with independent laser diode driver (LDD), thermoelectric cooler (TEC), or a combination of the two (LDD/TEC). On top of that, if any one of these devices is in the ON state when the *RST command is sent to the device, then an error is returned. I am checking this error # against what I know is expected for this case, and, if it matches, then it is ignored, as there are very likely going to be instances where something will be left ON from the previous test/user. Finally, in the rare case where all 16 channels are populated by LDD/TEC combination modules, then a string of 32 cases of the same error # separated by commas will be returned to the err? query. This takes almost 10 seconds, based on experimental results, which is why I am hoping to use the instrument's service request as a way to know when it is finished replying to a query.
Although my explanation above may still be resolved via another method, I am still questioning why the SRQ never seems to work. For the record, the computer interfacing manual for this line of instruments clearly states the following:
Note that bit 0 of the Standard Event Status Register contains the status of the Operation Complete flag (see *OPC). Enabling this bit via the *ESE command allows the user to update bits of the Status Byte Register. Then, if the Service Request Enable Register (*SRE) mask has bit 5 set, and the user issues an *OPC command, a service request (SRQ) will be issued upon completion of the currently processed commands. This may be used to initiate service request routines which depend on the completion of all previous commands.
Thanks, in advance, for any and all suggestions.
11-05-2009 11:44 AM
11-05-2009 12:31 PM
11-05-2009 12:49 PM
11-05-2009 02:38 PM
Yes. In fact, the driver as it was written before I modified it to try the viWaitOnEvent call utilized Do..Loops with a finite timeout while waiting for the MAV bit in the status byteto be set high. This seemed to work very well (status byte routinely returned a value of 48, which is MAV TRUE & Event status summary) with the exception of errors being encountered every once in a while for which I have not been successfuly in identifying why.
11-05-2009 03:09 PM