Data-Logger SD/MMC com Arduino

Os cartões de memória Secure Digital ou MultiMedia Card , são dispositivos capazes de armazenar dados

O SD (Secure Digital) é um padrão de armazenamento portável, usado em celulares, câmeras mp3 players, computadores pessoais, impressoras, sistemas de navegação GPS entre outros. O termo Segure Digital (Segurança Digital) provém da capacidade destes dispositivos de armazenar direitos autorais em seus arquivos [1].

A adoção dos cartões de memória da família SD no mercado de eletroeletrônicos vem crescendo muito nos últimos anos, desta maneira percebemos que é uma excelente tecnologia para ser usada em projetos eletrônicos em geral.

Adoção padrão SD por eletroeletrônicos

Fonte: http://www.sdcard.org/developers/tech/sdcard – 2

Comunicação via SPI

Os cartões SD comunicam-se através de uma Interface Periférica Serial (SPI – Serial Peripheral Interface), que permite que vários dispositivos troquem dados em full-duplex. O SPI é um protocolo síncrono que permite um dispositivo mestre (master) iniciar a comunicação com um escravo (slave). Para prover o sincronismo, o sinal de clock (pino SCK) pode ser gerado somente pelo mestre, e este sinal controla quando os dados podem mudar e quando são válidos para leitura. Por ser síncrono, esse protolo torna-se interessante para ser usado em um oscilador não tão estável, como um oscilador RC, pois a taxa de transferência varia apenas de acordo com as subidas e descidas do oscilador, não afetando a integridade dos dados. Por permitir vários escravos, o SPI precisa controlar qual deles está sendo acessado, e o faz com um sinal CS (Chip Select) ou SS (Slave Select), que não precisa ser conectado caso haja apenas um escravo[3].

Portas SPI no Arduino

O Arduino nomeia os pinos de entrada e saída sendo MOSI (Master Out Slave In) e MISO (Master In Slave Out) respectivamente. O Duemilanove e outros Arduinos baseados no chip Atmega168/328 usam o SPI nos pinos: 10 (SS), 11 (MOSI), 12 (MISO) e 13 (SCK). Atenção especial ao Arduino Mega: nele os pinos são em outras portas, isso pode salvar um bom tempo seu: 50 (MISO), 51 (MOSI), 52 (SCK) e 53 (SS). Lembrando sempre que o pino SS precisa ser configurado no setup() como OUTPUT, do contrário a interface SPI irá por o microprocessador em escravo (slave), ficando então inoperável. [4].

Dica: Se estiver trabalhando com alguma biblioteca específica e receber um erro como este: “no sd/mmc pin mapping available!” significa que a biblioteca em questão não implementa as pinagens de seu Arduino. Isso ocorreu-me em quanto trabalhava com o Arduino Mega 1280 em testes com softwares de leitura do sistema de arquivos FAT dos cartões SDs.

Os pinos do cartão MMC/SD

Os cartões MMC possuem apenas 7 pinos, já os SD 9, fora as conexões de controle de bloqueio de escrita do cartão que nesta versão do projeto não serão implementadas. Visto isso a figura abaixo ilustra com facilidade a identificação dos pinos.

pinagem cartão MMC/SD

Os cartões MMC/SD funcionam com alimentação de 2,7 à 3,6 Volts e seu nível lógico alto é 3.3 Volts. Confira abaixo a tabela dos pinos:

Pino # Nome do Pino Função do Sinal
1 CS ou SS Chip Select – Slave Select
2 SI ou MOSI Serial Input – Master Out Slave In (SPI)
3 GND Ground
4 Vcc Tensão CC de 2.7 à 3.6 Volts
5 SCK Serial Clock (SPI)
6 GND Ground
7 SO ou MISO Serial Output – Master In Slave Out (SPI)
8 NC
9 NC

Esquema elétrico

esquema elétrico arduino e cartão sd-mmc

O esquema elétrico é bastante simples não envolvendo nada mais que seis resistores que atuam como divisores de tensão.

Isso é necessário, pois como já dito, os cartões SD/MMC trabalham com nível lógico alto em 3.3 Volts. Repare também que a alimentação do cartão é feita na porta 3V3 do Arduino.

Após a passagem pelos resistores temos as conexões do pino 1 do SD ao pino 53 do Arduino, o pino 2 conecta-se ao 51, o pino 5 ao 52 e por último o pino 7 conecta-se diretamente ao pino 50. O Arduino  interpreta a tensão de 3 Volts como sendo nível lógico 1 e 0 Volts como nível lógico 0.

Os resistores usados foram 10k (10000 ohms) e 4k7 (4700 ohms). Se juntarmos os dois em série e conectarmos um deles em 5 Volts e outro em 0 Volts, a diferença de tensão (ddp) entre o positivo da fonte e a conexão dos resistores será de 3.4 Volts. Vamos à fórmula: Vres = V x R1 / R1 + R2 = 23500 / 14700 = 1.60 Volts. Agora Pegamos a tensão total (5 Volts) menos a tensão obtida e teremos 5 – 1.60 = 3.4 Volts que se encaixa muito bem nos requisitos do cartão de memória.


Circuito elétrico - Arduino com cartão de memória SD-MMC
Parece um pouco difícil de acreditar, mas é só este hardware mesmo que é ncessário para interfacear os cartões SD-MMC com o Arduino. Agora falta a camada de software que nos permitirá gravar e ler arquivos no cartão de memória. Inicialmente você precisa formatar seu cartão de memória com sistema de arquivos FAT16, se tiver dúvidas segue a dica: http://www.ladyada.net/make/logshield/sd.html.

Atualização em 24-10-11 – Circuito opcional com outros valores de resistores

Uso de outros resistores para dividir tensão

Outro exemplo de conexão entre o Arduino e o cartão SD pode ser visto aqui: http://img441.imageshack.us/img441/2391/schematicuo7.jpg. Neste caso temos o uso de resistores de resistores com 1.8k e 3.3k, mas se fizermos os cálculos chegaremos a 3.23 Volts, o que também está dentro da faixa de tensão aceitável pelo cartão de memória. Usei os resistores de 10k e 4k7 pois eram os que eu tinha aqui, você pode usar quaisquer resistores, desde que consiga uma ddp perto de 3.3 Volts.

Atualização em 09-07-12 – Detectando remoção do cartão SD

Nosso amigo Edipo me pediu sobre como poderíamos detectar se o cartão foi removido para poder então reiniciar o acesso via software. Bom, todos os soquetes de cartões que conheço possuem um sensor de presença do cartão. Alguns usam este mesmo sensor para detectar se ele é protegido contra gravação ou não.

Este sensor é basicamente um botão, logo podemos conectá-lo à uma interrupção externa do Arduino a qual pode informar nosso software que o cartão foi inserido ou removido. O status do cartão (inserido ou removido) pode ser controlado por uma simples flag.

Abaixo a foto de dois soquetes diferentes, encomendados na Farnell – excelente loja para se comprar componentes eletrônicos no Brasil, quais possuem diferentes contatos, porém ambos permitem a verificação da presença do cartão. Os dois contatos selecionados pela área em amarelo são as conexões que devem ser tratados como dois pinos de um botão. Para mais detalhes de como podemos trabalhar com botões, acesse esse material usado no curso de Arduino que estou ministrando em nossa cidade.

A camada de software – leitura e escrita de arquivos no cartão de memória

Feita a formatação você precisará de uma biblioteca capaz de ler sistema de arquivos FAT16. Fiz testes com várias, mas a primeira que consegui fazer funcionar com o Arduino Mega foi esta: http://code.google.com/p/sdfatlib/. Talvez pelo fato de que as outras assumem que você está com o Arduino padrão Duemilanove.

Olha só, fiz testes agora (10/05/11 às 20:49 kk) e percebi que com a biblioteca padrão do Arduino funciona também. Basta que alteremos o chipSelect para 53 (const int chipSelect = 53;) logo após a inclusão de <SD.h> e que dentro do setup() definamos pinMode(53, OUTPUT). Feito isso, testei aqui e funcionou perfeitamente. Mesmo sendo simples, segue aqui o fonte usado (disponível na instalação padrão da IDE do Arduino):

/*
  SD card datalogger

 This example shows how to log data from three analog sensors
 to an SD card using the SD library.

 The circuit:
 * analog sensors on analog ins 0, 1, and 2
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4

 created  24 Nov 2010
 updated 2 Dec 2010
 by Tom Igoe

 This example code is in the public domain.

 */

#include <SD.h>

// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 53;

void setup()
{
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(53, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
}

void loop()
{
  // make a string for assembling the data to log:
  String dataString = "";

  // read three sensors and append to the string:
  for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 2) {
      dataString += ",";
    }
  }

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

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
}

Com o arquivo acima carregado no Arduino, ele irá gerar um arquivo chamado datalog.txt dentro do cartão com as informações de leitura dos sensores analógicos 0 à 2. Isso pode ser muito útil para as mais difersas coisas, como por exemplo um logger de sensor de temperatura, direção do vento e umidade do ar.

Faça agora testes com o exemplo ReadWrite da biblioteca do Arduino lembrando sempre de alterar o pino 4, padrão em shields com SD/MMC, para 53 que é o usado no Arduino Mega.

Estudos e melhorias futuras

Com certeza o que apresentei aqui foi só uma introdução ao funcionamento de cartões de memória com Arduino. Entre futuros estudos podemos citar a redução do tamanho da biblioteca para que possa funcionar com o Atmega8, estudo aprofundado do protocolo SPI e quem sabe também, implementar sistema de arquivos ext4.

Referências

[1] http://www.sdcard.org/developers/tech

[2] http://www.sdcard.org/developers/tech/sdcard

[3] http://ww1.microchip.com/downloads/en/devicedoc/spi.pdf

[4] http://arduino.cc/en/Reference/SPI

http://www.interfacebus.com/Multi_Media_Card_Pinout_MMC.html

http://www.ladyada.net/make/logshield/sd.html

http://www.ladyada.net/learn/arduino/ethfiles.html

Minha Reflexão

O custo de um shield SD é alto. Com cerca de 25 centavos (6 resistores) e uma câmera fogográfica/placa mãe de notebook queimada, que tem como destino o lixo, podemos montar um DataLogger funcional e pronto para uso. Se tiveres vontade de montar um adaptador como esse, divirta-se, aprende-se muito fazendo isso! Se gostou deste estudo, comente abaixo, vamos trocar algumas ideias!

