Estoy haciendo 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.
Dado que los sensores funcionan a diferentes frecuencias, utilicé interrupciones de ticker para cada sensor excepto el de 3 ejes. Hice 3 ejes para ejecutar el ciclo while. Ahora todo está bien. Debería poder iniciar sesión según mis requisitos. El problema es que después de iniciar sesión durante 10 minutos, a veces 30 minutos, el registro se detiene.
Un aspecto importante aquí: fopen y fclose se hacen afuera usando una interrupción. Eso significa que inicialmente abro la tarjeta SD y escribo los datos durante 2 minutos; más tarde, cierro ese archivo usando tickers y creo un nuevo archivo.
A continuación puede 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 problema de tiempo...
Nunca, nunca, nunca ponga E/S de archivo en una rutina de interrupción, a menos que sea la única rutina para hacer E/S de archivo. ¡ Y aún así 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 ! La E/S de archivos simplemente no lo es.
Debe usar los tickers para almacenar los datos en los búferes de memoria y luego escribir los datos dentro de loop()
.
wfi
bucle de hilo vacío ( ). Las interrupciones solo son interrumpidas por una nueva llegada que tiene mayor prioridad. Tiene razón en un sentido, es posible que el bucle de subprocesos no se vea si las interrupciones retroceden y se encadenan.Su puntero de archivo se puede cambiar (mediante una interrupción) en el medio del archivo 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 poder interrumpirse.
Como prueba, mueva la actualización del archivo para activar cada 48000 iteraciones de bucle, dentro del bucle (y no escriba para los otros sensores de este conteo en el valor final)
Debido a que otras respuestas ya explicaron el problema, solo describo mi solución.
Establecer banderas en las rutinas de interrupción. Verifique en la rutina principal si se establece una bandera (si es así: haga algo).
levantador
Spehro Pefhany
Marca