WIP: add board battery percentage#403
Conversation
defaults to lipo with no changes to existing variants - adds two chemistry types to start lipo and lifepo - adds getBattPercent to MainBoard - adds getBattType to main board - companion UI now uses getBattPercent in renderBatteryIndicator
|
How about the mobile apps ? This is where most people interact with the devices and the batt% is calculated by the app itself based on the telemetry. Today all batt% are wrong because they are not reflecting the non-linear nature of LiPo when trying to translate voltage to "capacity". I would suggest to update your implementation of |
I'm working on some ideas to approach battery curves, thinking of maybe a map. Just dividing the usable range by 100 and mapping to the closest. rounding down seems better than rounding up. Then from there mapping the values to match the actual average discharge curves. |
|
This last change is giving me trouble, it should work fine but when I flash it on a companion with a display it hangs before rendering the screen. Something with the way I'm grabbing the percentage from the map but no compiler errors so I'm not sure what is wrong. Any help is appreciated. It does not hang when flashing on a companion without a display, i.e. T1000-e. |
|
turns out arduino can't do maps, at least without a 3rd party implementation. I switched to an array of struct but the jump in storage was a bit much, from 48 bytes to 240 or so for one battery curve. I wonder if two arrays of ints is less overhead, just use the index to reference each half of the pair.. |
|
Keep it simple.. lookup tables. #define TABLE_SIZE 21
const uint16_t millivoltTable[TABLE_SIZE] = {
4200, 4150, 4120, 4100, 4050,
4000, 3850, 3800, 3750, 3700,
3650, 3600, 3500, 3450, 3400,
3300, 3200, 3100, 3000, 2800,
2700
};
const uint8_t percentTable[TABLE_SIZE] = {
100, 95, 90, 85, 80,
75, 70, 65, 60, 55,
50, 45, 40, 35, 30,
25, 20, 15, 10, 5,
0
};
uint8_t getBestFittingValue(uint16_t mV) {
uint8_t ret = 0;
uint16_t min = (uint16_t)-1; // use a large initial value
for (uint8_t i = 0; i < TABLE_SIZE; i++) {
uint16_t diff = abs(millivoltTable[i] - mV);
if (diff < min) {
min = diff;
ret = percentTable[i];
}
}
return ret;
}You can have multiple tables like |
|
this is working except for the part using classes as I have no idea what i'm doing. I went with one multidimensional array as it was significantly less memory than multiple arrays. |
This is not true.. let's have a look:
Even if you add another 42 bytes for the LiFe array.. we are far away from your implementation memory footprint. |
|
I'm going for 1% resolution, so 3 x 100 elements for two chemistries and the charge scale. I suppose we could get it a bit slimmer by having only the chemistry curves and infer the SoC percentage but the index we found it during the scan |
|
either way, I have it all sorted out and removed the class idea. just finishing up adding the lifepo4 values and will squash and resubmit a fresh PR |
defaults to lipo with no changes to existing variants