Error en codigo y orden para SD

Buenas de nuevo, tengo este codigo, que busca y lee el archivo de la SD, y segun el mes, dia, hora y minutos actuales los compara con cada una de las filas de dicho archivo, o en teoria deberia hacer eso, pero no se si es porque no escribo los numeros correctos en el archivo de la Sd o porque no los compara bien con los datos del rt, que no consigo que encienda el led. sin embargo si descomento "if ((t.hour > 01) && (t.hour < 23)){" y esto " if (daycycle == atol(codigoSD)){" me enciende el led sin problemas.
El proposito de este codigo es bloquear y desbloquear el cierre mediante un rele a 220v de una puerta de mi casa, a determinadas horas y determinados dias para evitar se salga mi hija.

Surbyte, no me deja subir el archivo a.txt, pero no tiene gran cosa que no pueda poner aquí, esta hecho en formato mm/dd, hh:mm

a.txt, contenido:

11/10,09:00
11/11, 18:02
11/11, 20,00

Un saludo y gracias.
Pd: el codigo esta basado en uno creo recordar de noter y surbyte???

#include <SPI.h>
#include <SD.h>
#include <DS1307henning.h>

const int chipSelect = 53;
DS1307 rtc(20, 21); // Indica en que pines esta conectado el RTC.

Time t_temp, t;
File myFile;
float daycycle =(t.mon, t.date,t.hour,t.min);

int linea=0;
char codigoSD[12];

char bo;
int LedRojo = 8;

void setup()
{
  Serial.begin(9600);
  rtc.halt(false);
  pinMode(LedRojo,OUTPUT);
  pinMode(SS, OUTPUT);
  Serial.print("Initializing SD card...");
  
  if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
}

void loop()
{
  t = rtc.getTime(); // Actualiza las variables que usa el  RTC.  

 if ((t.hour > 01) && (t.hour < 23)){

    myFile = SD.open("a.txt");   
    bool encontrado = false;
    if (myFile) {
      Serial.println("leyendo...");
      do {
        bo = myFile.read();
        if (bo == '\n' ||  !myFile.available()) {
          codigoSD[linea] = '\0';
          linea = 0;
        if (daycycle == atol(codigoSD)){// compara la fecha (mmdd) y hora (hhmm) actuales con las lineas del arch
            encontrado = true;// reconocido .... encontrado, entonces pasamos abajo
            break;
          }
        } 
        else {
          codigoSD[linea] = bo;
          linea++;
        }
      } 
      while(myFile.available()); 
      myFile.close();// aqui o abajo



      if(encontrado) {
        Serial.println("encontrado");
        digitalWrite(LedRojo,HIGH);
        
      }
      else{
        ("No existe");
        digitalWrite(LedRojo,LOW);
        
      }
    }
    //myFile.close();
  }
}

Porque dices que no dejo subir el archivo, hazlo como adjunto.
Los códigos van con tag de código pero cosas como .txt los subes y ya.

Por cierto, sigues con el tema del horario?

Surbyte, no te echo a ti la culpa, te digo a ti que no me deja subirlo y ademas me sale esto: You have exceeded the number of posts you can make in a 5 minutes period. Please try again later

Respecto a lo de las horas, esos proyectos estan terminados y funcionando al 100%, desde el champiñero hasta el ultimo que he hecho que es el terrario.
Este proyecto es distinto......

Alguien tiene alguna idea de porque no responde el codigo, si es por algo que esta mal en este o es por las lineas del archivo txt?????
Saludos

Lo que estas haciendo equivale a:

atol("11/10,09:00\r");

Lo cual retornaría 11 o 0 (una de las dos).

Si lo que quieres es comparar una fecha en memoria con la del archivo, pues permíteme decirte que así no es como funciona atol.

Más tarde te ayudaré con eso, que ahora no estoy en casa; y más que modificar/visualizar código en un teléfono celular es complicado.

Lo prometido es deuda, solo que me encuentro un con problema:

float daycycle = (t.mon, t.date, t.hour, t.min); // supongo que son los cuatro bytes de la variable

Tu idea es almacenar 4 bytes en una sola variable, cierto?
Para eso pudiste haber creado un array de byte, o usar el tipo unsigned long.

