Como gravar dados do Arduino em arquivos em um cartão SD

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br


Neste tutorial, vamos conectar um sensor de pressão barométrica BMP280 a um Arduino e gravar os resultados em um arquivo CSV em um cartão MicroSD no Arduino. Mas antes disso, vamos relembrar alguns conceitos básicos relacionados.

Anúncio PCBWay

Como funciona o cartão SD

Cartão SD significa Secure Digital Card. Os cartões SD possuem memória flash não volátil, capaz de gravar em 16 MB / se capacidade de até centenas de GB.

Algo a ter em atenção, a memória flash é escrita e apagada em grandes blocos, não um byte de cada vez. A memória flash só pode passar por cerca de 10.000 ciclos de gravação / apagamento antes de “se esgotar”. Embora essa seja uma limitação conhecida, não deve ser um problema, pois é equivalente a escrever e apagar completamente todo o conteúdo do cartão uma vez por dia, todos os dias por 27 anos. O flash é feito de milhões de transistores MOSFET de porta flutuante e não possui partes móveis. Sua principal vantagem sobre a EEPROM é a quantidade de memória por tamanho especificado.

Os cartões SD usam uma arquitetura de sistema de arquivos de computador chamada FAT, que significa Tabela de Alocação de Arquivos. O FAT16 é para cartões de até 2 GB e o FAT32 é superior a 2 GB. Para saber qual é o seu, insira o cartão SD no slot para cartão do seu computador e, no Explorer, clique com o botão direito do mouse e escolha “Propriedades”. Isso informará qual sistema de arquivos o seu cartão está usando. Outra opção mais antiga era o NTFS, mas era para unidades mais antigas que podem ser divididas em partições.

Para reformatar o cartão, clique com o botão direito do mouse e selecione “Formatar”.

Os cartões SD são de vários tipos. É mostrado aqui um leitor de cartão SD da Adafruit e outro leitor de cartão SD da DFRobot. Você também pode obter leitores de cartão que usam cartões SD de tamanho padrão, mas eles são maiores e ocupam mais espaço. Todos os leitores de cartão SD funcionam na mesma biblioteca SD.h padrão.

Como gravar dados do Arduino em arquivos em um cartão SD 1
Dois módulos diferentes de cartão SD
Como gravar dados do Arduino em arquivos em um cartão SD 3
Pinagem

Registro de dados em um cartão SD com um BMP280 e um Arduino

Usando um cartão SD, criaremos um registrador de dados para este BMP280 conectado a um Arduino. Geralmente, um registrador de dados é um dispositivo eletrônico usado para registrar dados dos sensores ao longo do tempo e armazená-los para uso ou análise posterior.

O BMP280 será conectado enquanto eu2C e o cartão SD como SPI. Leremos o tempo decorrido desde que o Arduino foi iniciado e os incluiremos como dados no arquivo como um carimbo de data e hora de mudança. Essa é a base para um aplicativo de registro de dados. Aqui, usaremos um módulo de relógio em tempo real como cronometrista.

Como conectar o BMP280 ao Arduino

Para este tutorial, usaremos o I2Versão C 3.3V. Este, embora 3.3V, é compatível com 5V nos pinos de dados. Para obter mais informações sobre como o BMP280 funciona, consulte nosso tutorial sobre Comunicação sem fio entre dois arduinos.

Como gravar dados do Arduino em arquivos em um cartão SD 5
Pinagem BMP280
BMP280 Arduino
VCC3.3V
GNDGND
SCLA5
SDAA4
CSBNão usado
SDDNão usado

Como conectar o leitor de cartão SD ao Arduino

Cartão SD Arduino
MISSÔ 12
SCK 13
SS 10
MOSI 11
GND GND
5V 5V

Instalando as Bibliotecas

Existem algumas bibliotecas necessárias:

  • #incluir
  • #incluir
  • #incluir
  • SPI.he SD.h são bibliotecas padrão que acompanham o Arduino
  • A biblioteca BMP280 pode ser encontrada aqui.

Notas sobre o esboço

Nos dois esboços, evitei o objeto Arduino String fácil, mas desaconselhável. O objeto da corda não é seu amigo, é o lobo proverbial do pijama da avó! Programadores sérios evitam isso totalmente e usam cadeias de caracteres do tipo C. Leia mais sobre motivos para evitar o objeto string aqui.

