stawel / cheali-charger

cheap lipo charger
815 stars 271 forks source link

Stabilize ADC on NUC029xLAN platforms #321

Closed joshgarde closed 1 year ago

joshgarde commented 1 year ago

This PR helps stabilize the previously unstable ADC on NUC029xLAN CPUs by reimplementing the timer delay previously implemented for ADC capacitor discharge. But instead of discharging the ADC capacitor like in the original implementation, the timer instead delays the ADC's conversion until the ADC's mux can switch to the requested input channel and for both the ADC's external and internal capacitors to stabilize. The ADC's operating frequency was also lowered as higher frequencies seemed to hinder the ADC mux's ability to switch between inputs reliably.

Additionally, measurement count parameters were changed to optimize for ADC performance and stability. The resulting change allows the ADC to be much more stable during measurements while requiring less measurement rounds.

This change will also be utilized in the M051 CQ3 port as well.

joshgarde commented 1 year ago

Increased the mux delay again as it seems that the original value was specific to one silicon in my batch of chargers. Other silicon seems to need more of a delay to be stable.

joshgarde commented 1 year ago

Spent a day tuning the measurement counts so that the PID wasn't bouncing all over the place. I think I have a config now that provides a decent compromise between voltage accuracy and current stability.

stawel commented 1 year ago

looks good to me (please merge)

btw. the is a part of code that was very useful during ADC debugging atmega/50W version: https://github.com/stawel/cheali-charger/blob/master/src/hardware/atmega32/generic/50W/AnalogInputsADC.cpp#L37-L59 https://github.com/stawel/cheali-charger/blob/master/src/hardware/atmega32/generic/50W/AnalogInputsADC.cpp#L224-L231 dump data collected before cutoff: https://github.com/stawel/cheali-charger/blob/master/src/hardware/atmega32/generic/50W/SMPS_PID.cpp#L44-L45

atmega/200W version, dump data continuously: https://github.com/stawel/cheali-charger/blob/master/src/hardware/atmega32/generic/200W/AnalogInputsADC.cpp#L30-L52 https://github.com/stawel/cheali-charger/blob/master/src/hardware/atmega32/generic/200W/AnalogInputsADC.cpp#L245-L259

and the part where the data is dumped: https://github.com/stawel/cheali-charger/blob/master/src/core/drivers/SerialLog.cpp#L151

I'm not sure why there is no such code in M051 but I definitely used it at some point (I probably forgot to commit it).

For ADC debugging you only needed to uncomment line:

//#define ENABLE_DEBUG

this would print to UART as many "pure" ADC values as I could fit in RAM ("pure" == before averaging)

For example: from the data you could clearly see that when multiplexing between balancer inputs the voltage always "remembered" the last measured Input - that is why we discharge a capacitor placed right before the ADC input pin, and why there are never 2 balance port inputs measured one after another

maybe It would be useful to you.

best regards