Measure Voltage of battery powering Arduino Pro Mini

Hey everyone,
I was wondering if it was possible to measure the voltage of a battery that will be powering my Arduino Pro Mini in my upcoming portable project. The reason being is that even though my battery is protected with a TP4056 along with the protection circuit built-into the battery, I wanted to be able to see the voltage on an OLED to make sure everything is working correct.
I have seen people use an analog pin to read a battery voltage, but in most cases, the Arduino was powered by a different power source than the battery it was powering. I have a 3.7V, 1700 maH battery connected to a MT3608 boost converter which powers my board with 5V (the battery is attached to a protection board). Obviously, connecting the boosted output of the converter to m y board would be pointless, but since a LiPo has a maximum voltage of 4.2 volts, can I connect it to an analog pin to measure the voltage?

I know that some sensors exist to measure voltage, but I really can't buy extra stuff for this, I would like it to work without any additional components (also, sticking a massive sensor doesn't seem ideal for my project). My Arduino Pro Mini is a 5V board, just in case that helps

If it is possible, I would love some insight on how to do it!

If the Arduino is powered by 5V through a boost converter with common ground, just measure the battery voltage with the ADC. However, a boost converter wastes significant battery power and makes it very difficult to save battery power using sleep modes.

For the much better option of powering the Arduino directly by the battery, measure the battery voltage by comparing Vcc voltage with the internal 1.1V reference. Although the 1.1V reference is stable, it is not calibrated and can be anywhere between about 1.0 and 1.2V. So, you need to calibrate it yourself.

Code:

// function to read 1.1V reference against AVcc
// return battery voltage in millivolts
// must be individually calibrated for each CPU
// returns: battery voltage in mV

int readVcc(void) {

  int result;

   ADCSRA = (1<<ADEN);  //enable and
   ADCSRA |= (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2);  // set prescaler to 128

  // set the reference to Vcc and the measurement to the internal 1.1V reference

   ADMUX = (1<<REFS0) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1);
   delay(1); // Wait for ADC and Vref to settle

   ADCSRA |= (1<<ADSC); // Start conversion
   while (bit_is_set(ADCSRA,ADSC)); // wait until done
   result = ADC;
  
   // second time is a charm

   ADCSRA |= (1<<ADSC); // Start conversion
   while (bit_is_set(ADCSRA,ADSC)); // wait until done
   result = ADC;
  
   // must be individually calibrated for EACH BOARD

  result = 1148566UL / (unsigned long)result; //1126400 = 1.1*1024*1000
  return result; // Vcc in millivolts
}

Would be better if you had a 3.3volt ProMini for your solar rover,
and power directly from the battery, without a power-wasting boost converter.
Leo..

I’ve seen that number in other threads and forums, but I have absolutely no idea what it means. Do you mind elaborating just a bit or adding a link that can help me a bit? Also, from what I have seen, the Pro Mini does not have a AREF pin like the Nano or Uno. Where would I connect it?

Thank you!

Don't do anything with AREF.

There is a calibration constant in the code. You have to calculate a value, in order that the function returns a battery voltage reading that agrees with what your multimeter says.

Since the battery voltage is lower than your 5V Vcc on the Pro Mini, you can just connect the battery + terminal to any analog pin, preferably through a resistor, and do an analog read of the voltage. You just want to be sure the Pro Mini isn't powered down while that connection is in place.

The other option is to use a 3.3V 8MHz Pro Mini, and power it directly (at Vcc) from the battery, with no boost converter. Then you would measure battery voltage by doing an analog read of the 1.1V reference voltage inside the chip. As your battery voltage drops, the voltage of the reference reads higher. The reference voltage varies from chip to chip, so you would need to calibrate this process.

But doing it this way won't work if you have peripherals, such as your OLED display, which require 5V, or even require 3.3V, and won't operate properly over the battery range of about 3.5V up to 4.2V. Remember that whatever voltage you have coming in at Vcc is the also the high output voltage of the GPIO pins which connect to the peripherals, some of which may not like 4.2V.

If your peripherals could work at fixed 3.3V, a third option would be to replace your boost converter with a buck converter, or even a very low dropout linear regulator, and power the 3.3V Pro Mini from that. The regulator on the Pro Mini isn't good enough to use that way. But that would complicate measuring battery voltage because it would then be higher than Vcc. So you would need a resistor divider to bring the battery voltage down to the right range, which would use a little current.

