4 votos

Archivos corruptos generados por Arduino con la librería SD. ¿Cómo evitarlo?

Tengo un boceto que se ejecuta en un Ethernet Arduino (que viene con un lector de tarjetas SD y, por supuesto, una interfaz Ethernet).

Hay un lugar único en este boceto donde escribo a un archivo en la tarjeta SD, que básicamente se ve así:

char dpath[13]; // File path
char logline[30]; // String to be stored in

/* ... */

File dataFile;
if (dataFile = SD.open(dpath, FILE_WRITE)) {
    dataFile.println(logline);
}
dataFile.close();

No experimenté ningún problema durante unos meses teniendo un par de Arduinos ejecutando este sketch.

Recientemente, he puesto a trabajar a otro que se comporta de forma extraña. En concreto, veo que en la tarjeta SD ha generado un archivo algo corrupto.

El tamaño del archivo parece ser de 4,0 GB, aunque el tamaño total de la tarjeta SD es de 3,7 GB, y si intento leerlo con un editor hexadecimal aparece vacío:

$ du -h 20130206.DAT_ 
4,0G    20130206.DAT_

$ df -h
Filesystem   Size  Used  Avail  Use%   Mounted on
/dev/sdb1    3,7G   58M   3,6G    2%   /media/B045-FE58

$ hexdump 20130206.DAT_ 
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
fd000000

¿Qué puede estar pasando con el microcontrolador?

Lo pregunto aquí, porque no noto ningún problema de programación, y el sketch funciona bien en otras placas. ¿Debo tener en cuenta algunos problemas eléctricos conocidos? ¿Podría por ejemplo una fuente de alimentación no estabilizada o alguna radiación electromagnética estar provocando este comportamiento? Agradecería cualquier sugerencia sobre cuestiones electrónicas que debería comprobar.

2voto

panopticoncentral Puntos 1333

Tanto la interfaz de la tarjeta SD como la de WizNet comparten la misma interfaz SPI del microcontrolador. Hay un error conocido (o más bien un terrible descuido de diseño) en la librería de software SPI de Arduino en este sentido, que ocasionalmente causa corrupción de datos. No es a prueba de interrupciones. El problema se explica y se soluciona aquí:

http://www.dorkbotpdx.org/blog/paul/spi_transactions_in_arduino

Esto lo consigue permitiendo al usuario de la biblioteca encerrar el acceso al SPI con métodos de protección:

En pocas palabras, SPI.beginTransaction() protege su acceso al SPI de otras librerías basadas en interrupciones, y garantiza una configuración correcta mientras utiliza el bus SPI.

Oh, la profundidad del asunto significa que tienes que arreglar/reescribir todo lo que se aprovecha de la biblioteca SPI. El caso de uso de Arduino ha evolucionado hacia arriba en la complejidad de los proyectos muy simples, y las bibliotecas podrían tomar un tiempo para reflejar plenamente esta transición.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X