07-08-2016 07:09 AM
I need my application to wait for an I/O line to go high for at least 3ms. Currently, I have a brute-force loop in the code that reads single samples from the I/O line and measures how long the line was high. It works most of the time, but will occasionally miss.
Is there a hardware / firmware / driver option for pattern matching on the PXIe-6535? Basically, all I need is an event to fire when the card detects that Port0/Line0 has been high for more than 3ms.
07-11-2016 09:26 AM
Hi CurtisHx,
The PXIe-6535 doesn’t support pattern matched triggering, so you’ll have to implement this is software. Can you post your code so far so we can take a look?
07-11-2016 02:49 PM
while a software solution offers more flexibility ...
a quick tryout migth be a simple RC delay on an input. Use a potentiometer to adjust to the trigger threshold after 3ms ..
that input would give you a change detection event.
However it won't work if you have more shorter pulses before.....
07-12-2016 08:47 AM
Here's the code. Basically, it samples the Port0/Line0 as fast as the code allows. I measured about 75us between samples. It waits the line to go high, and then starts the "totalHighTime" stopwatch. If the line stays high for longer than 3ms (the actual pulse width is 5ms), then it sets the "foundHighTimeLongEnough" flag to true, which will exit the loop. There is also a timeout that exits the loop when the total run time has exceded "msToWait".
public System.Threading.Tasks.Task WaitFor3msHighTime(int msToWait) { return System.Threading.Tasks.Task.Run(() => { const double msHighTimeToLookFor = 3.0; using (NationalInstruments.DAQmx.Task task = new NationalInstruments.DAQmx.Task()) { var chan = task.DIChannels.CreateChannel("PXI1Slot5/Port0/Line0, "", ChannelLineGrouping.OneChannelForAllLines); chan.LogicFamily = DILogicFamily.TwoPointFiveVolts; DigitalSingleChannelReader reader = new DigitalSingleChannelReader(task.Stream); bool foundHighTimeLongEnough = false; Stopwatch totalHighTime = new Stopwatch(); Stopwatch totalRunningTime = new Stopwatch(); totalRunningTime.Start(); do { bool currentSample = reader.ReadSingleSampleSingleLine(); if (currentSample && !totalHighTime.IsRunning) { totalHighTime.Start(); } if (!currentSample) { if (totalHighTime.IsRunning) { if (totalHighTime.Elapsed.TotalMilliseconds >= msHighTimeToLookFor) foundHighTimeLongEnough = true; else totalHighTime.Reset(); } } } while (!foundHighTimeLongEnough && totalRunningTime.Elapsed.TotalMilliseconds <= msToWait); } }
07-12-2016 09:42 AM
Also, here's a scope shot of the waveform that I'm trying to trigger on. There's a short pulse (less than 1ms) followed by a longer pulse that stays high at least 4ms. Typical length is 5.5ms-6.5ms. This pulse train happens once per second, confirmed by watching the scope. The time betwee pulses can vary a little (between 5ms and 30ms). I have 2 PXIe-6535s setup exactly the same, and they both ocassionally miss. I added some logging into the code and all of the line samples are low when a miss occurs. However, the scope says that line was high for at least 4ms. I have to be able to detect that high time 100%, or my test system won't work.
07-12-2016 03:36 PM - edited 07-12-2016 03:43 PM
another idea:
feed the signal to two inputs, and create two events for the rising and falling edge. (i don't know, maybe if you can register both events on the same channel... )
without polling an event state mc maybe should do the job. The idea is to use the timeout of 300ms after a rising edge event ....
I never really used registered events ... however I added a try 🙂
my the edges are pure random up to 500ms...
EDIT: uups, I did it in LabVIEW and had a 300ms timeout instead of 3ms in mind.... however, hope you got my idea 😄
07-18-2016 07:20 AM
That's not a bad idea on the events. At one point the code was using events to detect the rising edge, but I found a problem where the event would fire on the both edges (rising and falling), regardless of configuration. Hence the current code situation.
I don't think the hardware is at fault. The software does some readings in other places in the code 100% successfully. However, that code is a low-level data read. The system gets setup to read X number of samples and the drivers take care of the rest. This code does a brute force loop. The above code runs fast enough to to be able to see at least a few dozen samples while the line is high. Timing that loop in software puts each iteration at about 100-200us. When it fails, the entire sample collection is low, even though I know there were times that line was high because I watched it on the scope...
Ordinarily, I would assume the DUT is the problem, but I've had enough past problems with this DAQ card and NI software that I'm not sure where to go fishing. It's probably not the actual DAQ hardware, based on the success of other DAQ reading code... It's almost like the DAQ drivers are caching the readings and giving incorrect readings...hmmm....
07-19-2016 09:36 AM
I finally captured a false failure on the scope. It's looking like it's a problem with the DAQ card. BAH!