Come calcolare la frequenza di misura del sensore e scrittura su sd

Salve,il progetto prevede la scrittura dell'accelerazione di gravita' (g) misurata da un accelerometro (adxl 335) e la scrittura su sd dei dati,insieme all'ora e data proveniente da un RTC.volevo chiedere,impostando il delay a 0,tra una misura e l'altra,come faccio a sapere con che frequenza il sensore preleva i dati?E come faccio a sapere con che frequenza vengono scritti i dati su sd?Premetto che i dati vengono prima inseriti in un buffer,e poi scritti su sd.Grazie mille.

Leggi la millis all'inizio del loop, leggi la millis alla fine dell'operazione che vuoi controllare, fai la differenza, la stampi con serial.print ricordandoti che il valore è in millisecondi.

PaoloP:
Leggi la millis all'inizio del loop, leggi la millis alla fine dell'operazione che vuoi controllare, fai la differenza, la stampi con serial.print ricordandoti che il valore è in millisecondi.

Dunque ho inserito la lettura della "millis all'inizio del loop" (gentilmente puoi controllare se e' esatto cio' ce ho fatto?) cosi' in pratica misuro il tempo di campionamento del sensore e la scrittura su sd.(impostando il delay a 0) avevo circa 10 letture ogni secondo,infatti si trova con cio che mi resistuisce la millis,infatti tra una lettura e l'altra mi da circa 100ms. Volevo chiederti,c'e' un modo per ottimizzare questi tempi,in modo che arduino campioni in tempi piu brevi?La scrittura su sd dipenda anche da da quale sd sto utilizzando?Io ho una vecchia kingstone da 2gb.Se utilizzassi una di classe 10,i tempi cambierebbero?
Ecco il codice:

#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
#include <SPI.h>
#include "ADXL335.h"


ADXL335 accelerometer;

RTC_DS1307 RTC;


File Dati; // La variabile di tipo file che useremo per il log

const int chipSelect =10;


String Buffer=""; // qui ci mettiamo i dati da scrivere per ogni log

unsigned long time;

void setup ()

{
  Serial.begin(9600);
  
  Wire.begin(); // inizializziamo la libreria WIRE per usare
  RTC.begin(); //il Real Time clock basato su ds1307
  accelerometer.begin();
  
  if (! RTC.isrunning()) 
  
  {
    Serial.println("RTC NON STA FUNZIONANDO");
    
    //LA SEGUENTE ISTRUZIONE SERVE SOLO PER REGOLARE L'OROLOGIO.ATTIVARE SOLO SE NECESSARIO.
  //  RTC.adjust (DateTime(__DATE__, __TIME__)); //imposta ora e data
    }
    
  Serial.print("\nSto verificando la presenza della scheda..\n");
  pinMode(10, OUTPUT); // fa funzionare la sdlib
  
  if (!SD.begin(chipSelect))
  
  {
     Serial.println("SD card non trovata");
     return;
     
  }
 else 
   {
     Serial.println("Scheda inserita e funzionante");
     Serial.println();
    
   }
}
void loop ()

{
  Serial.print ("time:");
  time=millis();
  Buffer=""; // Nuovo giro, stringa vuota!
/*  int  x;
  int y;
  int z;*/
  float ax,ay,az;
  DateTime now = RTC.now(); // leggiamo l'ora
  
  //accelerometer.getXYZ(&x,&y,&z);
  
  accelerometer.getAcceleration(&ax,&ay,&az);
 /* Buffer+=String(x); 
  Buffer+=",";
  Buffer+=String(y); 
  Buffer+=",";
  Buffer+=String(z);*/
 // Buffer+=",";
 // Buffer+=String(millis());
  
  Buffer+=('\t');
  Buffer+=String(ax); 
  Buffer+=" g,";
  Buffer+=String(ay); 
  Buffer+=" g,";
  Buffer+=String(az);
  Buffer+=" g";
  
   Buffer+=('\t');
  
  Buffer +=(now.day()); // Componiamo la data AAAA/MM/GG
  Buffer +=('/');
  Buffer +=(now.month());
  Buffer +=('/');
  Buffer +=(now.year());
  Buffer +=('\t');
  Buffer +=(now.hour());
  Buffer +=(':');
  Buffer +=(now.minute());
  Buffer +=(':');
  Buffer +=(now.second());
  Buffer +=('\t'); // tab per separare i campi
 
  Dati = SD.open("datalog.txt", FILE_WRITE); // apriamo il file in scrittura
  Serial.println(time);
  if (Dati)
  {
   Dati.println(Buffer);  // Scriviamo in un sol colpo i dati sul file
   Dati.close();     // chiudiamo e trasferiamo su SD
   Serial.print("Dati rilevati \t");
   Serial.println(Buffer);
  }
  else
  {
    Serial.println("Errore nell'apertura di datalog.txt");
  }
  delay (0);  // cadenza dellascrittura dei dati
  }

Dunque ho effettuato le modifiche che mi hai detto,ma mi da un errore su
accelerometer.getAcceleration(&ax,&ay,&az);

dice

sketch_apr11a:23: error: expected constructor, destructor, or type conversion before '.' token
sketch_apr11a:24: error: expected constructor, destructor, or type conversion before '(' token
sketch_apr11a.ino: In function 'void loop()':
sketch_apr11a:66: error: incompatible types in assignment of 'const char [1]' to 'char [100]'
sketch_apr11a:71: error: incompatible types in assignment of 'char' to 'char [100]'
sketch_apr11a:72: error: no match for 'operator+=' in 'Buffer += String(ax, 2u)'
sketch_apr11a:73: error: invalid operands of types 'char [100]' and 'const char [4]' to binary 'operator+'
sketch_apr11a:73: error: in evaluation of 'operator+=(char [100], const char [4])'
sketch_apr11a:74: error: no match for 'operator+=' in 'Buffer += String(ay, 2u)'
sketch_apr11a:75: error: invalid operands of types 'char [100]' and 'const char [4]' to binary 'operator+'
sketch_apr11a:75: error: in evaluation of 'operator+=(char [100], const char [4])'
sketch_apr11a:76: error: no match for 'operator+=' in 'Buffer += String(az, 2u)'
sketch_apr11a:77: error: invalid operands of types 'char [100]' and 'const char [3]' to binary 'operator+'
sketch_apr11a:77: error: in evaluation of 'operator+=(char [100], const char [3])'
sketch_apr11a:79: error: incompatible types in assignment of 'char' to 'char [100]'
sketch_apr11a:81: error: incompatible types in assignment of 'uint8_t' to 'char [100]'
sketch_apr11a:82: error: incompatible types in assignment of 'char' to 'char [100]'
sketch_apr11a:83: error: incompatible types in assignment of 'uint8_t' to 'char [100]'
sketch_apr11a:84: error: incompatible types in assignment of 'char' to 'char [100]'
sketch_apr11a:85: error: incompatible types in assignment of 'uint16_t' to 'char [100]'
sketch_apr11a:86: error: incompatible types in assignment of 'char' to 'char [100]'
sketch_apr11a:87: error: incompatible types in assignment of 'uint8_t' to 'char [100]'
sketch_apr11a:88: error: incompatible types in assignment of 'char' to 'char [100]'
sketch_apr11a:89: error: incompatible types in assignment of 'uint8_t' to 'char [100]'
sketch_apr11a:90: error: incompatible types in assignment of 'char' to 'char [100]'
sketch_apr11a:91: error: incompatible types in assignment of 'uint8_t' to 'char [100]'
sketch_apr11a:92: error: incompatible types in assignment of 'char' to 'char [100]'

ecco il codice modificato:

#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
#include <SPI.h>
#include "ADXL335.h"


ADXL335 accelerometer;

RTC_DS1307 RTC;


File Dati; // La variabile di tipo file che useremo per il log

const int chipSelect =10;

char Buffer[100];


unsigned long time;

DateTime now = RTC.now(); // leggiamo l'ora
accelerometer.getAcceleration(&ax,&ay,&az);
snprintf(buffer,100,"\t g,%d,%d,%d",ax,ay,az);

void setup ()

{
  Serial.begin(9600);
  
  Wire.begin(); // inizializziamo la libreria WIRE per usare
  RTC.begin(); //il Real Time clock basato su ds1307
  accelerometer.begin();
  
  if (! RTC.isrunning()) 
  
  {
    Serial.println("RTC NON STA FUNZIONANDO");
    
    //LA SEGUENTE ISTRUZIONE SERVE SOLO PER REGOLARE L'OROLOGIO.ATTIVARE SOLO SE NECESSARIO.
  //  RTC.adjust (DateTime(__DATE__, __TIME__)); //imposta ora e data
    }
    
  Serial.print("\nSto verificando la presenza della scheda..\n");
  pinMode(10, OUTPUT); // fa funzionare la sdlib
  
  if (!SD.begin(chipSelect))
  
  {
     Serial.println("SD card non trovata");
     return;
     
  }
 else 
   {
     Serial.println("Scheda inserita e funzionante");
     Serial.println();
    
   }
}
void loop ()

