Skip to content

ADCOptimization#8

Merged
void-spark merged 2 commits intovoid-spark:masterfrom
mooiweertje:ADCOptimization
Nov 16, 2025
Merged

ADCOptimization#8
void-spark merged 2 commits intovoid-spark:masterfrom
mooiweertje:ADCOptimization

Conversation

@mooiweertje
Copy link
Copy Markdown
Contributor

@mooiweertje mooiweertje commented Nov 11, 2025

Keeping the battery voltage in an array of 100 measurements is rather time and memory consuming. This improvement doesn't realy fix a problem but it does give the hardware more room to breath, for future enhancements. I'm working on current based battery level code which has a similar approach.

@mooiweertje
Copy link
Copy Markdown
Contributor Author

On pedelecforum I read that I could find some comments here but I don't see any.

@void-spark
Copy link
Copy Markdown
Owner

On pedelecforum I read that I could find some comments here but I don't see any.

I see this in the PR, it should be visible to you, I think? :)
They were inline, so might also see them in the changed files view :)
I don't normally use this :)

image

@mooiweertje
Copy link
Copy Markdown
Contributor Author

mooiweertje commented Nov 15, 2025

This is not for current but the existing voltage solution. I will do something similar for current in a later PR. If you like I offer the currentmeasument code now too. But it is in a trail state and maybe not generic yet,

The currentmeasurement implementation is here: https://github.com/mooiweertje/ion1/tree/AmpADC. It is in a beta test stage.

This does more or less the same as the array solution. There was an array with 100 values that are cummulated every iteration. Now there is a theoretical cummulation of 128 values where every iteration a real value is added and the average is substracted. The result is more or less the same. The 128 in stead of 100 is used to make it possible to divide using a shift 7 (>>7) which is much faster than a division. Nice to read you know shifting is a way of multiplying. This code is somewhere around a hundred times less power/resource hungry than the array one.
For me it is difficult to explain so maybe we can create an understandable comment together. Welcome to hardcore machine programming.

@void-spark
Copy link
Copy Markdown
Owner

This does more or less the same as the array solution. There was an array with 100 values that are cummulated every iteration. Now there is a theoretical cummulation of 128 values where every iteration a real value is added and the average is substracted. The result is more or less the same. The 128 in stead of 100 is used to make it possible to divide using a shift 7 (>>7) which is much faster than a division. Nice to read you know shifting is a way of multiplying. This code is somewhere around a hundred times less power hungry than the array one. For me it is difficult to explain so maybe we can create an understandable comment together.

I'm an actual programmer, I know bit shifting :) A good compiler may even optimize multiplications/divisions by bit-shifts :)
For this case the effect will be very minimal though :)
I think going through the array to calculate the average each time would be the most 'power hungry' part, although it's relative, esp32 is pretty fast, and I don't think you benchmarked the effect. I often prefer readability :)

I have a feeling of how/why this would work, numbers get added to the big number which makes it bigger, more bigger if the numbers are bigger, and subtracting the 'average', 128/th of the big number makes the big number shrink again, dividing it gives a smallish number as output. The most recent added number has the biggest effect on the big number.

But I'm not sure if the 'average' is actually guaranteed to be close to the average of the input numbers, or if it's just a number that with the chosen divider gets sort of in the same range as the output we want :)
Even if it works, it may need tuning to get it accurate, and for that it needs to be understood well :)
A link to a wikipedia page or other source with the algorithm used would help :)

I might write a small self contained test program to test it, see how it behaves with different inputs :)

@void-spark
Copy link
Copy Markdown
Owner

Google AI says it's a Exponential Moving Average (EMA) filter, so that's interesting :)

@mooiweertje
Copy link
Copy Markdown
Contributor Author

mooiweertje commented Nov 15, 2025

This does more or less the same as the array solution. There was an array with 100 values that are cummulated every iteration. Now there is a theoretical cummulation of 128 values where every iteration a real value is added and the average is substracted. The result is more or less the same. The 128 in stead of 100 is used to make it possible to divide using a shift 7 (>>7) which is much faster than a division. Nice to read you know shifting is a way of multiplying. This code is somewhere around a hundred times less power hungry than the array one. For me it is difficult to explain so maybe we can create an understandable comment together.

I'm an actual programmer, I know bit shifting :) A good compiler may even optimize multiplications/divisions by bit-shifts :) For this case the effect will be very minimal though :) I think going through the array to calculate the average each time would be the most 'power hungry' part, although it's relative, esp32 is pretty fast, and I don't think you benchmarked the effect. I often prefer readability :)

I have a feeling of how/why this would work, numbers get added to the big number which makes it bigger, more bigger if the numbers are bigger, and subtracting the 'average', 128/th of the big number makes the big number shrink again, dividing it gives a smallish number as output. The most recent added number has the biggest effect on the big number.

But I'm not sure if the 'average' is actually guaranteed to be close to the average of the input numbers, or if it's just a number that with the chosen divider gets sort of in the same range as the output we want :) Even if it works, it may need tuning to get it accurate, and for that it needs to be understood well :) A link to a wikipedia page or other source with the algorithm used would help :)

I might write a small self contained test program to test it, see how it behaves with different inputs :)

I'm afraid the mathematics are my own, so no reference to other inventors.

I'm a retired machine language coder that switched to Java at some point. I agree with all you say. Besides, I like the shifting because I think every programmer should be able to read that as you did. It will indeed have a negligible impact on the complete loop time, but it complements the purity of the complete code. Adding values to a single int instead of looping through an array does have a serious impact on memory and power, as you mentioned.

This little ESP32C3 is surprisingly powerful indeed.

@mooiweertje
Copy link
Copy Markdown
Contributor Author

mooiweertje commented Nov 15, 2025

Google AI says it's a Exponential Moving Average (EMA) filter, so that's interesting :)

That sound like what it is yes. The average is moving steered by the actual measured values. The higher the division the slower it steers. Similar to having a larger array.

@void-spark
Copy link
Copy Markdown
Owner

Ok, in that case I like the approach :)
And that means things can have 'standard' names, and there's whole books on the tuning :)
When I can motivate myself, I'll add comments to describe it in the context of a EMA, make sure correct names are used :)

I could let AI do it, but the rule with AI is never trust AI :D This is something I'd want to do myself :)

@mooiweertje
Copy link
Copy Markdown
Contributor Author

I've been using AI a lot this week and I am not too impressed. I will look into this EMA thing. I don't see the exponential part in my code.

@mooiweertje
Copy link
Copy Markdown
Contributor Author

mooiweertje commented Nov 15, 2025

I use Copilot mostly and it also says it is EMA and I see now what the exponential part is. Although I don't think it is exponential older values do get less relevant.
So I agree it is an EMA filter.

@mooiweertje
Copy link
Copy Markdown
Contributor Author

mooiweertje commented Nov 15, 2025

But logic will get only get you from A to B and imagination will take you everywhere. It isn't any simpeler than what it is. You can see it is working and the code is only 3 lines so think hard. Comments don't make complicated thought simpler.

@void-spark
Copy link
Copy Markdown
Owner

I'll accept it, then clean it up a bit to my liking :)

@void-spark void-spark merged commit 95a7983 into void-spark:master Nov 16, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants