I am having some trouble doing PWM measurement using a PXI6602 board.
I am using traditional nidaq with C++ and have configured a counter with: - continuous semi period measurement application - GATE POLARITY set to High-to-Low, - DMA - 20MHz timebase (can't use 100KHz for measurement accuracy reasons) - Double-buffered
What I want to do -----------------
The input signal can have a frequency between 10hz and 20kHz and a duty-cycle of 2% to 98% (meaning the shortest valid pulse is 1 us).
I am programming a measurement/control system that need to 'sample' the most recent PWM value (i.e, as a pair of high time and low time values) and send this pair into the system at a user-configured sample interval of 10Hz-1000Hz.
How I do it -----------
I use a sample thread that wakes up 10 to 1000 times per second and then uses GPCTR_Watch ( WRITE MARK ) to access the current write mark offset in the buffer. Using this offset I compute a new offset 2 (or 3) steps before the write mark offset since that is the place for the most recently written value. Finally I use GPCTR_Read_Buffer(.., 2 values, BUFFER_START, new offset ) to access the pair.
(The circular buffer may overflow when the input signal frequency is high relative the sample rate but I dont care about that since I am only interested in the most recent value.)
Since the Gate polarity is set to high-to-low I expect to get alternating high, low, high, low,... values in the buffer. The buffer size is evenly divisible by two ensuring the behavior when wrap-around occurs.
The offset I compute and use with GPCTR_Read_Buffer is always an even number 0, 2, 4, and so on.
This means that I always expect high values on event offsets and low values on uneven offsets.
The problem -----------
The setup works fine under most conditions but is not robust with respect to signal noise. More specifically if during a measurement the signal wire is disconnected and reconnected (a common case in this automotive application when the car's ignition is turned on-off) I would of course expect some 'bogus' high-low pairs in the buffer (which is ok and I can deal with) but what happens is that the card can change its data stream protocol and start writing high values on uneven offsets and low values on even offsets. This is really annoying because I have no way of detecting and resynchronizing in software from such a mode change, and the result of such a switch is catastrophic since the measured duty cycle becomes quite the opposite of the real duty cycle.
I would expect that in the presence of disconnect/reconnect event two bad things might happen: - very short spikes on the gate causing the counter to latch a zero count - or no signal change on the gate causing the counter to finally overflow (if the signal is disconnceted long enough)
In either case I assume it would store a value into the buffer to maintain the alternating principle.
I assume the problem in this case is short spikes ocurring on the gate and finally my question is if you can advice me how to handle the situation? - As I am only guessing as to what is going on (that short spikes are the problem) confirmation of under which conditions the card might switch the alternating writing mode would help in seeing possible solutions. - Is this the intended operation of the device or is it a bug? - Can read some register to determine if it writes high values on even or odd offsets? - Does it set a mode state change flag somewhere that I can access and react to? - Would activating the cards filtering function help (to suppress pulses shorter than 1 us)? - I have tried using two counters, one measuering the period time and the other measuring the pulse width, but I havent found a robust solution there either. The problem in that case is to keep a synchronized pair of period value and high value but that is also extremely difficult under these conditions. Therefore the semi period measurement mode seems most promising if it were not for the above described problem of spurious instream change of write protocol.
With semi-period measurement, the GATE POLARITY setting only really determines which will be the first edge measured. After this first edge, each edge (rising or falling) we trigger a measurement. There are a couple issues with your setup. The noise is definitely going to be a problem if you are connecting and disconnecting the signal wire during a measurement. You should turn on the 1us filter to deal with this issue. The other issue that I haven't thought of a way to get around for you is the switching of the high/low measurement. The glitching of the signal being connected in addition to the floating value of the PFI line may cause a false measurement to occur. My first inclination of an idea would be for you to use two pulse width measurements in the same signal, but this could potentially have some other problems if the last high pulse and last low pulse occurred at different times (like one occurred before you disconnected the signal and the other occurred after). Or it may just be that turning on the filters solves your problem. Hopefully some of this information has proven useful to you. Let me know if you have any other questions.