{
  Serial.print ("time:");
  time=millis();
  Buffer=""; // Nuovo giro, stringa vuota!

  float ax,ay,az;
 
  
  Buffer+=('\t');
  Buffer+=String(ax); 
  Buffer+=" g,";
  Buffer+=String(ay); 
  Buffer+=" g,";
  Buffer+=String(az);
  Buffer+=" g";
  
   Buffer+=('\t');
  
  Buffer +=(now.day()); // Componiamo la data AAAA/MM/GG
  Buffer +=('/');
  Buffer +=(now.month());
  Buffer +=('/');
  Buffer +=(now.year());
  Buffer +=('\t');
  Buffer +=(now.hour());
  Buffer +=(':');
  Buffer +=(now.minute());
  Buffer +=(':');
  Buffer +=(now.second());
  Buffer +=('\t'); // tab per separare i campi
 
  Dati = SD.open("datalog.txt", FILE_WRITE); // apriamo il file in scrittura
  Serial.println(time);
  if (Dati)
  {
   Dati.println(Buffer);  // Scriviamo in un sol colpo i dati sul file
   Dati.close();     // chiudiamo e trasferiamo su SD
   Serial.print("Dati rilevati \t");
   Serial.println(Buffer);
  }
  else
  {
    Serial.println("Errore nell'apertura di datalog.txt");
  }
  delay (0);  // cadenza dellascrittura dei dati
  }

Se usi un oggetto String, che viene allocato di continuo e ri-distrutto addirittura ad ogni loop() di certo impiega un pò.
Devi usare le stringhe (vettori di caratteri) con un buffer a dimensione fisso ben calcolato (da te).
Poi per stampare i dati dentro a questo array di caratteri puoi usare la snprintf().
In variabili globali metti (ma devi calcolare tu bene quanto grande, io metto 50):

char buffer[50];

Nella loop tu hai le istruzioni che leggono e sono okay, al posto di quei Buffer+= usi la snprintf

DateTime now = RTC.now(); // leggiamo l'ora
accelerometer.getAcceleration(&ax,&ay,&az);    // tue istruzioni di lettura
....
// al posto di Buffer
snprintf(buffer,50,"\t%d g,%d g,%d g\t%02d:%02d:%02d\t",ax,ay,az,now.hour(),now.minute(),now.second());
...
Dati = SD.open("datalog.txt", FILE_WRITE); // apriamo il file in scrittura
...

Anzitutto grazie per la pazienza,ma sono davvero agli inizi con la programmazione in c.Magari per alcuni queste cose sono delle banalita',ma per me sono abbastanza difficili (ad ogni modo ho gia provveduto ad ordinare un manuale di C)Allora ho modificato il codice nel modo seguente:

#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
#include <SPI.h>
#include "ADXL335.h"

ADXL335 accelerometer;

RTC_DS1307 RTC;


File Dati; // La variabile di tipo file che useremo per il log

const int chipSelect =10;

char buffer[70];

void setup ()

{
  Serial.begin(9600);
  
  Wire.begin(); // inizializziamo la libreria WIRE per usare
  RTC.begin(); //il Real Time clock basato su ds1307
  accelerometer.begin();
  
  if (! RTC.isrunning()) 
  
  {
    Serial.println("RTC NON STA FUNZIONANDO");
    
    //LA SEGUENTE ISTRUZIONE SERVE SOLO PER REGOLARE L'OROLOGIO.ATTIVARE SOLO SE NECESSARIO.
  //  RTC.adjust (DateTime(__DATE__, __TIME__)); //imposta ora e data
    }
    
  Serial.print("\nSto verificando la presenza della scheda..\n");
  pinMode(10, OUTPUT); // fa funzionare la sdlib
  
  if (!SD.begin(chipSelect))
  
  {
     Serial.println("SD card non trovata");
     return;
     
  }
 else 
   {
     Serial.println("Scheda inserita e funzionante");
     Serial.println();
    
   }
}
void loop ()

{
  float ax,ay,az;
  DateTime now = RTC.now(); // leggiamo l'ora
  
  snprintf(buffer,70,"\t%d g,%d g,%d g\t%02d:%02d:%02d\t",ax,ay,az,now.hour(),now.minute(),now.second());
 
 
  Dati = SD.open("datalog.txt", FILE_WRITE); // apriamo il file in scrittura
  
  if (Dati)
  {
   Dati.println(buffer);  // Scriviamo in un sol colpo i dati sul file
   Dati.close();     // chiudiamo e trasferiamo su SD
   Serial.print("Dati rilevati \t");
   Serial.println(buffer);
  }
  else
  {
    Serial.println("Errore nell'apertura di datalog.txt");
  }
  delay (0);  // cadenza dellascrittura dei dati
  }

Il programma viene compilato,ma ho errori nell'output:

tipo questo:
Dati rilevati -15744 g,15821 g,28832 g 16003:-32768:16300
voltage:
1.24
1.28
1.58
Dati rilevati -31488 g,15739 g,-7872 g 15986:-32768:16295
voltage:
1.23
1.27
1.57
Dati rilevati -31488 g,15659 g,-7872 g 15966:00:16293

Come si vede,i valori misura in g dell'accelerometro sono totalmente sbagliati, cosi' come i valori del RTC.
Forse il buffer dovrebbe essere inizializzato ogni volta?

Prima dello snprintf metti una serie di serial print con i dati per capire se ti arrivano errati o è la creazione del buffer che va male.
Prima dello snprintf ti sei dimenticato

accelerometer.getAcceleration(&ax,&ay,&az);

Si in realta' l'avevo messo nello sketch originale,ma si e' perso nel taglia e incolla che ho effettuato,per postarlo qui!Ad ogni modo,ho aggiunto un serial prima della creazione del buffer,e ho notato che il problema e' proprio quest'ultimo,in quanto all'inizo della sua creazione l'RTC funziona perfettamente.Cosa puo' essere?Riposto il codice aggiornato!

#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
#include <SPI.h>
#include "ADXL335.h"


ADXL335 accelerometer;

RTC_DS1307 RTC;

File Dati; // La variabile di tipo file che useremo per il log

const int chipSelect =10;

char buffer[50];

void setup ()

{
  Serial.begin(9600);
  
  Wire.begin(); // inizializziamo la libreria WIRE per usare
  RTC.begin(); //il Real Time clock basato su ds1307
  accelerometer.begin();
  
  if (! RTC.isrunning()) 
  
  {
    Serial.println("RTC NON STA FUNZIONANDO");
    
    //LA SEGUENTE ISTRUZIONE SERVE SOLO PER REGOLARE L'OROLOGIO.ATTIVARE SOLO SE NECESSARIO.
  //  RTC.adjust (DateTime(__DATE__, __TIME__)); //imposta ora e data
    }
    
  Serial.print("\nSto verificando la presenza della scheda..\n");
  pinMode(10, OUTPUT); // fa funzionare la sdlib
  
  if (!SD.begin(chipSelect))
  
  {
     Serial.println("SD card non trovata");
     return;
     
  }
 else 
   {
     Serial.println("Scheda inserita e funzionante");
     Serial.println();
    
   }
}
void loop ()

{
   float ax,ay,az;
   
    DateTime now = RTC.now(); // leggiamo l'ora
    accelerometer.getAcceleration(&ax,&ay,&az);
  
    Serial.print(now.day(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.year(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
 
  snprintf(buffer,50,"\t%d g,%d g,%d g\t%02d:%02d:%02d\t",ax,ay,az,now.hour(),now.minute(),now.second());
 
  Dati = SD.open("datalog.txt", FILE_WRITE); // apriamo il file in scrittura
  
  if (Dati)
  {
   Dati.println(buffer);  // Scriviamo in un sol colpo i dati sul file
   Dati.close();     // chiudiamo e trasferiamo su SD
   Serial.print("Dati rilevati \t");
   Serial.println(buffer);
  }
  else
  {
    Serial.println("Errore nell'apertura di datalog.txt");
  }
  delay (10000);  // cadenza dellascrittura dei dati
  }

E' senza dubbio la funzione snprintf, ma non conoscendola non ti so aiutare.

Allora ho provato con :
dtostrf(ax, 8, 2, buffer); dove ax e' l'accelerazione di tipo float e funziona bene
( a proposito se volessi stampare il valore anche di ay e az?)
Ho dichiarato nelle variabili globali:

static char buffer[50];
static float ax,ay,az;

poi ho provato con snprintf (ovviamente cancellando dtostrf)

snprintf(buffer,50,%02d:%02d:%02d\t",ax,ay,az,now.day(),now.month(),now.year());
e funziona l'rtc

Ora come faccio a stampare nel vettore di caratteri chiamato buffer,sia i valori ax,ay,az,che quelli del rtc, unire cioe' quello che ottengo da dtostrd e snprintf?