Reading 0-30V

I’m working on a project in which i am trying to take in 0-30v and scale it down to 0-5v so the Arduino can read it and then output it. Currently I’m checking output via the IDE serial monitor.

I attached a schematic/picture of my work that shows my wire & resistor configuration on the breadboard to the Arduino. I also attached a schematic-equation drawing showing my resistor choice calculation. I also verified the calculation via a online calculator:

I have modified existing code designed for a 0-25V configuration from:

Here is my code:

#include <Wire.h>

float voltage = 0.0;
int sensorPin = A11;  
float sensorValue = 0.0f;  

float vout = 0.0;
float vin = 0.0;
float R1 = 5000.0; 
float R2 = 1000.0; 

void setup() {
  Serial.println("Starting Voltage Reading");

void loop() {
  voltage = readVoltage();

float readVoltage(){

   sensorValue = analogRead(sensorPin);
   vout = (sensorValue * 5.0) / 1024.0; 
   vin = vout / (R2/(R1+R2));   
   return vin;

This is the first project i’ve ever tried and im just insure that i have implemented it 100% correctly. It’s fairly simple & straight forward, but i just have my doubts.

On the physical size I have tested the voltage divider configuration with a 1.5v battery and voltmeter to ensure the voltage going in matches what i expect to be coming out based upon equation… and it does (1.6V in, out .26V) so im quite confidant in that part of the project.

On the code side is where I am a little unsure. With the modifications i have made is it still adequate for properly measuring 0-30V?

Thanks for your time and input!

Basically ok - give it a go. I'd avoid using delay() as it locks up the processor just counting. - look at the BlinkWithoutDelay example.

And why do all those sums every loop? The voltage is simply the analog reading x a constant.

Figure out the constant just once in setup and use that..



You can find out yourself, whether your code computes the right voltage values, by comparing it to a voltmeter reading.

Perfomance can be increased a bit, when you use local variables in readVoltage(), so that the compiler can better optimize the code. Divisions are very expensive on an 8 bit AVR, so that I'd suggest the following modification:

float readVoltage(){
  int sensorValue = analogRead(sensorPin);
  float vout = sensorValue * (5.0 / 1024.0); 
  //vin = vout * (1 / (R2/(R1+R2)));   
  float vin = vout * ((R1+R2) / R2);   
  return vin;

The constant expressions do not normally deserve further optimization, such expressions are already evaluated at compile time.