Gestión de memorias microsd con arduino


Es obvio que las SD se han convertido en algo indispensable en nuestra vida digital , estando presentes en infinidad de dispositivos electrónicos como smartphones, cámaras digitales, cámaras de seguridad, reproductores multimedia, ordenadores, microcontroladores, y un larguísimo etcétera.

Por otro lado, de vez en cuando nos encontramos con proyectos basados en Arduino que necesitan una forma de almacenar una gran cantidad de datos de forma escalable y eficiente ( es decir, necesitamos construir lo que viene a llamarse un registrador de datos o en ingle «datalogger»), siendo lo ideal por tanto usar con nuestro microntrolador precisamente estas tarjetas SD o micro SD, dada su gran capacidad para empaquetar GigaBytes de datos en un espacio más pequeño que una moneda.

En este post vamos a ver que en realidad leer o escribir datos en una SD ( o microsd) en el entorno de la familia Arduino es en realidad muy sencillo gracias a las libreria SD y tambien la SPI para la comunicacion con el lector de SD.

Descripción general del hardware

Para este proyecto se ha probado el lector de sd de AZDelivery el cual nos proporciona una expansión fácil y económica del espacio de almacenamiento mediante la ranura SD. La comunicación es muy fácil con el microcontrolador a través del protocolo SPI (como vamos a ver ) y soporta tarjetas Micro SD (2G), tarjetas Micro SDHC (32G) (tarjeta de alta velocidad). Además el módulo lee todos los datos contenidos en la tarjeta SD y se puede conectar fácilmente a varios tipos de microcontroladores ( además si lo compramos a este fabricante incluye un E-Book que proporciona información útil sobre cómo comenzar su proyecto, ayuda con una configuración rápida y ahorra tiempo en el proceso de configuración proporcionándonos una serie de ejemplos de aplicación, guías de instalación completas y bibliotecas, etc.).

El módulo de la tarjeta micro SD contiene dos componentes principales que, sin duda, hacen que sea fácil agregar el registro de datos a su próximo proyecto Arduino:

  • El voltaje de funcionamiento de cualquier tarjeta micro SD estándar es de 3,3 V. Por lo tanto, no podemos conectarlo directamente a circuitos que usan lógica de 5V. De hecho, cualquier voltaje que supere los 3,6 V dañará permanentemente la tarjeta micro SD. Es por eso; el módulo tiene un regulador de caída ultrabaja incorporado que convertirá los voltajes de 3,3 V a 6 V a ~3,3 V.
  • También hay un chip 74LVC125A en el módulo que convierte la lógica de la interfaz de 3,3 V-5 V a 3,3 V. Esto se llama cambio de nivel lógico. Eso significa que puede usar esta placa para interactuar con microcontroladores de 3,3 V y 5 V como Arduino.

En realidad, hay dos formas de interactuar con tarjetas micro SD: modo SPI y modo SDIO. El modo SDIO es mucho más rápido y se usa en teléfonos móviles, cámaras digitales, etc, pero desgraciadamente este modo es más complejo y requiere la firma de documentos de confidencialidad( por esa razón, es probable que los aficionados como nosotros nunca encuentren el código de interfaz del modo SDIO). En su lugar, cada módulo de tarjeta SD se basa en el modo SPI de «menor velocidad y menos sobrecarga» que es fácil de usar para cualquier microcontrolador (como Arduino).

Asignación de pines del módulo de la tarjeta Micro SD

El módulo de la tarjeta micro SD que vamos a usar es bastante simple de conectar. Tiene seis pines:

  • VCC :El pin que suministra energía para el módulo y debe conectarse al pin de 5V en el Arduino.
  • TGNG (TIERRA): debe estar conectado a tierra de Arduino.
  • MISO (Master In Slave Out): es la salida SPI del módulo de tarjeta Micro SD.
  • MOSI (Salida maestra Entrada esclava): es la entrada SPI al módulo de tarjeta Micro SD.
  • SCK (reloj serie): pin acepta pulsos de reloj que sincronizan la transmisión de datos generada por Arduino.
  • CS (Selección de esclavo): es utilizado por Arduino (Master) para habilitar y deshabilitar dispositivos específicos en el bus SPI.

