Prob: Nessuna Scrittura su SD - Data Log MPU6050 Arduino Uno DIP f regolabile

Purtroppo sto ancora alle prime armi.
Sto studiando il Margolis e mi sono letto questo consigliato per i neofiti come me nel forum

Ho provato a cercare un po’ e a sbattere la testa sul codice.
Ho provato a cercare un po’ nel forum (avevo trovato questo nella sezione italiana)ma avendo modificato il codice inziale, credo ci sia un problema con le mie scarse competenze di programmazione.

Era tutto nato da questo progetto di Instructables

Obiettivo:
Creare un Datalogger delle accelerazioni con frequenza regolabile*

Problema:
Lo Sketch è formalmente corretto, il compilatore non segnala errori, ma non viene scritto nulla sulla SD

Il codice allegato funziona, ma non è stato realizzato da me.

Questo il codice che ho provato a riscrivere, cercando di capire tutte le variabili in gioco ed il loro significato.

  // For I2C:
  #include<Wire.h>


  // For the SD Card:
  #include <SPI.h>
  #include <SD.h>

  // Defines:
  const int MPU = 0x68;   // I2C address of the MPU-6050
  const int SD_CS = 10; // SD CS pin
  const int LEDpin = 9; // LED

  // Declaration of global functions:
  void Read_Write();
  void blinkL(unsigned long T, int N);
  void stampC();
  void errorFW();


  // Global variables:
  unsigned long Time0 = 0; // A starting time reference, in millis
  unsigned long TimeD = 0; // Delay required to match the desired R&W frequency. 
  bool LEDstatus = false;
  bool Serial_plus_SD = true; // Output to SD and Serial, or only to SD.

  unsigned long TimeDRW = 10UL; // Average time for data reading and writing to file, ms.
  unsigned int frequency = 300; // Data R&W frequency, Hz. Limited by TimeDRW: fmax=1000/TimeDRW.

  // Setup:
  void setup()
  {   
    // Configure the LED:
    pinMode(LEDpin, OUTPUT); 
    // Join I2C bus via Wire library:
    Wire.begin();
    Wire.beginTransmission(MPU);
    Wire.write(0x6B);  // PWR_MGMT_1 register
    Wire.write(0);     // set to zero (wakes up the MPU-6050)
    Wire.endTransmission(true);
    
    // Initialize serial communication:
    if (Serial_plus_SD)
    Serial.begin(57600);
    
    // Initialize SD card:
    if (Serial_plus_SD)
    Serial.println("\nInitializing SD card.");

    if (!SD.begin(SD_CS)) 
    {
    if (Serial_plus_SD)
      Serial.println("Card failed, or not present.");
    // Blink LED quickly to indicate trouble:
    blinkL(200UL, 10);
    digitalWrite(LEDpin, LOW);
    // And "do nothing else":
    while(1)
      ;
    }
    else
    {
    if (Serial_plus_SD)
      Serial.println("Card initialized.");  
    }
    

    // Blink LED to indicate readiness:
    blinkL(300UL, 10);
    
    // Calculate the required time delay in order to match the data logging frequency:
    if (1000UL <= TimeDRW * frequency)
    TimeD = 0UL; // if the specified frequency is too large, a cap is introduced.
    else
    TimeD = (1000UL-TimeDRW*frequency)/frequency;
    
    // Initialize time references:
    Time0 = millis();
     
  }


  // Main:
  void loop()
  {
    // Body of main/loop
    // Check status:
    Time0 = millis();
   // LED off and continue:
      digitalWrite(LEDpin, LOW);
       }

  void Read_Write()
  // function that reads the MPU and writes the data to the SD.
  {
   // Local variables:
    int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; // Variables read from MPU6050

    // Read data:
    Wire.beginTransmission(MPU);
    Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom(MPU,14,true);  // request a total of 14 registers
    AcX = Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
    AcY = Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
    AcZ = Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
    
    GyX = Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
    GyY = Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
    GyZ = Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
    
    Serial.print(AcX);
    Serial.print(',');
    Serial.print(AcY);
    Serial.print(',');
    Serial.print(AcZ);
    Serial.print(',');
    Serial.print(GyX);
    Serial.print(',');
    Serial.print(GyY);
    Serial.print(',');
    Serial.print(GyZ);
    Serial.print(',');
    
    Serial.println();
    
    
    // Data preparation for file saving:
    String dataString = ""; // string for assembling the data to log:

    // Add time tag:
    dataString += String(Time0); dataString += ",";

    // Append the MPU6050 data to the string:
    dataString += String(AcX); dataString += ",";
    dataString += String(AcY); dataString += ",";
    dataString += String(AcZ); dataString += ",";
    dataString += String(GyX); dataString += ",";
    dataString += String(GyY); dataString += ",";
    dataString += String(GyZ);
    
    // Open the file in append mode:
    File dataFile = SD.open("datalog.txt", FILE_WRITE);

    // If the file is available, write to it:
    if (dataFile) 
    {
    dataFile.println(dataString);
    dataFile.close();
    if (Serial_plus_SD)
      Serial.println(dataString);
    }
    // if the file does not open, pop up an error:
    else 
    errorFW();
    
    return;
  }


  void blinkL(unsigned long T, int N)
  // function that blinks the LED N times with a delay of T millis.
  {
    bool statusL = false;
    for (int i=0; i<N; i++)
    {
    delay(T);
    statusL = !statusL;
    digitalWrite(LEDpin, statusL);
    }
    return;
  }

  void errorFW()
  // function that informs about an error while writing in the file, and "holds on" the sketch
  {
    if (Serial_plus_SD)
    Serial.println("Error opening datalog.txt.");

    // In any case, blink LED quickly to indicate trouble:
    blinkL(200UL, 10);
    // LED off and "nothing else":
    digitalWrite(LEDpin, LOW);
    while(1)
    ;
   
    return;
  }

Che errore ho commesso?

Mi scuso in anticipo se è un errore stupido legato alla mia inesperienza.

Mi piacerebbe successivamente anche approfondire il problema legato alla velocità di lettura e scrittura.
Per questo mi è stato suggerito di approfondire il fenomeno di Alising e ho trovato questo post nel forum internazionale che sto cercando di capire meglio il problema.

*Regolabile quando si carica lo sketch non durante la registrazione dei dati

AcGySdBaseDPI.ino (8.67 KB)

hai creato le funzioni Read_Write(), blinkL(unsigned long T, int N) e errorFW(), e non le usi mai.

Rixcordati che il compilatore può solo verificare la sintassi, non certo che logica o le tue intenzioni siano sia corrette :slight_smile:

Grazie mille per il suggerimento, quindi un errore legato alla mia inesperienza di :slight_smile:
Ci sbatto un po’ la testa e ti aggiorno :smiley:

Ho riletto il codice originario e provo a spiegare il mio ragionamento così magari capisco l’errore metodologico.

Quando ho studiato il codice precedente
Read_Write
era richiamato all’interno di un ciclo if che però era in uno stato “low” ovvero il DIP era spento, quindi ho pensato che il compilatore non lo considerasse.

La parte alla quale mi riferisco è questa:

if (DIP03status)
  { // // DIP03status = HIGH <-> TRUE <-> OFF <-> go on reading
    if (Time0 < TimeR) // Then read data and save to file:
    {
      // Read and write:
      Read_Write();
  
      // LED on to indicate correct activity:
      digitalWrite(LEDpin, HIGH);
  
      // Spend some miliseconds in order to match the reading frequency requested:
      delay(TimeD);
    } // endof (if Time0>TimeR)

perchè non ci sono altre parti del codice dove Read_Write vengono richiamate.
Quindi avevo interpretato male il codice originario, pensavo che quella parte venisse saltata dal compilatore se il DIP03 era spento

Scusami se sembra un copia incolla, ma quel codice l’ho scritto su un po’ di fogli A4, ho fatto un po’ di schemi a blocchi per capire meglio.

Dopo il tuo suggerimento ho modificato il codice e FUNZIONA campiona come con il vecchio codice ad una frequenza di circa 52Hz con dei valori ballerini

La variazione tra 18 e 22 millisecondi mi sembra fisiologica e legata ad una velocità di default, ma la variazione tra 18 e 47 no.

  • A cosa può essere dovuto?
  • Inoltre come posso regolare la frequenza di scrittura? Effettivamente io non ho dichiarato nessuna variabile globale che mi permettesse di farlo, la devo scrivere all’interno della mia Funzione Read_Write?

Grazie mille ancora :slight_smile: