WIP/RFQ: Option to average ADC samples #3190
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I have a current sensor that gave very noisy reading when used with an airplane ESC. After some testing, I found that the current drawn by the ESC is very irregular, i.e., every 125us it draws a lot of current when the FETs are switching (8kHz switching frequency). This is reflected in the current sensor output.
The battery task currently updates at 50Hz, so it can randomly sample the current sensor output at a peak or valley, which leads to the fluctuating readings.
I see 2 possible ways to fix this:
Add a hardware low-pass filter to the current sensor output. Which isn't ideal, as it requires hardware changes
Average ADC samples over a longer time interval. This is implemented here.
On a typical F4 target with an APB2 clock of 84MHz, the ADC is running at 10.5MHz and a sample is obtained every 503 clock cycles (488 + 15). So for a single channel, the actual sampling rate is 20.9kHz, for 2 channels it is 10.4kHz and for 3 it is 7kHz.
With the previous implementation, we just use the last obtained ADC sample. So if we have 2 channels and e.g. update the battery status at 50Hz, there are over 200 samples obtained between each update that we don't use.
This PR adds the option to use a longer circular buffer that is filled by the DMA and averaged when the ADC is being read.
Other than using a bit more memory and averaging the samples when the ADC output is read, this doesn't add much additional processing (the DMA controller does most of the work "for free").
For the current sensor I have, this completely solves the problem when a 20 sample average is used. I tested this on the BrainFPV RADIX FC, which currently isn't a part of iNAV but it probably makes sense to use this on other F4 and F7 targets as well.