Preparación de la tarjeta micro SD

Antes de insertar la tarjeta micro SD en el módulo y conectarla al Arduino, debe formatear correctamente la tarjeta. Para la biblioteca Arduino que discutiremos, y casi todas las demás bibliotecas SD, la tarjeta debe estar formateada FAT16 o FAT32.

Si tiene una tarjeta SD nueva, es probable que ya esté formateada previamente con un sistema de archivos FAT. Sin embargo, es posible que tenga problemas con el formato de fábrica de la tarjeta o, si es una tarjeta antigua, debe reformatearse. De cualquier manera, siempre es una buena idea formatear la tarjeta antes de usarla, ¡incluso si es nueva!

Es recomendable utilizar la utilidad oficial de formateo de tarjetas SD : escrita por la asociación SD , ¡resuelve muchos problemas que surgen con un mal formateo! Descargue el formateador y ejecútelo en su ordenador, simplemente seleccione la unidad correcta y haga clic en FORMATEAR.

Captura de pantalla del formateador SD

Cableado: conexión del módulo de tarjeta Micro SD a Arduino

Ahora que su tarjeta está lista para usar, ¡podemos conectar la placa de conexión micro SD!

Para empezar, inserte el módulo de la tarjeta micro SD en una placa de pruebas. Conecte el pin VCC en el módulo a 5V en el pin Arduino y GND a tierra. Ahora nos quedamos con los pines que se usan para la comunicación SPI. Como las tarjetas micro SD requieren una gran cantidad de transferencia de datos, brindarán el mejor rendimiento cuando se conecten a los pines SPI del hardware en un microcontrolador. Los pines SPI del hardware son mucho más rápidos que «bit-banging» del código de la interfaz usando otro conjunto de pines.

Tenga en cuenta que cada placa Arduino tiene diferentes pines SPI que deben conectarse en consecuencia. Para placas Arduino como UNO/Nano, esos pines son digitales 13 (SCK), 12 (MISO) y 11 (MOSI). También necesitará un cuarto pin para la línea ‘chip/slave select’ (SS). Por lo general, este es el pin 10, pero en realidad puede usar cualquier pin que desee.

Si tiene una placa Mega, ¡los pines son diferentes! Querrá usar digital 50 (MISO), 51 (MOSI), 52 (SCK) y 53 (SS). Consulte la siguiente tabla para una comprensión rápida.

MOSIMISOSCKCS
Arduino uno11121310
Arduino nano11121310
Arduino mega51505253

En caso de que esté utilizando una placa Arduino diferente a la mencionada anteriormente, es recomendable consultar la documentación oficial de Arduino antes de continuar.

¡Eso es todo! ¡Ya estamos listos para registrar algunos datos!

Código Arduino: prueba del módulo de la tarjeta SD con CardInfo

Comunicarse con una tarjeta SD es un montón de trabajo, pero afortunadamente para nosotros, Arduino IDE ya contiene una biblioteca muy buena llamada SD que simplifica la lectura y escritura en tarjetas SD.

Si lo prefiere hay un ejemplo en el Ide de Arduino que se puede ver en el submenú Ejemplos y el boceto de ejemplo CardInfo.

Bosquejo SD Library CardInfo en Arduino IDE

Este boceto no escribirá ningún dato en la tarjeta. Simplemente le dice si logró reconocer la tarjeta y muestra información al respecto. Esto puede ser muy útil cuando se trata de averiguar si se admite una tarjeta SD. ¡Antes de probar cualquier tarjeta nueva, le recomendamos que ejecute este boceto una vez!

Vaya al comienzo del boceto y asegúrese de que la línea chipSelect esté correctamente inicializada, en nuestro caso estamos usando el pin digital #10, ¡así que cámbielo a 10!

Inicializar ChipSelect CardInfo Sketch en Arduino IDE

Bien, ahora inserte la tarjeta SD en el módulo y cargue el boceto. Tan pronto como abra el Serial Monitor, probablemente obtendrá algo como lo siguiente:

Salida de boceto de CardInfo en Arduino IDE - Trabajando

