Desarrollaremos ejemplos para trabajar con tarjetas SD o Micro SD, veremos las conexiones y características de estos dispositivos.

Las memorias SD son las más usadas por dispositivos portátiles, por su gran capacidad y su reducido tamaño, debido a su gran demanda son fáciles de conseguir en diferentes capacidades y precios. Estas características nos dan una buena alternativa de almacenamiento para usarlo en Arduino, sobretodo cuando necesitamos guarda gran cantidad de información.

Estas memorias vienen en tres tamaños, SD estándar, Mini SD y Micro SD, siendo este

último el tamaño más común, funcionalmente son iguales, pudiéndose usar adaptadores para utilizarlos en sockets de diferente tamaño.

 

 Con respecto al formato podemos encontrar 4 tipos, las tarjetas SD o SDSC (Standard Capacity), SDHC (High Capacity), SDXC (Extended Capacity) y las SDIO (Input/Output), permitiéndonos Arduino trabajar con los dos primeros tipos.

La comunicación de la memoria es por SPI pero trabajan con 3.3V, para utilizarlo con Arduino necesitamos módulos externos que aparte de tener el socket traen los componentes necesarios para adaptar los voltajes a TTL y poder conectarlo de forma fácil a nuestro Arduino.

Para este tutorial podemos usar cualquiera de estos dos módulos:

Modulo Micro SD: nos permite insertar una memoria Micro SD que son las más comunes en el mercado, el modulo se puede alimentar con 3.3V o 5V usando los pines respectivos.

 

Módulo SD card: Este módulo trae el socket grande para las memorias SD de tamaño estándar, pero usando un adaptador podemos usar también memorias micro SD

 

Arduino tiene una librería para usar estas memorias, que funciona con cualquiera de los módulos antes mencionados. La librería ya viene junto con el IDE de arduinos, por lo que no necesitamos instalar ni descargar nada.
  

Para poder usar la librería en nuestro Sketch es necesario incluir a la librería SD al inicio del código:

#include <SD.h>

A continuación explicamos las funciones principales de la librería SD, el cual es un resumen de la referencia proporcionada en la página oficial de Arduino: https://www.arduino.cc/en/Reference/SD

SD.begin(cspin)

Inicializa la biblioteca SD y la tarjeta, como parámetro se le indica el pin CS al que está conectado el modulo, si no se especifica cspin , se usa el valor por defecto del CS por hardware. Los demás pines deben estar conectados al SPI por hardware del Arduino.

SD.exists(filename)

Comprueba si existe el archivo especificado, filename es el nombre del archivo y/o directorio en la tarjeta SD si este existe la función nos retorna un true, de lo contrario retorna false.

SD.mkdir(directory)

Crea el directorio especificado, si los subdirectorios no existen, también se crearan. Por ejemplo: SD.mkdir(“Arduino/proyecto1/archivos), crea la carpeta “archivos” y si las carpetas Arduino y proyecto1 no existen, entonces también se crearan. La función retorna true si la creación del directorio fue exitosa de lo contrario nos retorna un false

SD.remove(filename)

Elimina el archivo (filename) de la tarjeta SD, se debe de incluir el directorio. Solo elimina el archivo más no el directorio. Devuelve true se logra eliminar el archivo de lo contrario nos retorna un false.

SD.rmdir(dirname)

Eliminar el directorio (dirname) de la tarjeta SD. El directorio debe estar vacío. Devuelve TRUE si la eliminación del directorio tuvo éxito o FALSE en caso contrario.

SD.open(filepath, mode)

Abre el archivo especificado y se debe de incluir el directorio si el archivo está en carpetas. Si el archivo no existe, se creara un archivo con el nombre especificado, pero no será posible crear el directorio si este no existe. Se puede abrir un archivo como solo lectura (si mode es FILE_READ) o como lectura y escritura (si mode es FILE_WRITE), el modo por defecto en caso no se especifique es FILE_READ

Ésta función nos retorna un objeto tipo FILE, el cual es necesario declararlo antes como una variable. Por ejemplo:

  File myFile;
  myFile = SD.open("archivo.txt", FILE_WRITE);

Funciones de la clase File:

file.available()

Compruebe si hay bytes disponibles para leer en el archivo y retorna el número de bytes disponibles

