Um dos pontos fracos do microcontrolador Arduino é sua a memória pequena. Quando se pretende tratar uma quantidade considerável de dados (registrar valores, ler ou escrever ficheiros, etc.), é preciso acrescentar espaço de memória. Para isso, pode-se utilizar um cartão Secure Digital, ou cartão SD, que permite alocar memória suplementar sem abrir mão das dimensões pequenas.
Material
- Computador
- 1 x Arduino UNO
- 1 x cabo USB para conectar o Arduino ao computador
- Módulo shield para cartão SD
Estrutura do shield para Cartão SD
Qualquer que seja o módulo escolhido, sua estrutura básica será sempre a mesma: um compartimento para encaixar o cartão SD e pinos para estabelecer uma interface.
O módulo shield para cartão SD apresenta 6 pinos que permitem estabelecer a conexão. 2 para a alimentação e 4 para estabelecer a ligação SPI (Serial Peripheral Interface)
- V ou 3.3V para a alimentação do módulo
- GND a terra do módulo
- CS ou ChipSelect para ativar a comunicação
- MISO (Master Input, Slave Output) pino de transmissão equivalente ao pino Tx de uma porta serial. Saída do módulo.
- MOSI (Master Output, Slave Input) pino de entrada equivalente ao pino Rx de uma porta serial. Entrada do módulo.
- SCK (Clock) relógio que permite sincronizar a comunicação
No caso de um shield, as conexões são predefinidas. Verifique como utilizar o componente na sua documentação técnica.
Esquema de ligação
- 3.3V com 3.3V
- GND com GND
- CS em geral com 4 (aqui com 10)
- MISO com 12
- MOSI com 11
- SCK com 13
Código para recuperar as informações de um cartão SD
Para interagir com o seu cartão SD, há uma biblioteca na IDE do Arduino: a SD.h. Há exemplos disponíveis no software e na internet.
#include <SPI.h> #include <SD.h> Sd2Card card; SdVolume volume; SdFile root; const int chipSelect = 10; void setup() { Serial.begin(9600); while (!Serial) { } Serial.print("\nInitializing SD card..."); if (!card.init(SPI_HALF_SPEED, chipSelect)) { Serial.println("initialization failed"); return; } else { Serial.println("Wiring is correct and a card is present."); } Serial.print("\nCard type: "); switch (card.type()) { case SD_CARD_TYPE_SD1: Serial.println("SD1"); break; case SD_CARD_TYPE_SD2: Serial.println("SD2"); break; case SD_CARD_TYPE_SDHC: Serial.println("SDHC"); break; default: Serial.println("Unknown"); } if (!volume.init(card)) { Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card"); return; } uint32_t volumesize; Serial.print("\nVolume type is FAT"); Serial.println(volume.fatType(), DEC); Serial.println(); volumesize = volume.blocksPerCluster(); // clusters are collections of blocks volumesize *= volume.clusterCount(); // we'll have a lot of clusters volumesize *= 512; // SD card blocks are always 512 bytes Serial.print("Volume size (bytes): "); Serial.println(volumesize); Serial.print("Volume size (Kbytes): "); volumesize /= 1024; Serial.println(volumesize); Serial.print("Volume size (Mbytes): "); volumesize /= 1024; Serial.println(volumesize); Serial.println("\nFiles found on the card (name, date and size in bytes): "); root.openRoot(volume); root.ls(LS_R | LS_DATE | LS_SIZE); } void loop(void) {}
Código para ler e escrever dados num ficheiro armazenado no cartão SD
#include <SPI.h> #include <SD.h> File myFile; String buffer; String filename = "test"; void setup() { Serial.begin(9600); while (!Serial) { } Serial.print("Initializing SD card..."); if (!SD.begin(4)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); myFile = SD.open(filename + ".txt", FILE_WRITE); if (myFile) { Serial.print("Writing to " + filename + ".txt..."); myFile.println("testing 1, 2, 3."); myFile.close(); Serial.println("done."); } else { Serial.println("error opening " + filename + ".txt"); } //Read file byte by byte myFile = SD.open(filename + ".txt"); if (myFile) { Serial.println("Read " + filename + ".txt byte by byte:"); while (myFile.available()) { Serial.write(myFile.read()); } myFile.close(); } else { Serial.println("error opening " + filename + ".txt"); } //Read file line by line myFile = SD.open(filename + ".txt"); if (myFile) { Serial.println("Read " + filename + ".txt line by line:"); while (myFile.available()) { buffer = myFile.readStringUntil('\n'); Serial.println(buffer); } myFile.close(); } else { Serial.println("error opening " + filename + ".txt"); } } void loop() { }
É possível apagar o ficheiro utilizando a função:
SD.remove("test.txt");
Atenção: Se os seus ficheiros não forem reconhecidos, experimente usar um nome curto para o ficheiro salvo no cartão SD (máximo 8 caracteres). O número de caracteres para ficheiros em cartões SD é limitado com o Arduino.
Experimente e combine estes exemplos para obter as funcionalidades que desejar. Se tiver problemas para utilizar o seu cartão SD com o microcontrolador Arduino, escreva-nos um comentário ou envie uma mensagem.
Bônus: Visualizar os ficheiros armazenados no cartão SD
Para se certificar de que os ficheiros estão salvos no cartão SD, é possível exibir os ficheiros armazenados na raiz. Para isso, basta utilizar o objecto File, que permite percorrer os diretórios do cartão SD.
//Libraries #include <SD.h>//https://www.arduino.cc/en/reference/SD #include <SPI.h>//https://www.arduino.cc/en/Reference/SPI //Constants #define SD_ChipSelectPin 4 //Objects File root; void setup() { //Init Serial USB Serial.begin(9600); Serial.println(F("Initialize System")); //Init sd shield if (!SD.begin(SD_ChipSelectPin)) { Serial.println(F("SD fail")); return; } printFilenames(); } void loop() { } void printFilenames(void ) { /* function printFilenames */ ////find files in SD card root = SD.open("/"); while (true) { File entry = root.openNextFile(); if (! entry) { break;// no more files } Serial.println(entry.name()); entry.close(); } }
Aplicação
- Aumentar a memória do seu robô
- Dar uma voz ao seu projecto