Puede que le parezca un galimatías, pero es útil ver que el tipo de tarjeta es : en el ejemplo se ha utilizado una SDHC (SD de alta capacidad), el tipo de volumen es FAT32 y el tamaño de la tarjeta es de unos 4 GB, etc.

Si tiene una tarjeta defectuosa, lo que parece ocurrir más con las versiones clonadas, es posible que vea:

Salida de boceto de CardInfo en Arduino IDE - Tarjeta corrupta mala

La tarjeta respondió en su mayoría, pero los datos son todos malos. Vea que no hay ID de fabricante / ID de OEM y la ID de producto es ‘N/A’. Esto muestra que la tarjeta devolvió algunos errores SD. Es básicamente una mala escena (si obtiene algo como esto, puede intentar reformatearlo o si todavía se descascara, debe desechar la tarjeta).

Finalmente, intente sacar la tarjeta SD y ejecute el boceto nuevamente, obtendrá lo siguiente:

Salida de boceto de CardInfo en Arduino IDE: error de inicialización

Como vemos ni siquiera se pudo inicializar la tarjeta SD. Esto también puede suceder si hay un error de cableado o si la tarjeta está dañada permanentemente.

Si el cableado es correcto, pero la tarjeta SD no está formateada correctamente, obtendrá algo como esto:

Salida de boceto de CardInfo en Arduino IDE - Sin formato adecuado

Código Arduino: lectura y escritura de datos

Teniendo en cuenta que ha inicializado con éxito la tarjeta SD, pasaremos a nuestro próximo experimento. El siguiente boceto hará una demostración básica de cómo escribir y leer datos de un archivo. Pruebe el boceto antes de comenzar su desglose detallado.

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

File myFile;

// change this to match your SD shield or module;
const int chipSelect = 10;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");

  if (!SD.begin()) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

  // re-open the file for reading:
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}

void loop()
{
  // nothing happens after setup
}

Una vez cargado el código, si todo está bien, aparecerá lo siguiente en el monitor serial.

Tarjeta Micro SD Biblioteca SD Salida en monitor serie

Si reinicia su Arduino y deja que el boceto se ejecute nuevamente; los nuevos datos escritos se agregan al archivo sin sobrescribir los datos anteriores.

Tarjeta Micro SD Biblioteca SD Segunda salida en monitor serie

Explicación del código:

El boceto comienza con la inclusión de la biblioteca SD integrada y la biblioteca SPI que nos permite comunicarnos fácilmente con la tarjeta SD a través de la interfaz SPI.

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

Una vez incluidas las librerías, lo siguiente que hacemos es declarar el pin Arduino al que chipSelect (CS)está conectado el pin del módulo de la tarjeta SD. El pin CS es el único que no está realmente fijo como cualquiera de los pines digitales de Arduino. No necesitamos declarar otros pines SPI ya que estamos usando una interfaz SPI de hardware y estos pines ya están declarados en la biblioteca SPI. Después de declarar el pin, creamos un objeto myFile , que se usará más adelante para almacenar datos en la tarjeta SD.

const int chipSelect = 10;
File myFile;

A continuación, en la setup()sección: Iniciamos la comunicación serial para mostrar los resultados en el monitor serial. Ahora, utilizando la SD.begin()función, inicializaremos la tarjeta SD y, si la inicialización es exitosa, la declaración » if » se vuelve verdadera y la inicialización de String «está lista». ” se imprime en el monitor serie, de lo contrario, la cadena “ ¡falló la inicialización! ” se imprime y el programa termina.

Serial.begin(9600);
  Serial.print("Initializing SD card...");
  if (!SD.begin()) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

A continuación, la SD.open()función abrirá el archivo llamado » test.txt «. En nuestro caso, como dicho archivo no está presente, se creará. El otro parámetro FILE_WRITE abre el archivo en modo de lectura y escritura.

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

Una vez abierto el archivo imprimiremos en el monitor serial el mensaje “ Writing to test.txt… ” y luego usando la myFile.println()función escribiremos el texto “testing 1, 2, 3”. en el archivo. Después de eso, debemos usar la close()función para asegurarnos de que los datos escritos en el archivo se guarden.

  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    myFile.close();
    Serial.println("done.");
  } else {
    Serial.println("error opening test.txt");
  }

