Subject: arduino nano A2D accuracy
Implementation:
I have a battery of 8 X 4.2V Li-ion cells wired in series
Each cell junction is connected to a potential divider the output of which drives an analogue input pin of an arduino nano
To compensate for resistor and other errors the unit is initially calibrated by providing a reference voltage to each input so that a volts per bit can be calculated and stored in EEPROM for use in later calculations. The calibrated A2D reference voltage is also stored. The reference voltage is provided in increments of 4.0V so:
4, 8, 12, 16, 20, 24, 28, 32
The run time code is currently very crude:
correctedVoltageArray[0] = (rawBinaryArray[0] * voltsPerBitArray[0]); // Do this only once
for(j=1; j <= 7; j++) // Do this 7 times
{
correctedVoltageArray[j] = ((rawBinaryArray[j] * voltsPerBitArray[j]) - (rawBinaryArray[j - 1] * voltsPerBitArray[j - 1])); // Calculate individual cell voltages
}
OK. Yes it works but if there is a 1 bit error in the top voltage reading then this will result in a 1 X voltsPerBitArray[7] final error.
Explanation:
Lets call the cell tapping voltages A, B, C, D, E, F, G, H
Lets assume each tap is 4.0V
They increase by 4 at each tap:
A = 4
B = 8
C = 12
D = 16
E = 20
F = 24
G = 28
H = 32
Using the formula (cell voltage CV = (this cell voltage - lower cell voltage)) cell H = H - G result CV = 4
If H has a +1 bit error where the volts per bit is Z then the result is CV = (4 + Z)
This is 'real' calculated data as an example:
Cell voltage 1 4.187773 Raw = 959 V/B = 0.004367
Cell voltage 2 4.195252 Raw = 963 V/B = 0.008705
Cell voltage 3 4.177235 Raw = 964 V/B = 0.013029
Cell voltage 4 4.211671 Raw = 956 V/B = 0.017544
Cell voltage 5 4.214136 Raw = 979 V/B = 0.021436
Cell voltage 6 4.220350 Raw = 982 V/B = 0.025668
Cell voltage 7 4.208635 Raw = 977 V/B = 0.030108
Cell voltage 8 4.225077 Raw = 964 V/B = 0.034896
The above cell voltages when checked with a DVM are all 4.21V
I would like to try a different approach:
CV = (thisVoltage + sum(lowerVoltages)) / cellFactor;
So:
resultA = (A)/1;
resultB = (B + A)/3;
resultC = (C + B + A)/6;
resultD = (D + C + B + A)/10;
resultE = (E + D + C + B + A)/15;
resultF = (F + E + D + C + B + A)/21;
resultF = (G + F + E + D + C + B + A)/28;
resultF = (H + G + F + E + D + C + B + A)/36;
Limitations:
I realise that this will not eliminate errors but it may give me results nearer to true values. In any event I am keen to see what the effect will be.
Problem:
I don't know how to turn the above into an algorithmic expression. Yes I could have a series of calculations but it should be possible to have only one.
Questions:
- Am I going off the rails here?
- Is there a better approach?
- Can anyone help to write the for loop for the above?
Finally - thank you if you get this far.
Brian