Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

Creating a GPIB slave device with NI488.2

Hi all (and merry christmas).

I'm having some real trouble trying to create a GPIB slave application using the ni488.2 / ib*** api. I know the standard response is to buy NI-Device, but I'm using a PC/104 card. Can anyone shed any light on the problem?

I have two PC's - one "System Controller", just running NI-MAX for the moment. The other is a custom C app running the slave application. The slave app is monitoring the LACS/TACS and is reading/writing at the appropriate times.

When sending a command from the controller using MAX, LACS is triggered, but the subsequent ibrd fails on a timeout. Any ideas?

I'll copy a code snippet below. Thanks!

Mat.
Anite Telecoms Ltd.



-----------------------------------------------------
void CGPIB::Main()
{
InitializeCriticalSection(ThreadLock);

Bd = ibfind("GPIB0");
ibconfig(Bd, IbcCICPROT , 0);
ibrsc(Bd, 0); //turn off system controller functionality
ibpad(Bd, 3); //set primary address to 3
ibtmo(Bd, T10s); //10sec timeout

char *buffer;
for(;;)
{
//wait for opportunities to either talk or listen
ibwait(Bd, 0);

//listening time...
if ((!(ibsta & ATN)) && (ibsta & LACS))
{
System::Console::Write(S"LACS");

buffer = new char[80];
ibrd(Bd, buffer, 80);

if (ibsta & ERR)
{
System::Console::Write(S"iberr:");
System::Console::Write(System::Convert::ToString(iberr));
}
else if (ibcntl > 0)
{
buffer[ibcntl] = 0;
EnterCriticalSection(ThreadLock);
RxQ.push(buffer);
LeaveCriticalSection(ThreadLock);
}
}

//talking time...
if (!(ibsta & ATN) && (ibsta & TACS) && (!TxQ.empty()))
{
System::Console::Write(S"TACS");
EnterCriticalSection(ThreadLock);
buffer = TxQ.front();
TxQ.pop();
LeaveCriticalSection(ThreadLock);

ibwrt(Bd, buffer, strlen(buffer));
if (ibsta & CMPL)
ibrsv(Bd, 0x0);

delete buffer;
}

//see if it's time to quit
EnterCriticalSection(ThreadLock);
if (QuitNow)
break;
LeaveCriticalSection(ThreadLock);

//surrender timeslice
Sleep(0);
}
LeaveCriticalSection(ThreadLock);
DeleteCriticalSection(ThreadLock);
}
0 Kudos
Message 1 of 6
(5,160 Views)
I recommend changing your code to do asynchronous I/O. This way if you start a read and it turns out that you need to cancel the read you can do it (if you use synchronous calls, you cannot cancel the I/O if you shouldn't have started it). You need this since the NI-488.2 API tells you the current state, but due to timing conditions, the current state may not be "correct" in 1 more second. For example:

(controller) ibwrt "*IDN?"
(device) you will become a listener and will start a read that completes with the correct data
(device) you will still be a listener since that is the correct addressing on the bus, therefore you will start a read again.
(controller) ibrd 100
(device) since you are still doing a read, you cannot respond to the ibrd request.

I used to have some example source code, but I can't seem to find it right now. However, the basic algorithm is to know what you need to wait on:

Default: LACS, DCAS, DTAS
Listening: CMPL, TACS, DCAS, DTAS
Talking: CMPL, LACS, DCAS, DTAS

Then you do the following:
currentwait = default;
loop forever
ibwait (currentwait);
if (DCAS) -> Handle clear, currentwait = default
if (DTAS) -> Handle trigger, currentwait = default
if (LACS) -> if ibwrta in progress stop it, then ibrda, currentwait = listening
if (TACS) -> if ibrda in progress stop it, if data to send, ibwrta, currentwait = talking
if (CMPL) -> handle I/O completion (queue data into queue, read next portion or write next portion if necessary)

Some things to node that if you are listening (ibrda in progress), and it stops due to DTAS or ibstop (due to TACS), you should have received data that you need to queue up.

By the way, if you want to use NI-Device with a PC/104, contact NI Technical Support as they may be able to help.
0 Kudos
Message 2 of 6
(5,157 Views)
Many thanks for the suggestion.

I have taken your advice and modified the code to suit ibrda and ibwta. Unfortunately, I still have this ongoing problem...

Running this new code looks as follows:

slave> App starts with CMPL flagged.
controller> writes data
slave> LACS is flagged and ibrda started.
slave> CMPL clears.
controller> times out with EABO
slave> never signals CMPL

Unfortunately, this new code probably adds more complexity to the existing problem. Surely the existing code would unreliably work in some fashion?

I contacted my NI rep last week regarding NI-Device for PC/104. Hopefully I'll get a positive answer next year and I'll switch to that. Alas, in the mean time, I'm stuck with NI488 calls.

Mat.
0 Kudos
Message 3 of 6
(5,145 Views)
Hello,

I believe I fielded an escalation from your NI Contact regarding the question of NI-Device on the PC/104. They should be getting something to you on that if they haven't already. If not, let me know your contact's name and I'll get in touch with them directly.

Scott B.
GPIB
National Instruments
0 Kudos
Message 4 of 6
(5,114 Views)
Could I be contacted about NI-Device for PC/104 GPIB too?
Thanks!
- Ian
0 Kudos
Message 5 of 6
(5,055 Views)
Ian,

Please contact your sales representative about this. PC/104 is technically not supported by NI-Device, but we can work around that. If you would like to speak to someone on the phone, you can call sales here: http://sine.ni.com/apps/we/nicc.call_me?p_action=country&p_lang_id=US

If you have trouble getting information about the PC/104, let me know by posting here.

Scott B.
GPIB Group
National Instruments
0 Kudos
Message 6 of 6
(5,027 Views)