Ahora vamos a leer el mismo archivo para verificar si la operación de escritura fue exitosa. Para hacer eso, usaremos la misma función, SD.open()pero esta vez como el archivo “ test.txt ” ya ha sido creado, la función simplemente abrirá el archivo. . Luego, usando la myFile.read()función, leeremos el archivo y lo imprimiremos en el monitor serie. La read()función en realidad lee solo un carácter a la vez, por lo tanto, necesitamos usar el ciclo «while» y la función myFile.available()para leer todos los caracteres en el archivo. Al final tenemos que cerrar el archivo.

myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    myFile.close();
  } else {
    Serial.println("error opening test.txt");
  }

Dado que este es solo un boceto de demostración para demostrar cómo leer y escribir archivos, no tiene sentido ejecutar el código varias veces, por lo que todo el código se colocó en la setup()función que se ejecuta solo una vez, en lugar de ponerlo en una loop()función que se ejecuta y otra vez

void loop() 
{
}

Algunas cosas a tener en cuenta

  • Puede usar print() println() funciones como objetos en serie, para escribir cadenas, variables, etc.
  • Read()solo devuelve un carácter a la vez. ¡No lee una línea completa o un número!
  • ¡Debes tener close() los archivos cuando hayas terminado para asegurarte de que todos los datos se escriban de forma permanente! Esto reduce la cantidad de RAM utilizada.
  • Puede abrir archivos en un directorio. Por ejemplo, si desea abrir un archivo en el directorio, puede llamar a SD.open("/myfiles/example.txt"). Tenga en cuenta que la ruta del archivo es relativa.
  • La biblioteca de la tarjeta SD no admite ‘nombres de archivo largos’. En su lugar, utiliza el formato 3 para los nombres de archivo , ¡así que mantenga los nombres de archivo cortos! Por ejemplo, datalog.txt está bien, pero «My Sensor log file.text» no lo está.
  • También tenga en cuenta que los nombres de archivo no distinguen entre mayúsculas y minúsculas, por lo que datalog.txt es el mismo archivo que DataLog.Txt es el mismo archivo que DATALOG.TXT

Otras funciones útiles en SD Library

Funciones utilizadas con el objeto SD

Hay algunas funciones útiles que puede usar con el objeto SD . Algunos de ellos se enumeran a continuación:

  • Si solo desea verificar si existe un archivo, use exists("filename.txt") cuál devolverá verdadero o falso.
  • Puede eliminar un archivo llamando remove("unwanted.txt") ¡cuidado! Esto realmente lo eliminará, y no hay una ‘Papelera de reciclaje’ para sacarlo.
  • Puede crear un subdirectorio llamando a mkdir("/mynewdir") mano cuando desee rellenar archivos en una ubicación. No pasa nada si ya existe pero siempre puede llamar SD.exists() arriba primero.

Funciones utilizadas con el objeto Archivo

Además, hay algunas funciones que puede usar con objetos de archivo :

  • Puede seek()en un archivo. Esto moverá el cursor de lectura/escritura a una nueva ubicación. Por ejemplo seek(0) , lo llevará al principio del archivo, ¡lo cual puede ser muy útil!
  • Así mismo puedes llamar al position()que te indicará en qué parte del expediente te encuentras.
  • Si desea saber el tamaño de un archivo, llame size() para obtener la cantidad de bytes en el archivo.
  • Los directorios/carpetas son archivos especiales, puede determinar si un archivo es un directorio llamando isDirectory()
  • Una vez que tenga un directorio, puede comenzar a revisar todos los archivos en el directorio llamando openNextFile()
  • Puede terminar necesitando saber el nombre de un archivo, por ejemplo, si llamó openNextFile()a un directorio. En este caso, llame al name()que devolverá un puntero a la matriz de caracteres con formato 8.3 que puede hacer directamente Serial.print() si lo desea.

Por cierto , aunque pueda parecer extraño es más económico comprar varios módulos que un único ( por unos 2€ en Amazon )

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.