Como usar o módulo SD Card com Arduino
Gravar informações em um SD Card é muito importante quando, trabalhando com sensores, temos a necessidade de armazenar os dados para consulta posterior, em situações onde não podemos monitorar o circuito todo o tempo.
Pode ser quando desejamos consultar a variação de temperatura de um ambiente ou então verificar quando um determinado alarme foi acionado. Para casos assim podemos gravar os dados do Arduino em um cartão, utilizando o módulo cartão SD:
Antes de mais nada não se assuste com a quantidade de pinos. São 16, mas usamos apenas 6 para conexão ao Arduino. Olhando o módulo de frente, você pode usar tanto os pinos da direita como os da esquerda, pois eles tem a mesma função. Observe a imagem abaixo:
Com relação aos cartões SD, eu testei 3 modelos de cartão no módulo. Sem citar nomes, o cartão de “marca” não funcionou de jeito nenhum, enquanto os cartões genéricos funcionaram perfeitamente. Todos foram formatados da mesma maneira, e testados com FAT e FAT32. O módulo funcionou com cartões pequenos, de 512 Mb, e também com cartões de maior capacidade, como os de 8 Gb.
Conectando o módulo SD Card cartão SD no Arduino
O módulo SD se conecta ao Arduino utilizando a interface SPI (arduino.cc/en/Reference/SPI), no nosso exemplo os pinos 4, 11, 12 e 13. A alimentação do módulo é feita por meio do pino 5V do Arduino.
Atenção com os pinos de sinal, pois eles trabalham com nível de sinal de 3.3V, de maneira semelhante aos módulos bluetooth que eu já mostrei aqui no site.
Utilize a calculadora desse link para calcular o valor dos resistores que você vai utilizar para montar o divisor de tensão. Eu usei resistores de 220 e 330 ohms, que forneceram um nível de sinal de aproximadamente 3V, suficiente para os testes:
Gravando dados no cartão SD
No circuito acima eu liguei um push-button à porta digital 3 para demonstrar como os dados são gravados no cartão SD. A cada toque no botão, um contador é incrementado e esse valor é gravado no cartão com o seguinte formato:
Contador: <valor>
O programa utiliza a biblioteca SD, que já está embutida na IDE do Arduino. No inicio do programa é feito um pequeno teste para verificar se as conexões estão corretas e se o cartão SD está sendo reconhecido. Caso esteja tudo ok, um loop verifica se o botão foi pressionado e em caso afirmativo, grava esse dado no cartão SD junto com o valor atual do contador:
// Programa: Teste escrita cartao SD // Autor: Arduino e Cia // Baseado no arquivo exemplo da biblioteca SD Card Arduino // Carrega a biblioteca SD #include <SD.h> Sd2Card SDcard; SdVolume volume; // Pino do Arduino conectado ao pino CS do modulo const int chipSelect = 4; // Pino do Arduino conectado ao push-button int pinobotao = 3; int contador = 0; void setup() { // Define o pino do push-button como entrada pinMode(pinobotao, INPUT); Serial.begin(9600); //Inicia a comunicacao com o modulo SD if (!SD.begin(chipSelect)) { Serial.println("Falha ao acessar o cartao !"); Serial.println("Verifique o cartao/conexoes e reinicie o Arduino..."); return; } Serial.println("Cartao iniciado corretamente !"); Serial.println("Aguardando acionamento do push-button..."); Serial.println(); } void loop() { int valor = digitalRead(pinobotao); // Verifica se o push-button foi acionado if (valor == 1) { // Delay caso o botão continue pressionado while(digitalRead(pinobotao) == 1) { delay(100); } // Incrementa o contador e envia os dados para o // Serial monitor contador=contador++; Serial.print("Botao pressionado. Contador : "); Serial.println(contador); // Abre o arquivo arquivo.txt do cartao SD File dataFile = SD.open("arquivo.txt", FILE_WRITE); // Grava os dados no arquivo if (dataFile) { dataFile.print("Contador : "); dataFile.println(contador); dataFile.close(); } else { // Mensagem de erro caso ocorra algum problema // na abertura do arquivo Serial.println("Erro ao abrir arquivo.txt !"); } } }
Após pressionar o push-button algumas vezes, coloque o cartão SD no seu computador, e abra o arquivo ARQUIVO.TXT. Você terá um arquivo nesse formato:
Gostou deste post de SD Card Arduino? Use os dados do cartão SD em uma planilha e gere gráficos, por exemplo. Confira no post Como importar dados do datalogger em uma planilha.
Oi Adilson bom dia.
Excelente post.
Será que daria pra ler o conteúdo do cartão diretamente pela serial sem tirar o SD do módulo?
Grande abraço
Boa tarde Márcio !
Obrigado. Tem como ler sim, estive pesquisando isso, só preciso descobrir agora se consigo ler apenas uma "parte" do texto. Por exemplo, fazer o Arduino procurar uma string em um arquivo texto.
Se eu conseguir, solto um novo post sobre isso. 🙂
Grande abraço. Valeu !
Amigo, estou fazendo um programa para gravar em um módulo SD um arquivo txt com as informações de um eletrodo de pH, no entanto esta gravando dados corrompidos, criando pastas e múltiplos arquivos corrompidos, tipo seus nomes está com letras em arabes simbolos e por ai vai.
O engraçado que o programa não houve modificações e antes funcionava, já formatei o cartão SD no tipo fat jah liguei o cable select do cartão SD no pino 4 e pino 10, a unica coisa que mudei foi implementar um modulo RTC e um DTH11.
Abaixo deixo meu programa.
Bom dia,
Já tentou separar o programa em partes para ver se alguma delas está interferindo na gravação ?
Abraço.
Ola amigo interessei no seu projeto, estou tentando fazer algo parecido, sera que podia entrar em contato comigo por email? [email protected] aguardo seu contato. abraços. David Conrado Universidade Federal de Rondônia UNIR.
#include // Biblioteca para o display LCD
#include // Biblioteca para SD card
#include // Biblioteca para o relógio
#include // Biblioteca para o Termo Higrometro
#define DHTPIN A3 // pino que estamos conectado
#define DHTTYPE DHT11 // DHT 11
DHT dht(DHTPIN, DHTTYPE);
DS1307 rtc(A4, A5); //Modulo relogio ligado as portas A4 e A5 do Arduino
LiquidCrystal lcd(8, 7, 6, 5, 3, 2); // Define as entradas digitais do display
// Declaração de variavéis de pH
int convph = 0; // Sinal do sensor de pH 0-1024
float ph = 0.00; // Valor já calculado para exibição do pH no display
// Declaração de variavéis de temperatura
int convtemp =0; // Sinal do sensor de temperatura 0 – 1024
float temp = 0.00; // Valor já calculado para exibição da temperatura no display
// Declaração de variavéis do Termo Higrometro
float t;
float h;
// Declaração de variavéis do data logger SD
int botaoAB = 0; // Botão A B
File arquivo;
int state = 0;
int tela=0;
// Caracteres
byte aluno[8] = {B01110,B01110,B00100,B01110,B10101,B00100,B01010,B10001};
byte term[8] = {B00100,B01010,B01010,B01110,B01110,B11111,B11111,B01110};
byte ur[8] = {B00100,B00100,B01110,B01110,B11111,B11101,B11011,B01110};
byte tol[8] = {B00000,B00100,B01110,B00100,B00000,B01110,B00000,B00000};
byte cloc[8] = {B01110,B10101,B10101,B10111,B10001,B10001,B01110,B10001};
void setup() // Programa principal
{
rtc.halt(false); //Aciona o relogio
//rtc.setDOW(TUESDAY); //Define o dia da semana
//rtc.setTime(20, 19, 20); //Define o horario
//rtc.setDate(02, 12, 2014); //Define o dia, mes e ano
rtc.setSQWRate(SQW_RATE_1);
rtc.enableSQW(true);
pinMode(10, OUTPUT);
pinMode(4, OUTPUT);
lcd.createChar(1, aluno); lcd.createChar(2, term); lcd.createChar(3, ur); lcd.createChar(4, tol); lcd.createChar(5, cloc);
lcd.begin(20,4); // Definição do tipo do display
lcd.print(" TCC – POLITEC "); lcd.write(1); lcd.print("Leandro "); lcd.write(1);
lcd.print("Vinicius"); lcd.print(" MEDIDOR DATA LOGGER");
Serial.begin(9600); // Inicia comunicação serial
if(!SD.begin(4)) // Verifica a comunicação com o SD card
{
lcd.setCursor(0, 3); lcd.print(" "); lcd.setCursor(0, 3);
lcd.print(" Sem cartao SD!");
Serial.println("Erro ao iniciar cartao SD!");
return;
}
dht.begin();
delay(1000); // Tempo de atualização do display
}
void loop() // Programa Principal com loops de repetição
{
// CÁLCULO DO pH E TEMPERATURA E UMIDADE
convph = analogRead(A1); // Variavél conv recebe valor de 0 – 1024 do eletrodo de pH
ph = (((convph- 219.00) * 5.00)/349.00) + 4.00; // Cálculo para atribuir o valor de pH
convtemp = analogRead(A0); // Variavél convtemp recebe valor de 0 – 1023 do PT-100
temp = (((convtemp – 205.01) * 100.00)/819.42); // Cálculo para atribuir o valor de temperatura
t = dht.readTemperature();
h = dht.readHumidity();
delay(800); // Atualização das leituras
// DATA LOGGER VIA SD
botaoAB = analogRead (A2);
if(botaoAB > 790 && botaoAB < 850){
state = !state;
delay(300);
}
if (state == HIGH){
arquivo = SD.open("data.txt", FILE_WRITE);
if(arquivo){
arquivo.print(ph);
arquivo.print(";");
arquivo.println(temp);
arquivo.close();
delay(1000);
}
}
if(botaoAB > 480 && botaoAB < 540){
tela ++;
delay (300);
if(tela == 5){
tela =1;
}
}
switch (tela){
case 1:
// LEITURA E EXIBIÇÃO DO PH
lcd.clear (); lcd.setCursor(0, 0); lcd.print(" PH-METRO");
//lcd.setCursor(0, 1); lcd.print(convph);
lcd.setCursor(6, 2); lcd.print(ph);
lcd.setCursor(11, 2); lcd.print(" pH");
if(ph >=6.5 && ph <=7.5){
lcd.setCursor(0, 3); lcd.print(" "); lcd.setCursor(0, 3); lcd.print(" Solucao Neutra");
}
if(ph >=3.5 && ph <6.5){
lcd.setCursor(0, 3); lcd.print(" "); lcd.setCursor(0, 3); lcd.print(" Acido Fraco");
}
if(ph <3.5){
lcd.setCursor(0, 3); lcd.print(" "); lcd.setCursor(0, 3); lcd.print(" Acido Forte");
}
if(ph >7.50 && ph <=10.5){
lcd.setCursor(0, 3); lcd.print(" "); lcd.setCursor(0, 3); lcd.print(" Base Fraca");
}
if(ph >10.50){
lcd.setCursor(0, 3); lcd.print(" "); lcd.setCursor(0, 3); lcd.print(" Base Forte");
}
break;
case 2:
// LEITURA E EXIBIÇÃO DE TEMPERATURA
lcd.clear ();
lcd.print(" TEMPERATURA PT-100"); //lcd.setCursor(0, 1); lcd.print(convtemp);
lcd.setCursor(5, 2); lcd.write(2); lcd.setCursor(7, 2); lcd.print(temp);
lcd.setCursor(14, 2); lcd.print("C"); lcd.setCursor(13,2); lcd.print((char)223);
break;
case 3:
// TELA DO TERMOHIGROMETRO
lcd.clear (); lcd.print(" TERMO HIGROMETRO");
lcd.setCursor(6,1);
lcd.write(2); lcd.print(t,1);lcd.print("C");lcd.print((char)223);
lcd.setCursor(5,2);
lcd.write(3); lcd.print(h,1);lcd.write(4); lcd.print("5% ");
break;
case 4:
// TELA DO DATA LOGGER VIA SD
lcd.clear (); lcd.print(" DATA LOGGER");
lcd.setCursor(0,1);
lcd.print("Data ");
lcd.print(rtc.getDateStr(FORMAT_SHORT)); lcd.print(" "); lcd.print(rtc.getDOWStr(FORMAT_SHORT));
lcd.setCursor(0,2);
lcd.write(5); lcd.print(" ");
lcd.print(rtc.getTimeStr());
if(state==HIGH){
lcd.setCursor(0, 3); lcd.print(" Gravando SD…");
}
else{
lcd.setCursor(0, 3); lcd.print("Aperte A para Gravar");
}
break;
}
}
Olá, gostei muito desse post, só me tira uma duvida… tem como usar um display para ler os arquivos existentes no SD?? uma visualização tipo do DOS do windows, quando nós digitamos o comando "DIR"… seria bom…
Boa noite,
Tem sim, só não consigo testar isso agora… Nos programas de exemplo da biblioteca SD tem um exemplo chamado CardInfo, que mostra todos os arquivos do cartão utilizando o comando root.ls(LS_R | LS_DATE | LS_SIZE);, que é "quase" um DIR do DOS. 🙂
Acho que você pode se basear nisso para ler os nomes dos arquivos que estão no cartão e jogar isso em um display LCD.
Abraço !
Desculpe pela pergunta, talvez seja meio besta, mas já que a comunicação é serial, porque não são utilizados os pinos RX e TX?
Bom dia Rigel,
Podem ser utilizados também, dependendo do projeto. Mas no caso, a porta serial é "simulada" pela conexão USB.
Não sei se essa era a sua dúvida, mas qualquer coisa volte aí.
Abraço !
Bom dia!
Uma pergunta, exemplo, tenho esses dados no meu sd:
23 44 23 f4
12 fd d3 d3
e3 22 32 23
Como faço para identificar cada linha como : 23 44 23 f4 pegar isso no SD e guardar numa varialve tipo String? para poder manipular?
att
Pedro Gonçalves
Bom dia Pedro,
Estou preparando um post sobre esse assunto, mas você pode ter algumas informações neste link: http://forum.arduino.cc/index.php?topic=127711.0
Abraço!
Bom dia!
Gostaria de saber se posso usar um divisor de tensão de R1=1000 R2=2000 ou R1=10000e R2=20000
Boa tarde,
Estou fazendo um projeto onde utilizo o shield yun dragino, onde o mesmo não utiliza USB para fazer a comunicação entre o PC e o arduino, ele cria uma rede e faz essa comunicação a partir dela. Então, será que funciona utilizar esse módulo SD para salvar os dados coletados?
Boa noite Rodolfo,
Não conheço essa placa, mas a princípio não vejo problema em utilizar o SD nessa configuração.
Abraço!
boa tarde
tenho uma maquinade ciclos repetivos, gostaria de saber como faço um programa para um arduino que informe a quantidade de peças que ela produziu e o tempo que ela ficou funcionando atraves de um sensor de pulso.
Boa noite,
Você vai precisar de um RTC, correto ? Estou deduzindo que você vai medir a produção diária. Que tipo de sensor você vai usar ?
Abraço!
Olá, Estou tendo o seguinte código de erro:
0x1, 0xFF
Você sabe o que pode ser?
Boa tarde,
Esse erro aparece na hora da compilação ?
Abraço!
Bom dia!
Existe algum motivo para não utilizar a saída 3.3v do próprio arduino e remover os resitores?
Grato
Bom dia,
Você vai precisar dos resistores pq o nível de sinal do módulo é de 3.3V, independente se você alimentar o mesmo com 3.3V ou 5V.
Abraço!
Bom dia, desculpe minha ignorancia, eu sou novo nessa area, mas se eu for realizar um prejeto com arduino, o sensor de temperatura dht22 e salvar as mediçoes em um cartao sd, precisarei ainda desse potenciometro, ou posso conectar o cartao direto ? obrigado
Oi Leonardo,
Esse projeto em específico não utiliza potenciômetro. Seria algum outro componente ?
Abraço!
Olá, fiz um código semelhante ao exemplo, mando gravar os dados que necessito, após retirar o cartão SD com o Arduino e colocar no PC, o arquivo está normal. Após colocar o cartão SD com o Arduino ainda ligado, o código não executa mais a escrita. Gostaria de saber o motivo, aguardo uma resposta, muito obrigado.
Boa noite Fábio,
Realmente depois que vc retira o cartão e coloca novamente, ele dá esse erro. É necessário reiniciar o Arduino.
Abraço!
Boa noite, o esquema de ligação da figura está realmente certo? Ainda vou testar aqui em casa, mas me parece que os resistores estão conectados diretamente um na saida do outro, fechando o circuito direto… por exemplo o fio amarelo, vc alimentou ele com positivo, passou por um resistor e já tem outro resistor em seguida, fechando circuito com o pino 12
Oi Hemerson,
Não, o fio amarelo sai do pino 12, vai para o resistor, e com o 2o. resistor (que está ligado ao negativo), ele faz um divisor de tensão. Não tem positivo no fio amarelo. passa direto….
Abraço!
Obrigado pela resposta amigo.
Abraço
Oi,
eu fiz o esquema conforme o artigo, mas só fica dando erro ao abrir arquivo txt e falha no cartão, já verifiquei todas as conexões. Pode me ajudar?
Ps.: uso um arduino mega. (mas usei os mesmos pinos)
Valeu Hemerson! Abraço.
Olá amigo, consigo salvar em um txt normal sem cartão SD ?
Boa Tarde,
Estou tendo dificuldades em fazer este projeto funcionar. Estou utilizando este módulo SD com um Arduino Mega.
Fiz a conexão dos resistores nos pinos Mosi-51, MISO-50, CLK-52, CS-53 e alterei a linha 12 para const int chipSelect = 53;
Testei 4 cartões SD de 1, 2, 4 e 64GB com formatação FAT e FAT32, mas nenhum dos testes que realizei funcionou. Poderia me ajudar?
Obrigado
Olá,
Como faço para o salvar os dados em arquivo "estilo excel" ao invés de um arquivo txt ?
Oi Rodrigo,
Você pode importar como txt no excel também.
Abraço!
Adilson
pra usar no arduino nano como faço com o pino 13? tem como usar outro no lugar? att
Bom dia,
O seu pino 13 do Nano está ocupado?
Adilson
Olá. Preciso armazenar dados de vários sensores, (10minitos de dados) e obtive um problema. Ao testar, os dados são gravados perfeitamente. Contudo, quando embarquei tudo e alimentei o Arduino com a tensão necessária, tive os dados gravados até uns 4 minutos.
Qual a explicação para isso? Como posso resolver ?
Olá, Esse módulo SD, possiu 2 linhas de dados iguais, pela descrição, seria possível eu conectar 2 arduinos neste módulo e fazer a leitura das informações do SD.?? simultaneamente. obrigado
Boa tarde,
Pergunta interessante. Teria que testar, mas não deixa de ser uma boa sugestão. 🙂
Abraço!
Adilson
Boa tarde,
consigo usar um desses cartões de 8Gigas novos?
Obrigada.
Oi Stella,
Consegue sim. Usei recentemente um de 8Gb da Sandisk, classe 4.
Abraço!
Adilson
Boa tarde,
estou tentando fazer um desenho esquemático utilizando o software Fritizing. E acredito que foi o mesmo utilizado por vc para fazer o desenho do circuito. Será que vc pode me enviar o módulo de cartão SD, para eu montar meu desenho?
Obrigado!
ola, como eu faria pra colocar o cartão para armazenar dados de valores obtidos por sensores, como temperatura, turbidez etc.
[…] com o módulo cartão SD tradicional, no módulo cartão micro SD temos apenas os pinos necessários: alimentação e interface SPI, […]
Boa noite
Tenho um projeto que preciso juntar um Dht11, um Mq 04 (metano) e um LDR com leitura de dados no módulo SD. O LDR lê e grava e o DHT11 lê com erro.