01-16-2023 01:12 PM
Hello,
Using the NI API, I have output a PWM signal which I then measure with another counter on the same card. Works fine. Without too much effort, I can introduce a disturbance such as disconnecting and then reconnecting the running PWM signal. This disturbance causes the PWM measurement to report an inverted duty cycle. An external oscilloscope will show a 20% duty cycle, the NI API will return and 80% duty cycle. I can then change the duty cycle on the fly to 70%. The oscilloscope will show a 70% duty cycle, but the NI API will return and 30% duty cycle. Any way to stop this or recognize that it is happening in the software?
Thanks for any info.
01-17-2023 06:29 AM
What DAQ device are you using? And please post the code (back-saved to ~LV 2018 or earlier, if necessary) for your measurement task.
Long long ago, E-series devices with old legacy DAQ drivers didn't support the ability to specify the polarity of the first edge for a semi-period measurement. So attempts to measure duty cycles could be ambiguous. I don't know whether it was a hardware or driver limitation, but any devices I know of designed in the last couple decades and using DAQmx are configurable and unambiguous.
-Kevin P
01-17-2023 10:41 AM
I am using a PCIe6612 on a Windows 10 OS with NIDAQmx
Request Code Attached.
ScanNI.cpp is a thread that is ticked every 10ms and it process the NI counters via vProcessCounter
NIControlService maps the counters (boMapPwm and boMapPwmMeasurement) and sets up the ScanNI thread.
PCIe6612.h contains class with member functions
01-18-2023 04:52 AM
Mea culpa, I wrongly assumed LabVIEW. That's what I know, not C++ or its API for DAQmx. I can only follow the broad strokes, not so much any of the details. So with that caveat up front, here goes...
1. You have a bunch of commented-out code labeled as "Finite Data Working Version". Is that "working" as in "work in progress", experimental, or "working" as in verified good?
2. I notice that you use Pulse measurement mode in your Continuous code while using Semiperiod measurement mode in your Finite code. Reasons?
3. Most of my substantive counter work pre-dates X-series boards and any notion of "pulse" measurement mode. I haven't need to experiment with it this past decade or so that it's been around, so I can't speak from experience about any caveats or quirks (if any).
I *did* use semiperiod a good bit though, hence my comments in a previous msg about very old hardware that gave ambiguous data b/c it didn't support polarity selection, i.e., there was no way to know whether the first value in the buffer would be a low time or a high time.
I checked in LabVIEW and both modes allow you to define this explicitly. I can't say for sure what the default behavior would be when you don't, but I wouldn't rule out the possibility that DAQmx might react to the first edge *whatever it is*.
In the case of semiperiod measurement, DAQmx returns a buffer with alternating high and low times. Or possibly low and high times, depending on where it starts. In the case of Pulse Frequency measurement, I cannot say for sure whether it *always* considers duty cycle to be high/(high+low) or whether it might consider it to be 1st/(1st+2nd) interval.
In any event, try being explicit about the "starting edge" configuration. In LabVIEW, the property node to set it looks like this:
4. It appears to me that you want your Continuous task to buffer measurements, overwrite old ones when the buffer fills, and return only the single most recently captured pulse measurement each time you want to read from it. That can be a valid approach when you don't ever want to wait for new data to arrive, and don't mind losing some of the data and possibly retrieving the same value many times.
Just be aware that there are also approaches that let you prevent waiting without a serious risk of losing or repeating data.
5. I'd encourage you to do more experiments, especially after incorporating the ability to explicitly define the "starting edge" polarity. Report back with findings.
-Kevin P
01-27-2023 09:43 AM - edited 01-27-2023 09:54 AM
Thanks for the help and information. Answering questions and reporting results below based on your numbering.
DAQmxSetCIPulseFreqStartEdge(hTask, sName, DAQmx_Val_Rising)
DAQmxSetChanAttribute(hTask, sName, DAQmx_CI_Pulse_Freq_Start_Edge, DAQmx_Val_Rising)
01-27-2023 11:45 AM
After more consideration, I'm pretty stuck.
Semiperiod measurement mode would deliver alternating high and low times in a single array. Calculation of freq and duty cycle are up to the application code, and an off-by-one error when indexing into the array would result in an apparent PWM inversion.
But you're using Pulse Frequency measurement mode, putting DAQmx in charge of tracking the distinction between rising and falling edges, high and low times so it can determine freq and duty cycle. There's no way to accidentally misinterpret the data on the app side.
All I can think of is that there may be extremely fast digital transitions or "ringing" caused by the abrupt signal disconnect, faster than the device can properly latch. So perhaps somehow an extremely brief high time like 2 nanosec is missed and the next low time of, say, 80 nanosec is captured. But now the FIFO holds 2 adjacent low times that will be delivered up to the task buffer, causing DAQmx to become "off-by-one" for subsequent data and mixing up which times are high times and which are low. And thus, duty cycle inversion.
That's just a highly speculative thought trail without enough basis to consider it a theory. But try configuring your PWM measurement task to add digital filtering on the input PFI pin. Try setting it for something in a range like 100-500 nanosec. That should suppress transients that are too fast for the board. If the digital filter helps, maybe my speculation wasn't so far off after all.
-Kevin P
-Kevin P