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