Gravar vários dados no cartão sd

Amigos preciso de ajuda, pois tenho um código que faz a leitura e medição com mpu6050 no caso uso o giroscópio e preciso guardar esses dados no cartao sd, porém preciso realizar várias leituras. Eu preciso que ao pressionar o botão o cartão salve a primeira leitura e fique assim, por exemplo, coleta_1, ai depois aperto de novo e salva coleta_2 e assim por diante, sempre criando um arquivo novo sem apagar as leituras anteriores. Já pesquisei bastante e tentei várias coisas e por isso estou recorrrendo a esse fórum. O código é

#include <I2Cdev.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include "MPU6050.h"

// Pino ligado ao CS do modulo
const int chipSelect = 4;

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

// O endereço do MPU6050 pode ser 0x68 ou 0x69, dependendo
// do estado de AD0. Se não for especificado, 0x68 estará implícito
MPU6050 sensor;

// Valores RAW (não processados) do acelerômetro e giroscópio nos eixos x,y,z
int ax, ay, az;
int gx, gy, gz;

long tempo_prev;
float dt;
float ang_x, ang_y, ang_z;
float ang_x_prev, ang_y_prev, ang_z_prev;

void setup() {
  
  Serial.begin(115200);    //Iniciando porta serial
  Wire.begin();           //Iniciando I2C  
  sensor.initialize();    //Iniciando o sensor

  if (sensor.testConnection()){ 
  Serial.println("Sensor iniciado correctamente");
  }
  else { 
  Serial.println("Erro ao iniciar o sensor");
  }

  Serial.println("Inicializando cartao SD...");
  //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 !");

}     
void loop(){  
  
  //Abre o arquivo coleta.txt
  dataFile = SD.open("coleta.txt", FILE_WRITE);
  
  // Ler as aceleracões e velocidades angulares
  sensor.getAcceleration(&ax, &ay, &az);
  sensor.getRotation(&gx, &gy, &gz);
  
  dt = (millis()-tempo_prev)/1000.0;
  tempo_prev=millis();
  
  //Calcular os ângulos com acelerômetro
  float accel_ang_x=atan(ay/sqrt(pow(ax,2) + pow(az,2)))*(180.0/3.14);
  float accel_ang_y=atan(-ax/sqrt(pow(ay,2) + pow(az,2)))*(180.0/3.14);
  float accel_ang_z=atan((sqrt(pow(ax,2)+pow(ay,2)))/az)*(180.0/3.14);
  
  //Calcular ângulo de rotação com giroscopio e filtro complementar  
  
  ang_x = 0.98*(ang_x_prev+(gx/131)*dt) + 0.02*accel_ang_x;
  ang_y = 0.98*(ang_y_prev+(gy/131)*dt) + 0.02*accel_ang_y;
  ang_z = 0.98*(ang_z_prev+(gz/131)*dt) + 0.02*accel_ang_z;
  
  ang_x_prev=ang_x;
  ang_y_prev=ang_y;
  ang_z_prev=ang_z;

 /*
  ang_x=ang_x*250.0/32768.0;
  ang_y=ang_y*250.0/32768.0;
  ang_z=ang_z*250.0/32768.0;
  */
  //Mostrar os angulos separadas

  //Serial.print("Rotação em X:  ");
  Serial.print(ang_x); Serial.print("\t");
  Serial.print("\t");
  //Serial.print("Rotação em Y: ");
  Serial.print(ang_y); Serial.print("\t");
  Serial.print("\t");
  //Serial.print("Rotação em z: ");
  Serial.print(ang_z);   //Serial.print("\t"); 
  //Serial.println(tempo); 
  
  Serial.print("\r\n");

  if (dataFile){
  //dataFile.print("Rotação em X:  ");
  dataFile.print(ang_x); Serial.print("\t");
  dataFile.print("\t");
  //dataFile.print("Rotação em Y: ");
  dataFile.print(ang_y); Serial.print("\t");
  dataFile.print("\t");
  //dataFile.print("Rotação em z: ");
  dataFile.print(ang_z); //dataFile.print("\t");
  //dataFile.println(tempo); 
  
  dataFile.print("\r\n");
  
   
  //Fecha o arquivo
  dataFile.close();
  }
  //Exibe um erro se não conseguir abrir o arquivo
  else
  {
  Serial.println("Erro ao abrir o arquivo coleta.txt");
  }
  

  delay(1);
}

