LA LIBRERÍA SD

Facebooktwittergoogle_pluslinkedinmailFacebooktwittergoogle_pluslinkedinmail

Esta librería, que forma parte del núcleo del IDE de Arduino, se usa para gestionar la comunicación con tarjetas SD incorporadas a cualquier dispositivo (pantallas TFT, shields de diversos tipos, etc). Incluye dos clases: una de ellas está orientada a gestionar el propio dispositivo (la tarjeta SD) y el otro se usa para la gestión de los contenidos en la tarjeta.

ATENCIÓN. Cuando trabajes con tarjetas SD recuerda que, como cualquier dispositivo de almacenamiento, estas tarjetas necesitan estar formateadas para ser utilizables. Normalmente, cuando compras una tarjeta, esta ya viene formateada por el fabricante. Si no es así, o necesitas formatearla de nuevo, la utilidad de formateo del sistema operativo no siempre es una opción adecuada con estar tarjetas (en realidad, no las formatea del modo que este tipo de dispositivo necesita). Existe una utilidad que te puedes descargar gratuitamente. Se llama SDFormatter y es un pequeño programita concebido para formatear tarjetas SD. Puedes obtenerlo en este enlace.

LA CLASE SD

Esta clase gestiona la tarjeta SD que conectemos a Arduino. Puede estar en cualquier dispositivo, cómo una pantalla TFT, un shield, etc.

La comunicación con la tarjeta SD utiliza SPI (ver en este enlace), lo que implica a los pines 11, 12 y 13 (en la mayoría de las tarjetas Arduino) o 50, 51 y 52 (en Arduino Mega). Adicionalmente se puede usar otro pin para seleccionar la tarjeta. Puede ser el pin SS por hardware (el 10 en la mayoría de las Arduino, o el 53 en la Mega), o bien un pin que elijamos, especificándolo en el método SD.begin(). Si usas el pin SS por hardware, debe ser configurado cómo de salida, o la librería SD no funcionará.

EL MÉTODO begin()

Inicializa la tarjeta SD. Se puede usar sin ningún argumento, si, cómo pin CS vamos a usar el pin por hardware de la tarjeta, cómo hemos mencionado arriba. Si no, pondremos cómo argumento, el pin que vayamos a usar que, previemente, deberá haber sido declarado cómo de salida. Por ejemplo:

SD.begin(9);

EL MÉTODO exists()

Se emplea para averiguar si en la SD existe o no un fichero concreto. Como argumento, le pasamos el nombre del fichero, con la ruta incluida, si no es la raíz de la SD. Por ejemplo:

SD.exists("imagen.bmp");

o bien:

SD.exists("imagenes/imagen.bmp");

Devuelve true si el fichero especificdo existe, o false en caso contrario.

EL MÉTODO mkdir()

Se emplea para crear directorios en la tarjeta. Podemos especificar el nombre de un directorio, y lo creará a partir de la raíz de la tarjeta. También podemos especificar una ruta completa, y creará los directorios que no existan para que quede la estructura especificada. Por ejemplo:

SD.mkdir("imagenes"); // Crea la ruta imagenes en la raíz, si no existe.

o bien

SD.mkdir("imagenes/bmp"); // Crea el directorio imagenes y, dentro de este, el directorio bmp.

Si el directorio especificado ya existe no crea nada.

EL MÉTODO open()

Abre un fichero en la tarjeta. Un fichero se puede abrir para lectura o para escritura. Si se abre para escritura y no existe, es creado en ese momento. Este método devuelve un objeto de la clase File, que será gestionado por los métodos de esa clase. Por ejemplo:

objetoFile = SD.open("imagenes/imagen.bmp", FILE_READ);

Esto creará un objeto con el fichero abierto para lectura (desde el principio del mismo). Si el fichero no existe dará error, por lo que, previamente, deberemos usar el método SD.exists() para asegurarnos de que el fichero está dónde creemos que está.

objetoFile = SD.open("imagenes/imagen.bmp", FILE_WRITE);

Esto creará un objeto con el fichero especificado para escribir en él, a partir del final del mismo. La ruta debe existir. Si el fichero no existe, se creará en ese momento.

EL MÉTODO remove()

Elimina un fichero de la tarjeta SD. Devuelve true si el fichero se ha podido eliminar, o false en caso contrario. La sintaxis es:

SD.remove(fichero);

EL MÉTODO rmdir()

Elimina un directorio en la tarjeta. Si se puede eliminar, devuelve true. Si no se puede eliminar, devuelve false. Si el directorio no existe, el retorno puede ser cualquiera. Como argumento, se le pasa la ruta hasta el directorio, que debe estar vacío para poder eliminarlo.

SD.rmdir("imagenes/bmp");

Esto borraría el directorio bmp, dentro de imagenes. El directorio imagenes se mantiene. Si queremos eliminarlo, deberemos llamar de nuevo al método, asi:

SD.rmdir("imagenes");

LA CLASE FILE

Esta clase se ocupa de la gestión de ficheros en la tarjeta SD. La librería soporta los sistemas de ficheros FAT16 y FAT32 en tarjetas SD y SDHC. Los nombres de ficheros se ajustarán al formato 8.3, es decir, un máximo de ocho caracteres en el nombre y de tres caracteres en la extensión. Opcionalmente, podrían incluir rutas separadas por slashes (/). A estos efectos ten en cuenta que el directorio de trabajo por defecto es el raiz de la SD.

