Funzione ITOA e problemi con concatenamento di stringhe.

Salve a tutti,sto realizzando un progetto "Datalogger". In pratica ho un sensore accelerometro adxl335 connesso ad Arduino uno e GSMSHIELD (utilizzata per ora come sd card writer per scrivere il file log). Ho bisogno che l'acquisizione avvenga in tempi rapidissimi (intorno ai 10ms). I parametri di acquisizione dell'accelerometro (ax,ay,az) sono tassativamente di tipo float,e come si sa,vi sono problemi ad inserire direttamente una variabile di tipo float in un array di stringhe. Ho cosi' pensato di dividere la parte decimale da quella intera,metterle in due varibili separate,e poi convertire questi due valori in stringhe tramite la funzione ITOA.In pratica devo poter visualizzare sul file datalog.txt,i valori delle accelerazioni,e successivamente ,grazie all'ausilio di un RTC l'ora e la data corrente in cui e' avvenuta la misura. Il mio problema e' che una volta create le due parti intere non riesco a concatenare il tutto in un unica stringa, ho utilizzato il comando strcat (),ma senza successo,magari sbaglio io!Qualcuno potrebbe dirmi come poter creare un unica stringa da poter poi scrivere su sd?Vorrei fare in modo inoltre di riempire il "buffer di stringhe",quanto piu possibile per poi successivamente scriverlo su sd,in modo da ottimizzare il tempo di scrittura.E' fattibile tutto cio'?Grazie in anticipo.IDi seguito lo sketch.

#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;

static char  axb[100];
static char  ayb[100];
static float ax,ay,az;

unsigned long time; // serve per misurare il tempo di esecuzione

void setup ()

