Incorrect Raw ADC value with voltage divider

Hello, I am trying to measure voltage of a solar panel based off a voltage divider but my raw ADC value seems to only be reading half of what it should be at 512 even when the multimeter is showing 5V which should be 1024.

Anyone know why this might be? my code and screenshot are attached below.

// Analog reference voltage (default 5V for Arduino UNO)
const float VREF = 5;

// ADC resolution for Arduino UNO (10-bit ADC)
const int ADC_RESOLUTION = 1024;

void setup() {
  Serial.begin(9600); // Start serial communication at 9600 baud
  pinMode(A0, INPUT); // Set A0 as input
}

void loop() {
  // Read the analog value from A0
  int rawADC = analogRead(A0);

  // Convert ADC value to voltage (divider output voltage)
  float Vout = rawADC * VREF / ADC_RESOLUTION;

  // Calculate the original input voltage (solar panel voltage)
  float Vin = Vout * 1.1;

  // Debugging Outputs
  Serial.print("Raw ADC Value: ");
  Serial.println(rawADC);

  Serial.print("Vout (Voltage Divider Output): ");
  Serial.print(Vout, 2); // Display 2 decimal places
  Serial.println(" V");

  Serial.print("Calculated Vin (Solar Panel Voltage): ");
  Serial.print(Vin, 2); // Display 2 decimal places
  Serial.println(" V");

  delay(1000); // Delay for readability
}

You say you are measuring 5V at the A0 pin?

Try changing this to be VREF = 5.0;

I saw that too, but it's a float constant so I don't think that's an issue.

well im not sure how to measure directly at A0 pin in proteus but across the resistor is 5V.

Oh, this is in a simulation? When you see this on real hardware, then it's something to worry about. Until then, welcome to the limitations of simulators.

2 Likes

Yeah I am about ready to order parts for my whole project. I just wanted to simulate everything first since I have to write a thesis and thought it would be good to have. Just nervous that my plan might not work. attached below,

Your 5kΩ/500Ω attenuator divides the incoming voltage by 11, not 1.1, so you need to calculate the solar panel voltage using:

// Calculate the original input voltage (solar panel voltage)
  float Vin = Vout * 11.0;

However this does not explain the voltage measured being out by a factor of 2.

In your simulation, do you set the output voltage of the solar panel to a certain value?

What is your solar panel's open circuit voltage in full sun? It's short circuit current in full sun?

Why do you want to measure a panel's voltage. It has very little to do with generated solar power (the reason we buy/use solar panels).

Open circuit panel voltage doesn't change much with illumination, and it also changes with panel temperature. Voltage is not a good measure of panel output. Current is.
Leo..

1 Like

To account for the effect of the voltage divider on your readings:

  1. Understanding the Voltage Divider:
  • With two 500-ohm resistors in series, the input voltage is divided by 2 at the midpoint.
  • For example, if the input voltage is 5V, the Arduino will read 2.5V at the midpoint.
  1. Adjusting the Reading:
  • To determine the original input voltage (before the divider), multiply the Arduino reading by the divider ratio, which in this case is 2.
  • Alternatively, you can adjust the circuit:
    • Option 1: Remove the voltage divider and feed the full input voltage directly to the Arduino if it is within the allowable range.
    • Option 2: Scale your readings in software to compensate for the divider.
  1. Example Calculation:
  • If your Arduino reads 2.5V at the midpoint of the divider, the original voltage is: Original Voltage=Reading×2=2.5V×2=5V\text{Original Voltage} = \text{Reading} \times 2 = 2.5V \times 2 = 5VOriginal Voltage=Reading×2=2.5V×2=5V

By understanding and compensating for the voltage divider, you can ensure accurate measurements. The reading you are getting is correct.

no idea if this is right, but the order of this calcliuation might be significant.
I'd prefer to work in mV and integer; so something like
int Vref = 5000mV, int resolution 1024,
LONG int temp = rawadc * Vref
int vADC = temp / resolution //millivolts

Hello,

Yes you are right. I am actually doing a whole project where I measure voltage and current to calculate power of dual axis solar tracker. I was just trying to set up a simulation 1 step at a time and ran into this issue with the voltage divider.

1 Like

Hello,

Thanks for the response. The voltage divider equation I used was the following,


The maximum voltage my solar panel can output is 5.5V but the arduino can only receive 5V. So I limit 5.5V to 5V with the divider. In the simulation you can see that at the divider the multimeter is reading 5V which indicates the A0 pin should be seeing 5V or 1024 rawADC. Then I multiply this by 1.1 to get the original 5.5V of the panel. (for a dual axis tracker so I can monitor voltage as it tracks the sun.) I am not sure any of your solutions would work? unless I am still mistaken?

Even if all your calculations are wrong or the resistor are wrong, if the voltmeter shows 5V then the rawADC must be 1023.
So something wrong in the simulation

Shouldn't that be:

float Vin = Vout / 1.1;

Ne'r mind, ignore me. :grimacing:
?

Your diagram shows an Uno R4 WiFi. You should be using the internal 1.5volt reference with that processor for voltage measurements, and divide panel voltage to ≤1.5volt. Results with default 5volt Aref are also dependent on Arduino supply voltage, and you don't want that.

It could be better to use a dedicated chip for current/voltage/power, like the INA226.
Leo..

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.