I'm looking for a way to accurately measure duty cycles on the Edison.
In particular the signals are 1 - 6 kHz, I need about 1us timing accuracy.
I have done this in the past multiple times on MCU's using:
- using a low pas filter and then use the A/D converter
- using random sampling and taking the average of high and low samples
- poling the pin in a calibrated loop
- using a timer with capture register and read out the register in the associated interrupt handler. Ideally 2 capture registers would be used, one for rising and one for falling edges.
In my current application only the last method would work as I need to measure 8 successive DC's individually. To improve the resolution the sequence could be be repeated and the results averaged.
Do we have access to timers with capture/compare registers in the Edison or the MCU? Or any other way to get the time with < 1us jitter on rising/falling edges?
All ideas welcome.
Let us investigate if it's possible to access this timers or if there's an alternate method to get the time that you're expecting to achieve. Right now I can only think of fast memory mapped I/O, however, according to your description this is not an option. I still would suggest you to take a look at this link http://www.i-programmer.info/programming/hardware/8770-exploring-edison-fast-memory-mapped-io.html?s... http://www.i-programmer.info/programming/hardware/8770-exploring-edison-fast-memory-mapped-io.html?s.... They provide a whole section/chapter on this topic, so you might get some ideas from there.
In theory I could using polling using mmaped IO. In duty-cycle measurement time is relative (%). So polling a signal for a full period and dividing the high polls by the total would result in the correct DC as long as the sample time is constant. This is not the case of course when interrupt handler and other kernel tasks interrupt the user space polling.
Alternative is to tie an interrupt handler to the input pin, and get the time from a counter with a constant clock on each edge. MRAA allows this, but of course the 'interrupt handler' is not a real interrupt handler (as it runs in user space) so if will be substantially delayed (latency). Again for duty-cycle measurement a constant delay will not cause an error in the DC. But jitter (a varying delay) will.
That's where capture/compare timer registers come into play. The time is captured in hardware and stored, then an interrupt handler has time until the next edge to read out the capture register.
This is also why you would want a separate capture for rising and falling edges: the time between a rising and falling edge for signals with 10% or 90% DC can be very short causing the interrupt handler to miss an edge. When separate the handler has a full period to get the value, in my case 160us.
Timers with capture registers are common, if not standard on MCU's. So I'm expecting (hoping) the Edison MCU has something like this on board.
Otherwise, doing the interrupt handler on the MCU and getting timer from there might be an option, assuming jitter in rocket on the MCU will be less than in linux on the CPU.
Thank you for your patience. Regarding your question about the timers, the MCU API doesn't have access to timers and registers. However, as you said in your last post, it should be possible to use the MCU interrupt to get accurate DC, I would suggest you to explore this option.
I was thinking of another possibility: to use the SPI input with the clock at 1MHz. If the CPU is not stretching the clock it could be used to get equidistant 1M samples/sec, then process the bytes to calculate tje D.C.
We encourage you to give that a try and please keep up posted on that. If that doesn't work you can always test our suggestion and see if that's a better option.