Arduino Voltage Reader not Working; SOLVED!

Hi all!

I have a 36v battery that is in an electric four-wheeler that I am trying to build a voltmeter for. The voltmeter has 7 LEDs for displaying battery level. The circuit works correctly with no problems (fixed in another post).

I programmed the low level of the battery to be 32V and the upper to be 41V. Somehow, all the LEDs are staying on, instead of showing battery status. But when the throttle on the four-wheeler is pressed, only ~3-4 LEDs light up because of the instant high power draw. It goes back to all 7 lit when the throttle is released.

I just checked right now and the battery is reading 36.7V on my multimeter, which according to my code, should mean only 4 LEDs are lit, instead of all 7 like they are.

Here is my code:

#include <math.h>

#define inputVoltPin A5

#define led1 6
#define led2 8
#define led3 9
#define led4 10
#define led5 11
#define led6 12
#define led7 13

float R1 = 100000;
float R2 = 10000;
float actualVolts = 5.00;

float inputVolts;
float volts1;
float input;

void setup() {  
  pinMode(inputVoltPin, INPUT);
  
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);

  for (int i=0;i<2;i++){
    digitalWrite(led1, HIGH);
    delay(200);
    digitalWrite(led2, HIGH);
    delay(200);
    digitalWrite(led3, HIGH);
    delay(200);
    digitalWrite(led4, HIGH);
    delay(200);
    digitalWrite(led5, HIGH);
    delay(200);
    digitalWrite(led6, HIGH);
    delay(200);
    digitalWrite(led7, HIGH);
    delay(500);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
  }
  for (int y=0;y<2;y++){
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    digitalWrite(led5, HIGH);
    digitalWrite(led6, HIGH);
    digitalWrite(led7, HIGH);
    delay(1000);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
    delay(500);
  }
}

void loop() {
  inputVolts = analogRead(inputVoltPin);

  volts1 = (inputVolts * actualVolts) / 1024.0; 
  input = volts1 / (R2/(R1+R2));
  
  if ((input < 32) && (input > 24)){
    digitalWrite(led1, HIGH);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
  }
  else if ((input >= 32) && (input < 33.75)){
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
  }
  else if ((input >= 33.75) && (input < 35.5)){
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, LOW);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
  }
  else if ((input >= 35.5) && (input < 37.25)){
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
  }
  else if ((input >= 37.25) && (input < 39)){
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    digitalWrite(led5, HIGH);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
  }
  else if ((input >= 39) && (input < 41)){
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    digitalWrite(led5, HIGH);
    digitalWrite(led6, HIGH);
    digitalWrite(led7, LOW);
  }
  else if (input >= 41){
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    digitalWrite(led5, HIGH);
    digitalWrite(led6, HIGH);
    digitalWrite(led7, HIGH);
  }
  else {
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    delay(500);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
    delay(500);
  }
}

Here is the schematic:
Schematic_Four-Wheeler Battery Status Indicator_2021-10-31.pdf (47.0 KB)

Any thoughts? Thanks in advance!

If your board has TXD broken out so you can route it to a serial-USB module, then some debugging print statements would show what's going on.

Is the schematic you provided, the complete design?

Hi @markd833,

No, my TXD is not broken out. I am using an Atmega328p-pu IC. My entire circuit is soldered on perf-board.

I did try inserting the IC into an Arduino Uno and looking at serial. When I attached a nine volt battery to the "+32V Bat" pin, the serial monitor displayed 8.7V, which I verified with my multimeter, which also said 8.7V.

Yes, that is the whole circuit.

Doesn't an analog read ALWAYS return an integer?
Paul

Hi @Paul_KD7HB,

I just checked. Sorry, it does return an integer. But I don't think that's the problem if I read the voltage of a nine volt battery just fine.

Notice an issue with one of those?

That you are using floats, use floats and not ints for comparison; input < 32.0f

Hi @Idahowalker,

Ok. Ill change all the numbers to floats and do @Paul_KD7HB suggestion and check back.

Those are not floats, above.

Those are floats, below.