file.read()

Lee un byte de la variable File (archivo abierto anteriormente con SD.open())

file.write(data)

Escribe un byte en el archivo, el archivo debe estar abierto en modo lectura y escritura. Usando file.write(buf, len) se puede escribir un array de byte (buf) pero se debe especificar el tamaño (len).

file.print(data)

Esta función tiene las mismas características que un Serial.print(); data puede ser una variable o texto, el cual será enviado como caracteres. Si queremos agregar al final un salto o nueva línea se usa file.println(data)

file.size()

Retorna el tamaño en bytes del archivo

file.position()

Retorna la posición actual en donde se leerá o escribirá el siguiente byte.

file.seek(pos)

Nos ubicamos en una posición específica en el archivo. Pos debe ser un número entre 0 y el tamaño en bytes del archivo

file.close()

Cerramos el archivo, y recién en este momento los datos se guardan en la SD, pudiendo extraer de forma segura nuestra SD.

 Explicado la librería empecemos viendo como conectar los módulos con nuestro Arduino:

 

Conexión entre Arduino y modulo SD y micro SD

 

Las conexiones para el modulo SD son las siguientes;

 

Módulo SD

Arduino Uno, Nano

Arduino Mega

GND

GND

GND

+3.3V

No conectado 

No conectado

+5V

5V

5V

CS

4

4

MOSI

11

51

SCK

13

52

MISO

12

50

GND

GND

GND

 *Se puede alimentar con 5V o 3,3V usando los pines correspondientes, pero no se debe de alimentar por ambos pines a la vez

 

Y las conexiones si se trabajan con el módulo micro SD son:

Módulo SD

Arduino Uno, Nano

Arduino Mega

CS

4

4

SCK

13

52

MOSI

11

51

MISO

12

50

VCC

5V

5V

GND

GND

GND

3.3V

No conectado

No conectado

*Se puede alimentar con 3,3V en lugar de 5V usando el pin correspondientes, pero no se debe de alimentar por ambos pines a la vez

 

Ej1.  Leer un archivo de la SD con nuestro Arduino

En este ejemplo vamos a leer un archivo de texto desde la SD.

Para esto insertamos nuestra SD a la PC, abrimos y creamos un archivo de hoja de texto, por ejemplo archivo.txt, e ingresamos el texto que posteriormente vamos a leer desde Arduino:

 

 Seguidamente extraemos la SD de la PC, lo insertamos en el módulo SD. Y cargamos el siguiente sketch en nuestro Arduino:

#include <SD.h>

File myFile;

void setup()
{
  Serial.begin(9600);
  Serial.print("Iniciando SD ...");
  if (!SD.begin(4)) {
    Serial.println("No se pudo inicializar");
    return;
  }
  Serial.println("inicializacion exitosa");
 
  myFile = SD.open("archivo.txt");//abrimos  el archivo 
  if (myFile) {
    Serial.println("archivo.txt:");
    while (myFile.available()) {
    	Serial.write(myFile.read());
    }
    myFile.close(); //cerramos el archivo
  } else {
    Serial.println("Error al abrir el archivo");
  }
}

void loop()
{
  
}

 

EL programa envía por el puerto serie todo el contenido del archivo guardado en la SD.

 

 Ej2. Leer datos desde la SD, Manipulando leds desde la SD

En este caso no solo vamos a leer el archivo desde la SD sino vamos a interpretar y realizar ciertas acciones con los datos.

En un archivo de texto vamos a guardar datos para encender y apagar leds y con esto ejecutar diferentes secuencias que estarán guardadas en la SD.

Conectamos ocho leds en los pines del 2 al 10, excluyendo el 4, con su resistencia respectiva.

Desde la PC en la SD en una hoja de texto guardamos las secuencias que deseemos realizar.

 

 El primer número de cada línea corresponde a la pausa o tiempo que va a estar presente la secuencia, los siguientes ocho números corresponde a la secuencia o estado de cada uno de los ocho leds, ustedes pueden escribir cualquier secuencia o tambien pueden descargar el archivo de texto que usamos para este ejemplo: Leds.txt

Después de escribir nuestras secuencias de los leds en la hoja de texto guardamos con nombre Leds.txt e insertamos la SD en el módulo de nuestro Arduino

El Sketch es el siguiente.

#include <SD.h>

File myFile;
int UltimaPocicion=0;
int pausa=1000;
int PinLeds[8]={2,3,5,6,7,8,9,10};//Pines de los Leds
void setup()
{
  Serial.begin(9600);
  Serial.print("Iniciando SD ...");
  if (!SD.begin(4)) {
    Serial.println("No se pudo inicializar");
    return;
  }
  Serial.println("inicializacion exitosa");
  for(int i=0;i<8;i++)
  {
    pinMode(PinLeds[i],OUTPUT);
  }
 
}

void loop()
{
  myFile = SD.open("Leds.txt");//abrimos  el archivo
  int totalBytes=myFile.size();
  String cadena="";
  
  if (myFile) {   
      if(UltimaPocicion>=totalBytes)   UltimaPocicion=0;
      myFile.seek(UltimaPocicion); 
      
      //--Leemos una línea de la hoja de texto--------------
      while (myFile.available()) {
          
      	char caracter=myFile.read();
          cadena=cadena+caracter;
          UltimaPocicion=myFile.position();
          if(caracter==10)//ASCII de nueva de línea
          {            
            break;
          }
      }
      //---------------------------------------------------
      myFile.close(); //cerramos el archivo
      Serial.print("Cadena Leida:");
      Serial.print(cadena);
      //-----------procesamos la cadena------------
      int index=0;
      char c=cadena[index++];
      pausa=0;
      while (c >= '0' && c <= '9')
      {
        pausa = 10*pausa + (c - '0');
        c = cadena[index++];
      }
      Serial.print("pausa=");
      Serial.print(pausa);
      Serial.print("   LEDS |");
      for(int i=0;i<8;i++)
      {     
        if(cadena[index+i*2]=='1')
        {
          digitalWrite(PinLeds[i], HIGH);
          Serial.print(" 1 |");
         
        }
        else
        {
          digitalWrite(PinLeds[i], LOW);
          Serial.print(" 0 |");
        } 
      }
      Serial.println();
      Serial.println();    
  
  } else {	
    Serial.println("Error al abrir el archivo");
  }
  delay(pausa);
}

Como se observa Leemos una línea de la SD la procesamos y mostramos la secuencia en los leds durante el tiempo que también obtenemos desde la SD,  es necesario después de cada lectura guardar la última posición de memoria para que en la segunda lectura continuemos la lectura desde esa posición, esto porque después de cada lectura cerramos el archivo.

A continuación se muestra la salida del monitor serial, que es un reflejo de lo que se muestra en los leds:

  

 Ej3. Guardando datos en la SD (Datalogger)

En este ejemplo guardaremos información de variables y sensores en nuestra SD

Para simular los sensores utilizamos 3 potenciómetros que deben estar conectados a los pines A0, A1 y A2 del Arduino.

El sketch es el siguiente:

#include <SD.h>

File myFile;
void setup()
{
  Serial.begin(9600);
  Serial.print("Iniciando SD ...");
  if (!SD.begin(4)) {
    Serial.println("No se pudo inicializar");
    return;
  }
  Serial.println("inicializacion exitosa");
}

void loop()
{
  myFile = SD.open("datalog.txt", FILE_WRITE);//abrimos  el archivo
  
  if (myFile) { 
        Serial.print("Escribiendo SD: ");
        int sensor1 = analogRead(0);
        int sensor2 = analogRead(1);
        int sensor3 = analogRead(2);
        myFile.print("Tiempo(ms)=");
        myFile.print(millis());
        myFile.print(", sensor1=");
        myFile.print(sensor1);
        myFile.print(", sensor2=");
        myFile.print(sensor2);
        myFile.print(", sensor3=");
        myFile.println(sensor3);
        
        myFile.close(); //cerramos el archivo
        
        Serial.print("Tiempo(ms)=");
        Serial.print(millis());
        Serial.print(", sensor1=");
        Serial.print(sensor1);
        Serial.print(", sensor2=");
        Serial.print(sensor2);
        Serial.print(", sensor3=");
        Serial.println(sensor3);       
                    
  
  } else {
    Serial.println("Error al abrir el archivo");
  }
  delay(100);
}

  

En el monitor serial muestra los datos que se están escribiendo en la SD:

  

 Y si insertamos la SD en nuestra PC podemos ver el archivo generado:

 

 Ej4. Exportando datos de nuestro datalogger a Excel.

En este caso los datos lo almacenaremos en forma de tabla pero no podremos guardarlos directamente en un archivo de Excel, sino los guardaremos en formato .csv el cual lo trabajaremos como si fuera una hoja de texto, las columnas lo separaremos por comas (u otro separador) y las filas por saltos de línea.

Para Excel también se podría trabajar en un archivo txt, pero en la extensión csv tenemos la posibilidad de importar no solo a Excel sino a otros programas como Calc de Open Oficce, Gnumeric, matalb o sistemas web.

Tomaremos el ejemplo anterior con la diferencia que guardaremos los datos en el formato explicado anteriormente.

El sketch para el Arduino es el siguiente:

#include <SD.h>

File myFile;
void setup()
{
  Serial.begin(9600);
  Serial.print("Iniciando SD ...");
  if (!SD.begin(4)) {
    Serial.println("No se pudo inicializar");
    return;
  }
  Serial.println("inicializacion exitosa");
  
  if(!SD.exists("datalog.csv"))
  {
      myFile = SD.open("datalog.csv", FILE_WRITE);
      if (myFile) {
        Serial.println("Archivo nuevo, Escribiendo encabezado(fila 1)");
        myFile.println("Tiempo(ms),Sensor1,Sensor2,Sensor3");
        myFile.close();
      } else {

        Serial.println("Error creando el archivo datalog.csv");
      }
  }
  
}

void loop()
{
  myFile = SD.open("datalog.csv", FILE_WRITE);//abrimos  el archivo
  
  if (myFile) { 
        Serial.print("Escribiendo SD: ");
        int sensor1 = analogRead(0);
        int sensor2 = analogRead(1);
        int sensor3 = analogRead(2);
        myFile.print(millis());
        myFile.print(",");
        myFile.print(sensor1);
        myFile.print(",");
        myFile.print(sensor2);
        myFile.print(",");
        myFile.println(sensor3);
        
        myFile.close(); //cerramos el archivo
        
        Serial.print("Tiempo(ms)=");
        Serial.print(millis());
        Serial.print(",sensor1=");
        Serial.print(sensor1);
        Serial.print(",sensor2=");
        Serial.print(sensor2);
        Serial.print(",sensor3=");
        Serial.println(sensor3);       
                    
  
  } else {
  	// if the file didn't open, print an error:
    Serial.println("Error al abrir el archivo");
  }
  delay(100);
}

  

El programa es similar al del ejemplo anterior con la diferencia que al inicio del archivo necesitamos poner el nombre de los campos o encabezado, esto lo hacemos en setup() si el archivo no existe ,entonces creamos uno y seguidamente escribimos la primera fila, para posteriormente en el void loop() solo dedicarse a escribir los datos, como el archivo ya ha sido creado, cada vez que se reinicie o se encienda el Arduino continuara escribiendo desde la última posición, si desean reanudar todo, deberán manualmente desde la pc eleiminar el archivo o por código en setup() remover el archivo con SD.remove(filename).

La salida del monitor serial es igual al del ejemplo anterior, pues solo se ha cambiado la forma de guardar en la SD:

 

 Después de obtener los datos que deseamos, el siguiente paso es ingresar la memoria SD a la PC ya con los datos guardados por nuestro Arduino.

 

 Al ingresar a la SD deben encontrar el archivo DATALOG.CSV, posteriormente abrimos Excel y en la barra de menús vamos a Datos y luego a Obtener datos externos - Desde texto.

 

 Seguidamente escogemos el archivo que deseamos importar, en nuestro caso datalog.csv y nos abrirá el asistente de importación, en el primer paso escogemos archivos delimitados

 

 En el paso 2 en separadores marcamos coma:

 

 En el paso 3 dejamos todas las columnas en general.

 

 Después de dar en finalizar, deberán escoger el lugar en donde se va iniciar la tabla:

 

 Finalmente tenemos los datos ya disponibles en Excel

 

 EL procedimiento para es similar para otras versiones de Excel y otros programas de hojas de cálculo.