Hello, i'm a new member and glad to be here.
Well, i'm trying to create an alert on my mega 2560 when my 12V battery does not supply enough current on my mega.
I thought it was possible to use the analogic A0 pin with a condition when the tension is under 4.5V the A3 led is high but it does not work.
Here's the small code i use
//mesure de tension
unsigned int mesure; //resultat de la conversion CAN sur 10 bits
float tension;
const int seuil = 4.5;
void setup () {
pinMode(A3, OUTPUT);
//initialisation serial
Serial.begin (9600);
}
void loop (){
mesure = analogRead(A0);
delay (1000);
tension = mesure * 5 / 1023;
if(tension < seuil)
{
digitalWrite(A3, HIGH);
}
else {
digitalWrite(A3, LOW);
}
Serial.println (tension);
delay (1000);
}
I thought maybe the mega becomes unstable under 5V and that is why it does not execute the program...Any suggestions ?
Never connect any pin of anything to a voltage greater than the supply voltage. This means that if you connect input A3 to 12V you are overloading it and likely to destroy it.
The analogue input only measures voltages with reference to the supply voltage which is 5V. So if you connect A3 to the pin 5V it will always read 1023 even when the signal from the 5V pin drops below 5V.
Thank you Grimpy_Nike for your answer.
I'm not supplying directly the mega with 12 volts, I use a 7808 Regulator to lower the tension to 8 volts connected to the jack.
The A0 is then supplied by a maximum of 5 volts.
Ok for pin A3 with a led which alway reads 1023.
Ok for your link but what kind of function instead of analogread can I use to read correctly the tension ?
Koal01
Here is a description of what I need. I have a program running on the mega which controls 2 motors driving a telescope. The mega and motors are supplied by a 12 v battery and I'd like to be aware when the battery tension begins to drop. I thought it could be interesting to make a led blinking when the tension is around 11 volts and the led becomes fix when it's below 11 volts.
What do I need to install this ?
Thanks
That is a very different prospect to what you asked in the first post.
All you want to monitor is the 12V battery. The reference voltage is regulated after this battery so you can just measure the 12V. As you can't put more than 5V into an analogue input you have to feed it into the Arduino through a potential divider.
So put a 10K resistor from the analogue input to ground. Then connect a 20K resistor to the same analogue input and connect the other end to your battery. Then a reading of 1023 corresponds to 15V, so you can read the battery voltage.
Never connect the analogue input to anything without powering up the Arduino, so make sure this can't happen.
Great, thank you Grumpy_Mike.
I first thought it was easily possible to measure a drop in tension in the 5V circuit of the arduino when the battery is getting empty and after several posts my prospects have changed...
Your wiring with 10k and 20k resistor to the analogue input is very interesting.
I don't understand this line :
Grumpy_Mike:
Never connect the analogue input to anything without powering up the Arduino, so make sure this can't happen.
You could get the voltage from the VIN pin to feed your voltage divider but it would be 0.6 volts lower because of the blocking diode, 8V on the jack would show 7.4V on VIN, using a 10k:6.8k divider would make it 3V.
Never mind, when the batt voltage fell below the 7808's drop out voltage it would just bottom out. :-[
I'm going to bed!
Grumpy_Mike, i don't intend to connect anything on A0, this pin will only be used to read the tension of the 12 volts battery with the wiring you suggested, the led will be installed on A3, is it safe like this ?
i don't intend to connect anything on A0, this pin will only be used to read the tension of the 12 volts battery with the wiring you suggested,
So you intend to connect it to 12V, that is not nothing. What I mean is do not connect it to the 12V and disconnect the power in any way to the Arduino, like disconnecting the 7808, so that the 12V is still getting into the Arduino BUT the 5V is not getting to the Arduino chip.
I'd like to measure a drop of in a safer way, it was my first idea. I noticed that when the 12v battery begins to drop, the Arduino has only 4.7, 4.6 volts, etc and the tension continues to fall. I just want to install an alarm with an approximative value to inform me that I have to prepare a new battery. I don't need precision in measures but just an empiric status, just a led lighting. If I could measure the drop just under the 5volts circuit without creating risks for the Arduino I would certainly prefer.
Sorry, I'm trying to be as clear as possible.
Koal01
So if i sum up...hoping that i won't say big errors.
I want to be alerted when my 12 v battery is lowering with a led lighting
I don't want to take risk of wiring 12 v to the mega to measure this drop
I'll use the Aref pin with the internal 2.56 or 1.1 volt reference.
I have 2 questions:
1 -Do you think that this example could fit ?
int inpin = 0;
int val = 0;
void setup() {
// set the analog reference as built-in 2.56Volts
analogReference(INTERNAL2V56);
Serial.begin(9600);
}
void loop() {
val = analogRead(inpin); // read the value of analog pin 0
Serial.println(val); // write the value to the serial port
}
2- Will i have to divide with resistors with the Aref pin in the middle ? if yes could you help me which resistor i need for 1.1 volt and 2.56 ?
If you have connected the analogue pin 0 to the 5V line and you have chosen the internal reference then no matter what the voltage is you will always read 1023.
Will i have to divide with resistors with the Aref pin in the middle ?
Thank you Grumpy_Mike, do you mean that the sketch from "Coding Badly" and "Leftly" can work without any wiring ???
// Function created to obtain chip's actual Vcc voltage value, using internal bandgap reference
// This demonstrates ability to read processors Vcc voltage and the ability to maintain A/D calibration with changing Vcc
// Now works for 168/328 and mega boards.
// Thanks to "Coding Badly" for direct register control for A/D mux
// 1/9/10 "retrolefty"
int battVolts; // made global for wider avaliblity throughout a sketch if needed, example a low voltage alarm, etc
void loop(void)
{
battVolts=getBandgap(); //Determins what actual Vcc is, (X 100), based on known bandgap voltage
Serial.print("Battery Vcc volts = ");
Serial.println(battVolts);
Serial.print("Analog pin 0 voltage = ");
Serial.println(map(analogRead(0), 0, 1023, 0, battVolts));
Serial.println();
delay(1000);
}
int getBandgap(void) // Returns actual value of Vcc (x 100)
{
#if defined(AVR_ATmega1280) || defined(AVR_ATmega2560)
// For mega boards
const long InternalReferenceVoltage = 1115L; // Adjust this value to your boards specific internal BG voltage x1000
// REFS1 REFS0 --> 0 1, AVcc internal ref. -Selects AVcc reference
// MUX4 MUX3 MUX2 MUX1 MUX0 --> 11110 1.1V (VBG) -Selects channel 30, bandgap voltage, to measure
ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR)| (0<<MUX5) | (1<<MUX4) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
#else
// For 168/328 boards
const long InternalReferenceVoltage = 1056L; // Adjust this value to your boards specific internal BG voltage x1000
// REFS1 REFS0 --> 0 1, AVcc internal ref. -Selects AVcc external reference
// MUX3 MUX2 MUX1 MUX0 --> 1110 1.1V (VBG) -Selects channel 14, bandgap voltage, to measure
ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
#endif
delay(50); // Let mux settle a little to get a more stable A/D conversion
// Start a conversion
ADCSRA |= _BV( ADSC );
// Wait for it to complete
while( ( (ADCSRA & (1<<ADSC)) != 0 ) );
// Scale the value
int results = (((InternalReferenceVoltage * 1023L) / ADC) + 5L) / 10L; // calculates for straight line value
return results;
Sorry for the bad tags...
Here's some change i introduced to adapt this code for a mega card and led actions, Arduino software is not installed on the computer i'm using so sorry for any basic errors :
// Function created to obtain chip's actual Vcc voltage value, using internal bandgap reference
// This demonstrates ability to read processors Vcc voltage and the ability to maintain A/D calibration with changing Vcc
// Now works for 168/328 and mega boards.
// Thanks to "Coding Badly" for direct register control for A/D mux
// 1/9/10 "retrolefty"
int battVolts; // made global for wider avaliblity throughout a sketch if needed, example a low voltage alarm, etc
pinmode(A3, OUTPUT);
void setup(void)
{
Serial.begin(38400);
Serial.print("volts X 100");
Serial.println( "\r\n\r\n" );
delay(100);
}
void loop(void)
{
battVolts=getBandgap(); //Determins what actual Vcc is, (X 100), based on known bandgap voltage
Serial.print("Battery Vcc volts = ");
Serial.println(battVolts);
Serial.print("Analog pin 0 voltage = ");
Serial.println(map(analogRead(0), 0, 1023, 0, battVolts));
Serial.println();
delay(1000);
if (battVolts < 4.6)
{
digitalWrite (A3, HIGH);
}
else
{
digitalWrite (A3, LOW);
}
}
int getBandgap(void) // Returns actual value of Vcc (x 100)
{
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
// For mega boards
const long InternalReferenceVoltage = 1115L; // Adjust this value to your boards specific internal BG voltage x1000
// REFS1 REFS0 --> 0 1, AVcc internal ref. -Selects AVcc reference
// MUX4 MUX3 MUX2 MUX1 MUX0 --> 11110 1.1V (VBG) -Selects channel 30, bandgap voltage, to measure
ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR)| (0<<MUX5) | (1<<MUX4) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
#endif
delay(50); // Let mux settle a little to get a more stable A/D conversion
// Start a conversion
ADCSRA |= _BV( ADSC );
// Wait for it to complete
while( ( (ADCSRA & (1<<ADSC)) != 0 ) );
// Scale the value
int results = (((InternalReferenceVoltage * 1023L) / ADC) + 5L) / 10L; // calculates for straight line value
return results;
}