Guardar datos en tarjeta SD

Buen día amigos,

Estoy en un proyecto, el mismo consiste en almacenar datos de funcionamiento de un motor a combustión en una tarjeta SD, por ahora solo quiero guardar los siguientes datos para luego verlos en una tabla de excel:

Hora de inicio
Fecha de inicio

Hora de parada
Fecha de parada

Para obtener datos de hora y fecha estoy usando un modulo RTC

Para guardar los datos en la SD cree las siguientes dos funciones:

[void hora_inicio(){
 String fechainicioString="";
 String horainicioString="";
  
File Archivouso = SD.open("registrouso.txt", FILE_WRITE);
fechainicioString +=String(dia)+String("/")+String(mes)+String("/")+String(Year);                  //Concatenamos caracteres para almacenarlos en la SD como una cadena de caracteres
horainicioString +=String(horaRTC)+String(":")+String(minutoRTC)+String(":")+String(segundoRTC);
      
      if (Archivouso){                                                                              //Si existe Archivouso:            
        Archivouso.println("Fecha de inicio");
        Archivouso.println(fechainicioString);
        Archivouso.println("Hora de inicio");
        Archivouso.println(horainicioString);
        Archivouso.close();
      }

      else{
        digitalWrite(ledrojo,HIGH);                                                              // se avisa que hay algun error en el archivo.
      }
}



//Funcion para almacenar los datos al parar el grupo electrogeno:

void hora_parada(){
  String fechaparadaString="";
   String horaparadaString="";
   
   File Archivouso= SD.open("registrouso.txt", FILE_WRITE);                                           //abrimos una archivo:registrouso para comenzar la escritura, solo puede existir un archivo abierto a la vez.

   
   fechaparadaString +=String(dia)+String("/")+String(mes)+String("/")+String(Year);                  //Concatenamos caracteres para almacenarlos en la SD como una cadena de caracteres
   horaparadaString +=String(horaRTC)+String(":")+String(minutoRTC)+String(":")+String(segundoRTC);
      
      if (Archivouso){                                                                               //Si existe Archivouso entonces comenzamos a guardar nuestros datos            
        Archivouso.println("Fecha de parada");
        Archivouso.println(fechaparadaString);
        Archivouso.println("Hora de parada");
        Archivouso.println(horaparadaString);
        Archivouso.close();
      }

      else{
        digitalWrite(ledrojo,HIGH);                                                              // se avisa que hay algun error en el archivo.
      }
}]

Luego defino los estados del motor:

0 motor parado
1 motor encendido
3 y 4 paradas por fallas

Luego en alguno parte de mi loop llamo a las funciones de almacenar cuando el motor cambia de estado:

[if (estadomotor!=estadoanterior)
{
  switch (estadomotor){
    case 0:
    
    hora_parada();
    break;
    case 1:
    hora_inicio();
    case 3:
   
    hora_parada();
    break;
    case 4:
 
    hora_parada();
    break;          
   }
}

Mi problema esta en que hago esto, pero no se genera ninguna archivo en mi sd; descargue ejmplos de dataloggers que son similares y se generan los archivos, pero en este caso no y no entiendo o no me doy cuenta donde se encuentra mi error.

¿Vienes a preguntar algo o solo a compartir?

Perdón lucario, subí el post por accidente sin completarlo, lo estoy editando

¿Como obtiene estadomotor un valor del 0 al 4? ¿Qué hay con el 2?

hugogimenez:
Mi problema esta en que hago esto, pero no se genera ninguna archivo en mi sd;

¿O sea que efectivamente se te enciende ledrojo?

El estadomotor 2 lo reserve cuando el motor se encuentra en régimen y el estado 1 en ralenti, cuando se encuentra en regimen de marcha por ahora no quiero almacenar ningún dato.

En cuanto al sostware, efectivamente sucede que se enciende el led rojo y no se almacenan los datos.

A continuación pongo el código de donde salen los estados del motor, que dependen de la presión de aceite y la temperatura, esta parte de mi proyecto funciona bien.

[//ACCIONES DE CONTROL 
//********************************************************************************************************************************************************************************************
void acciones_control(){
//ARRANQUE
// Se verifica que el motor arranque y una vez que lo hace se acelera y se prende el contactor
if (estadovigia==0 && estadooff==0)
{
if(estadomotor==0)
{
if(evento==0)                                                  //Este if se utiliza para sacar una "foto" a millis en un instante para poder definir un intervalo de tiempo.                                
{digitalWrite(parador,LOW);
tiempoarranque = millis();                                     //Iniciamos millis para temporizar una pausa sin utilizar la funcion delay que frena todos los procesos de arduino
evento=1;
}
if(millis()>=pausaarranque+tiempoarranque)                     //Definimos el intervalo de la pausa
 {
   if (presion>=15 )
      { estadomotor=1;
      pausap(2000);

         if (temp<95 )
         { digitalWrite (acelerador,HIGH);
           estadomotor=2;
           pausap(3000);
           digitalWrite(contactor, HIGH);
           estadocontactor = 1;
         }
   }
   else if(evento==1)
   {digitalWrite(parador,HIGH);
    pausap(4000);
    evento=2;
   }
   else
   {digitalWrite(parador,LOW);
   }
}
}
//********************************************************************************************************************************************************************************************
//REGIMEN
//Se verfican fallas por presion y temperatura

 if (estadomotor==2)
 {   if(temp<98 && temp >95)
    {digitalWrite (contactor, LOW);
     estadocontactor=0;
     pausap(3000);
     digitalWrite (acelerador, LOW);
     estadomotor=1;
     }
 }
 if (estadomotor==1)
 {   if(temp<95)
     { digitalWrite (acelerador, HIGH);
       estadomotor=2;
       pausap(2000);
       digitalWrite(contactor,HIGH);
       estadocontactor=1;
       }
 }
 if (98<temp>125)
 { digitalWrite (contactor, LOW);
  estadocontactor=0;
  pausap(3000);
  digitalWrite (acelerador, LOW);
  estadomotor=1;
  pausap(2000);
  digitalWrite(parador,HIGH);
  estadomotor=3;
  digitalWrite(alarma,HIGH);
  pausap(30000);
  digitalWrite(alarma,LOW);
 }
if (estadomotor==1 || estadomotor==2)
{
  if (presion< 15)
   { digitalWrite (contactor,LOW);
     estadocontactor=0;
     pausap(2000);
     digitalWrite(acelerador,LOW);
     estadomotor=1;
     pausap(2000);
     digitalWrite(parador,HIGH);
     estadomotor=4;
     digitalWrite(alarma,HIGH);
     pausap(30000);
     digitalWrite(alarma,LOW);
   }
}
}]

Ya, solo tenía la duda con estadomotor.

Hay varios motivos por los cuales no se abre un archivo:

  • Tarjeta no inicializada.
  • Conexión defectuosa.
  • Ausencia de partición en FAT32.
  • Tarjeta tiene activada la protección contra escritura (para lectura y escritura).
  • El archivo tiene activado el atributo "sólo lectura" (para lectura y escritura).
  • El archivo no existe en la ruta especificada (solo para lectura);
  • La ruta apunta a una carpeta (sí se abre, pero las funciones de lectura y escritura fallan).

A ver si con verificarlas das en el clavo.

gracias lucario, en cuanto a conexión y uso de tarjeta funciona bien porque hice el datalloger que viene de ejemplo y se generan los datos en la SD.

En el proyecto actual también incluí el siguiente código en el setup para que previo al arranque de loop se verifique si se encuentra la tarjeta sd operativa:

[//SETUP PARA LECTOR DE TARJETA SD:
 // Control de tarjeta SD:
  if (!SD.begin(chipSelect)) {
       digitalWrite(ledrojo,HIGH);
       
  }
  else{
       digitalWrite(ledverde,HIGH);
             
  }]

Por lo que yo pensé que era un error de codificación o algo que se me escapa de la vista y no me doy cuenta. La verdad es que es la primera vez que uso una SD por lo que no se si esta bien lo que estoy haciendo.
Aclaro que cuando corre el programa en el setup se enciende la luz verde.

Oh, no lo había notado. Encontré una de las razones que olvidé agregar a la lista: el nombre viola el estándar SFN u "8.3".

SD.open("registrouso.txt", FILE_WRITE);

"registrouso" supera los 8 caracteres permitidos.

Técnicamente, FAT32 tiene soporte LFN (nombre de hasta 255 caracteres Unicode); lo que ocurre es que los desarrolladores de la IDE de Arduino, por alguna razón no incluyen la versión más reciente de esta librería.

Si tuvieras la última versión, así como está sí te abre.

Tienes dos opciones:

  • Cambiar la librería.
  • Acortar el nombre del archivo, pero manteniendo el sufijo ".txt"

Gracias Lucario, lo voy a probar....

Lucario, acortando el nombre como me dijiste funciono perfecto, con la salvedad que solo me almaceno los datos de parada y no los de arranque.

Mi pregunta es yo puedo llamar dos veces al mismo archivo para escribir los datos de arranque y pare?

Si te fijas en el codigo hice un loop de hora de inicio y un loop de hora de pare con el mismo nombre de archivo (ahora lo llame reguso, que es mas corto). Mi intención es tener una tabla con todos los datos.

hugogimenez:
Mi pregunta es yo puedo llamar dos veces al mismo archivo para escribir los datos de arranque y pare?

Se supone que sí; siempre y cuando se haga referencia al mismo archivo en la misma ubicación (y se abra para escritura con FILE_WRITE), y que el acceso anterior lo haya cerrado.