Sensor Reading for Arduino Analog Inputs: Using a Voltage Divider

H
Hesaplamasyon İçerik Ekibi
•2024-09-21
Sensor Reading for Arduino Analog Inputs: Using a Voltage Divider
Interactive Tool

Voltage Divider Calculator

Perform this calculation instantly with your custom numbers using our dedicated tool.

Open Calculator→

Why Do We Need to Convert Sensor Resistance to Voltage?

Popular development boards and microcontrollers like Arduino, ESP32, and Raspberry Pi Pico use various sensors to perceive the world around them. In the electronics world, the vast majority of sensors that detect physical quantities like temperature, light, humidity, or force (for example, LDRs, i.e., light-dependent resistors, or thermistors, i.e., temperature-dependent resistors) only change their resistance values depending on external factors.

However, a fundamental problem arises here: The Analog-to-Digital Converter (ADC) pins of microcontrollers (for example, the A0, A1 pins on an Arduino Uno) cannot read resistance. They can only read the voltage applied to them and convert this voltage into a digital number. Exactly at this point, we need to convert the changing resistance value of the sensor into a changing voltage value that the microcontroller can understand. The simplest, cheapest, and most common way to do this is to build a voltage divider circuit.

In this article, you will learn why you need voltage dividers to read sensors in your Arduino projects and how to calculate the correct resistors. To save time when building your own circuits, you can quickly verify your calculations with the Voltage Divider Calculator tool.

How Arduino Analog Pins (ADC) Work

The ATmega328P microcontroller at the heart of the Arduino Uno houses an ADC (Analog-to-Digital Converter) module with 10-bit resolution. This means that it will convert a voltage between 0 and 5 Volts applied to the A0 pin into a digital number between 0 and 1023.

If the voltage at the pin is 0V, the Arduino reads the value 0 with the analogRead() function.
If the voltage at the pin is exactly 5V, it reads the value 1023.
If the voltage is exactly in the middle, i.e., 2.5V, it reads a value of approximately 512.

If we successfully convert the changing resistance of our sensor into a voltage varying between 0-5V, we can easily make sense of the data coming from the sensor within our Arduino codes.

Designing a Voltage Divider with LDR and Thermistor

A voltage divider circuit basically consists of two resistors connected in series. One of these resistors will be fixed (at a known value), and the other will be our sensor.

Let's recall the basic voltage divider formula:
Vout = Vin · [ R2 / (R1 + R2) ]

Where you place the sensor when building this circuit is entirely up to you, but the behavior of the voltage you read will change depending on where you place it.

Case 1: Sensor on Top (R1), Fixed Resistor on Bottom (R2)
If you connect the LDR (Light Dependent Resistor) as R1 (to the 5V side) and connect a fixed resistor to R2, our formula becomes: Vout = 5V * [ R_Fixed / (R_LDR + R_Fixed) ].
The characteristic of the LDR is that its resistance drops as light increases. As light increases, R_LDR will become smaller. Because the denominator (R_LDR + R_Fixed) in the formula becomes smaller, the value of the result will increase.
Result: As the light intensity INCREASES, the Vout (voltage) value read by the Arduino INCREASES.

Case 2: Fixed Resistor on Top (R1), Sensor on Bottom (R2)
If you connect the fixed resistor as R1 (to the 5V side) and connect the LDR as R2 (to the GND side), our formula becomes: Vout = 5V * [ R_LDR / (R_Fixed + R_LDR) ].
As light increases, R_LDR will become smaller. When R_LDR, which is in both the numerator and denominator of the formula, gets smaller, the value of the total fraction decreases (due to mathematical proportion).
Result: As the light intensity INCREASES, the Vout (voltage) value read by the Arduino DECREASES.

Usually, Case 1 (voltage/value increasing as light increases) is preferred because it is more intuitive for human perception in terms of coding. However, depending on the needs of your circuit or project, both methods are perfectly valid and correct.

How Should We Choose the Fixed Resistor (R) Value?

Choosing the fixed resistor you will use with the sensor is a critical step. If you choose a fixed resistor that is too large or too small, the reading range (sensitivity) of your sensor will narrow, and you will only read values from the Arduino within a very limited range (e.g., only between 900-950).

To achieve the best sensitivity (the widest voltage variation range), there is a generally accepted rule: The fixed resistor value should be close to the resistance of your sensor under normal operating conditions (or at the midpoint you want to measure).

An example LDR Calibration:

  • You measured the resistance of the LDR with a multimeter when your room was completely dark: 100kΩ (100,000 Ohms)
  • You measured it when your room was very bright: 1kΩ (1,000 Ohms)
  • You measured it under normal, dim room light (at the reference point you want to measure): 10kΩ (10,000 Ohms)

In this case, using a standard resistor with a value of 10kΩ as R_Fixed will give you the most balanced reading range. If you want to simulate in advance which voltage range you will obtain with which resistor value, you can experiment with the Voltage Divider Calculator tool.

Arduino Code Example

We built our circuit (LDR connected to 5V (R1), 10k Fixed resistor connected to GND (R2), and their midpoint connected to the A0 pin). Here is the simple Arduino code needed to read this data:

const int sensorPin = A0; // The pin where the midpoint of the voltage divider is connected
int sensorValue = 0;      // Digital value read from the sensor (0-1023)
float voltage = 0.0;      // Calculated voltage value (0.0 - 5.0)

void setup() {
  Serial.begin(9600); // Start serial communication (To see the results on the computer)
}

void loop() {
  // 1. Read the ADC value
  sensorValue = analogRead(sensorPin);
  
  // 2. Convert the read value to actual voltage
  // Dividing the 5.0V reference voltage by 1023 gives us the voltage ratio
  voltage = sensorValue * (5.0 / 1023.0);
  
  // 3. Print the values to the screen
  Serial.print("Read Value: ");
  Serial.print(sensorValue);
  Serial.print(" | Voltage: ");
  Serial.print(voltage);
  Serial.println(" V");
  
  delay(500); // Wait for 500 ms
}

Thanks to this code, you can monitor the instantaneous changes of the LDR directly as voltage. The voltage values calculated by the code will be shaped according to the formula Vout = Vin·R₂/(R₁+R₂) and the current resistance of the sensor.

Limitations and Things to Consider

While reading sensors with a voltage divider is extremely practical, some limitations may arise, especially in industrial or medical projects (like precision NTC thermistors) that require precise measurements.

  1. Internal Resistance of ADC (Loading Effect): The Arduino's ADC pin, when connected to the midpoint of the circuit, actually acts like a resistor (approx. 100MΩ) connected in parallel to the circuit. In sensors with a resistance below 100kΩ like an LDR, this very large internal resistance does not cause a problem (its effect is negligible). However, if you are using very high resistance sensors (e.g., on the order of MegaOhms), the internal resistance of the ADC will skew your measurement (Loading Effect). In such cases, it is necessary to add an Op-Amp buffer (Voltage Follower) in between the circuit.
  2. Power Dissipation (Self-Heating): Special care must be taken, especially when reading a thermistor (temperature sensor). A continuous current flows through the voltage divider. If you choose the resistor values too small (e.g., 100 Ohms), a high current will flow through the thermistor, and the thermistor will self-heat due to the power dissipation inside it (P = I^2 * R). This causes you to read the ambient temperature higher than it is. It is very important to comply with the current limits specified by the sensor manufacturers in their datasheets.
  3. Reference Voltage (Vin) Fluctuations: As seen in our formula, Vout = Vin · Ratio. If there is noise on the 5V supply line feeding the Arduino, or if the voltage fluctuates between 4.8V - 5.2V compared to the USB source, the Vout value you read will be directly affected. In precise measurements, a clean and regulated Vin (or a dedicated AREF - Analog Reference voltage) should always be used.

Conclusion

For anyone stepping into the world of Arduino and microcontrollers, it is essential to grasp the logic of the voltage divider in order to speak the language of resistance-based sensors. From making lights turn on in the dark with LDRs to measuring ambient temperature with thermistors, you will use this simple Vout = Vin·R₂/(R₁+R₂) math in countless projects. To avoid making mistakes and shorten the trial-and-error period when choosing the most appropriate resistor value in your designs, be sure to keep our Voltage Divider Calculator tool in your toolbox. Happy designing!

Ready to calculate?

Use Voltage Divider Calculator for precise, step-by-step results.

Launch Tool →