24V Solar Battery Balancer

As I remember I’v ben interested in electronics. In high school i was studying Electrical (high current, little les electronics). And university took me to programming. I almost forgot how fun it was to play with electronics until Arduino arrived on the market and I realized that I can combine my knowledge of programming with electronics.

After bunch of small projects like battery capacity tester and battery heat charging monitoring I was in need of solution for my solar system that I haw in my cabin.

The solar system was 2 years old when my problem happened. In winter I left my solar on for good 2 moths without monitoring it. At that time it was snowing and I didn’t clean the solar cells. When I got to it one of two AGM 240Ah batters that are connected in series had only 9V and other has goon into -1V (how is that even possible?). Guess it is possible an sometimes it happens . Maybe the battery is self was bad and maybe the batteries got out of balance. Hm “out of balance”?

While searching on the internet I found 24V balancers quite expensive. Then It accurred me why not build my one with Arduino for 1/10 of the price and at the same time haw some funn with it.

I know… I haw to buy another battery to replace that one who got to negative polarity. But this device that I’m building will insure that new and old (good) battery stay in balance.

Part list

1x Arduino Nano V3.0 – http://s.click.aliexpress.com/e/cFzbzsSc
1x Step Down Buck Converter – https://goo.gl/J2JNVa
1x 2-Channel Relay Module Shield – http://s.click.aliexpress.com/e/bvdsgtqg
1x 0.96 inch 128X64 OLED Display Module – https://goo.gl/Hunx2E
4x Halogen G4 12V – http://s.click.aliexpress.com/e/cNCZwMCY
— I’m using pre made voltage sensors but you can build then with these resistors; 
2x 30k ohm ressistor 
1x 10k ohm ressistor
2x 7.5k ohm ressistor

Schematics

Schematics

The code

// 24V Solar battery balancer by @munge83 iw3b.info

#include <Adafruit_SSD1306.h> // Display Libary

int Rl_1 = 5, Rl_2 = 6;
float dif = 0.5; // The difference between voltages as a condition for switching on the load
float v_min = 10.2;
int input_1 = A1, input_2 = A2;
int n = 20; // How many times is the average voltage measured 

float v1 = 0.00, v2 = 0.00; // volts input

float R1_1 = 29900.0, R1_2 = 40700.0; // calibrate the sensors by changing this values 
float R2_1 = 7500.0, R2_2 = 7500.0;

Adafruit_SSD1306 display(4);
 
void setup(){
   pinMode(input_1, INPUT);
   pinMode(input_2, INPUT);
   pinMode(Rl_1, OUTPUT);
   pinMode(Rl_2, OUTPUT);
   Serial.begin(9600);
   Serial.print("DC VOLTMETER");

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.display();
}

 void display_init (float vi1, float vi2){
  // Display 
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(2);

  display.setCursor(0,0);
  display.print("B1: ");
  display.print(vi1);
  display.print("V");

  display.setCursor(0,17);
  display.print("B2: ");
  display.print(vi2);
  display.print("V");

  display.display();
  
  Serial.print("INPUT 1 V= ");
  Serial.println(vi1,2);

  Serial.print("INPUT 2 V= ");
  Serial.println(vi2,2);
  
  }

// read the value at analog inputs
float volt_1(){
  float vout_1 = 0.00, vin_1 = 0.00;
  int average_1 = 0, value_1 = 0;
  for (int i=0; i < n; i++) {
  average_1 = average_1 + analogRead(input_1);
  delay(50);
  }
  average_1 = average_1/n;

  value_1 = average_1;
  vout_1 = (value_1 * 5.0) / 1024.0; // see text
  vin_1 = vout_1 / (R2_1/(R1_1+R2_1));

  return vin_1;
  }
  
float volt_2 (float in){
  float vout_2 = 0.00, vin_2 = 0.00;
  int average_2 = 0, value_2 = 0;
  for (int i=0; i < n; i++) {
  average_2 = average_2 + analogRead(input_2);
   delay(50);
  }
  average_2 = average_2/n;
  value_2 = average_2;
  vout_2 = (value_2 * 5.00) / 1024.0; // see text
  vin_2 = vout_2 / (R2_2/(R1_2+R2_2));
  vin_2 = vin_2 - in;
    
  return vin_2;
  }

void loop(){

  v1 = volt_1();
  v2 = volt_2(v1);
   
  display_init(v1, v2); 
  
   
  // Load #1
  if (v1 - v2  > 0 & abs(v1 - v2) > dif  & v1 > v_min ) {
    while (v1 >= v2 & v1 > v_min){
      v1 = volt_1();
      v2 = volt_2(v1);
      display_init(v1, v2);
      digitalWrite(Rl_1, HIGH);
      delay(1000);
      }
    digitalWrite(Rl_1, LOW);  
    }
      
  // Load #2
  if (v1 - v2  < 0 & abs(v1 - v2) > dif & v2 > v_min ) {
    while (v1 <= v2 & v2 > v_min){
      v1 = volt_1();
      v2 = volt_2(v1);
      display_init(v1, v2);
      digitalWrite(Rl_2, HIGH);
      delay(1000);
      }
    digitalWrite(Rl_2, LOW);
    } 

delay(600);
}

Leave a Reply

Your email address will not be published. Required fields are marked *

Captcha Captcha Reload

This site uses Akismet to reduce spam. Learn how your comment data is processed.