O esboço começa com a verificação de que o cartão SD está presente e de que a fiação está correta. Caso contrário, apenas parará e esperará para sempre. while(1) significa simplesmente “espere aqui”, desde que 1 seja verdadeiro – o que sempre é. Você também pode escrever while(1==1). Em seguida, o loop principal espera que você insira uma chave do monitor serial e converte automaticamente em letras minúsculas, caso você tenha digitado em maiúsculas. o switch(charRead) chamará uma função dependendo do que foi digitado.

Uma boa programação determina que, sempre que houver um lugar em que é provável que ocorra um erro do usuário, você o envolverá em algum tipo de verificação de erro. Neste esboço, todas as operações de arquivo fazem isso, pois é provável que o cartão SD esteja ausente ou o nome do arquivo esteja incorreto ou o arquivo esteja ausente.

No readfile() função, char inputChar = myFile.read() obtém um caractere de cada vez e o adiciona à célula seguinte na matriz de caracteres da string de entrada até encontrar o caractere de nova linha (10); em seguida, adiciona um 0 no final para finalizar a string corretamente e, em seguida, lida com a próxima linha.

myString = myFile.readStringUntil('n'); lerá uma linha inteira de cada vez (lê até encontrar o caractere invisível da nova linha). O restante do esboço não requer explicações.

Código Arduino para escrever, ler e excluir seqüências de texto no cartão SD

Vamos dar uma olhada em um esboço simples para gravar seqüências de amostra no cartão SD, lê-las novamente e excluí-las. Este esboço ainda não utilizará um BMP280. No início do esboço, há três pangramas – uma frase interessante que usa cada uma das 26 letras do alfabeto pelo menos uma vez. Os pangramas são frequentemente usados ​​pelos programadores para testar telas e impressoras.

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br
#include 
#include 
File myFile;
char fileName[] = "simple.txt";
const int chipSelect = 10;
char charRead;
char pangram_1[] = "The five boxing wizards jump quickly";
char pangram_2[] = "Pack my box with five dozen liquor jugs";
char pangram_3[] = "The quick brown fox jumps over the lazy dog";


///////////////////////////////////////////////
void setup()
{
  Serial.begin(9600);
  Serial.println("Simple SD Card Demo");

   if (SD.begin(chipSelect))
    {
    Serial.println("SD card is present & ready");
    } 
    else
    {
    Serial.println("SD card missing or failure");
    while(1);  //wait here forever
    }
    Serial.println("Enter w for write, r for read or d for delete");
}
////////////////////////////////////////////////
void loop() 
{
  //Create a loop to read a command character from the keyboard
  //This will be 'r' for read, 'w' for write and 'd' for delete.

  if (Serial.available()) 
     {
      charRead = tolower(Serial.read());  //force ucase
      Serial.write(charRead); //write it back to Serial window
      Serial.println();
     }
     
  //get command from keyboard:
   switch(charRead)
   {
    case 'r':
        readFromFile();   //read
        break;
    case 'w':
        writeToFile(); //write to file
        break;
    case 'd':
        deleteFile();  //delete
        break;
   }
}
///////////////////////////////////////////////
void readFromFile()
{
  byte i=0; //counter
  char inputString[100]; //string to hold read string
  
  //now read it back and show on Serial monitor 
  // Check to see if the file exists:
  if (!SD.exists(fileName)) 
      Serial.println("simple.txt doesn't exist."); 
  Serial.println("Reading from simple.txt:");
  myFile = SD.open(fileName);
  //--------------------------------  
  while (myFile.available()) 
  {   
   char inputChar = myFile.read(); // Gets one byte from serial buffer
    if (inputChar == 'n') //end of line (or 10)
    {
      inputString[i] = 0;  //terminate the string correctly
      Serial.println(inputString);
      i=0;
    }
    else
    {
      inputString[i] = inputChar; // Store it
      i++; // Increment where to write next
      if(i> sizeof(inputString))
        {
        Serial.println("Incoming string longer than array allows");
        Serial.println(sizeof(inputString));
        while(1);
        }
    }
  }
 }
