Grabación en micro SD fallo siempre en 178 ciclos

Saludos a todos. Y de antemano mis disculpas si incumplo alguna norma de foro.

Estoy trabajando un mini proyecto de lectura de sensorial con un Arduino uno genérico. Un sensor sds011. Un sensor bmp280, aht20. Y un reloj ds1307.

En si el proyecto. Es iniciar. Y cada minuto guardar las dos medidas del sds0011, la temperatura. Humedad. Altitud, fecha y hora.

Todo va bien iniciando los sensores. La sd. Y los ciclos comienzan perfectamente. Lo he intentado grabando en un solo .txt o creando varios .txt cada 60 ciclos. Pero siempre me guarda unicamente 178 veces ya sea un archivo con 178 registros. O 3 ficheros 2 de 60 registros y uno de 58.

He probado verificando en el comando la SRAM y siempre tengo Sram libre y sin alteraciones.

Adjunto mi último código.

Pd. Lo he montado en baquelita soldado todo. Y bueno todo correctamente el. Continuidad. Lo he probado en pc y con batería externa de 10000mha 2.1 A. 5v. Funciona pero solo 178 veces

Tu tema ha sido movido a la sección en español del foro. Utiliza el inglés en las secciones en inglés del foro.

Si no nos muestras el código difícilmente podamos darte alguna ayuda.

Saludos.

Mil disculpas por mi error de no pegar el código y adjuntarlo. también el tiempo de responder pero el trabajo no me lo ha permitido. adjunto mi codigo

#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_BMP280.h>
#include <AHT20.h>
#include "SDS011.h"
#include "RTClib.h"
#include <avr/wdt.h>

RTC_DS1307 rtc;
SDS011 my_sds;
Adafruit_BMP280 bmp;
AHT20 myAHT20;

const int chipSelect = 4;
int registrosActuales = 0;
int numeroArchivo = 0;
char fileName[13]; 

void generarNombreArchivo() {
  sprintf(fileName, "LOG%02d.TXT", numeroArchivo);
}

void setup() {
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  
  Serial.begin(9600);
  Wire.begin();
  Wire.setWireTimeout(3000, true); 

  my_sds.begin(2, 3);
  rtc.begin();
  myAHT20.begin();
  bmp.begin();
  
  if (!SD.begin(chipSelect)) {
    Serial.println(F("Error SD"));
  }

  // Buscar el índice inicial libre
  while (SD.exists(fileName)) {
    numeroArchivo++;
    generarNombreArchivo();
  }
  
  digitalWrite(10, LOW);
  wdt_enable(WDTO_8S);
}

void loop() {
  wdt_reset();
  
  // 1. Lectura de Sensores (SDS011 siempre activo)
  float temp = myAHT20.getTemperature();
  float hum = myAHT20.getHumidity();
  float pres = bmp.readPressure();
  float p25, p10;
  
  // Limpieza de buffer serie para evitar datos estancados
  while(Serial.available() > 0) Serial.read(); 
  int sds_error = my_sds.read(&p25, &p10);
  
  DateTime ahora = rtc.now();

  // 2. Escritura en SD
  File myFile = SD.open(fileName, FILE_WRITE);
  if (myFile) {
    digitalWrite(10, HIGH);
    myFile.print(p25); myFile.print(',');
    myFile.print(p10); myFile.print(',');
    myFile.print(temp); myFile.print(',');
    myFile.print(hum); myFile.print(',');
    myFile.print(pres); myFile.print(',');
    myFile.print(ahora.hour()); myFile.print(':');
    myFile.println(ahora.minute());
    myFile.close();
    digitalWrite(10, LOW);
    registrosActuales++;
  } else {
    SD.begin(chipSelect);
  }

  // 3. Lógica de Rotación (Cada 60 registros = 1 hora)
  if (registrosActuales >= 60) {
    registrosActuales = 0;
    numeroArchivo++;
    generarNombreArchivo();
  }
  
  // Espera segura de 60 segundos
  for(int i = 0; i < 60; i++) {
    wdt_reset();
    delay(1000);
  }
}

voy a intentar hoy, hacer uno que grabe por un hora, hora y media y reinicie todo, pero no estoy seguro que pueda funcionar.

de antemano mil gracias al tiempo y cualquier enseñanza.

Veo algunos errores:

  if (!SD.begin(chipSelect)) {
    Serial.println(F("Error SD"));
  }

Informa el error pero sigue adelante a pesar de no poder manejar la SD.

while (SD.exists(fileName)) {

El array fileName todavía no tiene ningún valor asignado, no va a entrar al lazo por lo que no puede determinar el ultimo nombre de archivo.

  } else {
    SD.begin(chipSelect);
  }

Por qué iniciar nuevamente la SD? (Por cierto debería cerrarla antes)

Gracias por tan pronta respuesta.

