Manejando un módulo de tarjeta SD con Arduino

 Hola!

En esta entrada intentaremos explicar cómo manejar un módulo de tarjeta SD con Arduino. Una vez aprendamos su manejo, podremos intentar integrarlo en nuestro proyecto de Robot. Y dar otro uso con un módulo de speaker.

El uso del módulo gestor de tarjetas SD se fundamenta en una interfaz serie, el bus SPI. 

Bus de comunicación

La función del bus es permitir la conexión lógica entre los diferentes subsistemas que componen el computador o en este caso el microcontrolador. Existen dos tipos de arquitectura de buses, los buses en serie y los buses en paralelo. Los buses en serie transmiten la información bit a bit mientras que los buses en paralelo pueden transmitir varios bit al mismo tiempo. Aunque a primera vista parece que los buses en paralelo presentan características más ventajosas para la comunicación de las distintas partes de la arquitectura que conforma el microcontrolador, en la realidad no es tan fácil, ya que la transmisión en paralelo presenta varias desventajas. En una conexión paralela, los ocho bits que salen al mismo tiempo no llegan al otro extremo al mismo tiempo; algunos llegan más tarde que otros. Esto se conoce como transmisión sesgada. El hecho de que los cables paralelos estén agrupados físicamente significa que una señal puede a veces dejar su huella en el cable adyacente lo que puede aumentar la posibilidad de errores en la comunicación. Por todo ello, la tendencia en los últimos años es reemplazar los buses paralelos por buses serie (que suelen ser multicanal) que permiten una mayor refrigeración al disminuir el espacio necesario y a unas velocidades muy elevadas de transmisión con una mayor fiabilidad.

Los buses de comunicación en Arduino


I2C (Abreviatura de Inter-IC -inter integrated circuits-, un tipo de bus serie diseñado por Philips Semiconductors a principios de los 80s, que se utiliza para conectar circuitos integrados), SPI (Serial Peripheral Interface) y UART (Universal Asynchronous Receiver-Transmitter, en español: Transmisor-Receptor Asíncrono Universal) son los periféricos de comunicación hardware más básicos y comunes que  los fabricantes utilizan en el desarrollo de microcontroladores, y como se muestra en la imagen Arduino no es una excepción. 

El controlador del UART es el componente clave del subsistema de comunicaciones series de una computadora. El UART toma bytes de datos y transmite los bits individuales de forma secuencial. En el destino, un segundo UART reensambla los bits en bytes completos.

Todos los buses y componentes indicados se utilizan para la transmisión de información (bits) en serie.

El bus SPI

Nos centraremos en el bus SPI como infraestructura sobre la que desplegar la conexión de nuestra tarjeta SD.

El bus SPI tiene interés como medio de comunicación porque una gran variedad de sensores y dispositivos comerciales disponen de un interfaz SPI como medio de comunicación.

El Bus SPI (del inglés Serial Peripheral Interface) es un estándar de comunicaciones, usado principalmente para la transferencia de información entre circuitos integrados en equipos electrónicos. El bus de interfaz de periféricos serie o bus SPI es un estándar para controlar casi cualquier dispositivo electrónico digital que acepte un flujo de bits serie regulado por un reloj (comunicación sincróna). 

Un bus de periféricos serie es la opción más flexible cuando se tiene tipos diferentes de periféricos serie. El hardware consiste en señales de reloj, data in, data out y chip select para cada circuito integrado que tiene que ser controlado. Casi cualquier dispositivo digital puede ser controlado con esta combinación de señales

El SPI es un protocolo síncrono. La sincronización y la transmisión de datos se realiza por medio de 4 señales:

  • SCLK (Clock): Es el pulso que marca la sincronización. Con cada pulso de este reloj, se lee o se envía un bit. También llamado TAKT (en alemán).
  • MOSI (Master Output Slave Input): Salida de datos del Master y entrada de datos al Esclavo. También llamada SIMO.
  • MISO (Master Input Slave Output): Salida de datos del Esclavo y entrada al Master. También conocida por SOMI.
  • SS/Select: Para seleccionar un Esclavo, o para que el Master le diga al Esclavo que se active. También llamada SSTE.

Conexiones y componentes

 

Las conexiones para los pines 11, 12, 13 están fijadas para las señales del bus SPI. Aunque se suele agrupar la señal SS en el pin correlativo, no tiene por qué ser así. De hecho en nuestro ejemplo vamos a usar el PIN digital 4 para conectar la señal SS de la tarjeta a Arduino.

 
Dónde conectar los pines de la SD en Arduino
El módulo de tarjeta SD (no microSD) que compré para realizar este proyecto costó 86 céntimos, es decir solo ha hecho falta usar el adaptador SD para microSD (que traen casi todas las tarjetas microSD que compramos) para poder insertar la tarjeta.

Podemos comprobar si hemos realizado bien el conexionado del módulo así como si funciona la tarjeta microSD con adaptador SD que hemos insertado con un código de ejemplo que incopora el IDE en la siguiente opción del menú.
 
 
Comprobar módulo tarjeta

 
Solo debemos cargar el sketch del ejemplo en nuestro arduino, cambiando el pin CS por el que hayamos puesto nosotros previamente y lanzar el monitor serie, si todo va bien nos mostrará información sobre la tarjeta insertada.

Lo siguiente es código que permitiría iniciar la SD y verificar a través del monitor serial si se inicia, escribe o lee contenido de la tarjeta SD.

#define SSpin 4
..
void setup() { 
iniciarSD();
     EscribirSD();
    LeerSD();
}

 void iniciarSD()
 {
  Serial.print(F("Iniciando SD ..."));
  if (!SD.begin(SSpin))
  {
    Serial.println(F("Error al iniciar"));
    return;
  }
  Serial.println(F("Iniciado correctamente"));
 }

 void EscribirSD()
 {
  int value;
  // Abrir archivo y escribir valor
  logFile = SD.open("datalog.txt", FILE_WRITE);
   Serial.println(F("ESCRIBIENDO EN SD"));
  if (logFile) {
        value=readSensor();
        logFile.print("Time(ms)=");
        logFile.print(millis());
        logFile.print(", value=");
        logFile.println(value);
        
        logFile.close();
 
  }
  else {
    Serial.println(F("Error al abrir el archivo"));
  }
 }

void LeerSD()
{

  //String dataLine;
  //char caracter;
  Serial.println(F("LEYENDO EN SD"));
  logFile = SD.open("datalog.txt");
 
 
  if(logFile){
    while (logFile.available())
   {
      //caracter = dataFile.read();
       Serial.write(logFile.read());  // En un caso real se realizarían las acciones oportunas
    }
    logFile.close();
  }
  else
  {
    Serial.println(F("Error al abrir el archivo"));
  }
}


En una futura entrada intentaremos reproducir sonido desde la tarjeta a través de un altavoz conectado a la protoboard.
 
Gracias por tu tiempo y atención!
Un saludo!

Fuentes

  • https://es.wikipedia.org/wiki/Serial_Peripheral_Interface
  • https://naylampmechatronics.com/blog/38_Tutorial-arduino-y-memoria-SD-y-micro-SD-.html
  • https://es.wikipedia.org/wiki/Controladora_de_perif%C3%A9rico
  • https://www.computerworld.es/archive/serial-versus-paralelo-cual-escoger
  • https://www.seeedstudio.com/blog/2019/11/07/arduino-communication-peripherals-uart-i2c-and-spi/