Arduino has 5V capability and one can use the analog pins like A0,A1 etc to measure voltage upto 5V but what if you want to measure voltage more than 5V like 9V battery voltage for example. You cannot the 9V voltage source to the analog input pins since it will exceed the maximum voltage limit of the Arduino (ATmega328P) Analog to Digital Converter(ADC) and permantenly damage the pin or the entire chip.
The solution to this is to use voltage divider to scale down the incoming voltage to 0V to 5V so that the ADC can safely measure the voltage. A voltage divider is made up of two resistors $R_1$ and $R_2$ in series and the junction between them is taken as the voltage to be measured.
The voltage divider formula is,
$V_{out}=V_{in}(\frac{R_2}{R_1+R2})$
Here, $V_{in}$ is the voltage you want to measure. $V_{in}$ is the input voltage like 9V from battery. The resistor $R_1$ is the resistor connected to the $V_{in}$ and the junction between the resistor which is also the voltage output $V_{out}$. The resistor $R_2$ is connected between the resistor junction and the ground.
To design the 9V battery measurable circuit, we have to taken into account the actual voltage thats on fresh battery. A new battery can have output voltage between 9.2V to even 10V. So we have to design the circuit assuming maximum voltage of 10V. Then we have to scale down the 10V to 5V so that the ADC pin can read it safely.
Knowing this, we need to select the values for the resistors. This is a good news because here in this case we can use equal value resistors. That is if we use $R_1=R_2=10k\Omega$ then the above equation for the output voltage gives,
$V_{out}=V_{in}(\frac{R_2}{R_1+R2}) = 9V \times(\frac{10k\Omega+10k\Omega}{10k\Omega})=5V$
So, the circuit diagram for measuring 9V battery with Arduino would look like this:
To display the measured voltage, an 128x32 OLED is connected as shown below.
So for example if the battery voltage is 10V then it correctly shows that voltage.
The program code for this project is below:
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Serial.begin(9600);
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.display();
}
void loop() {
int rawADC = analogRead(A0);
// Convert to voltage at the pin (0 to 5V)
float pinVoltage = (rawADC * 5.0) / 1024.0;
// Multiply by 2 because the voltage divider cuts the battery voltage in half
float batteryVoltage = pinVoltage * 2.0;
// If the reading is a tiny ghost voltage near 0, lock it to absolute zero
if (batteryVoltage < 0.1) {
batteryVoltage = 0.0;
}
// Debugging output to Serial Monitor
Serial.print("Raw ADC: "); Serial.print(rawADC);
Serial.print(" | Battery Volts: "); Serial.println(batteryVoltage, 2);
// --- OLED Display Configuration ---
display.clearDisplay();
// Header Title
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("BATTERY VOLTAGE:");
// Calculated Measurement
display.setTextSize(2);
display.setCursor(15, 15);
display.print(batteryVoltage, 2); // Displays the scaled up 0-10V battery value
display.print(" V");
display.display();
delay(500);
}
So in this way one can measure the actual voltage of a battery or battery source which is higher than 5V with Arduino.
Related Tutorials