if (daycycle == atol(codigoSD)) { // compara la fecha (mmdd) y hora (hhmm) actuales con las lineas del arch

Quieres comparar 4 bytes (valores) juntos? Si la respuesta es afirmativa, responde lo siguiente:

Es necesario que el contenido del archivo sea legible para un ser humano?
Es que para comparar 4 valores con otros 4 provenientes de la tarjeta SD, lo más sencillo sería que todo se escriba de forma binaria (no como "1010001101", sino que un caracter represente un valor).

Lucario, gracias por echarme una mano.

Lo que pretendo es comparar varias horas de varios dias escritos en la SD con la fecha y hora actual del RTC y encender un led.

Ejemplo: hoy es 11\14 y la hora 21:48, pretendo comparar esa hora con alguna que haya en la SD en el archivo a.txt y se encienda un led. No se que sera mas fácil si guardarla en una variable la fecha y hora actual y compararla con las líneas de la SD o compararla sin guardar, porque si tarda mucho en compararlas y pasa el minuto ese igual no hace nada.

Sería bueno fuera legible para humanos más que nada porque mi mujer no me queme el invento....

Prueba esto y me cuentas:

#include <SPI.h>
#include <SD.h>
#include <DS1307henning.h>

const byte chipSelect = 53;
DS1307 rtc(20, 21); // Indica en que pines esta conectado el RTC.

Time t_temp, t;
File myFile;
byte daycycle[] = {t.mon, t.date,t.hour,t.min};

char codigoSD[12]; // Aquí va en forma de texto
byte codigoBin[4]; // Aquí va en forma binaria (la cual es necesaria para la comparación con daycycle)
const byte LedRojo = 8;

void setup()
{
  Serial.begin(9600);
  rtc.halt(false);
  pinMode(LedRojo,OUTPUT);
  pinMode(SS, OUTPUT);
  Serial.print("Initializing SD card...");
  
  if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
}

void loop()
{
  t = rtc.getTime(); // Actualiza las variables que usa el  RTC.  

 if ((t.hour > 01) && (t.hour < 23)){ // Condición se cumple en el rango 02:00:00 - 22:59:59?

    myFile = SD.open("a.txt");   
    bool encontrado = false;
    if (myFile) {
      Serial.println("leyendo...");
      do {
       codigoSD[myFile.readBytesUntil('\r', codigoSD, sizeof(codigoSD) - 1)] = 0; // Lee una línea completa, sin '\r'
       myFile.read(); // Descarta '\n'
       aBinario();
       encontrado = !memcmp(daycycle, codigoBin, 4);
       // Compara todo daycycle con el código proveniente del archivo. Obviamente resulta en true si todos los cuatro valores coinciden.
       if (encontrado) break;
      } 
      while(myFile.available()); 
      myFile.close();// aqui está bien



      if(encontrado) {
        Serial.println("encontrado");
        digitalWrite(LedRojo,HIGH);
        
      }
      else{
        Serial.println("No existe");
        digitalWrite(LedRojo,LOW);
        
      }
    }
  }
}

void aBinario() {
  // Esta parte convierte los digitos de la fecha, a bianrio
  char* parte = strtok(codigoSD, ",");
  char* subparte = strtok(parte, "/");
  codigoBin[0] = atoi(subparte);
  subparte = strtok(NULL, "/");
  codigoBin[1] = atoi(subparte);

  // Esta parte convierte los digitos de la hora, a bianrio
  parte = strtok(NULL, ",");
  subparte = strtok(parte, ":");
  codigoBin[2] = atoi(subparte);
  subparte = strtok(NULL, ":");
  codigoBin[3] = atoi(subparte);
}

Si algo no lo entiendes, primero intenta leer en los comentarios. Si sigues sin entender algo, entonce pregunta por aquí :slight_smile:

Lucario, intentare probarlo estos dias y te comento.
Pido disculpas por no hacerlo antes pero me he quedado sin internet y sin cobertura totalmente y hasta que no vengan a repararlo no puedo, porque desde un movil es una castaña. Un saludo y gracias

Buenas.
Lucario código probado y no funciona el led. Por el serial sale que inicia la SD, lee el archivo a.txt, pero no encuentra la fila escribiendo no existe.
He probado:
18\11, 19:22
18111924
18,11,19,26
18 11 19 28
18.11.19.30
Y no reconoce a ninguna o cuando los compara con las del RTC no las encuentra, en pocas palabras el dayclicle y la fila de la SD no son iguales, puede ser porque no actualiza el dayclicle????
Saludos

Nuevo intento:

Cambia esto:

byte daycycle[] = {t.mon, t.date,t.hour,t.min};

Por esto:

byte* daycycle[] = {&t.mon, &t.date,&t.hour,&t.min};

La idea es que en vez de comparar con una copia de los valores, lo haga leyendo donde se ubican las variables directamente.

Lucario, tampoco consigo encender el led asi, he añadido al codigo para que salgan los datos que lee por el serial y los lee todos, pero algo falla al comparar con el rtc los datos reales o los archivos del A.txt no esten bien escritos que les falte algo. Voy a probar alguna idea que me venga por la cabeza. Un saludo

Segundo intento:

Cambiar:

byte daycycle[] = {t.mon, t.date,t.hour,t.min};

Por:

byte daycycle[4];
t = rtc.getTime(); // Actualiza las variables que usa el  RTC.

Por:

actualizarTiempo();

Agrega esto al final:

void actualizarTiempo() {
  t = rtc.getTime(); // Actualiza las variables que usa el  RTC.
  daycycle[0] = t.mon;
  daycycle[1] = t.date;
  daycycle[2] = t.hour;
  daycycle[3] = t.min;
}

Hola.
No he podido probar el código, pero igual el problema no está tanto en la comparación de los arrays como en la extracción de los valores del fichero. Deberías enviar por monitor serie los valores de los dos arrays a comparar para estar seguros. De todas formas, me parece un poco engorroso el sistema de extracción que has elegido (strok+atoi). ¿No sería más sencillo usar directamente myFile.parseInt? Lo único a tener en cuenta sería controlar si los finales de línea tienen uno (cr) o dos caracteres (cr+lf) para evitar desfase en los distintos valores. Mejor aún, introducir un carácter especial al principio de cada línea que sea el que "dispare" los cuatro parseInt consecutivos.

noter:
¿No sería más sencillo usar directamente myFile.parseInt?

Se puede? Digo... no lo documentan en la clase File, pero seguro que es una función que obliga a implementar todo lo que herede de Stream?

PD: por cierto, algo que olvidé un par de veces decir: el convertidor de texto a binario espera el siguiente formato:

MM/DD,hh:mm

Donde MM es el mes en números, DD es el día del mes (en números), hh es la hora en el formato de 24 horas supongo, y mm son los minutos.

No puedo asegurarlo al cien por cien, pero casi. Sólo tienes que probarlo; pero si File hereda, como creo, de Stream; puedes utilizar sus métodos. En este caso, va a separar con cualquier carácter delimitador que pongamos.

Lucario, tampoco funciona este nuevo intento.
Por el serial he visto que salen todas las filas del archivo, que no compara una a una y si no lo encuentra pasa a la siguiente.

Noter muchas gracias por la ayuda....

He estado mirando mirando y por internet he visto algunos codigos con htm puestos en la sd, que guarda la linea que leyo anterior, estoy intentando modificarlos para adaptarlos a este pero hasta ahora sin ningun exito. Saludos

Sadvance:
Lucario, tampoco funciona este nuevo intento.

Entonces imprime al monitor serie, los valores de las variables en el objeto t; cada vez que supuestamente se actualizan.

Serial.println(String(t.mon) + " - " + String(t.date) + " - " + String(t.hour) + " - " + String(t.min));

Algo tiene que andar mal.

Sadvance:
he visto algunos codigos con htm puestos en la sd, que guarda la linea que leyo anterior, estoy intentando modificarlos para adaptarlos a este pero hasta ahora sin ningun exito.

Si sigues usando mi convertidor de texto a binario, seguramente se debe a que no se a modificado para trabajar con ese formato.

Lucario, por el serial sale 23 - 11 -17 -10, dia, mes hora y minutos. He probado a ponerlo igual que sale en el seria y de todas las formas y sigue sin encender el led.

He probado con algunos de los de internet usando `parte de tu codigo y tampoco, es como si no comparara la hora y dia del rtc con las que hay en la SD. Seguire probando...................

Sadvance:
Lucario, por el serial sale 23 - 11 -17 -10, dia, mes hora y minutos. He probado a ponerlo igual que sale en el seria y de todas las formas y sigue sin encender el led.

Aparece exactamente lo mismo aún pasado un minuto?

Lucario, el rtc funciona perfectamente por el serial, el fallo debe de estar en la comparacion del las lineas de la SD con la hora.
Voy a hacer una prueba poniendo la fecha a mano para ver si la compara y veremos que sale...................
Saludos