You probably should just try your existing setup with the boost converter, and see what kind of battery life you get.

1 Like

Secret voltmeter.
Leo..

Sorry for the late reply, my family and I were on vacation.
Ok, so I can connect the battery voltage via a single resistor directly to an analog pin of my choice since I have a 5V board. May I ask why a resistor is needed, and can I use a 10K resistor?

If I’m right, using a resistor would decrease the voltage (for example, 5V would read something lower right?) so how can I get it to be accurate? I don’t want it to the hundredth, just something like 3.3, or 3.2 so I know to not let the battery discharge anymore. An since the VCC voltage supplied by the boost converter is pretty stable despite the battery voltage fluctuating, and since I’m measuring through an analog pin, I can completely ignore AREF (which I don’t think the pin is on the Pro Mini).

Basically, the setup I think you are trying to say is that my battery will go through a 5V boost converter and power my Arduino with 5V. Since my battery voltage unboosted is less than 5V, I can hook one end of the battery to a resistor and connect the battery directly to an analog pin and ground. If the ADC value is accurate (from the resistor), I can multiply it by ~.0049 (one value from 0-1024 is equal to .0049 volts) to get a decent reading of my battery voltage

I have a 5V pro mini, so I can ignore all of this, right?

You can connect the positive battery terminal directly to the analog pin, and read the voltage there. Inserting a resistor in that line won't change the voltage, and would be there only to limit current in case something goes wrong with your Arduino - your code crashes, or something like that. But it isn't essential.

But there's no connection from the analog pin to ground, if that's what you meant.

And yes, you can ignore all the 3.3V stuff.

Thank you, and one last question: Since the positive of the battery is being connected to the analog pin, wouldn’t the negative of the battery have to go to ground as well?

Yes, the battery can't supply power at all unless its negative terminal is connected to ground. But that should already be done through your TP4056.

If you use the version of the TP4056 board with battery protection, then battery negative should not be connected to Arduino. Because that would short the mosfet that protect the battery.
Leo..

1 Like

These are the modules that I have right now, I have bought them from this seller

Link to TP4056

I will try to draw up a simple diagram with pencil and paper will add it as soon as I am done with it

Yes, as said.
The 8-pin chip in the top-right is the mosfet switch between Arduino ground and battery(-).
So don't connect battery(-) to Arduino ground.
Leo..

1 Like

Ok, so here is a simple diagram I just drew

Does this seem like a proper setup? I will have other stuff connected to the pro mini, but since it is fed with 5V, there shouldn’t be a big problem. The main reason I want to measure the voltage is because the over discharge protect for the TP4056 is 2.5V, something way too low for a lipo battery. If I can get a decent reading of the voltage, I can turn the system off at 3.0-3.3v and avoid setting fire to everything.

This assumes a load, and a high internal resistance of the battery while almost fully discharged. If you then disconnect the battery, battery voltage will bounce back to it's real value (which might be close to 3volt). So what really matters is not disconnect voltage, but reconnect voltage.
Leo..

1 Like

Ok got it. My project so far is estimated to draw no more than 130 ma, so what do you think the lowest I can go is? Or does it mean that I can let the battery drain down to 2.5V and still be safe to recharge it?

Also last question, is the diagram above good?

Thank you!

The diagram looks good to me if the input current to the MT3608 is substantially less than 100mA from time to time, and not consistently 130mA. In your circuit, when USB is plugged in, it is both charging the battery, if needed, and powering the load, and current for both goes through the TP4056 charger. The charger is probably set to charge at 1A during the constant current phase, which means it will terminate charging in the constant voltage phase when charging and load current drops below 10% of that, or 100mA. But if the load current is always more than 100mA, the TP4056 will never see its current draw drop below the termination current level. So it will continue to output 4.2V to the battery/load indefinitely, and that's something you shouldn't do to a lithium battery.

The formal solution to that is called a load sharing circuit, but the simplest thing is to put your project to sleep for a while from time to time so with the reduced load current, charging can then terminate properly if it's time to do that. The charger can't distinguish between charging current and load current, so you need periods when it won't be confused by the load current.

Once terminated, charging won't resume until battery voltage drops below 4.1V.

1 Like

My battery is rated at 850 ma max for charging, so I plan to change the resistor to a 2k resistor (580 ma). I am definitely turn the project off with a switch when charging the battery, as I do not feel comfortable with load sharing with a lipo. If the load is disconnected while charging and the TP4055 is charging with a proper max current, will it work?