[SOLUCIONADO] El Loop no lee lineas anteriores después de quitar tensión

Saludos cordiales a la comunidad, tengo un problema de novato y solicito ayuda, gracias.

He buscado por la web y no he encontrado solución.

Utilizo Arduino uno, pero no el controlador entero, solo el AtMega328p_pu en una board el cual para re-programar desmonto, programo y monto (lo se, es mi primer proyecto). Esto es así porque ya esta instalado en el acuario con su caja de conexiones y demás.

Mi proyecto trata de controlar de un acuario, su iluminación a modo de amanecer, atardecer y anochecer, el paro marcha del filtro y del aireador (burbujitas), todo por control horario (recuerda).

De momento comentar que el código funciona bien (tengo problemas de armónicos pero eso es otro cantar), hace su función bien de momento.

El kit de la cuestión:

Como aun voy re-programando para ajustar valores de luces y tiempos me pasa que, al quitar el micro-controlador a mitad de programa, cuando lo pongo no recuerda donde estaba y se espera a la siguiente instrucción o sea a la próxima hora programada para ejecutar la instrucción pertinente.

Pregunta:

Se que es un LOOP y que es un bucle pero, esto se puede remediar de alguna manera?
Puedo poner y que recuerde lo que ha hecho y continúe?

Bueno os dejo el código para que veáis el tema:

#include <Wire.h>                   //Del IDE.
#include <RTClib.h>                 //Del IDE.
#include <LiquidCrystal_I2C.h>      //De: https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads/
#include <Adafruit_NeoPixel.h>      //Del IDE.



RTC_DS1307 rtc;
LiquidCrystal_I2C lcd (0x26, 2, 1, 0, 4, 5, 6, 7);
Adafruit_NeoPixel tira = Adafruit_NeoPixel(8, 2, NEO_GRB + NEO_KHZ800);
String daysOfTheWeek[7] = {"Dom", "Lun", "Mar", "Mie", "Jue", "Vie", "Sab"};

int rele1 = 3;  //FILTRO.
int rele2 = 4;  //BURBUJAS.