{
  Serial.begin(115200);
  
 
  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 ()

{
  // MISURO IL TEMPO DI ESECUZIONE 
  Serial.print("Time: ");
  time = millis();
  //prints time since program started
  Serial.println(time);
  
   
    DateTime now = RTC.now(); // leggiamo l'ora
    accelerometer.getAcceleration(&ax,&ay,&az);
  
  
   int Hix=ax;
   int Lox = ax*100-Hix*100;
   itoa(Hix,axb,10);
   Serial.print(Hix);
   Serial.print(",");
   itoa(Hix,axb,10);
   Serial.print(Lox);
   Serial.print("g");
   Serial.print("\t");
   int Hiy=ay;
   int Loy = ay*100-Hiy*100;
   itoa(Hiy,ayb,10);
   Serial.print(Hiy);
   Serial.print(",");
   itoa(Hiy,ayb,10);
   Serial.print(Loy);
   Serial.print("g");
   
   strcat(Hix,Lox);
   
  Dati = SD.open("datalog.txt", FILE_WRITE); // apriamo il file in scrittura
  
  if (Dati)
  {
   Dati.println(strcat(axb,ayb));  // Scriviamo in un sol colpo i dati sul file
   Dati.close();     // chiudiamo e trasferiamo su SD
   Serial.print("Dati rilevati \t");
   Serial.println(strcat(axb,ayb));
  }
  else
  {
    Serial.println("Errore nell'apertura di datalog.txt");
  } 
  delay (0);  // cadenza dellascrittura dei dati
  Serial.println(time);
  }

Non ho ben capito il problema... anzi... qual è il problema? :sweat_smile:
Se l'acquisizione deve avvenire in tempi rapidi, la scrittura su SD di questi valori di sicuro ti rallenterà il programma e non so se ci rientri nei tuoi 10 ms, considerando anche le conversioni da float a int che stai facendo.

Però se il problema è scrivere in un file i float, la struttura delle lib di Arduino ha riunificato la gestione della "stampa" dei dati in un unico oggetto Stream, grazie a cui dovresti poter scrivere sul file il dato in formato numerico senza dover fare tante conversioni di di tipo usando

Dati.print(ax, DEC);
Dati.print(",");
Dati.print(ay, DEC);
Dati.print(",");
Dati.print(az, DEC);

Così dovrebbe andare.

leo72:
Non ho ben capito il problema... anzi... qual è il problema? :sweat_smile:
Se l'acquisizione deve avvenire in tempi rapidi, la scrittura su SD di questi valori di sicuro ti rallenterà il programma e non so se ci rientri nei tuoi 10 ms, considerando anche le conversioni da float a int che stai facendo.

Però se il problema è scrivere in un file i float, la struttura delle lib di Arduino ha riunificato la gestione della "stampa" dei dati in un unico oggetto Stream, grazie a cui dovresti poter scrivere sul file il dato in formato numerico senza dover fare tante conversioni di di tipo usando

Dati.print(ax, DEC);

Dati.print(",");
Dati.print(ay, DEC);
Dati.print(",");
Dati.print(az, DEC);



Così dovrebbe andare.

Si in parole povere non riuscivo a capire una volta convertiti i valori in stringhe tramite ITOA come facevo a buttarli nel file!!:slight_smile: Scusami,ma sono alle prime armi con la programmazione e mi incasino con le stringhe.Fammi capire,quindi dopo fatto la conversione con ITOA,nella parte di codice in cui viene scritto il file,devo aggiungere la tua correzione?Per quanto riguarda la velocita',ho letto un bel po di materiale in rete,e a quanto pare alcuni sono anche riusciti a 200kb/s,per esempio tramite la libreria sdfat ma a quanto pare spesso dipende anche dalla sd card che si sta usando,tu sai qualcosa in merito?Ho

Dunque ho aggiunto,il codice postato da te al mio sketch.La velocita' di acquisizione tra una misura e' l'altra e' di 20ms.Pero' il valori mi vengono visualizzati non come lo schema nx,xy,nz,bensi' tutti in orizzontale,come nel modo seguente: :astonished:

-0.1534376144,0.0418748855,1.0351562500-0.1729688644,0.0223436355,0.9960937500-0.1729688644,0.0223436355,0.9765625000-0.1729688644,0.0223436355,0.9960937500-0.1729688644,0.0223436355,0.9765625000-0.1729688644,0.0223436355,0.9960937500-0.1534376144,0.0418748855,1.0156250000-0.1534376144,0.0418748855,1.0156250000-0.1534376144,0.0418748855,1.0156250000-0.1339063644,0.0418748855,1.0351562500-0.1143751144,0.0809373855,1.0546875000-0.11

Alcune precisazioni.
Come ti ho detto, con le scritture su SD non puoi aspettarti velocità molto elevate.

Il metodo che ho usato io non prevede le conversoni che facevi tu in precedenza ma scrive direttamente i dati.
Per mettere un ritorno a capo, basta aggiungere un Dati.println(); vuoto dopo il 3° dato. Oppure stampare il carattere "\n" che è il newline: Dati.print("\n");

leo72:
Alcune precisazioni.
Come ti ho detto, con le scritture su SD non puoi aspettarti velocità molto elevate.

Il metodo che ho usato io non prevede le conversoni che facevi tu in precedenza ma scrive direttamente i dati.
Per mettere un ritorno a capo, basta aggiungere un Dati.println(); vuoto dopo il 3° dato. Oppure stampare il carattere "\n" che è il newline: Dati.print("\n");

Infatti,percio' volevo creare un unico array di stringhe e poi scrivere tutto in un colpo solo.Tieni conto che dovrei aggiungere anche dai provenienti da un RTC,perdonami ma cosi' come mi hai suggerito tu non andrei a rallentare il tutto visto che per ogni singolodato il sistema dovrebbe aprire il file,scrivere e' chiuderlo?

La memoria RAM interna del microcontrollore è limitata. E quando vai ad usare diverse librerie pesanti come quelle che stai usando tu è facile consumarla. Io eviterei di creare buffer in memoria anche perché la lib SD già ne usa uno suo. Difatti i dati non sono materialmente scritti nel file finché non si riempie o lo si chiude esplicitamente con close() oppure non fai un flush(), che riversa il buffer sul file.

leo72:
La memoria RAM interna del microcontrollore è limitata. E quando vai ad usare diverse librerie pesanti come quelle che stai usando tu è facile consumarla. Io eviterei di creare buffer in memoria anche perché la lib SD già ne usa uno suo. Difatti i dati non sono materialmente scritti nel file finché non si riempie o lo si chiude esplicitamente con close() oppure non fai un flush(), che riversa il buffer sul file.

Si guarda,in effetti oltre al RTC il sistema dovrebbe anche gestire una connessione GSM tramite shield,e forse un sensore di prossimita'.Quindi la memoria e' preziosa.Sono alle prime armi per quanto riguarda questa tipologia di sistemi.Quindi potrei proseguire allo stesso modo che mi hai suggerito anche aggiungendo l'RTC e il sensore?A sto punto potrei riversare direttamente il dato di tipo float in scrittura sulla sd (sullo sketch che ho provato ora in realta' la conversione non l'ho eliminata),magari cosi' facendo risparmio memoria e guadagno qualche millisecondo,che ne pensi?

mooger:
A sto punto potrei riversare direttamente il dato di tipo float in scrittura sulla sd (sullo sketch che ho provato ora in realta' la conversione non l'ho eliminata),magari cosi' facendo risparmio memoria e guadagno qualche millisecondo,che ne pensi?

Meglio. Tieni solo conto che per i float il secondo parametro è quante cifre decimali vuoi.

Dati.print(numfloat, numdec);
Dati.println(1.23456, 3) gives "1.235"

Sì meglio. Ma conduci dei test perché la gestione dei file è un pò lenta.
Potresti anche cercare altre librerie per accedere alla SD, quella inclusa nell'IDE non è l'unica. E' una delle più complete come funzioni ma proprio per questo anche una di quelle che consuma più risorse.

Grazie mille,ora funziona! Come librerie per la sd conosco quella standard,e la SDFAT. Ho fatto un benchmark con entrambe e il risultato e' lo stesso,anche se dicono che la sdfat sia piu performante.Ho utilizzato come sd sia una vecchia kingston da 1gb,sia una Samsung 16gb classe 10. Per caso esistono anche altre librerie?

Prova a guardare QUI ...
... non è specifica per "Arduino" è generica e gira su svariate MCU. Vedo che, tra gli esempi pronti, c'è software anche per AVR :wink:

Guglielmo

P.S. : Versione ancora più ridotta QUI :wink: