parent
74e016434d
commit
91bc53a27a
@ -0,0 +1,194 @@ |
||||
# Frequency / Pulse measurement |
||||
|
||||
- Frequency measurement |
||||
- Direct method (counting pulses in a time period) |
||||
- Indirect method (measuring a single pulse) |
||||
- PWM measurement - Indirect method also reports duty cycle |
||||
- Single pulse measurement |
||||
- Free-running pulse counter |
||||
|
||||
### Direct vs Indirect method |
||||
|
||||
The direct method works well for a wide range of frequencies, from Hz to tens of MHz. For |
||||
very high frequencies, a prescaller can be enabled. This method has a best-case |
||||
resolution of 1 Hz, which could be increased by extending the measurement time, which |
||||
already needs to be long, usually 1 second or more for low frequencies. |
||||
|
||||
The indirect method has a sub-Hz resolution and is much faster than the direct method for |
||||
low frequencies. It can be used for signals up to tens of kHz, while the direct method |
||||
can handle 20 MHz or more without issues. |
||||
|
||||
*NOTE:* The accuracy of all measurements is dependent on the system clock speed. |
||||
To measure the system clock using an external counter, you can output it on a pin using |
||||
the MCO function configured in `SYSTEM.INI`. |
||||
|
||||
### Burst vs Continuous |
||||
|
||||
Both the direct and indirect methods can operate in a free-running or burst mode. |
||||
|
||||
- Burst mode performs one or several measurements (with averaging if using the indirect method). |
||||
- Free-running (continuous) mode performs periodic measurements without averaging. |
||||
The advantage is that the last measurement is always immediately available for read-out, without having to wait for the emasurement. |
||||
|
||||
## Commands |
||||
|
||||
### STOP (0) |
||||
|
||||
Stops all ongoing measurements. |
||||
|
||||
### INDIRECT_CONT_START (1) |
||||
|
||||
Start a free-running frequency / duty cycle measuring using the indirect method. |
||||
|
||||
### INDIRECT_BURST_START (2) |
||||
|
||||
Start a burst of indirect measurements. |
||||
Waits for the next rising edge before starting the measurements. |
||||
|
||||
*Request:* |
||||
- u16 - number of pulses to average |
||||
|
||||
*Response:* |
||||
- u16 - core speed in MHz |
||||
- u16 - number of pulses |
||||
- u64 - sum of all periods (in core ticks) |
||||
- u16 - sum of all on-times (positive interval of the pulse) |
||||
|
||||
GEX avoids using float here to reduce code size and avoid floating |
||||
point errors. To get the period, use `period_sec = periods / (mhz * 10e6 * count)` |
||||
|
||||
Frequency is `freq = 1 / period`. |
||||
|
||||
The average duty cycle is `duty = ontimes / periods` |
||||
|
||||
### DIRECT_CONT_START (3) |
||||
|
||||
Start repeated measurement using the direct method. |
||||
|
||||
*Request:* |
||||
- u16 - measurement time (ms) |
||||
- 0 = no change |
||||
- default 1000, configurable in the unit settings |
||||
- u8 - prescaller (1,2,4,8) |
||||
- 0 = no change |
||||
- default 1, configurable in the unit settings |
||||
|
||||
### DIRECT_BURST_START (4) |
||||
|
||||
Start a single direct measurement (pulse counting) over |
||||
a given time period. Longer periods can be used for higher precision |
||||
using averaging. |
||||
|
||||
*Request:* |
||||
- u16 - measurement time (ms), often 1000 (=1s) |
||||
- u8 - prescaller (1,2,4,8) |
||||
- 0 = no change |
||||
- default 1, configurable in the unit settings |
||||
|
||||
*Response:* |
||||
- u8 - prescaller (1,2,4,8) |
||||
- u16 - measurement time (ms) |
||||
- u32 - pulse count |
||||
|
||||
Calculate the frequency by `freq = (1000 * count * presc) / time_ms`. |
||||
|
||||
### FREECOUNT_START (5) |
||||
|
||||
Clear and start the free-running pulse counter. |
||||
|
||||
*Request:* |
||||
- u8 - prescaller (1,2,4,8) |
||||
- 0 = no change |
||||
- default 1, configurable in the unit settings |
||||
|
||||
### MEASURE_SINGLE_PULSE (6) |
||||
|
||||
Measure a single pulse on the input. Waits for a rising edge. |
||||
|
||||
*NOTE:* The result may be inaccurate if the input is High when starting the measurement. |
||||
|
||||
*Response:* |
||||
- u16 - core speed in MHz |
||||
- u32 - pulse length (core ticks) |
||||
|
||||
### FREECOUNT_CLEAR (7) |
||||
|
||||
Clear the free-running counter while retrieving the current value. |
||||
Normally no pulses should be missed, but please be aware that this |
||||
operation is not atomic and glitches can occur at high frequencies. |
||||
|
||||
*Response:* |
||||
- u32 - last counter value |
||||
|
||||
### INDIRECT_CONT_READ (10) |
||||
|
||||
Read the latest result from the continuous indirect method measurement |
||||
(measurement of individual pulses). |
||||
|
||||
*Response:* |
||||
- u16 - core speed in MHz |
||||
- u32 - period (core ticks) |
||||
- u32 - on-time (positive interval of the pulse) |
||||
|
||||
Duty cycle is `duty = ontime / period`. |
||||
Period `period_sec = period / (mhz * 10e6)`. |
||||
Frequency `freq = 1 / period_sec`. |
||||
|
||||
### DIRECT_CONT_READ (11) |
||||
|
||||
Read the latest result from the continuous direct method measurement (pulse counting). |
||||
|
||||
*Response:* |
||||
- u8 - prescaller (1,2,4,8) |
||||
- u16 - measurement time (ms) |
||||
- u32 - pulse count |
||||
|
||||
Frequency is `freq = (1000 * presc * count) / time_ms`. |
||||
|
||||
### FREECOUNT_READ (12) |
||||
|
||||
Read the current value of the free-running pulse counter. |
||||
|
||||
*Response:* |
||||
- u32 - counter value |
||||
|
||||
### SET_POLARITY (20) |
||||
|
||||
Set the measured pulse polarity. |
||||
|
||||
*NOTE:* This is normally configured in the unit settings. |
||||
Changes done through this method are temporary, not persisted to flash. The same |
||||
applies to the other SET_* commands. |
||||
|
||||
*Request:* |
||||
- u8 - active level (0,1) |
||||
|
||||
### SET_DIR_PRESC (21) |
||||
|
||||
Set prescaller for the direct mode measurement. |
||||
|
||||
*NOTE:* This does not take effect until the direct measurement is restarted. (TODO: fix?) |
||||
|
||||
*Request:* |
||||
- u8 - prescaller (1,2,4,8) |
||||
|
||||
### SET_INPUT_FILTER (22) |
||||
|
||||
Set input filtering (a hardware feature designed to ignore short glitches) |
||||
|
||||
*Request:* |
||||
- u8 - digital filtering factor (0-15, 0=off) |
||||
|
||||
### SET_DIR_MSEC (23) |
||||
|
||||
Set direct measurement period. |
||||
|
||||
*NOTE:* This does not take effect until the direct measurement is restarted. (TODO: fix?) |
||||
|
||||
*Request:* |
||||
- u16 - period in milliseconds |
||||
|
||||
### RESTORE_DEFAULTS (30) |
||||
|
||||
Stop any measurement and restore all the run-time configurable settings to their default |
||||
values (as configured in the unit settings). |
Loading…
Reference in new issue