Objetivos

 

  • Presentar la SD disponible en el Shield Ethernet.
  • Mostrar como leer y escribir en la tarjeta SD.
  • Ver algunos ejemplos sencillos de uso.
  •  

    Material requerido

     

    Imagen de Arduino UNO  Arduino Uno o similar.22
    Vista principal Un Ethernet shield R3

     

    Las SD Card<

     

    En los últimos años, las tarjetas SD y microSD se han popularizado mucho, debido al auge de la fotografía digital y la telefonía móvil. No es fácil encontrar un teléfono móvil o Tablet, a quien no se le pueda ampliar la memoria con una de estas tarjetas, con la excepción claro está, de Apple, que como es habitual va por libre.

    micro SD card micro SD a SD completa

     

    Basadas en la tecnología de memoria FLASH, permiten escribir con buena velocidad (Relativamente ) y además no pierden el contenido cuando las desconectamos, lo que las ha convertido en una solución de primera para intercambiar información.

    Desde cámaras de fotos, Teléfonos digitales y Memorias USBs, la tecnología FLASH ha tenido un éxito rotundo y una aceptación masiva, lo que ha llevado los precios a la baja y prácticamente han acabado con CDs DVDs y demás formatos ópticos para la transferencia de información.

    Hoy día no es raro comprar memorias USB de 8, 16 o 32 Gb por el precio de una entrada de cine. Y como nuestro Shield Ethernet lleva un lector grabador de tarjetas micro SD, no podíamos dejar pasar la ocasión sin ver cómo usarlas.

    Detalle SD card
     

    Aunque ya hemos comentado que los Arduinos, incluyen una memoria EEPROM interna que podemos usar como mini disco duro, no se puede comparar con la posibilidad de disponer de una tarjeta SD intercambiable, especialmente en lo que a capacidad se refiere.

    Por eso, en muchos proyectos, es muy interesante de disponer de uno de estos pequeños grabadores, que nos permitan ir registrando los datos que vamos leyendo de sensores, normalmente en combinación un Reloj de tiempo real RTC, y a los que posteriormente podemos acceder y procesador en nuestros PCs mucho más cómodamente.
     

    Características básicas de las SD Card

     

    Lo primero que os interesa saber es que Arduino puede leer y escribir SD Cards con ciertas limitaciones, debido a la librería actualmente en uso. Como siempre estas limitaciones o especificaciones pueden cambiar en el futuro, pero es importante que las tengáis en cuenta.

    La primera es que Arduino puede leer y escribir en estas tarjetas, pero no formatearlas. Esto debe hacerse desde vuestros PCs. No es grave, pero es así.

    Lo segundo es que vuestros PCs pueden manejar varios formatos de sistema de archivos, pero la librería SD por ahora solo soporta FAT16 y FAT32.

    Ambos formatos son una herencia de los viejos tiempos y de algún modo determinan el máximo tamaño de disco (O de tarjeta) que puedes usar. En principio si usas FAT32 deberías poder usar hasta una tarjeta de 32Gb.

    Así que si queréis que el Shield Ethernet lea vuestra tarjeta, nada de formatearla en NTFS de Windows, HPFS de Apple o extN de Linux. Solo FAT16 y FAT32.

    Después tenemos otra limitación con los nombres e archivos que quedan limitados al viejo formato 8.3, con nombre de 8 caracteres y extensiones de tres. Y nada de acentos en los nombres ni Ñs ni espacios en blanco. Nada que no sean letras y números, sin signos raros.

    Si usas Windows en cualquier versión, puedes introducir la tarjeta SD y formatearla desde el administrador de archivos. Introduce la tarjeta en el lector y cuando la reconozca, apuntala y pulsa el botón derecho. Elige la opción formatear y veras una ventana como esta:

    Formatear una tarjeta SD

    Opciones de formateo para SD

    En el sistema de archivos puedes elegir FAT32, y mantén el tick en la opción formato rápido. Con inicio te formateará la tarjeta.

    En OSX ve a Aplicaciones, Utilidades, Discos. Elije la tarjeta SD y selecciona el formato de disco MS-DOS FAT

    Como formatear una tarjeta SD
     

    Existe un programa que suelen recomendar si tenéis cualquier problema, que tiene versiones para Mac y Windows llamado SD Formatter  que podéis descargar gratuitamente de internet. Está desarrollado y soporte por la asociación de fabricantes de tarjetas SD.

    Por ultimo tenéis que saber que la librería puede no escribir inmediatamente los datos que le envías a la SD, y para asegurarse de que es así, debes hacer una llamada a flush (Vaciar) o close (Guardar y cerrar).

     

    Comprobando la SD Card

     

    Necesitáis saber que el Shield Ethernet y la librería, controlan el acceso a Ethernet y a la SD Card por SPI. Vimos que era así en el caso Ethernet y recordad que no podíamos usar unos pines en el Arduino, los que corresponden a la gestión el bus SPI.

    Usamos el pin 10, Slave Select habitualmente en un UNO para seleccionar el acceso a Ethernet (El 53 en un MEGA), y necesitamos otro pin para indicar que vamos a hablar con la tarjeta SD. En el caso de un Arduino UNO el Shield Ethernet utiliza el pin 4 y por también lo reservamos en las sesiones anteriores.

    Vamos a comprobar que la SD esta correcta y que podemos usarla. Aseguraros de que esta formateada y ponerle uso pocos ficheros en ella (con nombre 8.3) introducidla en el lector del Shield y enciende Arduino.

    Como la librería SD viene de serie con nuestro Arduino, podemos cargar uno de los ejemplos para comprobar que lee la tarjeta:  \\Achivo\Ejemplos\SD\CardInfo

    Salida ARduino
     

    Si todo va bien cuando lo corráis tendréis una salida parecida a esto:

    Os informa de que ha podido  identificar la SD, y os da información del tipo de formato, tamaño de la tarjeta y hasta hace un listado de los ficheros que contiene junto con algunas características.

    Si veis algo así, perfecto podemos seguir. SI recibís algún mensaje de error, necesitamos que lo corrijáis antes de seguir.

    Los problemas más típicos suelen ser

  • No tener bien encajado el Shield en el Arduino
  • Por defecto trae el pin 10 como output pero si usáis un Mega tenéis que cambiarlo
    pinMode(10, OUTPUT);     // change this to 53 on a mega
  •  

    El programa de control

     

    Para usar la tarjeta SD, tenéis en primer lugar que cargar las librerías SPI y la SD:

    #include <SPI.h>
    #include <SD.h>

    Después tenéis que activar el pin SS

    pinMode(10, OUTPUT);     // Para un Arduino UNO
    pinMode(53, OUTPUT);     // Para un MEGA

    Y como siempre, necesitamos iniciar la SD Card con

    SD.begin(4) ;

    Donde 4 es el chipSelect es de la tarjeta SD. El resto es fácil. Definir un objeto File para leer un fichero de la SD:

    File root;

    Ya solo queda abrir un fichero para lectura. Supón que se llama index.htm

    File dataFile = SD.open("index.htm ");

    Si consigue abrir correctamente dataFile tomara un valor que apunta a la estructura a leer del fichero, en caso contrario se pondrá a 0 indicando el error.

    Vamos a ver cómo hacer un programa  que lea un fichero en la SD y lo envié a la consola para ver lo que contiene:

    #include <SPI.h>
    #include <SD.h>
    const int chipSelect = 4;
    
    void setup()
       {  Serial.begin(9600);
          while (!Serial)  ;       // wait for serial port to connect. Needed for Leonardo only
          Serial.print("Probando SD card...");
          pinMode(10, OUTPUT);         // Esto es necesario aunque creas que no lo usas.
          if (!SD.begin(chipSelect))
               {  Serial.println("No hay tarjeta");
                  return;    // NO sigas
               }
          Serial.println("Sd encontrada.");
          File dataFile = SD.open("index.htm");
         if (dataFile)   // Si ha podido abrir el fichero
            {    while (dataFile.available())              // Mientras no llegues al final
                      Serial.write(dataFile.read());       // Lee el fichero y envialo al serie
                 dataFile.close();                         // Cierra el fichero al acabar
            }
         else     // SI no puede abrir el fichero
               Serial.println("Error, no puedo usar indes.htm");
       }
    void loop()
       { }
    
    

    SD.open() abre el fichero que buscamos y devuelve un puntero de tipo File para leer datos directamente., o un 0 si no puede.

    Conviene insistir en que la SD card es también una clase que deriva de stream y por tanto hereda propiedades que ya conocemos de otras sesiones. Es el caso de datFile.Available() que vimos anteriormente con Serial como Serial.Available(), es decir, mientras haya datos disponibles, pendientes de leer.

    dataFile.read(), lee un carácter del fichero y Serial.write lo envía a la consola. Por ultimo dataFile.Close, cierra y libera el fichero .

    [one-fourth]  [/one-fourth][three-fourth last][margin value=»5″ /][fancy-ul style=»rounded-tick»]

    [three-fourth last][margin value=»5″ /][fancy-ul style=»rounded-tick»]

    • Si no hacemos dataFile.close(), no podemos estar seguros de que se ha escrito todo lo que queríamos al fichero.
    • No basta con sacar la SD y llevártela. Si lo haces puedes corromper toda la información de la SD Card.
    • Además la librería SD solo permite un fichero abierto a la vez. Si quieres abrir otro fichero tienes que cerrar primero el anterior

    [/fancy-ul] [/three-fourth]

     

    Un programa que grabe datos en la SD card

     

    La tarjeta SD se comporta como la puesta Serie, y prácticamente se maneja igual, con pequeñas diferencias. En el programa anterior para leer el fichero,  usábamos:

    File dataFile = SD.open("index.htm");

    Sin pasarle ningún parámetro a SD.open() diferente del nombre del fichero. Esto hace que lo abramos en forma de lectura, lo que impide que escribamos en él. Solo podemos leer.

    Para conseguir escribir en un fichero usamos

    File dataFile = SD.open("data.txt", FILE_WRITE);

    La idea del nuevo programa, es que va a escribir unos valores que lee de las puertas A2 a A4 y lo graba en el fichero data.txt (Naturalmente, como no tenemos nada conectado, leerá basura, pero eso no nos importa mucho ahora mismo). La parte interesante del programa está aquí:

    Programa 65_2

    File dataFile = SD.open("data.txt", FILE_WRITE);
    if (dataFile)   // Si ha podido abrir el fichero
       {    dataFile.println("Vamos a escribir un par de textos en la tarjeta SD")
            for (int j=0 ; j <20 ; j++)
               {
                  dataFile.println("Analog 2: " + String(analogRead(A2)));
                  dataFile.println("Analog 3: " + String(analogRead(A3)));
                  dataFile.println("Analog 4: " + String(analogRead(A4)));
                  dataFile.println("....................................");
                  delay (100);
               }
            dataFile.close();
            Serial.println("Listo. Terminado");
            Volcado() ;
       }

    Abrimos el fichero data.txt y escribimos a él como si fuera la puerta Serie. Al acabar simplemente cerramos el fichero y listo.

    Volcado() es una función que hace lo que vimos en el programa anterior. Copia a la consola el contenido del fichero para que veáis lo que contiene.

    SAlida a consola del Arduino

    Si corréis el programa unas cuantas veces veréis que, la primera vez, crea el fichero data.txt y escribe lo que le pedimos en él. Pero si cuando hace el SD.open () el fichero ya existe, la información que le enviamos se añade al final, sin borra el contenido anterior.

    Lo que resulta muy práctico cuando quieres grabar información de sensores y generar un histórico

     

    Operando con la estructura de ficheros de la SD

     

    Siempre que creas un sistema de ficheros en un dispositivo vas a necesitar ayudas para mantenerlo. La librería SD de Arduino, nos da una serie de funciones para jugar con ficheros y directorios. Al hacer

    SD.open (“File.txt”)

    Se crea el fichero en caso de no existir y podemos leer, pero no escribir. Y cuando hacemos:

    SD.open("data.txt", FILE_WRITE)

    Se crea, si no existe, y escribirá desde el principio. Pero si existe, todo lo que escribamos decíamos que se añade al final de lo que ya existía.  Pero a veces nos interesa empezar una página en blanco, lo que podemos hacer borrando el fichero si existe:

    SD.remove(“data.txt”);

    Y mejor aún si comprobamos si existe antes:

    if (SD.exists(data.txt)
        SD.remove(“data.txt”) ;

    También podemos usar estructuras de directorios (Aunque no tengo claro hasta donde) y podemos crearlos y bórrarlos con la SD library:

    SD.mkdir("/a/b/c")
    SD.rmdir(filename)

    Mkdir puede crear directorios anidados y basta con referir el path completo del fichero y rmdir los elimina con todo su contenido

    También dispone de un juego completo de funciones de ayuda:

    Método Descripción
    File.Available() Nos indica que si hemos llegado al fin e un fichero
    File.flush() Se asegura de que se escribe en la SD todo. Algo que hace automáticamente al hacer close()
    File.read() Lee un carácter del fichero abierto y avanza a la siguiente posición
    File.write() Escribe un carácter al fichero y avanza la posición
    File.position() Te indica la posición donde escribirá/leerá el próximo carácter en relación al principio el fichero
    File.size() Devuelve el tamaño de un fichero
    File.seek(pos) Coloca el apuntador que indica donde leerá/escribirá en la posición que le indicamos a partir del inicio y siempre que este entre 0 y File.size()
    File.peek() Lee un char de la posición que marca el apuntador y no avanza
    File.isDirectory() Indica si el fichero abierto es o no un directorio

    Hay algún que otro método adicional que podéis consultar en la documentación de la SD library
     

    Resumen de la sesión

     

  • Hemos presentado la librería Arduino que nos permite acceder a la SD Card incluida.
  • Hemos visto un par de ejemplos sencillos, para mostrar cómo se lee y se escribe en la tarjeta.
  • Hemos visto que cuando escribimos, el modo por defecto, es añadir desde el final de lo que hubiera. La idea de esto es facilitar la creación de registros de datos de una forma cómoda, y es uno de los usos más habituales de las tarjetas SD.
  •  

    Deja una respuesta