voltage divider and running other circuits causes different voltage readings

Hello.

I have two simple circuits made up on a breadboard using my Arduino UNO.

I have one circuit with two push buttons, setup to switch a relay on and off. Either button turns the relay off/on depending what it already is. This works great.

My other circuit is made up using a simple voltage divider of 10kΩ and 20kΩ which allows me to read my vehicle voltage safely up to 15v.

The issue I have is when I'm presenting an external 12v to the voltage divider, if the relay circuit is turned off I get 12.9v, and if I turn the relay on, I get 12.5v.

My guess is that the internal reference voltage of 5v is fluctuating because of the relay circuit, but I have no idea why, or if this is normal, or what I can do to isolate each part of the project. I intended on adding 3 more relay circuits too so without testing further I'm guessing these will have more of an impact on the readings?

Maybe you could try connecting the Aref pin to the 3.3V pin. This one has a second voltage regulator, so it won't be influenced by the 5V circuit.
Change your resistor ratio, and add this line to your setup:

analogReference(EXTERNAL);

My maths isn't the best, I've been using this as a reference - http://cdn.instructables.com/FZJ/N71F/I7W1X2XO/FZJN71FI7W1X2XO.LARGE.jpg

Would a ratio of 10kΩ and 40kΩ be what I need based on 3v?

15V with a voltage divider of 39K and 10K will give you 3.06V, so that's alright.

The formula is easy to remember: V1/Vtot = R1/Rtot, where V1 is the voltage across R1
In other words, V1 = Vtot × R1 / (R1+R2)

A straight connection between Aref and 3.3volt could be unhealthy for the Aref pin if you forget to set Aref to EXTERNAL. See the Aref page in learning>reference.
Better drop the battery voltage to ~1volt, and use Arduino's inbuild 1.1volt bandgap reference.

Forget about Instructables, unless you know exactly what you're doing.
A zener diode is is useless.
It won't protect the analogue pin when the Arduino is off, and it could introduce errors.

I assume you're using a proper relay driver, and a kickback diode across the relay.

I've attached example code that uses the internal 1.1volt Aref, and averaging.
The analogue pin stays under 5volt with input voltages up to ~75volt if you use the resistor values from the sketch.
Leo..

/*
  0 - ~16volt voltmeter for 3.3volt and 5volt Arduinos
  uses the stable internal 1.1volt reference
  6k8 resistor from A0 to ground, and 100k resistor from A0 to +batt
  100n capacitor from A0 to ground for stable readings
  (100k + 6k8) / 6k8 = 15.70588 | used in formula
*/
float Aref = 1.075; // ***calibrate here*** | change this to the actual Aref voltage of ---YOUR--- Arduino
unsigned int total; // can hold max 64 readings
float voltage; // converted to volt

void setup() {
  analogReference(INTERNAL); // use the internal ~1.1volt reference  | change (INTERNAL) to (INTERNAL1V1) for a Mega
  Serial.begin(9600); // set serial monitor to this value
}

void loop() {
  for (int x = 0; x < 64; x++) { // multiple analogue readings for averaging
    total = total + analogRead(A0); // add each value to a total
  }
  voltage = (total / 64) * 15.70588 * Aref / 1024 ; // convert readings to volt
  // print to serial monitor
  if (total == (1023 * 64)) { // if overflow
    Serial.print("voltage too high");
  }
  else {
    Serial.print("The battery is ");
    Serial.print(voltage);
    Serial.println(" volt");
  }
  total = 0; // reset value
  delay(1000); // one second between measurements
}

Hi,
Welcome to the Forum

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

How are you powering and driving your relays?

Thanks.. Tom... :slight_smile:

Thanks for your help all. Here's what I have so far:

And here's my code:

/*
 Debounce

 Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
 press), the output pin is toggled from LOW to HIGH or HIGH to LOW.  There's
 a minimum delay between toggles to debounce the circuit (i.e. to ignore
 noise).

 The circuit:
 * LED attached from pin 13 to ground
 * pushbutton attached from pin 2 to +5V
 * 10K resistor attached from pin 2 to ground
*/

// constants won't change. They're used here to
// set pin numbers:
const int button1Pin = 2;    // the number of the pushbutton pin
const int button2Pin = 3;   
const int ledPin = 12;      // the number of the LED pin

// Variables will change:
int ledState = HIGH;         // the current state of the output pin
int button1State;             // the current reading from the input pin
int button2State;   
int lastButton1State = LOW;   // the previous reading from the input pin
int lastButton2State = LOW;

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can't be stored in an int.
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers

float AnalogWert;
float Powerwert;
long lastVoltageReadTime = 0; 
long lastVoltageReadDelay = 1000;  

void setup() {
  Serial.begin(9600); 
  pinMode(button1Pin, INPUT);
  pinMode(button2Pin, INPUT);
  pinMode(ledPin, OUTPUT);

  // set initial LED state
  digitalWrite(ledPin, ledState);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading1 = digitalRead(button1Pin);
  int reading2 = digitalRead(button2Pin);
  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH),  and you've waited
  // long enough since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading1 != lastButton1State || reading2 != lastButton2State) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:
    // if the button state has changed:
    if (reading1 != button1State || reading2 != button2State) {
      button1State = reading1;
      button2State = reading2;
      // only toggle the LED if the new button state is HIGH
      if (button1State == HIGH || button2State == HIGH) {
        ledState = !ledState;
 if(ledState == HIGH){
  Serial.println("Relay OFF");
 } else {
  Serial.println("Relay ON") ;
 }
      }
    }
  }

  // set the LED:
  digitalWrite(ledPin, ledState);

  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastButton1State = reading1;
  lastButton2State = reading2;

   if ((millis() - lastVoltageReadTime) > lastVoltageReadDelay) {
    lastVoltageReadTime = millis();
    AnalogWert = analogRead(A0);
    Powerwert = AnalogWert *(15.0/1023); //in case of higher voltage, change the code: powerwert = AnalogWert *(x/1023); x= your new power supply maximum voltage
    Serial.println(Powerwert);
  }
}

You are using a 10R and a 20K resistor for your voltage divider. This is incorrect, take a look at Wawa's code: use 6.8K and 100K respectively. And you didn't use "analogReference(INTERNAL);" in your setup.

Also, you are using external pull-down resistors for your buttons, that's completely unnecessary: all Arduino's have built-in pull-up resistors. Read more on how to take input from a button here.

PieterP:
You are using a 10R and a 20K resistor for your voltage divider. This is incorrect, take a look at Wawa's code: use 6.8K and 100K respectively. And you didn't use "analogReference(INTERNAL);" in your setup.

Also, you are using external pull-down resistors for your buttons, that's completely unnecessary: all Arduino's have built-in pull-up resistors. Read more on how to take input from a button here.

Sorry, that's what I have before going through all your feedback so I haven't made any changes yet, it's what I have as of my first post.

I didn't realise they had built in pull up resistors so that's very useful to know. I got that one from one of the arduino beginner tutorials but I can't find the link now unfortunately.

I'm hoping to have some time to go through all your feedback tomorrow and rebuild my circuit and code.

As you can tell, you're dealing with a complete beginner here. I really appreciate the help