Manual

do

Maker

.

com

Ler e escrever no SD card com Arduino

Ler e escrever no SD card com Arduino

Você provavelmente já pensou em expandir de alguma forma a memória do Arduino, seja para fazer um data logger ou para armazenar outros tipos de dados como, por exemplo, imagens para exibir no display. O propósito do artigo de hoje será lhe habilitar a utilizar o cartão SD (ou micro SD com adaptador) para leitura e escrita, através de um módulo para Arduino, utilizando o barramento SPI para fazer a comunicação.

Lista de materiais

Você precisará de quase nada para essa brincadeira! Vamos ao mais simples possível, sendo 3 ítens:

Barramento SPI

É melhor iniciar a explicação pelo barramento porque o SPI é um barramento serial um pouco mais complexo  que o UART ou I²C. De vantagem, você tem um barramento mais rápido que os demais e acaba sendo o ideal para escrita e leitura do cartão SD porque certamente você não quererá aguardar tempo demasiado pela carga dos dados.

A comunicação SPI contempla 4 pinos, dos quais 2 são elegíveis, enquanto outros 2 são forçosamente estáticos. Os pinos são esses descritos na tabela a seguir:

NomePino do ArduinoDescrição
MOSIElegível. Sugerido: 11MOSI significa:
Master Output Slave Input, ou seja, saída do master para a entrada do slave.
MISOElegível. Sugerido: 12MISO significa:
Master Input Slave Output, ou seja, a saída do slave vai para a entrada do master.
SCKDependente do Arduino. No Uno
o pino é o 13SCK é Serial Clock. Cada Arduino possui o barramento SPI em um lugar diferente
e será necessário consultar o pinout conforme a board utilizada.
CSDependente do Arduino. No Uno
o pino é o 4CS significa Chip Select. Em alguns casos você pode encontrar a descrição SS, que significa Slave Select.

O barramento SPI suporta diversos dispositivos simultaneamente, mas no nosso caso estamos focando exclusivamente na utilização do SD card.

Biblioteca

Se você procurar através do Library Manager da IDE do Arduino, você certamente encontrará ao menos 2 bibliotecas para tocar áudio a partir do SD card. Já se procurar diretamente nos exemplos no submenus de File->Examples-SD, diversas opções estarão disponíveis, dentre elas, escrever e ler no SD card. Abra-o para que nos mantenhamos em sintonia.

No início desse sketch você notará que coincidentemente o wiring sugere o mesmo esquema descrito na tabela supracitada. Porém esse pinout/wiring é próprio do Uno. Supondo que você queira utilizar o Arduino Leonardo, você deverá previamente fazer uma consulta no google por "Leonardo pinout". Ou veja o esquema nesse meu outro post onde trato de comunicação SPI com um Arduino Uno e um Leonardo.

De resto, são algumas poucas e ridiculamente simples linhas que o sketch utiliza para mostrar o quão simples é escrever no SD card. Vou dispor o código do exemplo devidamente adulterado para me favorecer de alguma forma:

/*
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4
*/

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

//criar um objeto File para manipular um arquivo
File myFile;

void setup() {
  Serial.begin(9600);
  while (!Serial);

  Serial.print("Inicializa o SD card...");

  if (!SD.begin(4)) {
    Serial.println("Nao inicializado. Veja no texto adiante sobre isso.");
    return;
  }
  Serial.println("Beleza! Seguindo...");

  /* A biblioteca SD tem um metodo para abrir arquivos e esse arquivo aberto
  sera armazenado no objeto myFile, descrito ao inicio desse codigo. Somente 
  um arquivo pode ser aberto por vez, portanto nao se esqueca de fecha-lo
  antes de abrir um novo ou voce tera problemas.
  */

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

  Se o arquivo foi aberto com sucesso, escreve nele
  if (myFile) {
    Serial.print("Escrevendo para bB.txt");
    myFile.println("manualdomaker.com");

    // Terminou de escrever, fecha-se o arquivo:
    myFile.close();

    Serial.println("Escrevinhado.");

  }
  else {
    // Se nao deu certo, comeca a dar merda desse ponto
    Serial.println("Nao foi possivel abrir o arquivo");
  }

  // Agora vamos abri-lo para leitura
  myFile = SD.open("bB.txt");
  if (myFile) {
    Serial.println("Conteudo de bB.txt:");

    // Le todo o arquivo...
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    //Finalizado, fecha-se o arquivo
    myFile.close();
  }
  else {
    // Se deu erro acima, aqui tambem dara.
    Serial.println("Nao pude abrir o arquivo.");
  }
}

void loop() {
  // Aqui poderia ser colocada uma rotina para leitura de sensores e entao os dados
  // poderiam ser gravados, precedendo-os pelo timestamp. Ai esta seu data logger! 
}


Troubleshooting

Não existem muitos erros prováveis, o que facilita a depuração do erro. Dentre as mais comuns estão:

Alimentação

Se o Arduino estiver com uma fonte externa de baixa corrente, provavelmente você poderá não suprir a alimentação de forma eficiente e isso poderá gerar erros estranhos.

A alimentação do módulo deve vir preferencialmente de uma tensão externa ao Arduino, de forma regulada. Isso porque o consumo do módulo pode chegar à 200mA!

Sobrecarga

Se você estiver com uma fonte com carga suficiente para o Arduino, mas estiver sobrecarregados de periféricos (sensores, LEDs etc), então você poderá obter erros semelhantes ao anteriormente citado.

Defeito no SD card

Se o cartão tiver algum problema físico em sua estrutura, gerará erros tal qual acontece em um celular ou em um notebook/PC.

Wiring

O wiring pode apresentar duas causas. A primeira pode ser um erro de wiring. Para resolver isso, reveja suas conexões conforme o Arduino em questão. Mais uma vez, sugiro a leitura desse outro artigo para o caso de ainda não estar íntimo do barramento SPI.

Um segundo problema com wiring pode ser mal contato na protoboard, jumpers ruins, oxidados ou em curto. Minha sugestão é a utilização de jumpers direto entre o SD card reader e o Arduino.

Nivel lógico

Utilize 3V3, não 5V, caso seu módulo seja 3V3.. Esse erro pode ir desde erros randômicos até a queima do módulo. É importante que você verifique isso na hora da compra para saber que tipo de módulo você está adquirindo.

Alguns módulos operam tanto em 3V3 como em 5V - é o caso desse módulo do nosso parceiro. Na hora de fazer o wiring, atente-se em conectar a tensão correspondente ao seu Arduino; se o Arduino for 3V3, conecte a alimentação do módulo em 3V3.

Inscreva-se no nosso canal Manual do Maker no YouTube.

Também estamos no Instagram.

Nome do Autor

Djames Suhanko

Autor do blog "Do bit Ao Byte / Manual do Maker".

Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.