float R1 = 100000.0f;
float R2 = 10000.0f;

There is debate that the f is needed but its my habit.

Using an Uno? Use ints as much as possible.

No, I'm using just the Atmega328 chip by itself. I figured the floats would give a slightly higher accuracy even though they use much more space.

Where is the forum topic that told you to use that schematic ?
AREF should not be connected to VCC, and there are not enough decoupling capacitors.

Hi @Koepel,

It is originally my circuit, with only one adjustment on the voltage divider.

Here is the other topic:

I just finished testing out the new version with the AREF pin disconnected, all of the numbers fixed to actual floats (ex. 10.00), and the variable from analogRead changed to an int, not a float. Still nothing. I charged the four-wheeler a little, so now its reading 37.4V, yet all 7 LEDs are still on.

New Code:

#include <math.h>

#define inputVoltPin A5

#define led1 6
#define led2 8
#define led3 9
#define led4 10
#define led5 11
#define led6 12
#define led7 13

float R1 = 100000.00;
float R2 = 10000.00;
float actualVolts = 5.00;

int inputVolts;
float volts1;
float input;

void setup() {  
  pinMode(inputVoltPin, INPUT);
  
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);

  for (int i=0;i<2;i++){
    digitalWrite(led1, HIGH);
    delay(200);
    digitalWrite(led2, HIGH);
    delay(200);
    digitalWrite(led3, HIGH);
    delay(200);
    digitalWrite(led4, HIGH);
    delay(200);
    digitalWrite(led5, HIGH);
    delay(200);
    digitalWrite(led6, HIGH);
    delay(200);
    digitalWrite(led7, HIGH);
    delay(500);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
  }
  for (int y=0;y<2;y++){
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    digitalWrite(led5, HIGH);
    digitalWrite(led6, HIGH);
    digitalWrite(led7, HIGH);
    delay(1000);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
    delay(500);
  }
}

void loop() {
  inputVolts = analogRead(inputVoltPin);

  volts1 = (inputVolts * actualVolts) / 1024.0; 
  input = volts1 / (R2/(R1+R2));
  
  if ((input < 32.00) && (input > 24.00)){
    digitalWrite(led1, HIGH);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
  }
  else if ((input >= 32.00) && (input < 33.75)){
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
  }
  else if ((input >= 33.75) && (input < 35.50)){
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, LOW);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
  }
  else if ((input >= 35.50) && (input < 37.25)){
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
  }
  else if ((input >= 37.25) && (input < 39.00)){
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    digitalWrite(led5, HIGH);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
  }
  else if ((input >= 39.00) && (input < 41.00)){
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    digitalWrite(led5, HIGH);
    digitalWrite(led6, HIGH);
    digitalWrite(led7, LOW);
  }
  else if (input >= 41.00){
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    digitalWrite(led5, HIGH);
    digitalWrite(led6, HIGH);
    digitalWrite(led7, HIGH);
  }
  else {
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    delay(500);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
    delay(500);
  }
}

I just had an idea. If the power voltage is less than 5v, will it read the input voltage as higher than it actually is?

Could be.

Just to verify, you do have the battery ground connected to the arduino ground?

With the 37.4V battery voltage, what voltage do you measure at the A5 pin?

Hi @david_2018,

Yes, I do have the battery connected to the Arduino ground.

I Just measured again, and the battery is still 37.4V with 3.3V on A5.

I also measured the power pin of the Arduino and it is exactly 5V.

One more note: When I just turned on the battery tester, only 4 LEDs turned on like they're supposed to be at 37.4V. Slowly after 2 minutes, all of the LEDs eventually turned on, 1 at a time with ~20 seconds in between. I tested everything again with the multi-meter and it was all the same.

Can you try a different analog input besides A5? Its possibly you might have damaged the input with some of your previous testing.

Oh, yeah. Ok. Ill try A4 and see how it goes.

Wow. That was it! Thanks everyone and @david_2018! I changed the input pin to A4 and that solved it. I also added the 5v power supply to an analog pin so there would be no change in voltage reading even if it drops less than 5V.