/////////////////////////////////////////////
void writeToFile()
{
  myFile = SD.open(fileName, FILE_WRITE);
  if (myFile) // it opened OK
    {
    Serial.println("Writing to simple.txt");
    myFile.println(pangram_1);
    myFile.println(pangram_2);
    myFile.println(pangram_3);
    myFile.close(); 
    Serial.println("Done");
    }
  else 
    Serial.println("Error opening simple.txt");
}
//////////////////////////////////////////////////
void deleteFile()
{
 //delete a file:
  if (SD.exists(fileName)) 
    {
    Serial.println("Removing simple.txt");
    SD.remove(fileName);
    Serial.println("Done");
   } 
}
///////////////////////////////////////////////

Notas sobre o código

O esboço começa da mesma forma que o anterior, com a verificação do cartão, exclui previamente o arquivo CSV em preparação e antes que você possa selecionar uma opção para executar na janela Serial. O cabeçalho (nomes da coluna) é pré-gravado no arquivo.

float QNH = 1022.67; QNH é um termo de aviação e usado como um fator de correção que, quando aplicado a um altímetro, permitirá ler com precisão a elevação acima do nível do mar no local atual. Para saber mais sobre isso, consulte o tutorial anterior aqui. Observe que você não precisa obter isso. No entanto, sem um valor corrigido, a leitura da altitude no seu local estará incorreta e poderá até ser negativa.

o loop() A função inicia com a redefinição do dataStr para 0 para atualizá-lo e obtém uma espécie de carimbo de data / hora com o millis() função (o número de milissegundos decorridos desde o início). Agora, é necessário adicioná-lo ao final (anexos) do dataStre também adicione a variável separada por vírgula. strcat() é um pouco confuso. Você esperaria algo assim: buffer = strcat(dataStr, temperature). Mas não é assim que realmente funciona. Um buffer é um armazenamento temporário para manter o resultado.

Código Arduino para salvar os dados do BMP280 em um arquivo CSV em um cartão SD

Este esboço lê o BMP280 e salva os valores no cartão SD no formato CSV. CSV significa Valores separados por vírgula e é frequentemente usado onde dados com estruturas semelhantes são salvas em arquivos ou transmitidas por um link. Também é compatível com o formato do MS Excel, de modo que, quando você abre o arquivo ou arrasta para o Excel, ele se configura automaticamente em linhas e colunas, com a primeira linha do arquivo criando títulos para as colunas. Uma vez no Excel, você pode exibir facilmente os dados como gráficos de vários tipos.

#include 
#include 
#include 
Adafruit_BMP280 bmp; 
File myFile;

// change this to match your SD shield or module:
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
//mega pin = 53;
const int chipSelect = 10;
float QNH = 1022.67; //Change the "1022.67" to your current sea level barrometric pressure (https://www.wunderground.com)
const int BMP_address = 0x76;

float pressure;   
float temperature;  
float altimeter; 
char charRead;
char runMode;
byte i=0; //counter
char dataStr[100] = "";
 char buffer[7];
////////////////////////////////////////////////////
void setup()
{
  Serial.begin(9600);
  Serial.println("BMP280/SD Card Demo");
  bmp.begin(BMP_address); 
  if (SD.begin(chipSelect))
  {
    Serial.println("SD card is present & ready");
  } 
  else
  {
    Serial.println("SD card missing or failure");
    while(1); //halt program
  }
  //clear out old data file
  if (SD.exists("csv.txt")) 
  {
    Serial.println("Removing simple.txt");
    SD.remove("csv.txt");
    Serial.println("Done");
  } 

  //write csv headers to file:
   myFile = SD.open("csv.txt", FILE_WRITE);  
   if (myFile) // it opened OK
    {
    Serial.println("Writing headers to csv.txt");
    myFile.println("Time,Pressure,Temperature,Altitude");
    myFile.close(); 
    Serial.println("Headers written");
    }
  else 
    Serial.println("Error opening csv.txt");  
  Serial.println("Enter w for write, r for read or s for split csv");  
}// end setup()

