I'm having a problem with my current program and i have no idea what to look for because ta simple long math is failing:
letme start by doing a quick review of the current state, i'm using the serial monitor and all "debug" lines for debugging.
Program reads SLO pin, i'm gonna start with SLO in high that is the "relaxed" state.
Serial monitor in this case prints:
la diferencia actual es: 23
la diferencia actual es: 1051
la diferencia actual es: 2081
la diferencia actual es: 3111
la diferencia actual es: 4142
la diferencia actual es: 5172
la diferencia actual es: 6202
which is the result of Serial.println((long)( millis() - fin_retardo )); //debug
so far so good because we load 0 in fin_retardo so millis()-0 = millis() and the program shows us how millis advances with a 1s delay...
now i switch SLO to LOW and this is where everything fails....
Serial monitor shows:
el fin del delay es: 1213392
13392
la diferencia actual es: 13455
contando
Testeando! loop: 0
Now here's the problem, the first IF is executing correctly if ((slo_state == LOW) && (contando == false)){ because contando is false and slo has been asserted low.
so program puts current millis() value in currenttime variable, then in the fin_retardo variable puts the currenttime+delta(which is 1200000) and sets the contando flag to true.
Then Prints the fin_retardo variable(1213392), in the next line the currenttime(13455)
This is where it goes wrong: the result of the operation (long)( millis() - fin_retardo) should be a negative number as fin_retardo is larger!, why is this failing?, yesterday i got this same program working and the only difference was that i declared the constant values at the beginning today and yesterday i was hardcoding them in the line itself...
thus since the result is a positive number, the second IF block if ((contando == true) && ((long)( millis() - fin_retardo ) >= 0)) is evaluated (falsely) true and program continues...
this is the code(sorry for the anotations in spanish, i think it's still understandable):
/*
Sketch cargador UC3906 en Arduino 0022
Chequea que la bateria este a flote, 2 semanas despues inicia el test de carga
activando un rele que desactiva el UC3906 y al mismo tiempo conecta la bateria a la resistencia de carga por
4 intervalos de 15 min con 15 min de descanso para enfriar las resistencias,
Luego reconecta el cargador y sigue el ciclo.
circuito:
El flote se señaliza por las señales colector abierto del UC3906:
State Level Output a traves del operacional TL081: 0 en Float, 1 Cargando
OC Indicate output: 0 si esta en overcharge, 1 puede que sea float o charge
* se puede monitorear Vbatt con un divisor de 36K y 18K o de 100K y 50K
* en paralelo a la salida de rele conectar el LED de monitoreo de test
pines:
Pin 2 - input: Reset (interrupt 0)
Pin 3 - input: SLO
Pin 4 - output LED: Cargando
Pin 5 - output: Rele
*/
// Constantes globales y definicion pines
const byte SLO = 3;
const byte ledcharge = 4;
const byte rele = 5;
const byte reset = 2;
const long tiempo_en_prueba = 300000; //15 min tiempo en prueba 900Kmsec, usar 300K para 5 min
const int tiempo_fraccion = tiempo_en_prueba/1000; //Para fraccionar los delays largos en el ejercicio
const unsigned long tiempo_para_ejercitar = 1200000; //20min hasta testear, en realidad tiene que ser 1209600000(2 semanas)
unsigned long fin_retardo = 0; //inicializo fin delay
boolean contando = false; //inicializo sin contar
volatile boolean reset_flag = false; //no esta reseteado
byte slo_state;
void setup(){
pinMode(SLO, INPUT);
pinMode(rele, OUTPUT);
pinMode(ledcharge, OUTPUT);
Serial.begin(9600);
attachInterrupt(0, reset_event, RISING);
}
void loop(){
posicion_inicio:
if (reset_flag == true){
fin_retardo = 0; //inicializo vars
contando = false;
digitalWrite (rele, HIGH); //activar rele
digitalWrite (13, HIGH); // debug
digitalWrite(ledcharge,LOW);
Serial.println("Reset!!!!!!"); //debug
delay(4000);
digitalWrite (rele, LOW); //desactivar rele
digitalWrite (13, LOW); //debug
}
slo_state = digitalRead (SLO); //leer pin SLO, recordar que esta negado
if ((slo_state == LOW) && (contando == false)){ //esta en float, no estoy testeando carga y aún no estoy contando para testear
unsigned long currenttime = millis();
unsigned long fin_retardo = currenttime + tiempo_para_ejercitar; // fin retardo, tiempo actual+diff tiempo hasta ejercitar
Serial.print("el fin del delay es: "); //debug
Serial.println(fin_retardo); //debug
Serial.println(currenttime); //debug
contando = true; //Empieza el conteo regresivo a la ejercitacion
}
else if (slo_state == HIGH && contando == true){
contando = false; //Si mientras cuento se va de flote, abortar cuenta
}
if (slo_state == HIGH) { // si no esta a flote, encender led de carga
digitalWrite(ledcharge,HIGH);
}
else digitalWrite(ledcharge,LOW); // si esta a flote, apagarlo
Serial.print("la diferencia actual es: "); //debug
Serial.println((long)( millis() - fin_retardo )); //debug
if (contando == true) Serial.println("contando"); //debug
delay(1000); //debug
if ((contando == true) && ((long)( millis() - fin_retardo ) >= 0)){ //Si termino la cuenta regresiva empezar a ejercitar
contando = false; //termino la cuenta regresiva
for(int l = 0; l < 4; l++){ // 4 loops de ejercitacion(0 a 3)
if (reset_flag == true) goto posicion_inicio; //abortar si reset
digitalWrite (rele, HIGH); //activar rele
digitalWrite (13, HIGH); // debug
Serial.print("Testeando! loop: "); //debug
Serial.println(l); //debug
//comienzo delay sintetizado
for (int i = 0; i < 1000; i++) {
delay (tiempo_fraccion);
if (reset_flag == true) goto posicion_inicio; //abortar si reset
} //fin delay sintetizado
digitalWrite (rele, LOW); //desactivar rele
digitalWrite (13, LOW); //debug
Serial.println("Descansando!"); //debug
//comienzo delay sintetizado
for (int i = 0; i < 1000; i++) {
delay (tiempo_fraccion);
if (reset_flag == true) goto posicion_inicio; //abortar si reset
} //fin delay sintetizado
} //fin loop ejercitacion
}
}
void reset_event(){
reset_flag = true; //set reset
}