ATENCIÓN. Los métodos detallados a continuación operan sobre un objeto de la clase FILE, que se ha creado con el método SD.open().

EL MÉTODO available()

Devuelve el número de bytes que hay disponibles para leer en el fichero al que representa el objeto desde el que llamamos al método. Por ejemplo:

ObjetoFile = SD.open("historia.txt", FILE_READ);
int disponibles = ObjetoFile.available();

Esto nos devolvería el número de bytes que quedan disponibles en el fichero para leer. Cómo acabamos de abrirlo, son todos los bytes que contiene el fichero. Si ya hubiéramos hecho una lectura, serían los que aún no hayamos leido. Dicho de otro modo. Cuando se abre un fichero, hay un puntero que marca por dónde vamos leyendo. Cuando se lee un byte del contenido, el puntero se desplaza al siguiente byte.

EL MÉTODO close()

Cierra un fichero. Si hemos hecho alguna operación de escritura en el mismo, el método se asegura de que los datos hayan quedado físicamente grabados en el fichero. La sintaxis general es:

objetoFile.close();

EL MÉTODO flush()

Este método se asegura de que los datos que hayamos enviado al fichero queden físicamente grabados en el mismo. Actúa igual, en ese sentido, que el método anterior, pero sin cerrar el mismo. La sintaxis general es:

objetoFile.flush();

EL MÉTODO isDirectory()

En la estructura de datos en un sistema de almacenamiento se tratan los directorios como un tipo especial de fichero. Este método nos devuelve un valor true si el fichero al que nos referimos es, en realidad, un directorio, o un false, si es un fichero como tal. La sintaxis general es:

boolean esDirectorio = objetoFile.isDirectory();

EL MÉTODO openNextFile()

Cuando se tienen almacenados directorios y ficheros en una tarjeta SD, existe un puntero que apunta al último directorio o fichero que se abrió, se creó o sobre el que se hizo cualquier operación. Si no se ha hecho ninguna operación, este puntero apunta al primer directorio o fichero de la llamada Tabla de Asignación de Archivos (de ahí el nombre FAT, File Allocation Table).

Este método abre el siguiente archivo (aquel al que está apuntando el puntero de la FAT). Es un poco engorroso, porque se aplica a un objeto de la clase FILE y genera otro objeto de la misma clase, así:

proximoFichero = objetoFile1.openNextFile();

EL MÉTODO peek()

Lee un byte del fichero al que se refiere, sin desplazar el puntero interno, por lo que el resultado de aplicar FILE.available() será el mismo antes y después de usar FILE.peek(). La sintaxis general es:

byte dato = objetoFile.peek();

EL MÉTODO position()

Devuelve la posición del puntero interno de un fichero. La sintaxis general es:

unsigned long posicion = objetoFile.position();

EL MÉTODO print()

Graba datos en un fichero. Los números se grabarán dígito a dígito. Por ejemplo, si queremos grabar 512 se grabará 5, 1 y 2. La sintaxis general es la siguiente:

objetoFile.print("Hola");

Opcionalmente, puedes pasarle un segundo argumento, para indicar si quieres grabar los datos en una base de numeración específica. Las opciones son: BIN (binario), OCT (octal), DEC (decimal) y HEX (hexadecimal). Por ejemplo:

objetoFile.print("Hola", BIN);

EL MÉTODO println()

Funciona igual que el método anterior, y con las mismas opciones, pero añadiendo, al final, una secuencia de salto de línea y retorno de carro. Si solo quieres enviar estas secuencias, puedes usar el método sin argumentos, así:

objetoFile.println();

EL MÉTODO rewindDirectory()

Cómo hemos comentado, existe un puntero que indica cual es el último fichero sobre el que se ha efectuado alguna operación. Si queremos reinicializar ese puntero, para que apunte al principio de la FAT, usamos este método, con la siguiente sintaxis:

objetoFile.rewindDirectoy();

EL MÉTODO read()

Lee el siguiente byte disponible del fichero. Al contrario que peek(), este método SÍ desplaza el puntero interno del fichero al siguiente byte. La sintaxis es:

byte dato = objetoFile.read();

EL MÉTODO seek()

Desplaza el puntero a un byte concreto del fichero, que se le pasa cómo argumento. Este valor estará entre 0 y el tamaño del fichero en bytes. Su sintaxis es la siguiente:

objetoFile.seek(posicion);

EL MÉTODO size()

Devuelve el tamaño del fichero en bytes. La sintaxis general es la siguiente:

unsigned long peso = objetoFile.size();

EL MÉTODO write()

Escribe datos en un fichero. Podemos usar dos sintaxis. La primera es la más simple:

byte escrito = objetoFile.write(dato);

En esta sintaxis, dato es un byte, carácter (char) o string (char*).

La otra opción es la siguiente:

byte escrito = objetoFile.write (arr, tam);

En este caso, arr es una matriz de caracteres o bytes y tam es el tamaño de la misma.

Este método devuelve el número de bytes que ha escrito en el fichero.

     

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *