I am having some trouble writing code for a car battery monitor, that controls a relay to switch to an alternate supply at a set voltage reading
const int referenceVolts = 5; // the default reference on a 5-volt board
const int R1 = 3900; // value for a maximum voltage of 18 volts
const int R2 = 1500;
// determine by voltage divider resistors
const int resistorFactor = 255 / (R2/(R1 + R2));
const int batteryPin = 0; // +V from battery is connected to analog pin 0
void setup()
{
Serial.begin(9600);
}
void loop()
{
int val = analogRead(batteryPin); // read the value from the sensor
float volts = (val / resistorFactor) * referenceVolts ; // calculate the ratio
Serial.print("2nd Battery Voltage: ");
Serial.println(volts); // print the value in volts
if (volts > 14.00) //if the volts are more than 14v
{
digitalWrite (8, HIGH); //turn on the relay to join batterys for charging
}
else
{
digitalWrite (8, LOW); //if they are less than 14v turn off relay to separate batterys
delay(3000);
}}
I have been testing with a 4.2v battery and a voltage divider of two 470ohm resistors after changing int r1 and r2 accordingly
but it`s outputting in the serial monitor a negative voltage of -4109 I was hoping for 4.2?
I have all grounds connected and the voltage divider to A0 through the resistor then +4.2v then through the other resistor to earth. Where am I going wrong?
Do you get what Delta & Mark are saying about integers? Integers are whole numbers or "counting numbers" (no decimals or fractions). If you do mathematical operations on integers in C/C++, by default, the result will be returned as an integer, including temporary/intermediate results like (1500/(3900+1500)).
Here's a simple solution... Most of those numbers/calculations are constants, so there's no need to make the Arduino re-calculate every time you run the program...
Please double-check my math, but with your voltage divider and the 5V reference, 14 V should give you an ADC reading of 796, and 1V should give you about 57. You can 'hard code' that constant into your sketch. If my math is correct, all your sketch has to do is divide your count by 57, and you have Volts! (as a truncated integer)
If you want your sketch to treat integers as-if they are floats and get the result as a float, here is a short tutorial about [u]typecasting[/u]. (Of course the actual value in the ADC register is always an integer.)
P.S.
If this is for a real battery charger and not just something you are playing with, I have a couple more suggestions:
You'll want to add some hysteresis. Something like this - If the voltage drops below 13.8V, turn the charger on. Leave the charger on 'till the voltage gets-up to 14.2V. Then shut it off, 'till it drops to 13.8 again. (Thermostats work this way.)
If you don't do that, you get "chatter" (a mechanical relay would make a "chattering" noise). Basically, the charge goes up to 14.0001V and the charger shuts-off. Then, a millisecond or so later the voltage drops to 13.9999V and it turns-on for a millisecond or so, and the cycle repeats... There is also noise in the ADC reading that can cause chatter.
Also, you don't really need a microcontroller to make one simple "decision" (is the voltage above or below a preset level?). An op-amp can be used as a [u]comparator[/u]. For hysteresis, you'll have to look-up how to use positive-feedback, or you can use two comparators and some simple logic circuitry (AND gates, OR gates, etc.).
Looks like I need to learn alot more first? I have only been doing this with no prior experience for a couple of months..
What the exact use of this sketch is to have a secondary battery in my van for powering other things whilst parked up with the engine off. Obviously then I want this battery isolated so as not to drain the main battery, then when the engine is started and the alternator is working, to switch a relay to reconnect the secondary battery for charging..