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:
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
}
/*
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