# Detecting the voltage input to the arduino.

I'm planning to power my arduino with a lipo battery and I'd like to have some sort of warning as to when the lipo is getting low.
It's going to be 2S (8.4V charged, 7.4V dead). So I want to , say, set a delay(10000) to run once when the voltage has dropped below 7.4.
Is there some sort of voltage detection system on the arduino or will I have to route it with a resistor to one of the analog in pins?

You'll need two resistors to make a voltage divider. Then you can use the INTERNAL voltage reference (1.1V) to compare it to so you don't have to compensate for a possibly falling reference voltage.

Step 1 will be bringing the voltage below 1.1V. 10K to Ground and 80K to your battery should divide the voltage by 9.

Step 2 is setting Aref to INTERNAL: analogReference(INTERNAL);

``````analogRead(A0);
``````

Step 4: Calculate the actual battery voltage. We'll do it in millivolts so we don't have to use floating-point.

``````unsigned long millivolts = (voltage * 1100UL) / 1024;  // 1100 is the 1.1V reference voltage
milllivolts *= (80+10)/10;  // Undo the voltage divider
``````

So something like this with the positive also going to the main power supply?

johnwasser:
You'll need two resistors to make a voltage divider. Then you can use the INTERNAL voltage reference (1.1V) to compare it to so you don't have to compensate for a possibly falling reference voltage.

Why would be be seeing a 'falling reference voltage and need to use the 1.1 volt internal reference? He is using a battery ( "It's going to be 2S (8.4V charged, 7.4V dead" ) that can't be wired directly to the boards Vcc so there has to be a voltage regulator powering the controller chip so the normal ADC reference should hold steady through the batteries range.
Lefty

Step 1 will be bringing the voltage below 1.1V. 10K to Ground and 80K to your battery should divide the voltage by 9.

Step 2 is setting Aref to INTERNAL: analogReference(INTERNAL);

``````analogRead(A0);
``````

``````

Step 4: Calculate the actual battery voltage. We'll do it in millivolts so we don't have to use floating-point.

``````

unsigned long millivolts = (voltage * 1100UL) / 1024;  // 1100 is the 1.1V reference voltage
milllivolts *= (80+10)/10;  // Undo the voltage divider

packocrayons:
So something like this with the positive also going to the main power supply?

No. 80K from the analog input to the + side of the power supply, as you have it, but the 10K goes from the analog input to Ground, not the positive side of the power supply to ground.

I'm not using a 5V regulator, there is already one on the arduino. All I have to do is wire the positive to the vin and negative to ground.
John, that makes sense, thanks.

packocrayons:
I'm not using a 5V regulator, there is already one on the arduino. All I have to do is wire the positive to the vin and negative to ground.

Yes, that doesn't contradict what I was saying. You are using a regulator, but just not one you have to install. You can use the standard 0-5vdc analog input range with no need to change from the default reference source.
Lefty

John, that makes sense, thanks.

retrolefty:
Why would be be seeing a 'falling reference voltage and need to use the 1.1 volt internal reference?

You are right that in this case where the battery is feeding a voltage regulator he wouldn't need to use the INTERNAL voltage reference as long as the supply voltage exceeds the minimum necessary for proper regulation. The INTERNAL reference is more necessary when using direct battery voltage (1.8V to 6V) on "+5V" pin.

In absolute sense, johnwasser's approach is better, as the internal reference is dedicated and has less fluctuation than the rail. What I think you don't need to do is to convert the reading back to mv -> you should compare the raw adc reading with a number corresponding to your Vref + divider ratio -> all to be programmed so you don't have to do the math. That saves a little bit time.

But I doubt you need that much accuracy. If I were to implement such a system, I would put the adc on autosampling (by the adc itself or via a timer). Once I read a series of consecutive low voltage ratings, the code sets up a flag. You can process that flag in the loop() or via a software-triggered interrupt.

Henry, that's right. It doesn't have to be super precise and what I'm planning to do is either output the voltage to a 7 seg display or learn how to use LCD's and print out the 3 voltages of the three different batteries on the hovercraft (that is what the project is going on)
Then I can just drive it close by and keep an eye.