respondo desde mi ignorancia, ya que he implementado leyendo por búsquedas y no es mi experticia realmente.

  if (!SD.begin(chipSelect)) {
    Serial.println(F("Error SD"));
  }```

Correcto. esto siempre me ha salido así en todos los ejemplos de configuración de escritura en SD, simplemente dicen error de lectura y continua. sufrí para acomodar una micro SD con el formato que pedía y que siempre leyera apenas energizaba el circuito.

while (SD.exists(fileName)) {

Acá no entiendo mucho. esto fue con IA y cuando hice mis pruebas si se logró crear apenas arranca el circuito el fichero LOG001.txt con 60 registros, el LOG002.txt con 60 registros y el LOG003.txt con 58 Registros (los mismos 178 Registros que me hizo en un código pasado donde grababa de corrido todo en un solo .txt).

  } else {
    SD.begin(chipSelect);
  }

para esto y simple idea mia. dije bueno no entro al loop donde hacia la escritura, intentare de abrir nuevamente la inicialización de la SD, pero no funcionó, aunque yo supongo que en la última lectura osea la 178 hace el myFile.close(); que está en el código.

mil gracias nuevamente por tu lectura y cualquier idea o camino que creas que puedo seguir te agradezco mucho

Pero entendés que es un error hacerlo de ese modo?
Si el sistema de archivos no se inicializa todo lo que sigue no tiene sentido porque no va a funcionar.
Lo lógico sería agregar un lazo que detenga todo allí.

Definitivamente el lazo while() de setup() no se ejecuta por lo que te dije antes.
Por cierto se generan 60 registtos que no se guardan porque el archivo no existe.
A partir del registro 61 se guardan porque se genera LOG01.TXT.

O sea que en realidad son 238 registros no 178 los que se generan, solo que 60 no se guardan.

El problema puede estar relacionado con el watchdog (que no lo incluí en mis pruebas) o con los sensores que tampoco incluí porque no los tengo.

void generarNombreArchivo() {
  sprintf(fileName, "LOG%02d.TXT", numeroArchivo);
}

para el primer numeroArchivo = 0, no existe y el While no sirve para nada entiendo.

Podés hacer

numeroArchivo = 1;
generarNombreArchivo();
while (SD.exists(fileName)) {
// lo que sigue...

para iniciarlizar fileName con LOG01.TXT y así se ejecuta el lazo como debería.

Mil gracias. Lo pruebo. Y te cuento

Gracias

O sin

numeroArchivo = 1;

y arrancaría con LOG00.TXT

Ahora, esto se supone que es para no reescribir los archivos que ya hubiese luego de un reinicio.
De acuerdo?

Las pruebas que hice con tu código, como te dije sin wdt ni lo relativo al hardware (excepto la SD, claro), las detuve pasados los 1000 registros guardados.

Entendido. ayer no alcance hacer las pruebas, pero hoy me pongo en ello.

la no sobre escritura después de un reinicio sería algo viable sólo el día que opere el circuito, ya que si falla y se reinicia el mismo dia donde trabajaría 8 horas seguidas sería bueno que no reescriba y tener la data completa. pero al finalizar las 8 horas de trabajo el plan es bajar la información y ponerlo al día siguiente desde cero osea grabando nuevamente LOG00.TXT.

ya te contare como me fue.

Gracias!

Hola Maximo.

Pues bien. he probado lo que me has enseñado y cambie la SD a una clase 10, y ha funcionado perfectamente!. me ha generado los archivos tal cual como los necesito para hacer la estadística. !

te agradezco mucho tu ayuda y el tiempo prestado! gracias

He analizado tu problema y la verdad que aunque encontraron una solución no explicaron porque fallaba a los 178 archivos puntualmente.
La verdad me pareció interesante analizarlo

Mi Solución : colocar generarNombreArchivo() antes

generarNombreArchivo();  // ← esto falta: fileName = "LOG00.TXT"
while (SD.exists(fileName)) {
  numeroArchivo++;
  generarNombreArchivo();
}

Porque cuando inicias el sistema arranca con
fileName -> se inicializa a "" (todos ceros) y eso le abre las puertas a escribir directo en el directorio Raiz.
Y entonces?
Resulta que los 178 nombres ocupan exactamente el tamañó máximo del directorio raiz y colapsa. Cuando se llena el directorio raiz, sd.open falla.

O sea SD.open("") siempre abre el mismo directorio raíz, luego registrosActuales se incrementa pero el nombre del archivo no cambia en realidad y aunque

if (registrosActuales >= 60) 

pasa, o sea se alcanza ese límite se generan nombres como log01.txt que si existen o el contador se resetea por algún reinicio parcial del delay + wdt y nunca llega a contar 60.

No eran 178 archivos, el problema era que no guardaba más de 178 registros. O sea, generaba 2 archivos con 60 registros, 1 con 58 y adiós.

Por lo visto, resultó ser un problema de la tarjeta SD.

Yo lo probé y llenaba el directorio.

Saludos.

si. parece que era eso, ya la he probado varias veces y la memoria de 32GB clase 10 va perfecto. la que use antes era una de 1 GB normalita ya que pense que era suficiente porque cada archivo de 3 Kb x 8 archivos 24 KB en total, una tontería!, pero NO. debe ser clase 10 para que soporte imagino yo, abrir y cerrar varias veces.