Iāve had a few people ask me how I did the Arduino battery meter so hereās how I did it:
Iām writing this assuming basic arduino programming knowledge and goodish math knowledge.
This is how the Arduino reads the battery voltage:
The Arduino analog pins can read anything from 0 to 5 volts so I just used resistors to drop the main voltage down before connecting to an analog pin. The voltage will still be proportional to the main voltage.
So now that the arduino can read the battery voltage it just needs to know what voltage correlates to what capacity. Since my LiFe batteries donāt discharge linearly I had to find an equation for the discharge curve. To do this I charged my battery fully then rode my board until it died, checking the battery voltage with a multimeter every mile and writing it down (I used the app Strava to know how many miles I had gone).
Once I had a table of data (distance traveled and voltage) I put the data in my calculator and used the calculators built in quartic regression to find an equation for the curve:
I put 5 LEDs on my board so I decided my battery meter would have 6 states: (1 means LED on and 0 means LED off)
Then I just had to use the equation to find out what the battery voltage would be at every increment.
The arduino analogRead() function doesnāt directly read the voltage. It only reads a fraction of the voltage determined by the resistors used in the first picture. It also doesnāt return the value of the voltage, it returns a number 0 through 1023 (0 being 0 volts and 1023 being the reference voltage(the reference voltage is really close to 5 volts)).
So now I had to find an equation that relates the battery voltage to the number the arduino analogRead() function returns. This is way easier than the last equation because it will be a linear one. I just needed two data points:
first data point:
battery voltage: 0
analogRead(): 0
second data point:
battery voltage: 33.6
analogRead(): 748
To find the second data point I just measured the battery with a multimeter and used the arduino serial monitor to display the results of analogRead().
Then I plugged these into my calculator and used linear regression to find an equation. I used that equation to translate all the battery voltage increments into what analogRead will say at those voltages:
So now I know what increments to change the LEDs at, time to program the ardiuno! The ardiuno code is really simple, here it is:
//longboard battery meter code
//Nick Wallick 10/20/16
int delayTime = 100;
int battery;
int flashingTimer = 0;
void setup() {
// put your setup code here, to run once:
pinMode(A7, INPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
startupAnimation();
startupAnimation();
}
void loop() {
//reads pin attached to resistors and battery
battery = analogRead(A7);
//BATTERY AT 5 BARS///////////////////////////////
if (battery >= 750){
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
digitalWrite(12, HIGH);
}
//BATTERY AT 4 BARS///////////////////////////////
if (battery < 750){
if (battery >= 741){
digitalWrite(8, LOW);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
digitalWrite(12, HIGH);
}
}
//BATTERY AT 3 BARS/////////////////////////////////
if (battery < 741){
if (battery >= 737){
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
digitalWrite(12, HIGH);
}
}
//BATTERY AT 2 BARS///////////////////////////////
if (battery < 737){
if (battery >= 734){
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, HIGH);
digitalWrite(12, HIGH);
}
}
//BATTERY AT 1 BAR///////////////////////////////
if (battery < 734){
if (battery >= 724){
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, HIGH);
}
}
//BATTERY AT FLASHING///////////////////////////////
if (battery < 724){
if (battery >= 683){
if (flashingTimer > 2000){
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
}else{
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
digitalWrite(12, HIGH);
}
flashingTimer = flashingTimer + 1;
if (flashingTimer > 8000){
flashingTimer = 0;
}
}
}
//BATTERY AT FAST FLASHING///////////////////////////////
if (battery < 683){
if (flashingTimer > 500){
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
}else{
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
digitalWrite(12, HIGH);
}
flashingTimer = flashingTimer + 1;
if (flashingTimer > 1000){
flashingTimer = 0;
}
}
}
void startupAnimation() {
digitalWrite(8, HIGH);
delay(delayTime);
digitalWrite(8, LOW);
digitalWrite(9, HIGH);
delay(delayTime);
digitalWrite(9, LOW);
digitalWrite(10, HIGH);
delay(delayTime);
digitalWrite(10, LOW);
digitalWrite(11, HIGH);
delay(delayTime);
digitalWrite(11, LOW);
digitalWrite(12, HIGH);
delay(delayTime);
digitalWrite(12, LOW);
digitalWrite(11, HIGH);
delay(delayTime);
digitalWrite(11, LOW);
digitalWrite(10, HIGH);
delay(delayTime);
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
delay(delayTime);
digitalWrite(9, LOW);
}
The code just reads the A7 pin and turns the right number of LEDs on depending on what A7 returns.
When writing the code I decided to add fast flashing, in addition to normal flashing, if the battery gets way too low so I know to turn it off. I also added a startup animation just cause it looks cool .
Hopefully this helps some people figure out how to make a battery meter!
Also hereās my full electrical drawing of the circuitboard I soldered the arduino to. The wires going up on the right go to the LEDs. This circuit board also has this mosfet switch.