Hello!
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.
Thank you very much in advance,
Marcus Rimen