From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Measurement Studio for VC++

cancel
Showing results for 
Search instead for 
Did you mean: 

Autodetect instruments

I want to write codes to automatically detect gpib instruments. Since I do not yet have the gpib card and instruments on my system (working offline), I cannot verify my codes. Just on ideas, was thinking about looping thru address 1 to 30, sending each address a write(*IDN?) and read back the idn string, taking care of exception along the way. Somehow, I feel there must be a better way to do this with the CW++ 4882 classes. Can you highlight some of the better functions to use? I suspect they are in the CNi4882Board class?

I find some of the function names intuitive but the corresponding help text lacks that little more details that I need.

Thanks
HuiKM
0 Kudos
Message 1 of 7
(3,579 Views)
Yes, there is a function for that, CNi4882Board::FindListeners. You pass in a CNi4882AddressList of the addresses that you want to search. Then you can you the GetResult method of each address to check if it was listening (which means a device is present and operating).

Here is an example that checks addresses 4 and 7 for listeners. This example is straight out of the help for the FindListeners function.

CNi4882Board myBoard("gpib0");
CNi4882AddressList deviceList;
deviceList.Add(4);
deviceList.Add(7);
myBoard.FindListeners(deviceList);
if (deviceList[0].GetResult()) {
// Device at address 4 is listening...
}
if (deviceList[1].GetResult()) {
// Device at address 7 is listening...
}

B
est Regards,

Chris Matthews
National Instruments
Message 2 of 7
(3,579 Views)
Hi Chris,

on that, some instruments require an EOS for their gpib commands. Does it matter with FindListeners(), meaning do I have to set CNi4882::SetEOSMode() as true, then false to detect both category of instruments? I am trying to something to the same effect as NI Explorer scan instruments, then process further to load instrument drivers that are supported.

Thanks
HuiKM
0 Kudos
Message 3 of 7
(3,579 Views)
Chris,

I have errors running the sample codes example. I traced the calls in NIspy scan instrument and came up with this which seems to work.

NI::CNi4882AddressList address_list;
// Create Address range 1 to 30
for(int i=0; i<30; i++)
{
address_list.Add(i+1);
}
NI::CNi4882Board gpib_board("GPIB0");
try
{
gpib_board.Reset();
gpib_board.RequestSystemControl();
gpib_board.InterfaceClear();
gpib_board.SetRemoteEnableLine();
gpib_board.SetConfigurationOption(CNi4882Board::ConfigureOption::cTiming, 1);
int dummy;
gpib_board.GetConfigurationOption(CNi4882Board::ConfigureOption::cPAD, dummy);
gpib_board.GetConfigurationOption(CNi4882Board::ConfigureOption::cSAD, dummy);
gpib_board.FindListeners(address_list);
}
catch (CNi4882Exception* e)
{
e->ReportError();
e->Delete();
return; // quit here
}
int index;
for(i=0; i<30; i++)
{
TRACE("address_list[%i].GetResult()=%i\n", i, address_list[i].GetResult());

if (address_list[i].GetResult())
{
// Listener found,
index = i +1; // index of address_list offset forward equals gpib Address
TRACE("Listener found at address=%i", index);



}

}

Well, the problem is with >>> if(address_list[i].GetResult()) which returns true for every single value of i. The returned values are:

address_list[0].GetResult()=22
address_list[1].GetResult()=-12851
address_list[2].GetResult()=-12851
address_list[3].GetResult()=-12851
address_list[4].GetResult()=-12851
address_list[5].GetResult()=-12851
address_list[6].GetResult()=-12851
address_list[7].GetResult()=-12851
address_list[8].GetResult()=-12851
address_list[9].GetResult()=-12851
address_list[10].GetResult()=-12851
address_list[11].GetResult()=-12851
address_list[12].GetResult()=-12851
address_list[13].GetResult()=-12851
address_list[14].GetResult()=-12851
address_list[15].GetResult()=-12851
address_list[16].GetResult()=-12851
address_list[17].GetResult()=-12851
address_list[18].GetResult()=-12851
address_list[19].GetResult()=-12851
address_list[20].GetResult()=-12851
address_list[21].GetResult()=-12851
address_list[22].GetResult()=-12851
address_list[23].GetResult()=-12851
address_list[24].GetResult()=-12851
address_list[25].GetResult()=-12851
address_list[26].GetResult()=-12851
address_list[27].GetResult()=-12851
address_list[28].GetResult()=-12851
address_list[29].GetResult()=-12851

The only valid result is >>>address_list[0].GetResult()=22

It seems to me using the if check is questionable. Instead, if(address_list[i].GetResult()>0) might probably do the trick but the order have to be ignored.
I hope you can verify this or am I doing something wrong here?

Thanks...
HuiKM
0 Kudos
Message 4 of 7
(3,579 Views)
Let me address your questions. First, you asked about EOS settings for the FindListeners command. The answer to this is no, you don't need to set this for these commands. FindListeners is a GPIB-bus level command and doesn't send command strings to the instrument.

Second, you showed some changes that you had to make to get FindListeners to work for you. Yes, the commands you added are used to put the GPIB bus in the proper state to accept the FindListeners command (Setting up the GPIB bus). I neglected to put this info in my first response.

Third, it turns out that the example of FindListeners in the help is incorrect. I reported this to our developers and they are going to fix the help. Sorry about that mistake. The correct u
se of FindListeners would be:

NI::CNi4882AddressList address_list;
// Create Address range 1 to 30
for(int i=0; i<30; i++)
{
address_list.Add(i+1);
}
NI::CNi4882Board gpib_board("GPIB0");
try
{
gpib_board.Reset();
gpib_board.RequestSystemControl();
gpib_board.InterfaceClear();
gpib_board.SetRemoteEnableLine();
gpib_board.SetConfigurationOption(CNi4882Board::ConfigureOption::cTiming, 1);
int dummy;
gpib_board.GetConfigurationOption(CNi4882Board::ConfigureOption::cPAD, dummy);
gpib_board.GetConfigurationOption(CNi4882Board::ConfigureOption::cSAD, dummy);
gpib_board.FindListeners(address_list);
}
catch (CNi4882Exception* e)
{
e->ReportError();
e->Delete();
return; // quit here
}
int i = 0;
while(address_list[i].GetResult()>0)
{
// Listener found at address: address_list[i].GetResult()
// Insert code here to talk to device

i++;
}


Let me know if you have questions.

Chris
0 Kudos
Message 5 of 7
(3,579 Views)
The EOS would be used when I loop through the valid listeners' address with *IDN? command. Thank you for your response on that. Using

while(address_list[i].GetResult()>0)
{
....
}

I assumed all the valid listeners will occupy the forefront addresslist indexes. A -ve value from address_list[i].GetResult() means the rest of subsequent elements are all -ve values, that there are no more valid listeners. The While loop is alot more efficient and eliminate redundancy.

Am very impressed with the speed of your reply and the help this forum provides. Thank you.

HuiKM
STAr-Quest Technologies
0 Kudos
Message 6 of 7
(3,579 Views)
Yes, you would use the EOS when sending messages to the instruments such as "*IDN?".

And yes, the returned address list will have valid addresses at the front that are returned by GetResult and negative values at the end of the list. For example, searching an address list of

1
2
3
4
5

may yield a list with

2
3
-VAL
-VAL
-VAL

If there are only instruments at adresses 2 and 3.

Chris
0 Kudos
Message 7 of 7
(3,579 Views)