Monday 3 March 2014

Arduino-based battery monitor

Hello again!

I started with the Ship Computer last October but had to stop working on it for a couple of months and hoped to start over again in January.

Which, unfortunately I didn't.

The same time I am setting up a trip around Ionian for which I am planning to get going by mid May, that is, less than 2 and a half months away, and I have to prepare the boat and everything.

Which means that probably there won't be much time for software development...

Nevertheless, I absolutely need some of the functionality the ship computer was going to give me, and knowing that probably I won't have the Ship Computer ready for this trip, I started thinking of alternatives.

One thing that I have to have is a battery monitor.

On the boat I have a 120W solar panel for charging a 65AH battery and,  if absolutely necessary, I can also use the outboard alternator for additional 60W of battery charging power. As far as consumption goes, I have installed led-based navigation and cabin lights so that will keep the consumption down. Other source of power consumption include the instruments and the autohelm, for which I am particularly worried.

Anyway, since I only carry a single battery, I need to know how much consumption is there, what is the charging current when applicable and the battery voltage.

In order to get this functionality, I used an arduino Pro Mini, a current sensor (similar to this), a voltage divider set up with two resistors and a 16x2 LCD screen connected to I2C.

For powering I used a low cost 6V UBEC like this one: http://r.ebay.com/NQZ0ne
  
The finished project looks like this:
 In this picture:
  • #1 is the current sensor
  • #2 if the arduino Pro Mini
  • #3 is the insulation for the arduino
  • #4 is the UBEC with the insulattion sleeve in place
  • #5 is the 16x2 LCD screen
 I have also prepared a youtube video that shows the system working:
The source code for the project is very simple and has as following:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

float amperes=0;
float volts=0;

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

void setup()
{
  // initialize the lcd
  lcd.begin(16,2);              
  lcd.clear();
  lcd.print("Amps=");
  lcd.setCursor ( 0, 1 );
  lcd.print("Volts=");
}
void clearValues(){
  lcd.setCursor ( 6, 0 );
  lcd.print("       ");
  lcd.setCursor ( 7, 1 );
  lcd.print("       ");
}
void showValues(float Amps,float Volts){
  clearValues();
  lcd.setCursor ( 6, 0 );
  lcd.print(Amps,3);
  lcd.setCursor ( 7, 1 );
  lcd.print(Volts);
}

void loop()
{
  // MEASURE CURRENT
  // ampere sensor connected to A3
  amperes=0;
  long temp=0;
  //150 reads, 15 usec delay = total 2.25msec
  for(int i = 0; i < 150; i++) {
    temp+=analogRead(A7);
    amperes = amperes + (.0264 * analogRead(A3) -13.51) / 150;
    //function calibrated for 5A sensor
    delayMicroseconds(15);  //15 usec delay for the A2D to "reset"
  }
  temp/=150;
  amperes=(0.0049*(temp-512))/0.185;
  //negative on discharge, positive on charge
  amperes*= (-1);  
  //
  // MEASURE VOLTAGE
  // voltage divider (1/5) conected at pin  A2
  temp=0;
  //150 reads, 15 usec delay = total 2.25msec delay for a measurement
  for(int i = 0; i < 150; i++) {
    temp+=analogRead(A3);
     delayMicroseconds(15);  //15 usec delay for the A2D to "reset"
  }
  temp/=150;   // get the average value
  volts=temp*5.01*((19.93+6.8)/6.8)/1024.0;  // calculate actual voltage
  showValues(amperes,volts);
  delay(300);
}


The whole setup is simple, works like a charm and is a way to get some limited but needed functionality even if the Ship Computer is not ready in time for the trip.

That said, I hope to be back soon with a post about the ship computer itself!

Thanks for reading,
G.

No comments:

Post a Comment