1 #include <LightChrono.h>
4 const float APPARENT_SHUNT_RESISTANCE = 0.453;
5 const float VOLTAGE_REFERENCE = 2.494;
10 const int digits[] = {2, 3, 4, 5};
11 const int segments[] = {6, 7, 8, 9, 10, 11, 12, 13};
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};
24 const bool U[7] = {false, true, true, true, true, true, false};
25 const bool A[7] = {true, true, true, false, true, true, true};
26 const bool E[7] = {true, false, false, true, true, true, true};
28 unsigned char display_state = 0;
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;
43 void writeDigit(char d, char val, bool dec) {
77 for (int i = 0; i < 7; ++i) {
79 digitalWrite(segments[i], HIGH);
81 digitalWrite(segments[i], LOW);
85 digitalWrite(segments[7], HIGH);
87 digitalWrite(digits[d], LOW);
89 digitalWrite(digits[d], HIGH);
90 digitalWrite(segments[7], LOW);
93 void writeLetter(char d, const bool val[]) {
94 for (int i = 0; i < 7; ++i) {
96 digitalWrite(segments[i], HIGH);
98 digitalWrite(segments[i], LOW);
101 digitalWrite(digits[d], LOW);
103 digitalWrite(digits[d], HIGH);
106 void showNumber(float 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);
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);
122 void showCurrent(float current) {
123 int camp = current * 100;
124 writeDigit(0, (camp/100U) % 10, true);
125 writeDigit(1, (camp/10U) % 10, false);
126 writeDigit(2, camp % 10, false);
130 void showWh(float watthours) {
132 writeDigit(0, (w/1000U) % 10, true);
133 writeDigit(1, (w/100U) % 10, false);
134 writeDigit(2, (w/10U) % 10, false);
140 // put your setup code here, to run once:
142 analogReference(EXTERNAL);
144 for (int i = 0; i < 4; ++i) {
145 pinMode(digits[i], OUTPUT);
146 digitalWrite(digits[i], HIGH);
148 for (int i = 0; i < 8; ++i) {
149 pinMode(segments[i], OUTPUT);
150 digitalWrite(segments[i], LOW);
154 digitalWrite(15, LOW);
156 pinMode(19, INPUT_PULLUP);
157 pinMode(20, INPUT_PULLUP);
158 pinMode(21, INPUT_PULLUP);
164 if (timer.hasPassed(1000)) {
165 unsigned long passed = timer.elapsed();
167 battery_voltage = readVoltage(A0);
169 if (battery_voltage < 0.8) {
170 blank_timer.restart();
172 shunt_voltage = readVoltage(A1);
173 shunt_current = shunt_voltage/APPARENT_SHUNT_RESISTANCE;
176 amps_in_period = shunt_current * passed/1000;
177 watts_in_period = amps_in_period * battery_voltage;
179 ampseconds += amps_in_period;
180 wattseconds += watts_in_period;
181 mamphours = ampseconds/3.6;
182 mwatthours = wattseconds/3.6;
185 if (debounce.hasPassed(300) && !digitalRead(19)) {
186 display_state = (display_state + 1) % 4;
188 } else if (blank_timer.hasPassed(200)) {
189 switch (display_state) {
191 showNumber(mamphours);
194 showVoltage(battery_voltage);
197 showCurrent(shunt_current);
206 float readVoltage(int pin) {
209 for (int i = 0; i < 4; ++i) {
210 val = val + analogRead(pin);
214 return (val / 4) * VOLTAGE_REFERENCE/1023.0;