void setup() {
  lcd.setBacklightPin(3, POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.begin(16, 2);
  tira.begin();
  tira.show();
  pinMode(rele1, OUTPUT); 
  pinMode(rele2, OUTPUT);
  if (! rtc.begin()) {
    lcd.println("Modulo RTC no encontrado !");
    while (1);
  }
        
}   




void loop() {
   char buffer[20];   
   tira.show();


  DateTime fecha = rtc.now();

  lcd.setCursor(0,0);
  lcd.print(daysOfTheWeek[fecha.dayOfTheWeek()]);
  lcd.setCursor(5, 0);
  sprintf (buffer, "%02d/%02d/%4d", fecha.day(), fecha.month(), fecha.year());
  lcd.print(buffer);
  lcd.setCursor(5,1);  
  sprintf(buffer, "%02d:%02d:%02d", fecha.hour(), fecha.minute(), fecha.second());
  lcd.print(buffer);

  

    //Burbujas ON 7:50h
  if (fecha.hour() == 7 && fecha.minute() == 50){
    digitalWrite(rele2, HIGH);
  } 
    
    //Filtro ON 7:55h
  if (fecha.hour() == 7 && fecha.minute() == 55){
    digitalWrite(rele1, HIGH);
  } 
    
    //Filtro off 17:44h
  if (fecha.hour() == 17 && fecha.minute() == 44){
    digitalWrite(rele1, LOW);
  }
    
    //Burbujas off 23:30h
  if (fecha.hour() == 23 && fecha.minute() == 30){
    digitalWrite(rele2, LOW);
  }

    


    //Amanece 8:00h
  if (fecha.hour() == 8 && fecha.minute() == 0){
    for (int i = 0; i < 2; i++) {
      tira.setBrightness(25);
      tira.setPixelColor(i, 255, 150, 0);        
      tira.show();
    }
  }
  
    //Amanece 8:30h
  if (fecha.hour() == 8 && fecha.minute() == 30){
    for (int i = 0; i < 4; i++) {
      tira.setBrightness(50);
      tira.setPixelColor(i, 255, 150, 0);        
      tira.show();
    }
  }

    //Amanece 9:00h
  if (fecha.hour() == 9 && fecha.minute() == 0){
    for (int i = 0; i < 6; i++) {
      tira.setBrightness(75);
      tira.setPixelColor(i, 255, 150, 0);        
      tira.show();
    }
  }

    //Amanece 9:30h
  if (fecha.hour() == 9 && fecha.minute() == 30){
    for (int i = 0; i < 8; i++) {
      tira.setBrightness(100);
      tira.setPixelColor(i, 255, 150, 0);        
      tira.show();
    }
  }

    //Medio día 10:00h
  if (fecha.hour() == 10 && fecha.minute() == 0){
    for (int i = 0; i < 2; i++) {
      tira.setBrightness(125);
      tira.setPixelColor(i, 255, 255, 255);        
      tira.show();
    }
  }

    //Medio día 10:30h
  if (fecha.hour() == 10 && fecha.minute() == 30){
    for (int i = 0; i < 4; i++) {
      tira.setBrightness(150);
      tira.setPixelColor(i, 255, 255, 255);        
      tira.show();
    }
  }
   
    //Medio día 11:00h
  if (fecha.hour() == 11 && fecha.minute() == 0){
    for (int i = 0; i < 6; i++) {
      tira.setBrightness(175);
      tira.setPixelColor(i, 255, 255, 255);        
      tira.show();
    }
  }

    //Medio día 11:30h
  if (fecha.hour() == 11 && fecha.minute() == 30){
    for (int i = 0; i < 8; i++) {
      tira.setBrightness(200);
      tira.setPixelColor(i, 255, 255, 255);        
      tira.show();
    }
  }    

    //Medio día 12:00h    
  if (fecha.hour() == 12 && fecha.minute() == 0){
    for (int i = 0; i < 8; i++) {
      tira.setBrightness(255);
      tira.setPixelColor(i, 255, 255, 255);
      tira.show();
    }
  }



    //Atardecer 17:45h                                     
  if (fecha.hour() == 17 && fecha.minute() == 45){
    tira.setBrightness(255);
    tira.setPixelColor(0, 255, 255, 255);
    tira.show();
  }

  if (fecha.hour() == 18 && fecha.minute() == 0){
    tira.setBrightness(255);
    tira.setPixelColor(1, 0, 0, 255);
    tira.show();
  }

  if (fecha.hour() == 18 && fecha.minute() == 15){
    tira.setBrightness(255);
    tira.setPixelColor(2, 0, 0, 255); 
    tira.show();
  }

  if (fecha.hour() == 18 && fecha.minute() == 30){
    tira.setBrightness(255);
    tira.setPixelColor(3, 0, 0, 255);
    tira.show();
  }

  if (fecha.hour() == 18 && fecha.minute() == 45){
    tira.setBrightness(255);
    tira.setPixelColor(4, 0, 0, 255);  
    tira.show();
  }

  if (fecha.hour() == 19 && fecha.minute() == 0){
    tira.setBrightness(255);
    tira.setPixelColor(5, 0, 0, 255);
    tira.show();
  }

  if (fecha.hour() == 19 && fecha.minute() == 15){
   tira.setBrightness(255);
   tira.setPixelColor(6, 0, 0, 255);
   tira.show();
  }

  if (fecha.hour() == 19 && fecha.minute() == 30){
   tira.setBrightness(255);
   tira.setPixelColor(7, 255, 255, 255);
   tira.show();
  }



    //Apagado 22:00h
  if (fecha.hour() == 22 && fecha.minute() == 0){
    for (int i = 0; i < 2; i++) {
      tira.setBrightness(128);
      tira.setPixelColor(i, 0, 0, 0);
      tira.show();
    }
  }
  
    //Apagado 22:30h
  if (fecha.hour() == 22 && fecha.minute() == 30){
    for (int i = 0; i < 4; i++) {
      tira.setBrightness(85);
      tira.setPixelColor(i, 0, 0, 0);
      tira.show();
    }
  }

   //Apagado 23:00h
  if (fecha.hour() == 23 && fecha.minute() == 0){
    for (int i = 0; i < 6; i++) {
      tira.setBrightness(42);
      tira.setPixelColor(i, 0, 0, 0);
      tira.show();
    }
  }
  
   //Apagado 23:30h
  if (fecha.hour() == 23 && fecha.minute() == 30){ 
    tira.clear(); 
  } 
}

Gracias de nuevo y saludos.

El problema es que tu codigo solo inicia la secuencia cuando es justo el minuto concreto de inicio y si reinicias fuera de ese minuto ya no funciona,y aqui tienes otro fallo porque ,por ejemplo esto:

if (fecha.hour() == 8 && fecha.minute() == 30){

se cumple mientras el minuto sea 30 o sea si el loop se repite ,por poner un ejemplo 10 veces por segundo,60 segundos * 10 = 600 veces hasta que cambia el minuto.Una posible solucion que implica cambiar bastantes cosas,seria por ejemplo que el inicio de una secuencia no sea justo en una hora y minuto determinado ,si no entre una franja horaria: si hora esta entre 8.30 y 9:00 e implementar una variable booleana que indique cuando se esta dentro de un franja ,para no repetir las acciones durante la duracion de la franja horaria.

Convierte la hora actual a minutos y en el condicional comparas en el rango que lo quieres activo.

if (horaenminutos >= 510 && horaenminutos <=  720)

Gracias por responder, vais a ver lo novato que soy:

es posible que me estéis diciendo los dos lo mismo??

lo podría poner de manera que (según los entiendo) si una orden empieza a las 8:30h y la siguiente a las 9 la de las 8:30 decirle que sea de 8:30 a 8:59?

es mas o menos lo que me decís??

es que @Jose cuando me hablas de booleana en mi cerebro empieza a nevar o a dar palmas un mono, disculpadme, de verdad.

Esto va por ti también @krnlpanic, es lo que me comentas en tu ejemplo??

Gracias a los dos

Mas o menos es lo mismo, pero si no lo conviertes a minutos no te va a funcionar como quieres.
Si pusieras como ejemplo que sea a partir de la 8 horas y 30 minutos, a las 9 dejaría de cumplirse por no superar los 30 minutos.

vale voy a intentar hacer algo, pero, sería mucho pedir que me pusierais un ejemplo??

Gracias

@jose

o sea que empieze a la hora y minuto que sea y durante "x" tiempo??

krnlpanic:
Convierte la hora actual a minutos y en el condicional comparas en el rango que lo quieres activo.

if (horaenminutos >= 510 && horaenminutos <=  720)

He probado pero no se hacer el comando.

Lo siento es que tengo que entender cono se hace para poder hacerlo y solo conozco lo que hay en mi codigo ( y no todo)

De eso se trata ,de que vayas aprendiendo,si te dan el codigo hecho nunca aprenderas nada.Solucionar el problema que planteas no es tan facil si quieres que funcione bien...Empieza por partes pequeñas ,como hacer una funcion a la que la pases como parametros la hora y los minutos y te devuelva los minutos totales como te indicaron arriba https://descubrearduino.com/funciones/ .Ves pensando que esto plantea problemas si tienes intervalos que empiezan antes de media noche y acaban de madrugada,por ejemplo de 23:45 a 0:30 ,ya que aqui no vale esa comparacion y tambien lo que puse arriba,una vez entras en una franja ,no debes volver a ejecutar lo que hay dentro hasta volver a llegar a esa hora.

ok voy a intentarlo

Gracias

Pasar la hora actual a minutos no tiene complicación, multiplicar las horas por 60 y sumar los minutos actuales en una misma variable, después ya tienes mi ejemplo de como compararlo.

ya lo he intentado pero como no tengo experiencia busco un ejemplo, lo intento pero no puedo, lo he intentado con el link que me ha enviado @Jose pero no lo he conseguido. he buscado videos pero no he encontrado uno que lo explique de manera que yo lo entienda.

Para mi resulta difícil.

Incluso me he peleado con el sublime tex3 que parece mas intuitivo y tampoco.

Sigo intentando

Gracias chicos.

Una pista:

int minutosTotales(Int Horas,Int Minutos){

  int totalMinutos;

  // Lo que va aqui te lo han explicado arriba

  return totalMinutos;

}

Vale, a ver chicos, lo he intentado, a ver si lo s tiros van por aqui:

int minutosTotales(int fecha.hour(), int fecha.minute()){  
  int por60 = 60;
  minutosTotales = fecha.hour() * por60;
  return minutosTotales;
  int Totalminutos = fecha.minute() + minutosTotales;
  return Totalminutos;
}


void setup() {
 Totalminutos;  

/*No se exactamente que poner, 
 solo se que hay que poner la declaracion del cuerpo 
 de la funcion pero no exactamente que es
 */
 }

void loop() {
  int Totalminutos = 0;
  if (Totalminutos() >= 510 && Totalminutos() <= 540){ 

    /*entre las 8:30h y las 9h. Esto se debe a: 
    las 8:30h = 8.5
    8.5 * 60  = 510
    9h           =  9
    9    * 60  = 540
    */

    for (int i = 0; i < 2; i++) {
      tira.setBrightness(125);
      tira.setPixelColor(i, 255, 255, 255);        
      tira.show();
    }
  }

}

esto lo he hecho a base de recopilar todo lo que me habeis dicho

que es esto:

/*
if (fecha.hour() == 8 && fecha.minute() == 30){
------------------------------------------------------------------

if (horaenminutos >= 510 && horaenminutos <=  720)
------------------------------------------------------------------


int minutosTotales(Int Horas,Int Minutos){

  int totalMinutos;

  // Lo que va aqui te lo han explicado arriba

  return totalMinutos;

}
-------------------------------------------------------------------------------------------------
1Return type  2function name 3(argument1, argument2, ...)

1TIPO DE DEVOLUCIÓN: es el tipo de valor devuelto por la función puede ser cualquier tipo de datos
2NOMBRE DE LA FUNCIÓN: es el identificador por el cual se puede llamar a la función
3ARGUMENTO: Parámetros pasados a la función, cualquier tipo de datos 

{

4Statements
4Declaraciones o cuerpo de la función

}
-------------------------------------------------------------------------------
int sum_func (int x, int y) // es el tipo de valor 
devuelto por la función puede ser cualquier tipo 
de datos 
{ 
int z = 0; 
z = x+y ; 
return z; // return the value 
} 

void setup () { 
Statements // Declaraciones o cuerpo de la función 
} 

Void loop () { 
int result = 0 ; 
result = Sum_func (5,6) ; // function call 

}

-------------------------------------------------------------------
*/

Ejemplo de definicion de la funcion,por ejemplo ,despues de las variables ,antes del setup() (tambien pueden ir en un fichero aparte si tienes muchas) y de uso de la funcion:

//Variables

//Funciones

int minutosTotales(Int Horas,Int Minutos){

  int totalMinutos;
  totalMinutos = Horas * 60 + Minutos; // Hora y Minutos son los parametros
                                                         // pasados a la funcion    
  return totalMinutos;

}
void setup(){   // Codigo  }
void loop(){
  int h = fecha.hour();
  int m = fecha.minute();
  int minutos = minutosTotales(h,m);
  // Tienes el valor en la variable minutos
}

Entonces voy por buen camino, no??

del codigo tengo algo bien?

Bueno ,recuerda lo que te puse sobre si tienes temporizaciones que empiezan antes de media noche y acaban de madrugada y alguna manera de implementar que lo que tenga que hacer entre esas horas lo haga solo una vez,no durante toda la duracion del periodo.Tambien tendrias que repasar el uso de millis() (Hay informacion en Documentacion),tal como tienes tu sketch ahora ,la comprobacion de la hora y el refresco de datos del lcd se realiza constantemente
lo que puede pasar varias veces por segundo,no tiene sentido cuando tu precision es de minuto,es decir con que compruebes cada minuto si ha cambiado la hora es suficiente.

de todas formas me dice:

'minutos' cannot be used as a function

de esto

  if (minutos() >= 600 && minutos() <= 1260){

que por probar he hecho esto:

#include <Wire.h>                   //Del IDE.
#include <LiquidCrystal_I2C.h>      //De: https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads/
#include <Adafruit_NeoPixel.h>      //Del IDE.
#include <RTClib.h>                 //Del IDE.


RTC_DS1307 rtc;
LiquidCrystal_I2C lcd (0x26, 2, 1, 0, 4, 5, 6, 7);
Adafruit_NeoPixel tira = Adafruit_NeoPixel(8, 2, NEO_GRB + NEO_KHZ800);
String daysOfTheWeek[7] = {"Dom", "Lun", "Mar", "Mie", "Jue", "Vie", "Sab"};
int rele1 = 3;  //FILTRO.
int rele2 = 4;  //BURBUJAS.

int minutosTotales(int h, int m){
  int por60 = 60;
  int totalMinutos;
  totalMinutos = h * por60 + m;
  return totalMinutos;
  }



void setup() {
  lcd.setBacklightPin(3, POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.begin(16, 2);
  tira.begin();
  tira.show();

  pinMode(rele1, OUTPUT); 
  pinMode(rele2, OUTPUT);

  if (! rtc.begin()) {
    lcd.println("Modulo RTC no encontrado !");
    while (1);
  }


        
}   




void loop() {
   char buffer[20];   
   tira.show();
   
  DateTime fecha = rtc.now();

  lcd.setCursor(0,0);
  lcd.print(daysOfTheWeek[fecha.dayOfTheWeek()]);
  lcd.setCursor(5, 0);
  sprintf (buffer, "%02d/%02d/%4d", fecha.day(), fecha.month(), fecha.year());
  lcd.print(buffer);
  lcd.setCursor(5,1);  
  sprintf(buffer, "%02d:%02d:%02d", fecha.hour(), fecha.minute(), fecha.second());
  lcd.print(buffer);

   int h = fecha.hour();
   int m = fecha.minute();
   int minutos = minutosTotales(h,m);

jose:
Bueno ,recuerda lo que te puse sobre si tienes temporizaciones que empiezan antes de media noche y acaban de madrugada y alguna manera de implementar que lo que tenga que hacer entre esas horas lo haga solo una vez,no durante toda la duracion del periodo.

noo, todo el codigo esta programado desde las 7 hasta las 23h

tenia un delay pero me recomendaron el el foro que lo quitara y por eso lo quite, creo que lo tenia bajo de esto

 lcd.setCursor(0,0);
  lcd.print(daysOfTheWeek[fecha.dayOfTheWeek()]);
  lcd.setCursor(5, 0);
  sprintf (buffer, "%02d/%02d/%4d", fecha.day(), fecha.month(), fecha.year());
  lcd.print(buffer);
  lcd.setCursor(5,1);  
  sprintf(buffer, "%02d:%02d:%02d", fecha.hour(), fecha.minute(), fecha.second());
  lcd.print(buffer);

lo pongo otra vez??

pero tenia un delay de (1000)

Vuelve a leer el post #16 que lo edite mientras escribias.
De donde sacas esto? if (minutos() >= 600 && minutos() <= 1260){
Quita los parentesis,es una variable no una funcion.

if (minutos >= 600 && minutos <= 1260){