Digital I/O

cancel
Showing results for 
Search instead for 
Did you mean: 

How do I wait for a bit in C?

I'm writing an easy program in C for my Daqcard-AI-16E-4. I'm trying to control a set of sonars (Polaroid 6500) for a mobile robot.
 
So far, I haven't had problems following the examples included in the installation. But now, I'm having problems waiting for a bit to happen. The Polaroid 6500 is activated sending a bit from LOW to HIGH, then some pulses are emitted, and an ECHO is received, generating another bit to change from LOW to HIGH.
 
So, I have to wait for the ECHO bit to change it's state, so that I can determine the time between the emission of pulses and the ECHO bit.
 
I'm using this simple while structure:
 
while ((iState == 0) && (iStatus == 0)) {
   iStatus = DIG_In_Line(iDevice, iPort, iLine4, &iState);
   iRetVal = NIDAQYield(iYieldON);
   }
 
iRetVal = NIDAQErrorHandler(iStatus, "DIG_In_Line",
    iIgnoreWarning);
 
I'm not sure if it's working, the timer I'm implementing always send me 0. Any ideas?
 
BTW. I've looked for many ways to do a timer. I have found that maybe the best one for this case, is using the windows library WINMM.LIB , since I need precision in ms. Is something like this:
 
timeBeginPeriod(1); 
   
   QueryPerformanceFrequency(&freq);
   QueryPerformanceCounter(&t1); //before activating a sonar.
/////////////////////////// code ///////////////////
   QueryPerformanceCounter(&t2); // after supposedly receving the ECHO bit.
timeEndPeriod (1);
 
Any suggestions? Has any one before has made a timer for a similar event with NI DAQ cards in C++?
 
Thanks 🙂
 
 

Message Edited by cfgauss on 04-18-2006 06:05 PM

0 Kudos
Message 1 of 6
(3,838 Views)
Hello cfgauss,

Have you considered using a counter input task rather than a digital input task for this operation?  All digital I/O operations on the DAQCard-AI-16E-1 are software timed, meaning that you are basically taking a snapshot of the state of a digital line with each call to the DIG_In_Line function.  The rate at which you can take these snapshots is completely dependant on your operating system and how fast it is executing the code.  With a counter input task, you can perform a period measurement, which will compare the signals on a counter input line to a 20MHz reference clock onboard the device, resulting in a much higher accuracy measurement.  Take a look at the following tutorial about period measurements with counters:

Developer Zone Tutorial: Period Measurement with a Counter

There are also text-based example programs showing how to program counter input applications installed in the C:\Program Files\National Instruments\NI-DAQ\Examples\Visual C\Ctr folder.  Take a look at the program titled STCSinglePeriodMeasure.c.

I hope this helps.

Regards,
Travis G.
Applications Engineering
National Instruments
0 Kudos
Message 2 of 6
(3,811 Views)
Ah! Thank you!
0 Kudos
Message 3 of 6
(3,802 Views)
Sorry, I have a problem. I hope someone knows what I'm doing wrong.

I compiled the example STCsinglePeriodMeasure.C , it works. When I see the message "Apply your digital pulse train to the GATE of the counter now", I do it  and the counting goes fine. The counting starts when I apply the pulse so it doesn't matter in which moment I apply the pluse after I saw the message on screen, so I assume the structure do-while in the example does 2 things:
------------
do {
        iStatus = GPCTR_Watch(iDevice, ulGpctrNum, ND_ARMED,
         &ulArmed);
        iRetVal = NIDAQYield(iYieldON);
    } while ((ulArmed == ND_YES) && (iStatus == 0));
------------
First: The first pulse starts the counter.
Second: The next pulse stops the counter.

If I'm wrong please tell me.

I'm trying to set the first pulse at the same time with a signal that is emmited from a port in the card (with DIG_Out_Line), (iLine3 = 3), to do this , I'm trying it in the next code with the first while. To get the second pulse and finish counting I wait for an external signal that is entered by other port (DIG_In_Line), this is the second while. I have everything well connected to the needed pins. With "DIG_Out_Line(iDevice, iPort, iLine3, iStateOFF)" I generate the first pulse from low to high and is sensed with the pin GPCTR0_SOURCE, setting iLine3 to istateON makes the  pulse to go from high to low. To get the second pulse i wait for a high signal with "DIG_In_Line(iDevice, iPort, iLine4, &iState)", this signal also is connected to GPCTR0_SOURCE with the help of an OR gate (7432).

(Code attached)

I'm not sure if I'm making myself clear, sorry. I can post my entire code, it has just some more lines, and I can explain how I have connected my pins.
Any help would be appreciated, Thanks.

0 Kudos
Message 4 of 6
(3,776 Views)
Hello cfgauss,

The code with the do-while loop in the example program is monitoring the counter to check if it is armed.  When the counter is armed, within each iteration of the do-while loop, the NIDAQYield function is called in order to allow the program to process any system events.  When the counter gets two rising edges, it performs its period measurement and the counter proceeds to disarm, which causes the do-while loop to stop executing.

As for your application, if I understand you correctly it sounds like you are generating the first rising edge from your DAQ device using the DIG_Out_Line function, and you are getting your second rising edge from an external source.  You should have both these signals passing into the gate of your counter.  For a period measurement, the internal timebase is used as the source of the counter, set using the function call:

Status = GPCTR_Change_Parameter(iDevice, ulGpctrNum, ND_SOURCE,
     ND_INTERNAL_100_KHZ);

and the two signals used for the period measurement should be passed into the gate of counter, set with this function:

iStatus = GPCTR_Change_Parameter(iDevice, ulGpctrNum, ND_GATE,
     ND_DEFAULT_PFI_LINE);

The terminal for the gate can be set to any PFI line, but in this case is set ot the default PFI line for the counter gate, which is device specific and can be found in the E-Series Help Manual (PFI9 for your counter 0 on your device).  It sounds like from your post that you are connecting these signals to the source, rather than the gate, which could be your problem.

By the way, besides the example programs installed by the NI-DAQ driver, the best resource for programming with Traditional NI-DAQ in text based languages is the Traditional NI-DAQ (Legacy) C Function Reference Help, which you can find under Start > All Programs > National Instruments > NI-DAQ.  I hope this helps!

Regards,
Travis G.
0 Kudos
Message 5 of 6
(3,760 Views)
Thank you Travis.

I had a better idea and it worked, now my system is working!

I rather used the event count mode. Then I set the SOURCE for the internal 100 MHz counter. Now I just check with a Do-While for my exernal signal while the counter goes on. Maybe I lost a little precision with this way, I think it should be about 1 ms or less, because my readings are incredible accurate, thanks to the counter in the card... oh yes. I'm happy 🙂

Thanks again.
0 Kudos
Message 6 of 6
(3,754 Views)