170 Comments

  1. Paulo, como leigo em eletrônica, pergunto: utilizando uma placa leitora de SD card padrão, uma bateria de 3.3v, um interruptor, e um pouco de solda, não tempos como gravar diretamente pulsos no cartão SD ? Imagino que para registrar tempo a cada click, seria necessário algum chip complementar. Vc já fez algo parecido ?

    1. Olá Fabio. Muito interessante sua pergunta/sugestão.

      Primeiro devemos lembrar que para armazenar dados precisamos de uma tabela de alocação de arquivos, certo? O cartão SD usado neste tutorial foi formatado em FAT32, porém funciona também em FAT16.

      Respondendo sua pergunta: Com uma placa de cartão SD, um regulador de 3.3v e um interruptor apenas não é possível fazer isso, pois você precisa implementar a camada de software necessária para acessar o cartão usando a tabela de alocação de arquivos qual o cartão trabalha.

      Aí entra o Arduino para facilitar nossa vida! Basta fazer as conexões seguindo esse tutorial, e via software processar o que desejas. Neste caso, basta incluir a biblioteca (neste exemplo #include < SD.h >) que se encarrega de abstrair toda a camada "de baixo nível" da tabela de alocação de arquivos para você. Ou seja, não é necessário saber como ela funciona, basta incluí-la e saber fazer as chamadas corretas para abrir o cartão, escrever algo lá (os pulsos que você falou), e por fim fechá-lo.

      Já trabalhei bastante com cartão SD amigo Fabio, então se quiseres posso te ajudar a desenvolver seu projeto. Basta me passar mais informações que daremos um jeito!

      1. Boa tarde parceiro, estou trabalhando com o cartão SD porem em meu projeto ja estou utilizando os pinos 11,12 e 13 será que seria possivel alterar estes pinos para outros pinos do arduino?

        1. Oi Elton!

          O cartão SD usa a interface SPI do Arduino. O microcontrolador Atmega 328 (usado no Arduino Uno, Duemilanove, nano etc) tem uma interface SPI e ela usa os pinos 10, 11, 12, 13, confira aqui. O Arduino Mega usa as portas 50, 51, 52 e 53 para SPI.

          Logo, se desejas usar o cartão SD, precisa usar a interface SPI, e como ela é fisicamente conectada nos pinos respectivos, você deverá modificar seu projeto para se adequar a isso.

          Abraços!

      2. Oi Paulo, difícil encontrar alguém com tanta boa vontade em auxiliar o próximo, parabéns e continua assim.

  2. Caro Paulo, estou tentando comunica meu arduino com um cartão MMC/SD, porém arduino sempre me retorna um erro e pelo que me parece é da biblioteca(SD), você já se deparou com algo do tipo?

    In file included from SD_Size.cpp:23:

    /usr/share/arduino/libraries/SD/SD.h:26: error: expected class-name before '{' token

    SD_Size.cpp: In function 'void loop()'

    E seria possível fazer com outros valores de Resistência?

    E eu não compreendi o cálculo da seguinte função:

    "Vres = V x R1 / R1 + R2 = 23500 / 14700 = 1.60 Volts"

    Sendo R1 = 10 000

    R2 = 4 700

    (V x 10000) / (10000+4700) = 10000V / 14700

    Qual Valor de V para 23500, 2.35?! se for de onde é este 2.35V??

    pois R1(10000) vezes 2.35 resulta em 23500

    Estou um pouco confuso..

    Aguardo respostas, obrigado!

    abração !!!!

    1. Olá Roberto,

      Já tive vários erros de comunicação, biblioteca etc, mas esse ainda não. Pelo que pesquisei rapidamente, existe um problema com a IDE 0018 Alpha, qual a versão de sua IDE? Estou rodando aqui com a vesrão 0022 do Arduino IDE, não tenho esse problema.

      Tente rever sua instalação neste link.

      Sobre outros valores de resistência seria sim perfeitamente possível. Como mostro no próprio post, o link para a imagem externa, eles usam resistores de 3.3k e 1.8k

      Usando a regra da divisão de tensão (Fonte: Introductory Circuit Analysis pg 135, figura 5.10):

      Vx = Rx x E / Rt

      Vx = R1 x 5 / R1 + R2

      Vx = (3300 x 5) / (3300 + 1800)

      Vx ou Vres = 3.23

      A medida da tensão sempre é do GND até o resistor, neste caso o 3.23 é a tensão que passa pelo resistor maior, neste exemplo o de 3k3 (3300 ohms).

      Veja no post a imagem que inseri explicando isso, talvez fique mais claro.

      Abraços

  3. Li sua publicação no GOOGLE e vi que V. é um expert em informatica. Se puder me dar uma dica, agradeço muito.

    Segue: No sistema de som de meu carro, tenho encaixe para cartão SD, para reprodução de musica. No entanto, ele so reproduz musicas gravadas em MP3, e não estou conseguindo gravar minhas musicas favoritas, pelo computador, que possam ser reproduzidas no veiculo.

    1. boa noite,
      tente verificar os padroes do mp3 que vc esta tentando gravar, ha taxas de bit rate, entre outras. se seu aparelho for muito antigo pode ser esse o problema, tem ue ver a qualidade maxima do audio que ele aceita e tentar na faixa que seu aparelho opera.

  4. Olá Paulo,

    comprei um data-logger shield da adafruit para arduino, estou usando um mega1289 com a biblioteca SD, tudo perfeito, o único problema é que os arquivos criados não têm a data atual e sim 01/01/2000. Você sabe como é atribuída a data ao arquivo criado no SD card?

    1. Olá Alexandre,

      Muito simples de resolver. No seu arquivo .pde (em um trecho) tem o seguinte código:

      // fetch the time
      now = RTC.now();
      // log time
      logfile.print(now.unixtime()); // seconds since 1/1/1970
      logfile.print(", ");
      logfile.print('"');
      logfile.print(now.year(), DEC);
      logfile.print("/");
      logfile.print(now.month(), DEC);
      logfile.print("/");
      logfile.print(now.day(), DEC);
      logfile.print(" ");
      logfile.print(now.hour(), DEC);
      logfile.print(":");
      logfile.print(now.minute(), DEC);
      logfile.print(":");
      logfile.print(now.second(), DEC);
      logfile.print('"');

      mude isso para:

      // fetch the time
      now = RTC.now();
      // log time
      logfile.print(now.unixtime()); // seconds since 1/1/1970
      logfile.print(", ");
      logfile.print('"');
      logfile.print(now.day(), DEC);
      logfile.print("/");
      logfile.print(now.month(), DEC);
      logfile.print("/");
      logfile.print(now.year(), DEC);
      logfile.print(" ");
      logfile.print(now.hour(), DEC);
      logfile.print(":");
      logfile.print(now.minute(), DEC);
      logfile.print(":");
      logfile.print(now.second(), DEC);
      logfile.print('"');

      Veja que você pode mudar a ordem como desejar, é bastante simples. Basta alternar a ordem de chamada dos métodos day(), month() e year().

      Bons experimentos!

  5. Prezado,

    Segui seu tutorial passo a passo, com a diferença de ter usado no lugar de um suporte para cartões de memória, eu utilizei um adaptador de sd para microsd, em teoria onde funciona SD funciona o micro SD, quando utilizamos o adpatador.

    Porém sempre da o seguinte erro

    Initializing SD card…Card failed, or not present

    você conseguiu corrigir isso?

    1. Olá amigo Anthony,

      você tem o esquema elétrico deste adaptador? O que pode estar ocorrendo é um erro simples de pinagem. Outro detalhe importante: está usando o arduino Mega? e os resistores, quais são?

      Esse erro tive várias vezes e todas elas por erros de conexões elétricas ou uso incorreto dos resistores.

      Abraço!

  6. Paulo,

    Acabei conseguindo aqui, primeiro atualizei a ide para a 0023 ou também 1.0.

    Em segundo lugar, eu retirei todos os resistores e funcionou perfeitamente,

    Agora eu vou colocar eles novamente e testar.

    Quanto ao adaptador são aqueles adaptadores de microsd, para cameras fotograficas que usam cartões sd segue uma foto, eles são apenas condutores que alteram a pinagem do microsd para ficarem compativeis com o sd.

    <a target="_blank" href="http://www.lpginformatica.com.br/LPG%20Arquivos/micro%20sd.jpg&quot; rel="nofollow"&gt <a href="http://;http://www.lpginformatica.com.br/LPG%20Arquivos/micro%20sd.jpg” target=”_blank”>;http://www.lpginformatica.com.br/LPG%20Arquivos/micro%20sd.jpg

    obrigado! ótimo o seu artigo!

    1. Obrigado pelas considerações.

      Agora entendi do que estava falando. Também uso esses adaptadores e nunca tive problemas com o acesso devido à usá-los. Bons estudos aí e se precisar de alguma dica, é só voltar.

  7. Paulo,

    Gostaria de uma informação, tenho um a camera intra oral e esta so aceita cartao MMC. Voce consegueria fazer ler outro tipo de cartao? Como o SD?

  8. Muito bom esse tutorial. Aqui eu improvisei soldando uma barra de pinos direto em um adaptador MicroSD/SD.

    Funcionou perfeitamente. Testei todos os códigos de exemplo da biblioteca SD do Arduino e não tive problemas com nenhum.

    1. Olá Maurício,

      que bom que funcionou! Implementei esses dias a solução descrita aqui em meu TCC também, funcionou certinho!
      Preciso descobrir agora o porquê dos shields usarem o conversor lógico em vez dos resistores…

      Obrigado pelo retorno.

  9. Paulo,

    Eu to usando o arduino duemilanove e o meu circuito faz o uso de um display e também de uma circuito para gravação de dados no display . Acontece que duas portas(11 e 12 ) coincidem . Tem como eu usar para gravar outra porta do arduino

    1. Oi Novack,

      qual o modelo de seu display? que bibliotecas está usando?
      basicamente o que precisará fazer é alterar os pinos na própria biblioteca, geralmente funciona.

      Mas para ter certeza preciso de mais informações ok?

  10. Paulo, boa noite sou leitor do seu blog a um tempo e parabens pelo grande trabalho, estou com uma duvida preciso ler o SD com o arduino, mas precisava mostrar o arquivo de texto no display 128×64 usando a biblioteca GLCD, e não consegui mostrar o texto no display teria como me dar uma ajuda, obrigado.

    1. Oi Wellington,

      Obrigado pelas considerações, sem dúvida alguma posso lhe ajudar! Pelo que entendi sua dúvida está mais relacionada com o display do que com o cartão SD certo?
      Já trabalhei com esse display, como pode ver neste tutorial.

      Entre em contato comigo por email, enviando seu código fonte e detalhes mais específicos de onde parou que aí daremos um jeito ok?

      Abraços!

  11. Boa tarde Paulo,

    Em caso de remoção do SD durante a execução do sistema, ele não identifica que foi removido.
    Você tem ideia de como seria possivel identificar essa remoção e “carregar” novamente quando detectasse que o cartão foi inserido?

    Att,

    1. Oi Edipo,
      que bom que nos trouxe essa dúvida. Já havia pensado nisso também.
      Atualizei o post com informações para você solucionar este problema, basicamente deverás trabalhar com as interrupções externas do Arduino e tratar os dois contatos do soquete, vistos nas imagens recém postadas, como os de um botão comum.

      Se tiver alguma dúvida em relação ao software, me avisa que posso lhe ajudar.

      Abraços

  12. Paulo,
    Eu to usando o arduino duemilanove e o meu circuito faz o uso de um display e também de uma circuito para gravação de dados no display . Acontece que duas portas(11 e 12 ) coincidem . Tem como eu usar para gravar outra porta do arduino

    Paulo Marcos Trentin
    junho 24th, 2012 – 09:35

    Oi Novack,

    qual o modelo de seu display? que bibliotecas está usando?
    basicamente o que precisará fazer é alterar os pinos na própria biblioteca, geralmente funciona.

    Mas para ter certeza preciso de mais informações ok?

    display 16×2 – biblioteca liquid crystal e sd

    outra
    eu não to conseguindo abrir o datalog

    1. Oi Novack,

      quando começamos a misturar circuitos em um mesmo projeto é que começa a ficar divertido e difícil hehehe. Mas é nessas ocasiões que aprendemos detalhes e avançamos o nosso conhecimento.

      As portas 11 e 12 são conexões MOSI e MISO respectivamente. Ou seja, são usadas no barramento SPI, usado pelo cartão de memória. Mais detalhes você encontra aqui. Não tenho certeza se entendi, mas quando você se refere à “gravação de dados no display” está falando em gravar os dados do display no cartão de memória é isso?

      De qualquer modo, os pinos para controlar o display podem ser facilmente alterados quando usando a biblioteca LiquidCrystal. Ao iniciá-la, nesta linha:
      LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

      Altere o número 12 e 11 para os pinos que deseja conectar os fios de controle do display. Por exemplo use:
      LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

      E altere também a conexão elétrica do display, conectando o fio que conectava o pino 12, agora para o pino 7 e o fio que estava conectado no pino 11 para o pino 6. Faça os testes e informe se funcionou ok?

      Bons estudos!

  13. Eu vou pegar dois dados(corrente elétrica e tensão)em duas portas analógicas e vou mostrá-los e gravá-los . Eu entendi o que vc falou , funcionou legal. Mas eu estou tendo problemas ao abrir o arquivo datalog.txt sobre isso o que eu faço.

    1. Certo, quando disse que funcionou se refere a gravação de dados no cartão?
      Se sim, então a leitura não deve lhe dar muitos problemas. Qual o erro que está tendo?
      Me passa o código fonte também, assim fica mais fácil ajudar.

  14. Olá Paulo. Gostei muito do seu site, e esse tópico do datalogger já me inspirou a fazer uns testes hehe. Eu queria saber se você pode me ajudar com o seguinte: Eu preciso fazer um datalogger como esse, com cartão SD e talz, mas utilizando um PIC16F877A, por questões de custo, principalmente. Isso será adicionado a um projeto de um contador que eu fiz, e a intenção era fabricar varias placas, sendo assim a mudança de PIC para Arduíno não compensa, pois vai encarecer e muito o projeto. Você tem algum conhecimento de PIC? Conhece alguma biblioteca pra SD semelhante a esta do Arduíno? Eu andei pesquisando bastante nos últimos dias mas é informação demais e cada lugar diz uma coisa diferente ._. eu não tenho muita experiência em comunicação serial, então é fácil se confundir…

    Bom, se puder me ajudar com alguma informação…

    Desde já agradeço!

    P.S.: Muito legal o conserto da máquina de lavar xD

    1. Oi Eduardo, que bom que gostou do site!

      Trabalhar com cartão é muito emocionante, pois expande muito os horizontes de um projeto embarcado.
      Porém não entendo como o custo de um microcontrolador para outro irá interferir em seu uso, afinal a diferença é de 10,00 reais aqui no Brasil. A menos que você pretenda fazer algo para ser produzido em escala industrial, aí sim.

      Do contrário, Arduino é muito, muito fácil de implementar.

      Bom, mas se a ideia é mesmo fazer em PIC, tudo é possível!
      Eu acredito que você terá muito trabalho, mas posso lhe ajudar sim. Não conheço quase nada sobre PIC, já brinquei mas não muito sério. Encontrei alguns projetos na internet, veja:
      http://www.compsys1.com/workbench/On_top_of_the_Bench/MMC_Project/mmc_project.html#SD9
      https://www.marcusbannerman.co.uk/index.php/research/electronicspics/40-pic-projects/76-fat32-library-for-pic18-devices.html
      http://www.gedanken.demon.co.uk/gps-sd-logger/
      http://www.microchipc.com/sourcecode/ (procure por mmc)

      Me informe o que já estudou, o que conhece sobre PIC, que ferramentas usa, aí posso tentar trabalhar com algo semelhante aqui para obtermos os mesmos resultados.

  15. Boa tarde,
    Eu estou a fazer um projecto com um arduino uno, o meu projecto para ja consiste em guardar as horas em um cartão SD, estou usando um Rtc “ds1307”, e o cartão Sd como vocês estão a utilizar em cima.
    Testando o rtc sozinho as horas dão certo, mas quando tento guardar no cartão SD o rtc dá valores completamente estúpidos como por exemplo “165:165:85”.

    Não sei se isto é algum problema eléctrico ou de software, ja tive a exprimentar imensos softwares e a ver muitos esquemas electricos e ainda não percebi porque não dá.

    Agradecia a vossa ajuda,
    Obrigado

    1. Oi Fernando,
      Para poder lhe ajudar, preciso que poste aqui o código fonte que está usando para eu analisá-lo ok?
      Ao gravar um texto qualquer no cartão, funciona corretamente?

      Aguardo.

  16. Olá Paulo, de novo!
    Cheguei em casa e fui logo pro Arduino para testar a sua aplicação. Primeiro soldei os fios no adaptador microSD baseado na imagem que você postou, depois fui procurar os componentes e eu possuia todos os componentes que você usou. Montei tudo numa protoboard e fui programar o Arduino. Infelizente não deu muito certo com seu código, apresentou um erro na compilação dizia na linha “if(!SD.begin(chipSelect)) {” dizendo: ‘SD’ was not declared in this scope, mas acredito que seja porque não usei a biblioteca que você citou no seu artigo, então aproveitei a biblioteca SD que tinha no Arduino e usei um exemplo que vinha com ela e o troço funcionou corretamente.

    Fiquei feliz por ter economizado pelo menos uns 80 reais (contando o SD Shield e frete).

    Na pergunta que te fiz anteriormente já descobri porque utilizar o divisor de tensão… os pinos digitais trabalham com 5V quando estão em HIGH, por isso o divisor para que eles escrevam e se comuniquem com o SD em 3.3V.

    Cara, parabéns novamente e sucesso!

    1. Oi Ticva,

      obrigado por voltar e compartilhar, assim esse blog cresce e mais pessoas podem se beneficiar dessas informações. Esse erro ” ‘SD’ was not declared in this scope” é causado por não estar incluso a biblioteca SD no início do programa: “#include ” (parece que houve um erro no meu editor aqui na hora que salvei e o acabou não aparecendo, mas já corrigi.

      Realmente a economia é muito alta!

      Sobre a questão dos 3.3V é isso mesmo, que bom que conseguiu rodar tudo, parabéns também!

  17. Amigo, seu site eh exemplar….So agora comecei no mundo arduino…
    Minha duvida eh a seguinte, se o cartao SD necessita de 2.7 a 3.6 volts, naum poderia ligar o VCC do cartao diretamente
    ao 3v3 do arduino ? Agradeco sua atencao…

    1. Oi Carlos,

      obrigado pelas considerações, e seja bem vindo ao mundo Arduino!
      Isso mesmo, a alimentação do cartão – pino 4 – vai conectada diretamente ao 3v3 do Arduino (repare com atenção o desenho de conexão).

      Já os pinos digitais (SS, MOSI e SCK) precisam passar pelo divisor separado, afinal são conexões de dados.
      Não sei se entendi corretamente sua pergunta, no mais pergunte novamente ok?

      Abraços

  18. Olá Paulo.

    Desculpe a demora em respondê-lo. Quando eu disse do custo, falo de um Arduíno contra um PIC e não do ATMega. Um Arduíno fica próximo de 100 reais enquanto um PIC fica na caa dos 10 a 20 reais no máximo. Eu não sei como programar um ATMega e nem o custo =/

    Bom, eu olhei alguns sites que você me passou e também olhei as bibliotecas MMCSD e FAT do compilador CCS, que eu utilizo. O problema nisso tudo é a memória. O PIC que possuo aqui é um 16F877A com somente 368 Bytes de RAM =/ e todas as bibliotecas que vi são pra PIC18, e necessitam de pelo menos 1MB de RAM pra implementar as funções…

    Também li que só é possível gravar no cartão SD em blocos de 512 Bytes, mas não estou 100% certo quanto a isso….

    De qualquer forma, perdi muito tempo tentando entender algumas coisas e tentando adaptar as bibliotecas pra utilizá-las com meu PIC de 368 Bytes de RAM, mas não obtive sucesso.

    Você sabe me dizer se isso é possível?

    Eu implementei um contador de ciclos com esse PIC, para uma máquina de ensaio, e preciso acrescentar um datalogger. Na verdade preciso armazenar a contagem a cada 10mil ciclos, salvando o valor atual num cartão SD para que possa ser lido num PC depois. Por mais que a princípio pareça mais fácil trocar o microcontrolador, vamos assumir que eu deva fazer com este, seria possível? Se puder me ajudar eu agradeço muito…. ando quebrando a cabeça com isso e não sai nada =/

    Você tem meu email, qualquer coisa pode me mandar mensagem a qualquer hora. A propósito, se você tiver gmail, fique livre pra me adicionar no gtalk…

    Desculpe o incômodo, mas tô precisando de ajuda e não encontro ninguém que entenda do assunto e esteja disposto a ajudar…

    Desde já agradeço.

    1. Oi Eduardo,

      li uma vez em um livro de robótica: “pesquisa nunca é em vão”. Isso nunca mais me saiu da cabeça, e costumo levar essa frase muito a sério.

      Discutindo um pouco sobre PIC e AVR hehe: Um PIC custa mesmo 10 a 20 reais, porém se você somar um gravador USB (qual custa cerca de 100,00 reais: http://produto.mercadolivre.com.br/MLB-432164039-gravador-picburner-usb-zif-pic-de-brindesoftwarescd-soft-_JM) à isso verá que mudam as coisas. O Arduino já possui esse gravador integrado. Uma vez gravado, basta retirar o microcontrolador e ele fica solto como o PIC.

      Mas vamos assumir que você só pode fazer este projeto com o PIC. Encontrei alguns projetos que podem nos dar uma luz: http://mondo-technology.com/sdcard.htm e http://justanotherlanguage.org/content/jallib/tutorials/tutorial_sd_card. Parece que será complicado com este modelo de pic. Deve ser obrigatoriamente o 16f877?

      Parece mesmo que só podemos ler 512 bytes por vez do cartão, e como esse PIC tem apenas 368 podemos usar uma “memória RAM” externa.

      Estou disposto a lhe ajudar, mas como já lhe disse, minha experiência com PIC é mínima. Possuo um 16F877, vou fazer alguns testes e lhe manter informado Eduardo. Se conseguirmos fazer isso, irei fazer um tutorial aqui no site para complementar este.

      Conversamos por email então, abraços.

  19. Fala Paulo,

    Parabens pelas dicas! Pelo que vi vc é o que possui o melhor material em portugues p/SD na net.
    instalei meu leitor de SD(lc studio do DX) na minha mega 2560 e funcionou bem! Todos os sketchs de exemplo rodaram. Meu probelma e que preciso do SD para gravar nele os valores armazenados na EEPROM até a posição 30 e, posteriormente, le-los do cartao para grava-los novamente na EEPROM. Isto porque preciso editar os valores no computador…
    alguma sugestao???

    []s

    1. Oi Augusto,

      a ideia deste post sobre cartões SD foi realmente suprir essa falta de material em português sobre o assunto. Como não existe muito segredo, fiquei maravilhado com os resultados.

      Minha sugestão é o uso de um arquivo .txt para fazer isso. Existem exemplos de como ler e gravar um arquivo txt nos exemplos que acompanham a IDE do Arduino.
      Se tiver dúvidas de como fazer isso me avisa que desenvolvo e posto um código fonte aqui.

      Abraços

  20. É possivel gravar pulsos em grande velocidade como 10 pulsos por segundo ou até 100 pulsos por segundo ?

    Ah, e se esse tutorial funciona com Arduino Uno…

    Obrigado pela força!

  21. Pois é Paulo,

    Tenho tentado, mas sem exito! se vc tiver algum sketch de auxilio, pelo menos me apontando o norte a seguir,
    Ficaria muito grato!!!

    Grande abraço e muito obrigado!

  22. Salve Paulo,

    parabéns pelo trabalho cara e pelo site, vi o vídeo da sua apresentação de TCC e achei muito foda, parabéns.

    Sou iniciante e fiquei com uma super dúvida quanto aos resistores usados, eu sempre usei essa formula (R= V/I) para calcular os resistores quando ia fazer alguma coisa com led. No caso usando a formula ficaria, 5V – 3.3V = 1.7V -> R= 1.7/I , eu teria que saber quanto miliamperes deve ser aplicado no sd certo? E assim eu ia encontrar um valor para o resistor que devo usar corretamente, ou não devo fazer dessa forma?

    Obrigado.

    1. Oi Fellipe,
      que bom que assistiu a apresentação e muito obrigado pelas considerações!

      Exatamente, seu raciocínio está correto, pode ser calculado desta maneira mesmo.
      Como o cartão de memória não tem um consumo alto de corrente (normalmente entre 45 e 80 mA, confira aqui) temos várias configurações de resistores possíveis. Se você tiver um resistor, pode com a tensão de saída calcular também o valor do outro, confira aqui na wikipedia a fórmula.

      É incrível como a eletrônica pode ser cheia de detalhes nas coisas mais simples hehehe

      Bons estudos!

      1. Salve Paulo,

        obrigado pela resposta e pelas dicas de estudo, eu fiz aqui o Data-Logger SD/MMC usando um arduino duemilanove e algumas peças que retirei de algumas sucatas que encontrei aqui em casa, fiz baseado no seu tutorial, mas fiz uma organização e programação diferente para servir no duemilanove, também coloquei um LDR para fazer uns testes, no caso para salvar os dados do sensor no sd.

        Aqui tem algumas fotos para você ver como ficou: https://www.facebook.com/media/set/?set=a.477036855654560.115615.100000447507617&type=3

        Obrigado cara pela força, té mais.

  23. Boa tarde Paulo.

    Preciso de tua ajuda. Pretendo comprar uma PCI para cartão SD, porém para funcionar precisarei das bibliotecas para cartão SD. Sei que ele trabalha com comunicação SPI. Vou usar os microcontroladores da Atmel, AT90S8535 ou AT90S2313. Onde posso achar as libs do cartão SD para estes microcontroladores ?

    1. Oi Sandro,

      pelo que pesquisei ambos os microcontroladores que me passou são bastante limitados. Não encontrei nenhuma biblioteca SD para eles (será por falta de poder de processamento/memória?). Qual o motivo em usá-los?

  24. Boa noite
    Estou precisando ler um dado que está na linha 4 do meu arquivo .txt no meu cartão SD. Teria uma função para ler dados na linha especifica e utilizar no meu programa.
    Estou utilizando o Arduino Mega e ja tentei diversas diversas bibliotecas.
    Muito obrigado

    1. Oi Fabio,
      trabalhar com arquivos .txt é sempre emocionante!

      Para contar as linhas você precisa saber se leu um ‘\n’ certo?
      No padrão Windows a nova linha é data por CR (Retorno de Carro) + LF (Alimenta Linha), veja aqui detalhes sobre isso. Neste caso seu código deve detectar se o caractere atual lido é o LF, e o anterior é o CR (CR + LF). Algo como:

      if (byteAnterior == 13 && byteAtual == 10) { aqui o contador de linha }

      Lembrando que 13 é o código DECIMAL da tabela ASCII que corresponde ao CR e 10 ao LF.
      Faça testes e se possível passe aqui para dizer se funcionou ok?

      Bons estudos!

  25. Gostaria de saber se isso tudo serve, para cartão microSD como adaptador. E qual é a pinagem para um UNO, isso ficou meio nebuloso pra mim…
    grato

    1. Oi João,

      realmente, eu acabei não focando no Arduino Duemilanove ou Uno, pois os exemplos que encontrava sempre eram para estes hehe.
      A única mudança é em relação a comunicação SPI, no Mega ela segue esses padrões: 50 (MISO), 51 (MOSI), 52 (SCK), 53 (SS). Já no Uno, os pinos usados são: 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK). Então basta mudar os pinos visto no tutorial para seu correspondente, por exemplo o fio que vai no pino 53 do meu Arduino Mega, irá no 10 do Arduino Uno e assim por diante. Lembre de adaptar o software também (chipSelect = 10).

      Sobre o adaptador, uso com frequência cartões microSD, e têm funcionado muito bem.

      Bons estudos!

  26. Parabéns pelo site, muito informativo.
    Estou tentando ler um micro sd no ethernet shield, porém o mesmo não é reconhecido, qualquer cartão sd funciona com esse shield?

  27. Grande, parabéns pelo projeto, realmente muito bom!!!

    Teria como me mandar como proceder para usar com o arduino UNO?

    Eu tenho um SD MODULE ( http://www.dfrobot.com/wiki/images/thumb/b/b3/SD_module.jpg/400px-SD_module.jpg ) que eu não consigo fazer funcionar com os exemplos, sempre da erro de leitura do cartão.

    Os pinos deles são: MISO, SCK, SS, MOSI, GND, 5V, e o cartão é um de 2GB Transcend, não consigo inicializar esse cartão com esse módulo de jeito nem um, tem como me dar um Help?!

    Obrigado

    1. Oi Bruno,
      Obrigado pelas considerações!

      Esse módulo parece-me ser muito bom. O esquema de conexão é: 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK). Logo, o pino 10 do Arduino UNO ou Duemilanove é o Chip Select no protocolo SPI.

      Lembre-se do software, altere a linha onde tem a definição do pino a ser usado para ativar o chip (chipSelect = 53) para chipSelect = 10.
      Faça os testes e me diga se funcionou. Teste também com outros cartões.

      Bons estudos!

      1. Grande, Obrigado pela explicação, eu tinha feito ela funcionar poucas horas depois que eu postei, o meu desafio agora é mexer com o Xbee via Serial, já li tudo quanto é documento, mas nao entendi como enviar dados para ele (para o Xbee como ler 1 Xbee específico e tal)…, Se souber ou onde eu possa ler a respeito agradeceria muito!!!

        Obrigado

          1. Boa Tarde, por favor, se pudesse fazer este, preciso ligar os 4 Xbee 1 coordenador e 3 end point, comprei o livro intrumentação eletronica sem fio para ler mais a respeito, mas o camarada me escreve os exemplos em assembly… não sei o que deu na cabeça dele para não escrever em C, e por isso estou na mesma…, mas agradeço, vlww

  28. Parabéns Paulo, excelente material! Estava pesquisando sobre sd card e sem dúvida seu post é uma mão na roda! Tô querendo comprar um sd card, mas só encontro no Laboratório de Garagem e tá esgotado! Poderia me indicar algum site em conta ?? Obrigado

      1. Olá Paulo,

        Gostaria de saber se tem como eu verificar se os dados que eu enviei para Sd card foi recebido corretamente pelo mesmo. Você já fez algum programa que fizesse essa verificação?? Obrigado

  29. Boa tarde Paulo,

    Eu uso cartão SD para gravaçao de dados de interrupção externa (velocidade e rotação, que chegam a no máximo 58km/h e 4000rpm)com Arduino UNO. Porém não consigo visualizar os dados reais, os valores gravados no SD são valores bem estranhos (-2123, -1235, etc.), tanto pra velocidade quanto para rotação. O que pode estar ocasionando isso? Tem alguma sugestão?

    Parabens pelo post, ficou muito bacana!

    1. Opa, obrigado Daniel!

      Olha, me parece um erro de conversão de tipo de dados. Precisaria ver seu código fonte para poder lhe ajudar. Se não quiser postar aqui, entre em contato comigo por email que podemos tentar resolver isso.

      Abraço

      1. Segue o programa. Desde já agradeço!

        #include

        int CS_pin = 10;
        int pow_pin = 8;

        float refresh_rate = 0.0;

        float ve1,ve2,ve3,ve4,vex,vey;
        int v,ones,hundreds,tens;
        unsigned long delaytime=250;
        int rotacao;
        float velocidade;
        volatile int count,count2;
        unsigned long previousMillis,tmp,tmp2,tempo20,temp,temp1,temp2, tempo,tempo2,tempo1;
        unsigned long int aux;

        void setup() {

        Serial.begin(9600);
        Serial.println(“Initializing Card”);
        //CS Pin is an output
        pinMode(CS_pin, OUTPUT);

        //Card will Draw Power from Pin 8, so set it high
        pinMode(pow_pin, OUTPUT);
        digitalWrite(pow_pin, HIGH);

        if (!SD.begin(CS_pin))
        {
        Serial.println(“Card Failure”);
        return;
        }
        Serial.println(“Card Ready”);

        File logFile = SD.open(“LOG.csv”, FILE_WRITE);
        if (logFile)
        {
        logFile.println(“, , , ,”); //Just a leading blank line, incase there was previous data
        String header = “Rotacao, Velocidade”;
        logFile.println(header);
        logFile.close();
        Serial.println(header);
        }
        else
        {
        Serial.println(“Couldn’t open log file”);
        }

        attachInterrupt(0,interupcao, FALLING); // ligando a interupcao da rotacao
        attachInterrupt(1,interupcao2,FALLING); // ligando a interupcao da velocidade

        count = 0;
        count2 = 0;
        aux = 0;
        }

        void loop() {

        /////////////////// TRATAMENTO DE ROTACAO
        if (count >= 1)
        {
        detachInterrupt(1);
        detachInterrupt(0);
        tempo = millis()-tempo1;
        tempo1 = millis();
        //Serial.println(tempo);
        //Serial.print(” tempo”);
        // Serial.println();
        if(tempo >= 5)
        {
        rotacao = 30000/tempo*count;
        int led = map(rotacao,1300,4200,0,10);
        //Serial.println(rotacao);
        //Serial.print (“ROTACAO”);
        //Serial.println();

        }
        count = 0;
        attachInterrupt(1,interupcao2,FALLING);
        attachInterrupt(0,interupcao,FALLING);
        }
        ////////////////// TRATAMENTO DA VELOCIDADE (Médias feitas para diminuir um pouco o ruído)

        if (count2>=1)
        {
        detachInterrupt(0);
        detachInterrupt(1);
        temp = millis()-temp1;
        if(temp >= 100)
        {
        temp1 = millis();

        velocidade = 5853.9/temp*count2;
        ve1 = velocidade;

        if (ve1 > ve2)
        {
        vex = ve1;
        vey = ve2;
        }

        else
        {
        vex = ve2;
        vey = ve1;
        }

        ve3 = vex – vey;

        if (ve3 < 20)
        {
        ve4 = ve1 ;
        ve2 = ve1;
        }
        else
        {
        if( vex == vey)
        {
        ve4 = ve1;
        ve2 = ve1;
        }
        else
        {
        ve4 = vey;
        ve2 = vey;
        }
        }

        //Serial.println();
        //Serial.print("Velocidade ");
        //v = ve4;
        // ones=v%10;
        //v=v/10;
        //tens=v%10;
        //Serial.println("velocidade");
        //Serial.println(ve4);
        //Serial.print(velocidade);
        //Serial.println();

        count2 = 0;
        }
        attachInterrupt(0,interupcao,FALLING);
        attachInterrupt(1,interupcao2,FALLING);
        }

        String dataString = String(rotacao) + " , " + String(v);

        File logFile = SD.open("LOG.csv", FILE_WRITE);
        if (logFile)
        {
        logFile.println(dataString);
        logFile.close();
        Serial.println(dataString);
        }
        else
        {
        Serial.println("LOG.csv");
        Serial.println("Couldn't open log file");
        }

        }

        void interupcao()
        {

        count++;

        }
        void interupcao2 ()
        {

        count2++;

        }

        1. Olá Daniel,

          fiz testes com seu código com o sensor de rotação. Como não tenho tal sensor, não sei como ficaram seus dados.
          Mas veja esta imagem, e repare que os dados processados pelo software são os mesmos salvos no cartão.

          Recomendo você revisar a metodologia de cálculo.
          Alguns projetos que podem lhe ajudar:
          http://labdegaragem.com/profiles/blogs/projeto-tac-metro-com-arduino
          http://playground.arduino.cc/Main/ReadingRPM
          http://www.alpha.triggerdog.com/blog/?p=17
          http://mods-n-hacks.wonderhowto.com/how-to/build-cheap-arduino-tachometer-measure-rpms-spinning-fans-and-more-0138986/

          Recomendo você refatorar o código, a fim de simplificá-lo o máximo possível. Lembre-se de sempre debuggar via serial
          o valor gravado no cartão.

          Bons testes!

  30. Parabens pelo seu modulo.
    Montei um parecido a alguns meses.
    Porém, estou com problemas em usar o MMC card
    “Initializing SD card…Card failed”
    usei R1 e R2 4k7 e 2k smd disponiveis,
    Poderiam ser eles que estão dando erro??
    Estranho pq funciona normal com SD e Micro SD-card.
    E os card estão formatados com FAT.

    1. Oi Nilton,

      Os resistores podem ser o problema sim! é muito comum isso acontecer..
      Essa questão de funcionar com alguns cartões e não com outros eu diria que é falta de corrente.

      Neste caso, tente fazer a divisão com resistores de menor impedância possível.
      Sua fonte de 3.3v está ok?

      Bons testes!

      1. fontes estão OK sim
        no forum do arduino.cc me disseram q a biblioteca do SD nunca funcionou com MMC-card
        Estranho mas fazer oq.
        Por acaso vc tem algum MMC pra testar, ou ja usou um destes???

          1. Claro,
            Eu ja usei SD e micro-sd funcionam na boa.
            a ideia era aproveitar um MMC q tenho sem uso
            ae ao testar deu erro e fiquei curioso em saber por que?
            afinal diziam q MMC e SD eram 100% compativeis
            e notei q num é BEEM assim, tem sim diferenças.
            fica a observação..
            obrigado a atenção
            e aproveitando BOAS FESTAS PRA VC.
            caso os maias estejam errados mesmo rsrs

  31. Paulo, primeiramente parabéns pelo site, pelas idéias e pelo ideal de colaborar e ajudar o pessoal a descobrir o mundo arduino, gostei muito do seu site.

    Com base no datalogger com o SD/MMC, andei pesquisando e tentando uma forma de gravar em um pendrive no arduino, mas por fim só achei páginas de vendas de shields usb… tem alguma idéia, um norte apenas mesmo, de como fazer isso sem utilizar um shield?

    E obrigado pelo material disponibilizado aqui no site, foi/é/será sempre de grande ajuda!

    Abraços

    1. Oi Luis Arruda,
      desculpa a demora em responder, agora estou voltando com o blog!

      Muito obrigado pelas considerações!

      A empresa tato.ind.br vende um circuito eletrônico que acessa o pendrive através de uma API que você pode interagir com o Arduino. Se ainda tiver interesse me avise que posso lhe enviar mais materiais.

      Abraços

  32. Olá Paulo!
    Estou realizando alguns testes com o arduino Uno e breakout cartão SD. Em um dos códigos do livro arduino básico (Capitulo 15, código 42), etá ocorrendo o seguinte erro:
    Type any character to start error:
    card.init failed
    SD error: 2,78

    O que poderia estar gerando esse erro?

    1. Oi Daniela,

      esse erro normalmente acontece por algum erro de conexão elétrica.
      Para lhe ajudar preciso de fotos detalhadas do seu projeto (mostrando bem onde cada fio está sendo conectado) ok?

  33. Olá Paulo. Parabens pelo projeto, muito bom mesmo.
    Estou tentando implementar um codigo aqui utilizando o PIC, e consegui escrever e ler algumas coisas, por´m tenho algumas duvidas que talvez vc possa me ajudar.
    Estou criando um arquivo TXT no pc, gravo ele no cartão e com o pic eu leio e altero ele, e quando coloco ele novamente no pc está modificado do jeito que eu fiz, porém o endereço da memeria do cartão que fica o txt é uma incognita para mim, fico varrendo endereço por endereço procurando a “string” inicial d txt, e isso demora muito.
    Existe um documento que eu ache isso, ou um endereço deçe que me diga o endereço inicial da parte de dados dele?
    Obrigado.

    1. Oi Rafael,
      desculpe a demora em lhe responder. Infelizmente não sei responder sua pergunta, como não trabalho com pic nunca passei por este problema. De qualquer modo minha recomendação é que você use sempre a biblioteca de acesso ao cartão disponibilizada pelo fabricante, assim você economiza tempo e ganha em funcionalidades.

      Espero que já tenha resolvido seu problema.
      Abraços

  34. Olá, gostei muito do tutorial, demais!

    Estou querendo implementar um sistema datalogger afim de registrar o tempo + 8 entradas A/D, é possível gravar um txt com o tempo + 8 tabulações com os dados para uso posterior em excel por exemplo?

    Outra dúvida é quanto a autonomia do cartão SD, como faço para calcular quanto tempo um cartão de 2Gb irá durar antes de encher por exemplo?

    Abraço

    1. Oi Pablo, obrigado pelas considerações!
      Espero que ainda seja útil, sinto pela demora em responder.

      Sim, é possível gravar esta quantia de entradas e até mais no cartão. Para que o excel abra basta salvar em .csv ok? Sobre a autonomia vai depender exclusivamente de quanto em quanto tempo será gravado, mas com 2GB vai muito longe. Imagine que cada gravação ocupe 40Bytes do cartão, um cartão de 2GB tem 2000000000 de bytes (2 bilhões de bytes! – aproximadamente claro), será possível gravar 50 milhões de registros deste tamanho o que é muita coisa!

  35. Caro Paulo.

    Como fazer para que o nome do arquivo log seja dinamico, isto é, um arquivo novo a cada mes.
    nao consigo passar um string como nome do arquivo, o metodo so aceita constantes.

    Existe um meio de converter string em constante?

    Grato

  36. Caro Paulo.
    Acabei achando a resposta.

    Envio a contribuição para todos.

    …….

    char filename[] = “LOGGER00.CSV”;
    for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
    // only open a new file if it doesn't exist
    logfile = SD.open(filename, FILE_WRITE);
    break; // leave the loop!
    }
    }
    if (! logfile) {
    error("couldnt create file");
    }
    Serial.print("Logging to: ");
    Serial.println(filename);

    ……

    Ainda nao testei mas a origem é um TCC
    deve estar testado.

    Grato

  37. Ola Paulo,

    poderia me informa se e possivel ler uma linha especifica do cartão microSD e atribuir os dados de leitura
    a uma variavel?, e como poderia realiza isso?.
    so para fica mais claro estou realizando um projeto para a minha conclusao de curso, que sera necessario armazena os dados no cartao em um determinada situação como queda de energia e resgata-la depois quando a energia volta-se.agradeço o apoio.

    1. Oi Leone, desculpa a demora em responder,
      espero que ainda seja útil: é possível ler uma linha inteira do cartão sim. Veja este exemplo, tem um local onde a seguinte instrução está dentro de um while: myFile.read(). Esta instrução retorna um caractere do arquivo que você está lendo, e graças ao while (myFile.available()) todo o arquivo é lido.

      Se você fizer assim: char meuCaractere = myFile.read(); a variável meuCaractere terá cada caractere do arquivo de texto que se está lendo, logo você pode testar se é um \n (if meuCaractere == ‘\n’) e saber se está em uma nova linha, entendeu? Tudo isso pode ser usado, depois é só converter o valor da linha para um inteiro (se cada linha tem um número por exemplo), ou parametrizar os valores da linha com algum caracteres separador em especial, como a vírgula, o pipe, etc.

      Bons estudos!

      1. Obrigado pela ajuda Paulo,

        consegui solucionar o problema de outra forma usando a EEPROM do Arduino, fica uma outra duvida como no exmplo bem simples

        2013 19:56
        2013 20:56
        2013 8:56

        Fanzendo uma analize, esses numeros estão gravado no arquivo no cartao de memoria, como poderia acessa e realiza a leitura de cada linha separadamente ? e como posso ler um caracter especifico ou melhor busca esse caracter e converter em valor inteiro.

  38. Boa tarde, Paulo.

    Parabéns pelo site. Realmente muito informativo.

    Paulo, estou desenvolvendo um projeto com arduino usando um leitor de cartão SD para a gravação de 3 sensores.

    Minha dúvida: É possível iniciar o cartão de SD sem ir na IDE do arduino e iniciar a serial?

    Obrigado

    José Carlos

    1. Oi José,
      obrigado pelas considerações!

      Sim, é possível perfeitamente. O início da serial feito no Arduino é apenas para que você possa interagir com o Arduino. Mas é só mudar o código para que não use a serial e pronto, irá funcionar sem ela.

  39. Olá Paulo,
    Estou com a idéia de fazer meu TCC com arduíno, a idéia é usar um sensor de temperatura e umidade e um sensor de percepção de gases para medir o nível de gás carbônico em uma incubadora de pintinhos, a idéia era criar um equipamentoo que acompanhasse todo o processo do embriao desde a granja de poedeiras ate a saída para a granja de corte, porém não tem como passar dados via serial para o pc, então queria utilizar um SD card, neste caso teria que armazenar dados de leitura a cada 10 minutos e guardar por 30 dias aproximadamente, para que no final do processo eu pudesse trabalhar esses dados afim de comprovar se os ovos passaram pelas condições necessárias para um bom desenvolvimento. Gostaria de saber se é possível, e como faço para o PC ler dados do SD e se tem algum programa que lê esses dados. Pensei em usar o módulo Ethernet Shield, se puder me ajudar, desde ja agradeço.

    1. Oi Tiago.
      Sim, é possível fazer isso que você deseja. Aqui no meu site tenho um artigo onde mostro como acessar um cartão SD. Fazer a transmissão via rede deixaria seu projeto ainda mais interessante!

      Mande suas dúvidas, na medida do possível vou respondendo

  40. Olá Paulo
    Estou quebrando a cabeça com um projeto de tcc de timer horário com o Arduino .
    estou usando Arduino uno e um rtc botões e display para fazer as alterações de horários do timer para ligar motores por exemplo
    Estou com um problema e que tem que alterar os horários via usuário o código esta ficando muito complexo.
    Tem como colocar os horários de ligar e desligar dentro de um arquivo no cartão de memoria fazendo o Arduino buscar essas informações e executalas.
    Se puder me ajudar, desde já agradeço.

  41. Olá Paulo,

    estou tentando armazenar as medições de temperatura, umidade do ar e luminosidade em um shield SD Card acoplado ao Arduino Duemilanove, porem fiz a verificação do seu código no software Arduino 1.0.5 e o mesmo está com a seguinte informação: ‘SD’ was not declared in this scope. Enfim, vou até Import library coloco a biblioteca SD já existente no Software do Arduino e aparece a mensagem de Error compiling? Se puder me ajudar, ficarei grata, pois estou aprendendo…

    1. Oi Mirele,

      Quando você inclui a biblioteca, aparece esta linha em seu código: #include ?
      Se não, insira-a manualmente e teste.
      Se sim, me mostre seu código para poder lhe dar mais informações.

  42. Estou tentando ligar arduino mega e o shield ethernet w5100 e Ja tentei de várias formas e nada dessa coisa funcionar. Se puder ajudar eu agradeço.
    no status da ligação de rede em “enviados” fica sempre zerado no “recebidos” sempre altera. Ja fiz a ligação conforme o explicado e também direto, e nada de funcionar. na serial monitor mostra sempre “server is at 0.0.0.0” . Eu estou colocando o ip no programa que vai para o arduino. Alguém tem alguma idéia.

    1. Ola Júnior,
      lembre-se que a maior parte dos shields w5100 não suporta o arduino Mega por padrão. Para fazê-los funcionar nele, precisa fazer a conexão dos pinos 50,51,52 e 53 (interface SPI) manualmente.

      Agora os novos shields w5100 estão vindo com suporte ao Mega, procure comprar um desses quando puder. Para fazer o seu funcionar, acredito que este tutorial resolva seu problema: http://leandrozilli.blogspot.com.br/2012/11/ethernet-shield-w5100-com-atemega2560.html

      Bons estudos!

  43. Estou pensando em implantar em um projeto na qual irei utilizar alguns sensores ligados a um único arduino Uno para fazer monitoramento e gerenciamento de um equipamento remoto usando o shield de ethernet ou zigbee ( rede Mesh ) de 100 e de 1600 metros em área aberta .

    Neste projeto, pretendo usar : 1 x sensor de chuva, 4 x sensor de corrente não invasivo, 4 x sensor de temperatura (sonda) ;

    a intenção é usar o SD card para armazenar as medições mas estou preocupado com a questão da memória. é possível eu utilizar o SD card para armazenar o programa ( sketch ) integral ou parcial ?

    desde já, agradeço pela ajuda e orientação.

    1. Oi Acácio,
      desculpe-me pela demora em responder. Espero poder ainda ser útil.
      Gostei do seu projeto! Porém pelo que pesquisei não existe ainda um modo de fazer o Arduino ler o programa principal dele a partir de um cartão SD. Se encontrar um modo, ficaria muito grato se voltasse aqui para contribuir.
      Uma alternativa que vejo é usar um arduino com maior capacidade como o Mega.
      Mas lembrando, se a ideia for apenas salvar os dados lido dos sensores, com o Uno e um cartão SD é perfeitamente possível fazer isso. Talvez seja um jeito mais simples de resolver seu problema.

  44. Ola Paulo,
    Meus paragens pelo site, realmente o melhor material em português sobre SD, paragens por ser tão solicito e atencioso com os perguntadores como eu.
    Preciso de desenvolver uma solução que grave arquivos de imagem de vários cartões SD (aprox. 10), para um único cartão, ao mesmo tempo, da forma mais rápida possível… Pensei em mais de um atmega para fazer o controle disso com velocidade aceitável, mas n achei nada sobre como conectamos diretamente. Você consegue me ajudar?
    Desde já agradeço!!!
    Abraço.

    1. Oi João, muito obrigado, que bom que gostou!
      Se entendi você quer copiar um cartão para vários outros, certo? Isso é aplicação para uma loja ou algo do tipo?

      Com um Arduino fica difícil fazer e lhe digo o porquê: no arduino temos um barramento SPI (que é usado para se comunicar com o cartão) e por isso, conseguimos acessar um cartão por vez. Podemos ter vários cartões sim, mas somente podemos acessar um por vez. Qual o problema? Simples: você precisa copiar essas imagens do cartão e salvar em um lugar temporário (memória RAM, ou HD), mas o Arduino não oferece tal capacidade na própria placa (ele tem 32KB apenas! hehe).
      Solução 1: comprar memória RAM para o Arduino (vários MB), porém seria muito trabalhoso e dependendo do tamanho da imagem seria muito lento para fazer a cópia, sem falar que envolveria bastante programação: quebrar o arquivo em partes, copiar um pouco, salvar um pouco e aí por diante.

      O que recomendo: compre vários leitores de cartões USB e adapte em seu pc. Aí com um programa em C++ ou Java, você pode acessar o desejado e copiar para os demais com a maior facilidade (algumas linhas de código). Sem falar que seria mais rápido de desenvolver a solução e o funcionamento em si mais garantido.

      Com um raspberry ou cubieboard dá pra fazer o mesmo.

      Espero ter ajudado!

  45. ola paulo tenho dvd automotivo que tem entrada para sd, ele funcionava e depois parou de funcionar, quando coloco o cartao nao reconhece nem faz leitura e tambem nao abre. o que pode estar acontecendo, me ajude pois eu tenho o gps gravado no cartao e nao consigo visualizar o mesmo no radio

    1. Se entendi Wanderson, o seu cartão que antes usava no dvd automotivo não está sendo lido em outros lugares.
      É provável que o cartão tenha simplesmente queimado. Você pode tentar rodar um programa de recuperação de dados neste cartão (caso seja reconhecido no windows). Talvez lhe ajude

  46. Paulo estou usando o Arduino Duimilanove e uma placa de Datalogging e tambem estou usando um sensor SHT de Temp-Umidade que usa as portas 11 e 10, isto pode dar conflito ja que o SD.h usa a mesma porta MOSI – pin 11 ou tem jeito de resolver isto?

    1. Oi Armando, você pode usar outras portas para se comunicar com este sensor SHT.
      Procure esta definição:
      #define dataPin 10
      #define clockPin 11

      e faça as alterações. O pino clock deve estar em pwm ok.

  47. Ola Paulo,
    Muito boa sua explicação para o funcionamento do cartão,
    poderia me explicar, como executar uma ação com o arduino apos ler o arquivo dentro do SD ?

    exemplo, lê uma palavra, exemplo “Teste123”, escrita em um arquivo “Teste.txt” ,
    caso seja “Teste123” escrito no arquivo, ele acenderia um led.
    tentei o simples mas o arduino diz que não posso comparar ponteiros com inteiros :

    myFile = SD.open(“test.txt”);
    if (myFile) {
    Serial.println(“test.txt:”);

    while (myFile.available()) {
    Serial.write(myFile.read());
    if ( myFile.read() == “Teste123”);
    digitalWrite(Led, HIGH);
    }

    myFile.close();
    } else {

    Serial.println(“error opening test.txt”);
    }
    }

    1. Olá Rafael, fico feliz que gostou da explicação..

      Sobre seu problema, o que ocorre é o seguinte: a função read() lê apenas um byte. Você irá precisar ler os dados do cartão (conjunto de bytes) e armazená-los em um buffer. A leitura deve ser feita até estourar o buffer, ou uma regra ser atendida, por exemplo até receber o byte \n (quebra de linha).

      Aqui um exemplo com a leitura da Serial, mas a lógica é a mesma

      Bons estudos!

      1. Paulo, obrigado pela ajuda,
        mas estou encalhado justamente em ler o arquivo.

        exemplo, se fosse via serial seria somente ler com Serial.read() ou Serial.readBytes(), colocar em buffer e interpretar,
        mas, estava usando a biblioteca SD.h, e não intendo como ler o myFile.read(), toda vez que tento ler esse ponteiro para armazenar no buffer e interpreta-lo da erro.
        será que estou tentando ler o comando errado?

  48. Boa noite Paulo, parabéns pelo trabalho e pela iniciativa.

    Estou utilizando um cartao sd para gravar alguns dados em um cartao sd e fazer um datalogger, estou ainda na fase de gravar os dados e fazer tudo funcionar junto. separadamente tudo funciona.
    Tenho sensor de temperatura e umidade, RTC, acelerometro e cartao sd. estou usando o arduino uno.

    Estou tendo problema com a inicialização do acelerometro em conjunto com o cartao sd.

    Tenho certeza que o problema não é no hardware pois testando separadamente tudo funciona.
    o caso é que após usar a funcao calibrate() do acelerometro nao consigo abrir o arquivo do cartao sd. exatamente neste comando ocorre algum erro a linha :File dataFile = SD.open(“datalog.txt”, FILE_WRITE); no meu caso nunca vai para “1” e consequentemente nao abre o arquivo e nao consigo gravar. Se puder ajudar agradeço.

    Segue o meu codigo:

    #include
    #include //Carrega a biblioteca do MMA7361
    #include //Carrega a biblioteca do cartão SD.
    #include

    #define DHTPIN 2 // O pino onde o DHT vai esta conectado
    #define DS1307_ADDRESS 0x68
    #define DHTTYPE DHT22 // DHT 22 – RHT03 – AM2302

    byte zero = 0x00;
    const int chipSelect = 4; // PARA O CARTAO SD… NAO ENTENDI..

    float tmax=50,tmin=0,temp, umid;

    AcceleroMMA7361 accelero;
    int x;
    int y;
    int z;

    DHT dht(DHTPIN, DHTTYPE);

    void setup()
    {
    ///SENSOR
    Serial.begin(9600);
    while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
    }
    Serial.println(“Datalogger para Temperatura, umidade e Acelerometro”);
    Serial.print(“temperatura maxima: “);
    Serial.println (tmax);
    Serial.print(“temperatura minima: “);
    Serial.println (tmin);

    Serial.println(“Initializando Cartao SD…”);
    // make sure that the default chip select pin is set to
    // output, even if you don’t use it:
    pinMode(10, OUTPUT);

    // see if the card is present and can be initialized:
    if (!SD.begin(chipSelect)) {
    Serial.println(“Cartao falhou, ou nao esta presente”);
    // don’t do anything more:
    return; // para onde vai caso aconteça este return????????????
    }
    Serial.println(“cartao inicializado.”);

    Serial.println(“”);
    Serial.println(“Fim do Setup”);

    dht.begin(); // inicialização do sensor dht…

    Wire.begin(); // inicialização do RTC

    ///ACELEROMETRO

    accelero.begin(9, 8, 6, 5, A0, A1, A2);
    accelero.setARefVoltage(3.3); //Seta a voltagem de referencia AREF como 3.3V
    accelero.setSensitivity(LOW); //Seta a sensibilidade (Pino GS) para +/-6G

    accelero.calibrate();
    delay(2000); // delay para garantir no minimo 2s entre cada uma das leituras

    } // fim do void setup…

    void loop()
    {
    ///SD_CARD

    // make a string for assembling the data to log:
    String dataString = “”;

    // read three sensors and append to the string:
    for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin tmin && temp < tmax)
    {
    //noTone(ALARME);
    //leituraSerial();
    }
    else
    {
    Serial.println("PERIGO!!! TEMPERATURA FORA DO ESPERADO");
    Serial.print("Temperatura deve estar entre ");
    Serial.print(tmin);
    Serial.print(" e ");
    Serial.println(tmax);
    Serial.print("Umidade relativa: ");
    Serial.print(umid);
    Serial.print(" %\t");
    Serial.print("Temperatura: ");
    Serial.print(temp);
    Serial.println(" *C\n");

    }
    }

    Serial.print("Umidade relativa: ");
    Serial.print(umid);
    Serial.print(" %\t");
    Serial.print("Temperatura: ");
    Serial.print(temp);
    Serial.println(" *C\n");

    x = accelero.getXAccel(); //Obtem o valor do eixo X
    y = accelero.getYAccel(); //Obtem o valor do eixo Y
    z = accelero.getZAccel(); //Obtem o valor do eixo Z

    Serial.print("\nx: "); //Mostra os valores no serial monitor
    Serial.print(x);
    Serial.print(" \ty: ");
    Serial.print(y);
    Serial.print(" \tz: ");
    Serial.println(z);

    Mostrarelogio();

    } // FIM DO LOOP…

    ///INICIO DAS FUNÇÕES…

    byte ConverteParaBCD(byte val){ //Converte o número de decimal para BCD
    return ( (val/10*16) + (val%10) );
    }

    byte ConverteparaDecimal(byte val) { //Converte de BCD para decimal
    return ( (val/16*10) + (val%16) );
    }

    void Mostrarelogio(){
    Wire.beginTransmission(DS1307_ADDRESS);
    Wire.write(zero);
    Wire.endTransmission();

    Wire.requestFrom(DS1307_ADDRESS, 7);

    int segundos = ConverteparaDecimal(Wire.read());
    int minutos = ConverteparaDecimal(Wire.read());
    int horas = ConverteparaDecimal(Wire.read() & 0b111111);
    int diadasemana = ConverteparaDecimal(Wire.read());
    int diadomes = ConverteparaDecimal(Wire.read());
    int mes = ConverteparaDecimal(Wire.read());
    int ano = ConverteparaDecimal(Wire.read());

    //Mostra a data no Serial Monitor
    Serial.print("Data: ");
    Serial.print(diadomes);
    Serial.print("/");
    Serial.print(mes);
    Serial.print("/");
    Serial.print(ano);
    Serial.print(" ");
    Serial.print("Hora : ");
    Serial.print(horas);
    Serial.print(":");
    Serial.print(minutos);
    Serial.print(":");
    Serial.print(segundos);
    switch(diadasemana)
    {
    case 0:Serial.println(", Domingo");
    break;
    case 1:Serial.println(", Segunda");
    break;
    case 2:Serial.println(", Terca");
    break;
    case 3:Serial.println(", Quarta");
    break;
    case 4:Serial.println(", Quinta");
    break;
    case 5:Serial.println(", Sexta");
    break;
    case 6:Serial.println(", Sabado");
    } // PARA MOSTRAR A DATA NO SERIAL MONITOR….
    }

    1. Olá Marcelo,
      é muito comum quando usamos vários dispositivos no Arduino, eles entrarem em conflito. Você é do tempo de conflito de IRQ? hehe, a ideia é a mesma: dois ou mais dispositivos querem usar o mesmo recurso.

      O que pode estar ocorrendo é que uma das bibliotecas conflita com a outra. Sugiro o seguinte: não use a biblioteca para ler o acelerômetro, afinal ele lhe fornece 3 saídas analógicas e a biblioteca serve apenas para inicializá-lo. Esta inicialização pode ser manual, ou seja, via jumpers alimentando-o corretamente.

      Bons testes, passa aqui depois para postar novidades de seu projeto!

      1. Paulo boa noite, foi exatamente isso que fiz.

        Deixei de usar essa função calibrate que estava dando problema e estou fazendo a leitura direta dos canais a/d. Desta forma tudo funciona, inclusive a gravação no cartão sd.
        Ainda estou fazendo testes, quando estiver rodando 100% posto aqui como ficou.

        Abraços e muito obrigado pela ajuda.

Leave a Reply

%d