I am making a solar charge controller using Arduino. So for starting, I thought I should calibrate the voltage so that I am able to read the exact voltage of battery and solar charger. For testing purposes, I do not have any solar panel, so I used a 12V power supply and set its output voltage to 13.56. I used the following calculations for getting exact voltage:

float solarData = 0;
float batData = 0;
float batScale = 0;
float solarScale = 0;
float batPinVolt = 0;
float solPinVolt = 0;
float batVolt = 0;
float solVolt = 0;

Vcc = readVcc()/1000.00;    //getting the exact voltage of arduino
solarScale = analogRead(A0);  //reading solar analog data
batScale = analogRead(A1);    //reading battery analog data
solPinVolt = (solarScale/1024.0) * Vcc;   
solVolt = solPinVolt * (9.80 + 2.168)/2.168;    //I used 10k & 2.2k so entered their exact value  
batPinVolt = (batScale/1024.0) * Vcc;
batVolt = batPinVolt * (9.80 + 2.168)/2.168;    

Initially, I faced few problem regarding the exact voltage of the Arduino which I used as a reference voltage to calculate voltage. But then I found a solution here. So below is the code which calculate the voltage of Arduino

long readVcc() 
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1125300L / result; // Back-calculate AVcc in mV
  return result;

Now when I uploaded the code, I got the exact values of the voltages.

Now I wrote a logic where if the battery voltage is less than 12V then start charging until it is above 13V. Following is the code:

if((solVolt > batVolt)&& ( batVolt <= 12.00 ))
digitalWrite(chargePin,HIGH);  //enable charging
digitalWrite(loadPin,LOW);     //load off
else if((solVolt > batVolt)&&(batVolt > 12.00)&& (batVolt <= 13.00 ))
 digitalWrite(chargePin,HIGH);   //enable chargin
 digitalWrite(loadPin,LOW);      //load off
// // shut down when battery is fully charged or when sunlight is not enough
else if ((batVolt > 13.00) or (solVolt < batVolt))
 digitalWrite(chargePin,LOW);    //disable charging
 digitalWrite(loadPin,HIGH);     //load on

But when I uploaded the code, the Arduino started showing wrong values of the voltages. Power supply was set to 13.5, but it showed 13.15 and battery voltage was 11.8, but it showed 12.7.

Now due to this what exactly happened was it started charging so the value of battery voltage 12.7 (which is wrong) started increasing. When it was above 13V, Arduino turned off the chargePin. So when the chargePin is low, it shows the exact battery voltage which is low so it again started charging it and this loop keeps on going. This is all because of the wrong values of voltages. Following is the schematic:

enter image description here

I am following the article I found on Instructables. (cannot post more links due to reputation). I want to know why there is change in voltage. Can anyone please help me on what I am doing wrong.

  • And now you know why you need to stop charging when reading the voltage. Commented Sep 9, 2016 at 7:27
  • @IgnacioVazquez-Abrams I am trying to stop the charging by setting the chargePin to low which will turn off the transistor. But when the charging stops it shows the exact value of battery voltage which is lower than what arduino shows. So it again charging it rather than cut off. I want to know why it shows wrong values.
    – S Andrew
    Commented Sep 9, 2016 at 7:31
  • What tolerance are the resistors in the voltage divider? Commented Sep 9, 2016 at 7:35
  • What are those variable data types? Float?
    – Nick Gammon
    Commented Sep 9, 2016 at 7:52
  • @IgnacioVazquez-Abrams Resistor values are R1=10k R2=2.2k.
    – S Andrew
    Commented Sep 9, 2016 at 7:56

1 Answer 1


In order to charge a battery you have to apply a voltage to the battery terminals that is higher than the batteries own internal voltage. That's pretty much the definition of charging a battery.

Basically you're trying to do the impossible, you can't measure the batteries off charge voltage while charging it because as soon as you start charging the voltage at that point changes.

When charging your supply is 3.5V and your supply measurement is 13.15. That means you're loosing 0.35V in battery cables and F1. The battery voltage is 12.7V so that's 0.45V loss in D1 and Q1.

That first loss seems too high and the second one too low, D1 should drop typically drop 0.58V, so you may have some resistor tolerance or noisy reading issues. The total voltage drop seems reasonable but the split looks wrong.

The best solution to what your are trying to do is to measure the charge current.

Move D1 to the other side of R1 so there is no diode drop between your two voltage measurements and add a small resistor in series where D1 used to be. The difference between the two measured voltages and the resistance between those points now tells you the charge current. Stop charging when the current drops below a certain threshold. Larger resistors make it easier to measure accurately but have an obvious efficiency hit, make sure you check the resistors power rating.

You may be able to avoid adding the resistor and simply use the on resistance of Q1 as your resistor. This will be a little variable between devices so it's not suitable for mass production but for a one off it should be good enough as long as it's not too small for you to measure the current accurately.

One further note: With a supply of 13.5V you will never get the battery to 13V. You have a diode in there with a 0.6V drop so the highest you could get is 12.9V. On the plus side this means you can keep charging until the current drops to 0 with no risk of overcharging. Or alternatively switch D1 for a schottky diode with a drop of around 0.2V

  • I made my circuit according to the schematic which I have posted but there were few things which I was doing wrong. After your suggestions I have made few changes. Now at least I am getting accurate voltage. I want to know how to measure the actual voltage when the battery is charging. As you said, when we connect battery to solar/power supply, its voltage increase, if it was 11 v, then it started showing 12v. So in code also it will consider it as 12v. Then how can we measure the actual battery voltage while charging..? I need this because I also need to protect the battery....
    – S Andrew
    Commented Sep 9, 2016 at 13:16
  • ...the battery from overcharging. If it will show voltage other than actual voltage, then I guess its impossible to measure its voltage. Is there any way of protecting the battery from overcharging.??
    – S Andrew
    Commented Sep 9, 2016 at 13:18
  • You can't charge unless you apply a voltage greater than the batteries voltage to its terminals. Which means it is impossible to know for sure the voltage you will measure when you remove the charge voltage. It may be possible to estimate what it will be as a function of charge voltage and charge current but that won't be perfect. If you want to prevent overcharging then limit the charge voltage to the maximum battery voltage and charge until the charge current is almost zero.
    – Andrew
    Commented Sep 9, 2016 at 14:58
  • Lets say I have set max voltage to be 13v. Current battery volt is 11v. So as soon as I start charging, MOSFET conducts and battery volts increases to 12v(lets say). So it will charge till 13v and stop charging. When no charge voltage, actual battery volt has increase from 11v to 12v so it will again start charging. How to handle this condition.
    – S Andrew
    Commented Sep 10, 2016 at 13:25
  • If you charge to the point where there is no charge current flowing then the voltage you are measuring will be the batteries at rest voltage. If there is still a charge current then the amount the battery voltage will drop will be roughly proportional to the charge current. You need to stop thinking purely about voltages, you need to take the current into account.
    – Andrew
    Commented Sep 12, 2016 at 8:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.