Power monitor circuit

For the bag movement alarm project, I wanted to be able to monitor the battery level so I can warn the user when they need to change the battery.  A simple way to do this is just to monitor the voltage of the battery, as batteries have a pretty well articulate discharge curve:  with more discharge, the lower the voltage.  The real question is the shape of this curve:  at a certain point of discharge, the voltage will drop off a cliff.  It is just before this point (i.e. where there is just a little bit left) that I want to indicate that it is discharged.  The TrinketPro only needs to be over 5.5V to operate, so there is considerable give in the battery.

So how to monitor the voltage?  The easiest way is to use an analog in pin to monitor the voltage, but the max voltage on the analog in is +5v, and our battery can be a bit more than +9v when fully charged.  It is not cool to put the +9v direct the the Arduino analog in pin, so the solution is a voltage divider.

I put two equal resistors (I used 1k) between the +9v and the ground of the battery.  At the mid point, I attached another resistor (I used 47k) to a jumper to the A0 pin.  This means that when the +9v is showing, the voltage at the A0 pin should be +4.5v.  When the battery voltage is less (say 6v), then the voltage at the A0 pin will be 3v.  To calculate, just need to back that up (i.e. multiply the read voltage by 2), and need to know what the top end of the A0 reading is (from what I understand, this is AREF).

The circuit is pretty simple:

Battery Monitor Circuit.  The orange jumper goes to the A0 pin on the Arduino.

Battery Monitor Circuit. The orange jumper goes to the A0 pin on the Arduino.

Later, I also added a 100nF capacitor between the center of the voltage divider and ground, just to smooth out any spikes that might occur.  Of note, the size of the capacitor between the A0 pin and the center of the voltage divider seemed to not have any affect on the readings.

And the code is simple as well (including the prints to serial):

int batteryVoltagePin = A0;
float lowVoltageLevel = 6.0;
float actual5vOutVoltage = 5.03;

void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
pinMode(batteryVoltagePin, INPUT);
}

// the loop routine runs over and over again forever:
void loop() {
boolean isVoltageTooLow = voltageCheck();

// —- SERIAL COMMS —-
Serial.print(” Voltage too low: “);
Serial.print(isVoltageTooLow);
Serial.println();
// —- SERIAL COMMS —-

delay(500);
}

boolean voltageCheck() {
// read the input on the voltage :
int sensorValue = analogRead(batteryVoltagePin);

// Convert the analog reading (which goes from 0 – 1023) to a voltage (0 – 5V):
float voltage = sensorValue * (actual5vOutVoltage/1023.0) * 2;

// —- SERIAL COMMS —-
Serial.print(” SV: “);
Serial.print(sensorValue);
Serial.print(” Voltage: “);
Serial.print(voltage);
// —- SERIAL COMMS —-

// check to see if the voltage is below the threshold
boolean isVoltageTooLow = false;
if (voltage < lowVoltageLevel) {
isVoltageTooLow = true;
}
return isVoltageTooLow;
}

For the most part, this works, but it is not extremely accurate.  When I measured the two batteries I have (one fully charged, one more discharged), I am off by ~0.3V or so.   This is okay for this purpose, which is to get a general state of discharge.  Also, the readings jump around a bit, and a better strategy may be to average several readings to be more accurate and stable.

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s