Olá,

  1. Leia com atenção o tópico para novos usuários do fórum.
    How to get the best out of this forum
    Como está em inglês, se tiver dificuldade use o tradutor do google.

Para que possamos ajuda-lo, post seu código, mas não esqueça que ao postar use as tags </>.

ArduinoForum

Ao usar SD em "Arduino" somente poderá usar nomes de arquivo com 8 dígitos, então no seu projeto você poderia usar de coleta_0 até coleta_9, pois a partir de 9 o nome do arquivo teria mais que 8 dígitos.

Olá,
não encontrei no seu código a definição do "botão" citado no seu descritivo.

pq ainda não consegui incrementar, nesse código ele apenas salva simples quando ligo o arduino e faço a medição com mpu6050. Eu preciso de ajuda pra criar a lógica do botão

Hi,
Qual arduino vc está usando?

Arduino UNO

Olá,
como não tenho este sensor, não consigo testar aqui,

Teste este código ai e depois conta o resultado.

O botão deve ser ligado entre o pino 5 e o GND.

#include <I2Cdev.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include "MPU6050.h"

#define botao 5

// Pino ligado ao CS do modulo
const int chipSelect = 4;

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

// O endereço do MPU6050 pode ser 0x68 ou 0x69, dependendo
// do estado de AD0. Se não for especificado, 0x68 estará implícito
MPU6050 sensor;

// Valores RAW (não processados) do acelerômetro e giroscópio nos eixos x,y,z
int ax, ay, az;
int gx, gy, gz;

long tempo_prev;
float dt;
float ang_x, ang_y, ang_z;
float ang_x_prev, ang_y_prev, ang_z_prev;
String fileName;
int fileCount = 0;
//-----------------------------------------------------------------------------
void setup() {

  pinMode(botao, INPUT_PULLUP);
  Serial.begin(115200);    //Iniciando porta serial
  Wire.begin();           //Iniciando I2C
  sensor.initialize();    //Iniciando o sensor

  if (sensor.testConnection()) {
    Serial.println("Sensor iniciado correctamente");
  }
  else {
    Serial.println("Erro ao iniciar o sensor");
  }

  Serial.println("Inicializando cartao SD...");
  //Inicia a comunicacao com o modulo SD
  //CriaFileName();
  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 !");
  //CriaFileName();
}
//-----------------------------------------------------------------------------
void loop() {

  if (digitalRead(botao) == LOW)
  {
    delay(30);
    if (digitalRead(botao) == LOW)
    {
      dataFile = SD.open(fileName, FILE_WRITE);
      if (dataFile) {
        dataFile.print(ang_x); Serial.print("\t");
        dataFile.print("\t");
        dataFile.print(ang_y); Serial.print("\t");
        dataFile.print("\t");
        dataFile.print(ang_z); //dataFile.print("\t");
        dataFile.print("\r\n");
        dataFile.close();         //Fecha o arquivo
        CriaFileName();
      }
      else        //Exibe um erro se não conseguir abrir o arquivo
      {
        Serial.print("Erro ao abrir o arquivo : ");
        Serial.println(fileName);
      }
    }
  }

  // Ler as aceleracões e velocidades angulares
  sensor.getAcceleration(&ax, &ay, &az);
  sensor.getRotation(&gx, &gy, &gz);

  dt = (millis() - tempo_prev) / 1000.0;
  tempo_prev = millis();

  //Calcular os ângulos com acelerômetro
  float accel_ang_x = atan(ay / sqrt(pow(ax, 2) + pow(az, 2))) * (180.0 / 3.14);
  float accel_ang_y = atan(-ax / sqrt(pow(ay, 2) + pow(az, 2))) * (180.0 / 3.14);
  float accel_ang_z = atan((sqrt(pow(ax, 2) + pow(ay, 2))) / az) * (180.0 / 3.14);

  //Calcular ângulo de rotação com giroscopio e filtro complementar

  ang_x = 0.98 * (ang_x_prev + (gx / 131) * dt) + 0.02 * accel_ang_x;
  ang_y = 0.98 * (ang_y_prev + (gy / 131) * dt) + 0.02 * accel_ang_y;
  ang_z = 0.98 * (ang_z_prev + (gz / 131) * dt) + 0.02 * accel_ang_z;

  ang_x_prev = ang_x;
  ang_y_prev = ang_y;
  ang_z_prev = ang_z;

  /*
    ang_x=ang_x*250.0/32768.0;
    ang_y=ang_y*250.0/32768.0;
    ang_z=ang_z*250.0/32768.0;
  */
  //Mostrar os angulos separadas

  //Serial.print("Rotação em X:  ");
  Serial.print(ang_x); Serial.print("\t");
  Serial.print("\t");
  //Serial.print("Rotação em Y: ");
  Serial.print(ang_y); Serial.print("\t");
  Serial.print("\t");
  //Serial.print("Rotação em z: ");
  Serial.print(ang_z);   //Serial.print("\t");
  //Serial.println(tempo);

  Serial.print("\r\n");
  delay(1);
}
//----------------------------------------------------------
void CriaFileName()
{
  fileName = "cole_" + String(fileCount) + ".txt";
  Serial.println(fileName);
  fileCount++;
}

Testei aqui o que acontece, quando o botao tá em nível lógico baixo o código gráva cada loop que o código faz, ou seja, ele tá gravando uma linha em cada arquivo e não a leitura completa em cada arquivo. Era pra guardar os dados de uma leitura completa, assim se eu to fazendo uma medição e por exemplo durou tantos segundos o arquivo vai ser cole_1 ai quando a perto de novo começa a gravar o segundo arquivo cole_2 e assim por diante

Olá!

O código que o Rui postou armazena os valores de ang_x, ang_y e ang_z, assim como o código que você forneceu no início.

O que quer dizer com leitura completa?

Por que você não adiciona as linhas de escrita para os valores faltantes?

Abraço.

Bom dia, olá!
Deixa eu explicar melhor. Esse projeto vai medir o tremor de motor e preciso guardar os dados apertando num botão. Por exemplo, o motor está rodando e quero gravar a leitura de tremor ai aperto o botão e depois preciso parar de gravar entao aperto outro. E cada nova leitura ele vai mudar o nome do arquivo: coleta_1, coleta_2,coleta_3, pra que eu não precise estar tirando o cartão de memória para passar pro computador e depois realizar nova coleta, ou seja, posso fazer dezenas de leituras num mesmo cartão sem sobreescrever

Olá!

O código faz exatamente o que você quer.

O problema deve estar no estado inicial do seu botão.

Este trecho faz a verificação do estado atual do botão.

  if (digitalRead(botao) == LOW)
  {
    delay(30);
    if (digitalRead(botao) == LOW)
    {

Da forma como montou o circuito o botão deve estar sempre em LOW por isso grava todos os loops.

Para que o código funcione corretamente o circuito precisa estar dessa maneira:

Ou seja com o pino digital sempre conectado ao 5 V através de um resistor.

P.S. Não use o pino 13 para esse propósito, pois ele tem um LED conectado a ele.

Abraço.

certo, amanhã eu testo hj to sem os materiais, mas desde já te agradeço!

OPA, boa noite!
Cara, montei cirvuito como esse e não funcionou do jeito q eu esperava. Nessa imagem está a leitura, na segunda imagem é quando aperto no botão. Observe que quando aperto no botão ele salva apenas uma linha, preciso q salve toda leitura até onde eu apertar e ele encerrar a gravação e se preparar pra proxima


image

Olá!

Acho que entendi o que quer.
Tente este código:

#include <I2Cdev.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include "MPU6050.h"
#include <Bounce2.h> // https://github.com/thomasfredericks/Bounce2/archive/refs/heads/master.zip

#define PINO_BOTAO 5

// Pino ligado ao CS do modulo
const int chipSelect = 4;

Bounce2::Button botao = Bounce2::Button();

// O endereço do MPU6050 pode ser 0x68 ou 0x69, dependendo
// do estado de AD0. Se não for especificado, 0x68 estará implícito
MPU6050 sensor;

// Valores RAW (não processados) do acelerômetro e giroscópio nos eixos x,y,z
int ax, ay, az;
int gx, gy, gz;

unsigned long tempo_prev;
float dt;
float ang_x, ang_y, ang_z;
float ang_x_prev, ang_y_prev, ang_z_prev;
int contador = 0;

void setup()
{
  botao.attach(PINO_BOTAO,  INPUT);
  botao.interval(5);    // Intervalo em ms
  botao.setPressedState(LOW);

  Serial.begin(115200); // Iniciando porta serial
  Wire.begin();         // Iniciando I2C
  sensor.initialize();  // Iniciando o sensor

  if (sensor.testConnection())
  {
    Serial.println("Sensor iniciado correctamente");
  }
  else
  {
    Serial.println("Erro ao iniciar o sensor");
  }

  Serial.println("Inicializando cartao 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 !");
}

void loop()
{
  String nomeArquivo;
  bool terminado = false;

  botao.update();

  if (botao.pressed())
  {
    nomeArquivo = "coleta_" + String(contador) + ".csv";
    Serial.println(nomeArquivo);

    File arquivo = SD.open(nomeArquivo, FILE_WRITE);

    if (arquivo)
    {
      while (terminado == false)
      {
        // Ler as aceleracões e velocidades angulares
        sensor.getAcceleration(&ax, &ay, &az);
        sensor.getRotation(&gx, &gy, &gz);

        dt = (millis() - tempo_prev) / 1000.0;
        tempo_prev = millis();

        // Calcular os ângulos com acelerômetro
        float accel_ang_x = atan(ay / sqrt(pow(ax, 2) + pow(az, 2))) * (180.0 / 3.14);
        float accel_ang_y = atan(-ax / sqrt(pow(ay, 2) + pow(az, 2))) * (180.0 / 3.14);
        float accel_ang_z = atan((sqrt(pow(ax, 2) + pow(ay, 2))) / az) * (180.0 / 3.14);

        // Calcular ângulo de rotação com giroscopio e filtro complementar
        ang_x = 0.98 * (ang_x_prev + (gx / 131) * dt) + 0.02 * accel_ang_x;
        ang_y = 0.98 * (ang_y_prev + (gy / 131) * dt) + 0.02 * accel_ang_y;
        ang_z = 0.98 * (ang_z_prev + (gz / 131) * dt) + 0.02 * accel_ang_z;

        ang_x_prev = ang_x;
        ang_y_prev = ang_y;
        ang_z_prev = ang_z;

        arquivo.print(ang_x);
        arquivo.print(",");
        arquivo.print(ang_y);
        arquivo.print(",");
        arquivo.print(ang_z);
        arquivo.print("\r\n");

        Serial.print(ang_x);
        Serial.print(",");
        Serial.print(ang_y);
        Serial.print(",");
        Serial.println(ang_z);
        Serial.println("");

        botao.update();

        if (botao.pressed())
        {
          arquivo.close();
          contador++;
          terminado = true;
        }

        delay(10);
      }
    }
    else
    {
      Serial.print("Erro ao abrir o arquivo : ");
      Serial.println(nomeArquivo);
    }
  }
}

Aperte o botão para iniciar a coleta e depois aperte novamente para terminar.

Se demorar muito para terminar a coleta o arquivo ficará gigante visto que o intervalo entre leituras está com 10 ms.

Abraço.

Pow mano deu certo!!! Faz tempo que eu estava procurando uma solução!!!!
Sou muito grato pela ajuda e disponibilidade, você é sensacional!!!!

Fico feliz em ter ajudado.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.