Registro de múltiples datos de sensores en la tarjeta SD al mismo tiempo: la escritura se cuelga

2

Estoy realizando un proyecto de registrador de datos con 5 sensores diferentes que incluye un sensor de 3 ejes que funciona a 800 Hz. Mi requisito es registrar los datos en una tarjeta SD. Aquí tengo que registrar el sensor de 3 ejes a 800 Hz y todos los demás sensores a 1 Hz.

Debido a que los sensores funcionaban a diferentes frecuencias, utilicé interrupciones de ticker para cada sensor excepto en 3 ejes. Hice 3 ejes para ejecutar en bucle while. Ahora todo está bien. Debería poder iniciar sesión según mi requisito. El problema es que después de registrar durante 10 minutos, a veces 30 minutos, el registro se detiene.

Un aspecto importante aquí: fopen y fclose se realizan en el exterior mediante una interrupción. Eso significa que inicialmente abro la tarjeta SD y escribo los datos durante 2 minutos; más tarde, cierro ese archivo con tickers y creo un nuevo archivo.

A continuación puedes ver mi ejemplo de código.

// tickers used to create a new SD file at regular intervals.

 void onFileUpdate(void) 
    {    
        static int fileNumber = 0;
        if (logFile)
        fclose(logFile);
        char fileName[20];
        sprintf(fileName,"/sd/PCE-DL%03d.txt",fileNumber++);
        logFile = fopen(fileName,"w");
    }

// Ticker object for Light sensor which run at 1HZ by an inturrupt.

void onLight(void)
 {  
  LUX = max44009.getLUXReading();
   fprintf(logFile,"\r\n                                 %f  ",LUX);
 }

 // RTC ticker

 void onRtc(void)
 { 
    seconds = mktime(&t);
    rtc8564.get_time_rtc(&t);   // read RTC data
    strftime(buf, 40, "%I:%M:%S %p (%Y/%m/%d)", localtime(&seconds)); 
    fprintf(logFile,"\r\n %s", buf);
 } 

// my while loop

 while(1) { 
   accelerometer.getOutput(readings);
   fprintf(logFile,"\r\n%i,%i,%i", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]); 

      }
  }

No sé por qué está colgando. Puede ser un problema de tiempo ...

    
pregunta Gandhi

3 respuestas

11

Nunca, nunca, nunca ponga la E / S de archivo en una rutina de interrupción, a menos que sea la rutina solo hacer archivo I / O. Y entonces todavía ¡no lo hagas!

Una interrupción puede interrumpir cualquier cosa, incluida la E / S de archivos. ¡Y las interrupciones deben ser rápidas, rápidas, rápidas ! El archivo I / O simplemente no lo es.

Necesitas usar los tickers para almacenar los datos en buffers de memoria, luego escribe los datos dentro de loop() .

    
respondido por el John Burger
5

El puntero del archivo se puede cambiar (por una interrupción) en la mitad de fprintf . Todas las demás rutinas de salida se encadenarán en lugar de interrumpirse (suponiendo que tengan la misma prioridad), pero su bucle while debe ser interrumpible.

Como prueba, mueva la actualización del archivo para que se dispare cada 48000 iteraciones de bucle, dentro del bucle (y las escrituras para los otros sensores de este conteo se encuentran en el valor final)

    
respondido por el Sean Houlihane
1

Debido a que otras respuestas ya explicaron el problema, solo describo mi solución.

Establecer indicadores en las rutinas de interrupción. Verifique en la rutina principal si un indicador está establecido (si es así: haga algo).

    
respondido por el gidiei

Lea otras preguntas en las etiquetas