]> git.friedersdorff.com Git - max/battery_tester.git/blob - battery_tester.ino
Fix decimal point and stupid initial state
[max/battery_tester.git] / battery_tester.ino
1 #include <LightChrono.h>
2 #include <Chrono.h>
3
4 const float APPARENT_SHUNT_RESISTANCE = 0.453;
5 const float VOLTAGE_REFERENCE = 2.494;
6
7 float ampseconds = 0;
8 float wattseconds = 0;
9
10 const int digits[] = {2, 3, 4, 5};
11 const int segments[] = {6, 7, 8, 9, 10, 11, 12, 13};
12
13 const bool one[7] = {false, true, true, false, false, false, false};
14 const bool two[7] = {true, true, false, true, true, false, true};
15 const bool three[7] = {true, true, true, true, false, false, true};
16 const bool four[7] = {false, true, true, false, false, true, true};
17 const bool five[7] = {true, false, true, true, false, true, true};
18 const bool six[7] = {true, false, true, true, true, true, true};
19 const bool seven[7] = {true, true, true, false, false, false, false};
20 const bool eight[7] = {true, true, true, true, true, true, true};
21 const bool nine[7] = {true, true, true, true, false, true, true};
22 const bool zero[7] = {true, true, true, true, true, true, false};
23
24 const bool U[7] = {false, true, true, true, true, true, false};
25 const bool I[7] = {false, false, true, false, false, false, false};
26 const bool P[7] = {true, true, false, false, true, true, true};
27
28 unsigned char display_state = 0;
29
30 Chrono timer;
31 Chrono debounce;
32 Chrono blank_timer;
33
34 float shunt_voltage = 0;
35 float shunt_current = 0;
36 float battery_voltage = 0;
37 float amps_in_period = 0;
38 float watts_in_period = 0;
39 float mamphours = 0;
40 float mwatthours = 0;
41
42
43 void writeDigit(char d, char val, bool dec) {
44     const bool *segs;
45     switch (val) {
46         case 0:
47             segs = zero;
48             break;
49         case 1:
50             segs = one;
51             break;
52         case 2:
53             segs = two;
54             break;
55         case 3:
56             segs = three;
57             break;
58         case 4:
59             segs = four;
60             break;
61         case 5:
62             segs = five;
63             break;
64         case 6:
65             segs = six;
66             break;
67         case 7:
68             segs = seven;
69             break;
70         case 8:
71             segs = eight;
72             break;
73         case 9:
74             segs = nine;
75             break;
76     }
77     for (int i = 0; i < 7; ++i) {
78         if (segs[i]) {
79             digitalWrite(segments[i], HIGH);      
80         } else {
81             digitalWrite(segments[i], LOW);
82         }
83     }
84     if (dec) {
85       digitalWrite(segments[7], HIGH);
86     }
87     digitalWrite(digits[d], LOW);
88     delay(1);
89     digitalWrite(digits[d], HIGH);
90     digitalWrite(segments[7], LOW);
91 }
92
93 void writeLetter(char d, const bool val[]) {
94     for (int i = 0; i < 7; ++i) {
95         if (val[i]) {
96             digitalWrite(segments[i], HIGH);
97         } else {
98             digitalWrite(segments[i], LOW);
99         }
100     }
101     digitalWrite(digits[d], LOW);
102     delay(1);
103     digitalWrite(digits[d], HIGH);
104 }
105
106 void showNumber(float number) {
107     int n = number;
108     writeDigit(0, (n/1000U) % 10, false);
109     writeDigit(1, (n/100U) % 10, false);
110     writeDigit(2, (n/10U) % 10, false);
111     writeDigit(3, n % 10, false);
112 }
113
114 void showVoltage(float volts) {
115     int cvolts = volts * 100;
116     writeDigit(0, (cvolts/100U) % 10, true);
117     writeDigit(1, (cvolts/10U) % 10, false);
118     writeDigit(2, cvolts % 10, false);
119     writeLetter(3, U);
120 }
121 void showCurrent(float current) {
122     int camp = current * 100;
123     writeDigit(0, (camp/100U) % 10, true);
124     writeDigit(1, (camp/10U) % 10, false);
125     writeDigit(2, camp % 10, false);
126     writeLetter(3, I);
127 }
128
129 void showWh(float watthours) {
130   int w = watthours;
131   writeDigit(0, (w/1000U) % 10, true);
132   writeDigit(1, (w/100U) % 10, false);
133   writeDigit(2, (w/10U) % 10, false);
134   writeLetter(3, P);
135 }
136
137
138 void setup() {
139     // put your setup code here, to run once:
140     Serial.begin(9600);
141     analogReference(EXTERNAL);
142
143     for (int i = 0; i < 4; ++i) {
144         pinMode(digits[i], OUTPUT);
145         digitalWrite(digits[i], HIGH);
146     }
147     for (int i = 0; i < 8; ++i) {
148         pinMode(segments[i], OUTPUT);
149         digitalWrite(segments[i], LOW);
150     }
151
152     pinMode(15, OUTPUT);
153     digitalWrite(15, LOW);
154
155     pinMode(19, INPUT);
156     pinMode(20, INPUT);
157     pinMode(21, INPUT);
158 }
159
160 void loop() {
161     
162
163     if (timer.hasPassed(1000)) {
164         unsigned long passed = timer.elapsed();
165         timer.restart();
166         battery_voltage = readVoltage(A0);
167
168         if (battery_voltage < 0.8) {
169             blank_timer.restart();
170         } else {
171             shunt_voltage = readVoltage(A1);
172             shunt_current = shunt_voltage/APPARENT_SHUNT_RESISTANCE;
173
174
175             amps_in_period = shunt_current * passed/1000;
176             watts_in_period = amps_in_period * battery_voltage;
177
178             ampseconds += amps_in_period;
179             wattseconds += watts_in_period;
180             mamphours = ampseconds/3.6;
181             mwatthours = wattseconds/3.6;
182         }
183     }
184     if (debounce.hasPassed(300) && !digitalRead(19)) {
185         display_state = (display_state + 1) % 4;
186         debounce.restart();
187     } else if (blank_timer.hasPassed(200)) {
188         switch (display_state) {
189           case 0:
190             showNumber(mamphours);
191             break;
192           case 1:
193             showVoltage(battery_voltage);
194             break;
195           case 2:
196             showCurrent(shunt_current);
197             break;
198           case 3:
199             showWh(mwatthours);
200             break;
201         }
202     }
203 }
204
205 float readVoltage(int pin) {
206
207     int val = 0;
208     for (int i = 0; i < 4; ++i) {
209         val = val + analogRead(pin);
210         delay(0.5);
211     }
212
213     return (val / 4) * VOLTAGE_REFERENCE/1023.0;
214 }