Skip to content

Latest commit

 

History

History
81 lines (66 loc) · 4.3 KB

README.md

File metadata and controls

81 lines (66 loc) · 4.3 KB

Measure duration between input pin changes with PIO

Measure duration between input pin changes. Exact frequency and duty cycle measurements for low range frequncies (< 5 kHz).

The basic idea is to count instruction between changes of the input pin. Because each instruction has a well defined duration the frequency can be calculated.

PIO program:

  • wait in a loop for input high
  • in the loop decrement a counter
  • each loop takes 3 cylces
  • when the input is high publish the counter in the rx fifo
  • do the same for input low.
  • fire an interrupt

The statemachine runs at 125Mhz. That means each cylce takes 8 ns. The input change is detected with a granularity of 3 instructions * 8 ns / instruction = 24ns. Given this the accuracy is better than 0.003% for frequencies up to 1000 Hz. There are some more instructions between the counting loops, which also wiggle the result. But these are a fixed time and only occour once for each signal change.

The frequency is limit to about 3 kHz, because of the slow interrupt handler to empty the rx fifo. This might be improved , if the values are written in a dma buffer, so that interrupts rate could be lowered to read the buffer

Example output for a 50 Hz signal with 50% duty cylce:

Low [#] : Counter for input low
High[#] : Counter for input high
H+L [#] : Sum of low and high counter

Example output for 50 Hz signal with 50% duty:

 Time   Loops      Low [#]   High [#]  H+L[#]  Period [ms]    Frequency [Hz]  Duty [%]
--------------------------------------------------------------------------------------
 507      26       416664    416664    833328     19.9999      50.0003         50     
 506      51       416663    416664    833327     19.9998      50.0004         49.9999 
 517      77       416664    416664    833328     19.9999      50.0003         50     
 517      103      416663    416664    833327     19.9998      50.0004         49.9999 
 517      129      416664    416663    833327     19.9998      50.0004         50.0001 

Example output for 1000 Hz signal with 25% duty:

Time   Loops      Low [#]   High [#]  H+L[#]  Period [ms]    Frequency [Hz]  Duty [%]
--------------------------------------------------------------------------------------
511      496      31249     10417     41666      0.999984     1000.02         25.0012 
509      1002     31249     10417     41666      0.999984     1000.02         25.0012 
501      1500     31249     10417     41666      0.999984     1000.02         25.0012 
510      2006     31249     10417     41666      0.999984     1000.02         25.0012 
511      2513     31249     10417     41666      0.999984     1000.02         25.0012 
506      3021     31250     10416     41666      0.999984     1000.02         24.9988 

Example output for 93 Hz signal with 6.25 duty:

Time   Loops      Low [#]   High [#]  H+L[#]  Period [ms]    Frequency [Hz]  Duty [%]
--------------------------------------------------------------------------------------
502      46       420030    27999     448029     10.7527      92.9999         6.24937 
502      93       420030    28000     448030     10.7527      92.9997         6.24958 
501      140      420029    28000     448029     10.7527      92.9999         6.2496 
501      187      420029    28000     448029     10.7527      92.9999         6.2496 
502      233      420030    27999     448029     10.7527      92.9999         6.24937 

Example output for 2000 Hz signal with 50 duty:

 Time   Loops      Low [#]   High [#]  H+L[#]  Period [ms]    Frequency [Hz]  Duty [%]
--------------------------------------------------------------------------------------
 511      978      10416     10417     20833      0.499992     2000.03         50.0024 
 501      1963     10416     10417     20833      0.499992     2000.03         50.0024 
 509      2966     10416     10417     20833      0.499992     2000.03         50.0024 
 501      3951     10416     10417     20833      0.499992     2000.03         50.0024 
 501      4941     10416     10417     20833      0.499992     2000.03         50.0024 
 502      5920     10417     10416     20833      0.499992     2000.03         49.9976 
 506      6918     10416     10417     20833      0.499992     2000.03         50.0024