////////////////////////////////////////////////////////////
void loop(void) 
{
 dataStr[0] = 0;
 pressure = bmp.readPressure()/100;  //and conv Pa to hPa
 temperature = bmp.readTemperature();
 altimeter = bmp.readAltitude (QNH); //QNH is local sea lev pressure
//----------------------- using c-type ---------------------------
 //convert floats to string and assemble c-type char string for writing:
 ltoa( millis(),buffer,10); //conver long to charStr
 strcat(dataStr, buffer);//add it onto the end
 strcat( dataStr, ", "); //append the delimeter
 
 //dtostrf(floatVal, minimum width, precision, character array);
 dtostrf(pressure, 5, 1, buffer);  //5 is mininum width, 1 is precision; float value is copied onto buff
 strcat( dataStr, buffer); //append the coverted float
 strcat( dataStr, ", "); //append the delimeter

 dtostrf(temperature, 5, 1, buffer);  //5 is mininum width, 1 is precision; float value is copied onto buff
 strcat( dataStr, buffer); //append the coverted float
 strcat( dataStr, ", "); //append the delimeter

 dtostrf(altimeter, 5, 1, buffer);  //5 is mininum width, 1 is precision; float value is copied onto buff
 strcat( dataStr, buffer); //append the coverted float
 strcat( dataStr, 0); //terminate correctly 
 //Serial.println(dataStr);
 //---------------------------------------------------  
 //create a loop to read from the keyboard a command character
 //this will be 'r' for read, 'w' for write and 'd' for delete.

  if (Serial.available()) //get command from keyboard:
     {
      charRead = tolower(Serial.read());  //force ucase
      Serial.write(charRead); //write it back to Serial window
      Serial.println();
     }
 
  if(charRead == 'w')  //we are logging
      runMode="W";
  if(charRead == 'r')  //we are reading
      runMode="R";
  if(charRead == 'd')  //we are deleting
      runMode="D";
 //----------------------------------------------------
  if(runMode == 'W') //write to file
  {     
   //----- display on local Serial monitor: ------------
   Serial.print(pressure); Serial.print("hPa  ");
   Serial.print(temperature); 
   Serial.write(0xC2);  //send degree symbol
   Serial.write(0xB0);  //send degree symbol
   Serial.print("C   ");  
   Serial.print(altimeter); Serial.println("m");
   //---------------------------------------------
   // open the file. note that only one file can be open at a time,
    myFile = SD.open("csv.txt", FILE_WRITE);     
    // if the file opened okay, write to it:
    if (myFile) 
    {
      Serial.println("Writing to csv.txt");
      myFile.println(dataStr); 
      myFile.println(dataStr); 
      myFile.close();
    } 
    else 
    {
      Serial.println("error opening csv.txt");
    }
    delay(1000);  
  }
//--------------------------------------------------
    if(runMode == 'R')  //we are reading
   {
    if (!SD.exists("csv.txt")) 
        Serial.println("csv.txt doesn't exist."); 
   Serial.println("Reading from csv.txt");
   myFile = SD.open("csv.txt");
    
   while (myFile.available()) 
  {   
   char inputChar = myFile.read(); // Gets one byte from serial buffer
    if (inputChar == 'n') //end of line (or 10)
    {
      dataStr[i] = 0;  //terminate the string correctly
      Serial.println(dataStr);
      i=0; //reset the counter
    }
    else
    {
      dataStr[i] = inputChar; // Store it
      i++; // Increment where to put next char
      if(i> sizeof(dataStr))  //error checking for overflow
        {
        Serial.println("Incoming string longer than array allows");
        Serial.println(sizeof(dataStr));
        while(1);
        }
    }
  }
}
  //------------------------------------------- 
  if(runMode=='D')
  {
   //delete a file:
   if (SD.exists("csv.txt")) 
      {
      Serial.println("Removing csv.txt");
      SD.remove("csv.txt");
      Serial.println("Done");
     } 
  }
  //-----------------------------------------
   
} //end main
///////////////////////////////////////////////

Escrevendo usando o projeto e a saída da janela serial

Se tudo estiver conectado corretamente, abra a janela serial no Arduino receptor e você verá o seguinte:

Como gravar dados do Arduino em arquivos em um cartão SD 7

Agora, remova o cartão, insira-o no seu PC e abra o arquivo CSV no MS Excel (ou arraste e solte-o) e você deverá ver os títulos das colunas e os dados formatados em colunas. Por fim, destaque as colunas de tempo e pressão e escolha inserir um gráfico. Você deve obter algo como o abaixo (fiz uma respiração pesada no sensor BMP para causar algumas flutuações de pressão!):

Como gravar dados do Arduino em arquivos em um cartão SD 9

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br
Leia Também  20 lições para sua vida a partir da biografia de Leonardo da Vinci