Question About Voltage Divider

//variable int 'total' declared - pin not set input/output - not needed and has worked several times before: - Aref set to 1.099 - int 'voltage' declared:

void battery_sense() { // battery_sense()
total = 0; // Reset value
analogRead(17);
for (int x = 0; x < 16; x++) {
total = total + analogRead(17);
}
voltage = total * Aref / 1023;
//Serial.print("The battery is ");
//Serial.print(voltage);
//Serial.println(" volts");
delay(100);
Can you run this little experiment:

Use a 10K/10K or 1K/1K divider.

Take Arduino 5V on top and Arduino ground on the bottom and midpoint to A0 [NOTE, no aref connection] and run this code:

C:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(115200);
  pinMode(A0,INPUT);

}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1024.0);
  // print out the value you read:
  Serial.println(voltage);
  delay(1000);
}
See if you don't get ~ 2.5V in each case before pronouncing the UNO bricked.[/CODE]
 
//variable int 'total' declared - pin not set input/output - not needed and has worked several times before: - Aref set to 1.099 - int 'voltage' declared:

void battery_sense() { // battery_sense()
total = 0; // Reset value
analogRead(17);
for (int x = 0; x < 16; x++) {
total = total + analogRead(17);
}
voltage = total * Aref / 1023;
//Serial.print("The battery is ");
//Serial.print(voltage);
//Serial.println(" volts");
delay(100);
Can you post your entire code, or a test code that gives you the same bad results? [edit and what Arduino you are using]
I am not seeing AnalogReference() or how/why you are using aref.
 
Last edited:

Thread Starter

dandy1

Joined Sep 30, 2017
178
Does the compiler automatically configure I/Os according to the calls to use them? Though this is by no means inconceivable, "usually" it is necessary to explicitly configure I/Os that are not single function. While it can be tedious, I've often resorted to looking at an assembler listing from a compiler to determine what it actually does. This wouldn't be necessary if the documentation was good.

Though compilers refer to ports symbolically, remember that the registers associated with them, both for data and configuration, are just addresses somewhere in the processor's total address space. If you do something wrong anywhere in your program you can reconfigure a port without having had any intent to do that.

If you suspect a problem with configuration, don't connect I/O pins directly to 5 V. Usually it will cause no harm, but it is safer to use a series resistor of something around 5k to limit the current in case the pin is configured as an output and is set LOW. This also allows you to conveniently use a meter or oscilloscope to check the voltage on the pin.

It is common for microcontroller analog inputs to require quite low drive impedance to assure accuracy. Often this is because ADC inputs are "sampled" by charging a capacitor internal to the ADC. The results in a short duration but relatively high magnitude current "spike." If the source impedance is too high, the capacitor may not charge "fully" resulting in a reading that is incorrect. Often you can improve performance by adding a small capacitor (and you must be careful of the type used) from the input to ground, but only if the signal doesn't change rapidly. The cap acts as a charge reservoir so the impedance is very low for that transient spike. Usually this is detailed either in the datasheet or an ap note for the processor.
ebp - thanks for your input it may just be the fact that i have, somehow - managed to recofigure them without the slightest bit of understanding how i done so, being that pis 6 an7 are ok. where pins are declared they are done so like ''pinMode (X, OUTPUT)" but none of my analog inputs are declared in the setup as i just call the function 'analogRead (A0)' as needed - on a single function basis. So i never intentionally recofigure pins nor do i use code (because i am a novice) that would do this - if a pin is reconfigured i assume that it does this everytime code is uploaded. i've always wanted to understand the proper side of programing but thats a bridge way off in the distance- for now anyway.
at the very least the code worked before now with very little changes to values rather than variables or pin cofigs so im leaning on the side of a failed mcu.
 

Thread Starter

dandy1

Joined Sep 30, 2017
178
Can you post your entire code, or a test code that gives you the same bad results? [edit and what Arduino you are using]
I am not seeing AnalogReference() or how/why you are using aref.
will post the code....

float Aref = 1.099; // change this to the actual Aref voltage of ---YOUR--- Arduino, or adjust to get accurate voltage reading

yes that comes from another sketch which i referenced to build my code, being unsure (a novice) of how the programing works. I am yet to look into that and i understand that it is not needed here but i havnt got round to updating the code yet as it all works (or did) as it is. I am sorry if this has misleads the post but this effectivly can be ignored.
 

Thread Starter

dandy1

Joined Sep 30, 2017
178
CODE

SETUP ROUTINE(take NO notice of the comments)

#include <SoftwareSerial.h>
SoftwareSerial sim800(11, 10); // A0 = D14, A1 = D15
#define ONE_WIRE_BUS 18 // For temp sensor
//#include <Servo.h>
#include <OneWire.h>
#include <DallasTemperature.h>
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature.
//Servo myservo; // servo object to control the choke
//////////////////////////////////battery sense vars///////////////////////////////////////
float Aref = 1.099; // change this to the actual Aref voltage of ---YOUR--- Arduino, or adjust to get accurate voltage reading
unsigned int total; // A/D output
float voltage; //
/////////////////////////////////counter vars for engine control///////////////////////////
//unsigned long run_time; 7 // For auto timeout of engine
unsigned long start_time; // For auto timeout of starter
unsigned long time_checked; // Network check timer
long run_interval = 120000; // Shutdown time
/////////////////////////////////sim800 vars/////////////////////////////////////////////
int current_status;
boolean network_status;
int signal_level;
char network_name[9] = " "; // need to reserve a length, otherwise strange results
char c; // for decoding the sim reply
const int check_interval = 5000;
const int red = 13; //3
const int green = 12; //2
const int sim_rst = 2; //7
bool warmUp = 0;
//bool timeOut = 0;
//////////////////////////////////ignition and starter/////////////////////////////////
const int ign_ctrl = 3; //9
const int start_ctrl = 4; //10
const int choke_ctrl = 5;
///////////////////////////////////vars for hall sensor////////////////////////////////
int RPS;
int val;
//int srv;
int count = 1;
int pulsePin = 19;
//const int chokeClosed = 110;
//const int chokeOpen = 180;
///////////////////////////////////socket vars////////////////////////////////////////
bool socketState1 = 0;
bool socketState2 = 0;
bool socketState3 = 0;
bool socketState4 = 0;
const int socket1 = 8;
const int socket2 = 9;
const int socket3 = 14;
const int socket4 = 15;
/////////////////////////////current sensing//////////////////////////////////////////////
//const int mVperAmp = 166; // use 100 for 20A Module and 66 for 30A Module
//double Voltage = 0;
//double VRMS = 0;
//double AmpsRMS = 0;
int power = 0;
const float vcc = 4.85;// supply voltage 5V or 3.3V
const float factor = 0.04;// 20mV/A is the factor
float voltageForCurrent;
float ACvolts;
//#define VIN 20
//////////////////////////////////////////////////////////////////////////////////////////

void setup() {
pinMode (socket1, OUTPUT);
pinMode (socket2, OUTPUT);
pinMode (socket3, OUTPUT);
pinMode (socket4, OUTPUT);
analogReference(INTERNAL); // use the internal ~1.1volt reference
pinMode(green, OUTPUT); // green LED
pinMode(red, OUTPUT); // red LED
pinMode(ign_ctrl, OUTPUT); // blue LED
pinMode(start_ctrl, OUTPUT);
pinMode(choke_ctrl, OUTPUT);
pinMode(pulsePin, INPUT);
digitalWrite(socket1, LOW);
digitalWrite(socket1, LOW);
digitalWrite(socket3, LOW);
digitalWrite(socket4, LOW);
digitalWrite(green, HIGH); // 1x blink green and red LED
digitalWrite(red, HIGH);
delay(500);
digitalWrite(green, LOW);
digitalWrite(red, LOW);
digitalWrite(ign_ctrl, LOW); //Ignition off
digitalWrite(start_ctrl, LOW);
//digitalWrite(choke_ctrl, LOW); //starter off
pinMode(sim_rst, OUTPUT); // sim800 RESET pin
Serial.begin(9600);
sim800.begin(9600);
Serial.println();
sensors.begin();
if (!simOK()) {

dev();
}
}


AND THIS IS THE FUNCTION

void battery_sense() { // battery_sense()
total = 0; // Reset value
analogRead(17);
for (int x = 0; x < 16; x++) {
total = total + analogRead(17);
}
voltage = total * Aref / 1023;
//Serial.print("The battery is ");
//Serial.print(voltage);
//Serial.println(" volts");
delay(100);
v(16); // "BATTERY"
delay(1200);
if (voltage <= 11.5) {
v(17); // "WARNING"
delay(1200);
v(16); // "BATTERY"
delay(1200);
v(17); // "WARNING"
delay(1200);
Serial.println("BATTERY LOW!");
engine_off();
}
else {
int volt = voltage * 100;
int Fi = (volt / 1000) % 10;
v(Fi); delay(800); // "first digit"
int Se = (volt / 100) % 10;
v(Se); delay(800); // "second digit
v(18); delay(800); // "POINT"
int Th = (volt / 10) % 10;
v(Th); delay(800); // "Third digit"
int Fo = volt % 10;
v(Fo); delay(800); // "fourth digit"
v(19); delay(2000); // "VOLTS"
engine_start();
}
}
 
- if a pin is reconfigured i assume that it does this everytime code is uploaded..
No, just
will post the code....

float Aref = 1.099; // change this to the actual Aref voltage of ---YOUR--- Arduino, or adjust to get accurate voltage reading

yes that comes from another sketch which i referenced to build my code, being unsure (a novice) of how the programing works. I am yet to look into that and i understand that it is not needed here but i havnt got round to updating the code yet as it all works (or did) as it is. I am sorry if this has misleads the post but this effectivly can be ignored.
It can't be ignored if you are using the line (from your code fragment: voltage = total * Aref / 1023;
because voltage will alway be (total * 1.099 )/ 1023

change float Aref = 1.099; to float aref = 5.00
and voltage= total * (aref/1024) and see if it doesn't make more sense.

again assuming an arduino uno / no aref connection giving an internal reference of 5.0 V
edit: unless I am not reading correctly
 
Last edited:

Thread Starter

dandy1

Joined Sep 30, 2017
178
Can you run this little experiment:

Use a 10K/10K or 1K/1K divider.

Take Arduino 5V on top and Arduino ground on the bottom and midpoint to A0 [NOTE, no aref connection] and run this code:

C:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(115200);
  pinMode(A0,INPUT);

}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1024.0);
  // print out the value you read:
  Serial.println(voltage);
  delay(1000);
}
See if you don't get ~ 2.5V in each case before pronouncing the UNO bricked.[/CODE]
i would think that would achieve the same as post #16
 

Thread Starter

dandy1

Joined Sep 30, 2017
178
No, just


It can't be ignored if you are using the line (from your code fragment: voltage = total * Aref / 1023;
because voltage will alway be (total * 1.099 )/ 1023

change float Aref = 1.099; to float aref = 5.00
and voltage= total * (aref/1024) and see if it doesn't make more sense.

again assuming an arduino uno / no aref connection giving an internal reference of 5.0 V
edit: unless I am not reading correctly
OK - so the Aref actually requires connection physically?
(aref/1024) am i not already using the full scale?

will try...

EDIT.....

thank you ray, just realised ( and learned) how not to bang your head on a wall. That had been staring me in the face for months - yet its so simple! best thing is that somehow it actually worked!

but now itll work better...
 
Last edited:
see post #32
I am not saying that you should connect the aref pin. I am talking about the variable in your program Aref. For 0-5V you do not need to connect the aref pin and you do not want to exceed 5V on the aref pin.
 
Last edited:
Consider this:
C:
void battery_sense() { // battery_sense()
total = 0; // Reset value
analogRead(17);
for (int x = 0; x < 16; x++) {
total = total + analogRead(17);
}
voltage = total * Aref / 1023;
In my code, I used float voltage = sensorValue * (5.0 / 1024.0); to convert the analog reading to voltage and it assumes that the analog voltage in can vary from 0-5V.

If I take 16 samples of analogRead(A0) and each sample voltage if 2.5V, each analog reading (each sensor value) will be 511 or, if you like 512 with 1023 - let's not get into 1024 vs 1024 right now.

In your code, total will be 511*16 = 8176 - total = total + analogRead(17);
Your voltage will be (8176 * 1.099) / 1023 = ~8.78. voltage = total * Aref / 1023;
8.78/17=~.549 per sample

If you set aref to 5.0 look what happens
In your code, total will be 511*16 = 8176 - total = total + analogRead(17);
Your voltage will be (8176 * 5.0) / 1023 = ~39.96. voltage = total * 5.0 / 1023;
39.96/16=~2.5 V per sample
 
OK - so the Aref actually requires connection physically?
(aref/1024) am i not already using the full scale?

will try...

EDIT.....

thank you ray, just realised ( and learned) how not to bang your head on a wall. That had been staring me in the face for months - yet its so simple! best thing is that somehow it actually worked!

but now itll work better...
I am glad that you have it working, and I hope that you understand a bit more about the UNO ADC.

One caution though: You can't put more than 5V into an UNO analog input pin or you will fry it like the eggs I had for breakfast.

If you want to know a bit more about the vref pin and when you might want to use that you can look at this thread https://forum.allaboutcircuits.com/...-understanding-input-signal-impedance.139010/ and particular the posts between @KeepItSimpleStupid and myself. Additionally, there are other arduino commands that need to be used be used when you use the aref pin.
 
A couple of things.

1. Connecting Vref to Vdd=5 V is NOT the same as connecting it to a 5.000 V reference. When sensors are connected to Vdd they are Ratiometric. If Vdd varies to 4.8=5.1 V or whatever, the answer will be the same if the sensor is ratiometric. Automotive sensors are usually ratiometric. They also usually don't measure ground or Vdd, but 10's of mV away from the rails. Many times the reference 1/2 the supply and again ratiometric.

2. Say you had a 3-but A/D converter and each bit is 1V and unipolar, so values of 01b, 01b and 11b. It can represent 0-3V.
Vin = bits*(3 v FS / 3 bits). You don't divide by 4 (a power of 2). Bipolar is a little stranger because for a 16 bit converter, the range is -32768 to 32767 decimal.
The max positive value for a 16 bot converter is (2^15)-1 where 15=(16 bit unipolar converter)-1
 

Thread Starter

dandy1

Joined Sep 30, 2017
178
I am glad that you have it working, and I hope that you understand a bit more about the UNO ADC.

One caution though: You can't put more than 5V into an UNO analog input pin or you will fry it like the eggs I had for breakfast.

If you want to know a bit more about the vref pin and when you might want to use that you can look at this thread https://forum.allaboutcircuits.com/...-understanding-input-signal-impedance.139010/ and particular the posts between @KeepItSimpleStupid and myself. Additionally, there are other arduino commands that need to be used be used when you use the aref pin.
thanks for the advice and the links - will definatley read up on that.
 
Top