Hi,
I have a few things that I need help with. One of them is to make my code not read the internal 1.1v ref too often.
I have a series of five LEDs that show the battery level (My standalone Atmega328 is powered by a lipo battery).
The problem is that when the battery voltage hits the level between two of the LEDs, the two LEDs flicker on and off. Example: If the voltage is 3,4v (3400), the 20% (3000 to 3400) and 40% (3400 to 3600) LEDs flicker on and off one at the time. The voltage is not stable enough for this not to happen.
I would like to solve this by having my code not read the voltage level "all the time" but with a 1 minute interval.
Could someone please guide me on how to modify my code for this? Or if you have any other good solution?
(Note that I cant use long delays since I have a pushbutton that I use to jump from case to case)
Here is my code. I have shortend the code for this topic, so yes, I know parts of the code is missing:
// 1.1v Battery monitor START
long readVcc() {
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate AVcc in mV
return result;
}
void setup() {
Serial.begin(9600);
pinMode(B20, OUTPUT);
pinMode(B40, OUTPUT);
pinMode(B60, OUTPUT);
pinMode(B80, OUTPUT);
pinMode(B99, OUTPUT);
}
void loop() {
buttonPoll = analogRead(button) > 500 ? 1 : 0; //For using A7 as button input
if(buttonPoll == 1){
delay(30); //For debounce 30ms should be enough
unsigned long chrono = millis();
while (buttonPoll == 1)
buttonPoll = analogRead(button) > 500 ? 1 : 0;
if (millis()-chrono < 500) state = old + 1; //Short press under 0.5 second
else state = 0; //Long press is over 0.5 second
}
else {
delay(50);
}
long currentVoltage;
currentVoltage = readVcc();
// ----- SWITCH CASE ------
if (currentVoltage >= 3000) {
switch (state) {
case 0:
// Batterydisplay
if ((currentVoltage > 3200) && (currentVoltage < 3400)) {
digitalWrite(B20, HIGH);}
else {
digitalWrite(B20, LOW);}
if ((currentVoltage > 3400) && (currentVoltage < 3600)) {
digitalWrite(B40, HIGH);}
else {
digitalWrite(B40, LOW);}
if ((currentVoltage > 3600) && (currentVoltage < 3800)) {
digitalWrite(B60, HIGH);}
else {
digitalWrite(B60, LOW);}
if ((currentVoltage > 3800) && (currentVoltage < 4000)) {
digitalWrite(B80, HIGH);}
else {
digitalWrite(B80, LOW);}
if (currentVoltage > 4000) {
digitalWrite(B99, HIGH);}
else {
digitalWrite(B99, LOW);}
old = state;
break;
case 1:
//my code here
old = state;
break;
case 2:
//my code here
old = state;
break;
case 3:
//my code here
old = state;
break;
old = 1;
break;
} //Switch case
} //If voltage is over...
else { //For low battery, only use NL
digitalWrite(NL, HIGH);
digitalWrite(UV,LOW);
digitalWrite(LED13,LOW);
digitalWrite(X1A,LOW);
digitalWrite(X1B,LOW);
digitalWrite(X1C,LOW);
digitalWrite(B20,LOW);
digitalWrite(B40,LOW);
digitalWrite(B60,LOW);
digitalWrite(B80,LOW);
digitalWrite(B99,LOW);
digitalWrite(RED,LOW);
digitalWrite(GREEN,LOW);
digitalWrite(BLUE,LOW);
//Add code that makes LED B20 to blink slowly for 10 seconds
//old = 1;
}
delay(1); // delay in between reads for stability
}