buongiorno a tutti,
sto cercando di scrivere su una scheda sd il valore di vari sensori che si aggiornano a 100Hz.
ho notato che con il passare del tempo (2 ore circa) il tempo di scrittura dei dati sulla scheda sd aumenta drasticamente, utilizzo la libreria SD di Arduino.
sto lavorando con IMU e GPS e quando il programma inizia a salvare riesco ad avere dei tempi tra un ciclo e l'altro di circa 20ms (50Hz invece che 100Hz) questo penso sia dovuto alla velocità di scrittura sulla scheda SD in quanto ogni 5Hz scrivo su un file diverso dal precedente gli stessi dati (su un file campiono al massimo della velocità raggiungibile mentre su un altro campiono a 5Hz) e vedo che il tempo tra una scrittura e l'altra raddoppia solo in quel caso.
il problema arriva dopo circa un ora dall'inizio di esecuzione del programma, i tempi di scrittura nella scheda SD raddoppiano! (da 20ms a 40).
non essendo un informatico non ho le conoscenze sufficienti per capire il vero e proprio funzionamento della libreria SD ma posso intuire che con il passare del tempo, il file diventa più grosso e di conseguenza più pesante ed è come se ci mettesse di più ad aprirlo. potrebbe essere questo il problema (scrivo tutto su un file .CSV)?
Potresti provare ad acquisire "a blocchi" aggiornando il file sulla SD ad intervalli regolari.
Avresti comunque il rallentamento quando la dimensione dello stream (il file) diventa grande, ma quantomeno sarebbero in qualche modo prevedibili.
Non so ... forse lavorare con record a lunghezza fissa (così da poter fare accessi diretti) e preallocare lo spazio inizialmente per il massimo di record previsti, probabilmente porterebbe ad accessi costantemente della stessa durata (una seek() per posizionarsi sul record già preallocato e successiva scrittura) ...
grazie a tutti del consiglio, per ora ho risolto limitando il file a 20000 righe.
il problema grande è che risulta molto scomodo in quanto alla fine ho circa 18-20 file da unire facendo coppia e incolla.
puoi spiegarti meglio? teoricamente io non conosco a priori le righe massime che andrò a creare.
Teoricamente non è necessario: visto che l'istruzione write() restituisce il numero dei byte che sono stati scritti, a questo punto sarebbe sufficiente aggiornare un contatore globale del numero totale dei byte del file e fare il seek() come suggerivi.
Con questa simulazione io ottengo dei valori costanti di circa 10/12 millisecondi per record (mentre non usando l'istruzione seek() i tempi incrementano mano a mano come è stato riscontrato da @nocentini)
allora, ho studiato un pochino il programma che mi hai fornito e se ho capito bene (non sono troppo pratico con la classe string e tutte le conversioni del caso)
vado a leggere quanti byte sono stati scritti nel file e lo salvo nella variabile "pos" (così ho indicazione di dove dovrò andare a scrivere nel file)
tramite: "file.seek(pos);" vado a posizionarmi dopo i byte già scritti sul file
crei un array di caratteri che contiene i dati dei sensori raccolti.
tramite "pos += file.write(line);" vai a scrivere l'array di caratteri sulla scheda sd e incrementi il valore dei byte scritti
corretto?
Vero, deformazione professionale sono un normale utilizzatore di accessi random e/o ISAM e il record a lunghezza fissa è un po' una mia fissazione, lo trovo estremamente comodo per accessi diretti e velocissimi
Anche io tendenzialmente farei con un record a lunghezza fissa.
In questo caso però ho pensato che @nocentini abbia bisogno di una frequenza di campionamento elevata ed ogni manipolazione delle stringhe aggiuntiva avrebbe impiegato risorse e tempo (penso ad esempio a quanto può essere "onerosa" l'istruzione sprintf() per una piccola MCU come quella dell'Arduino).
Magari no, in effetti sarebbe il caso di verificare
edit:
In effetti mi ero posto un non-problema...
Usando snprintf e formattando a lunghezza fissa ogni linea, il tempo di esecuzione è pressoché uguale (ho aggiornato anche lo sketch online).
ho provato e tutto funziona correttamente! grazie mille delle vostre risposte.
ho un'altra domanda, non so se devo aprire un nuovo post...
praticamente essendo che la velocità di scrittura sulla scheda SD alla fine dei conti è di circa 10ms e la frequenza di aggiornamento dell'IMU è di 100Hz=10ms alla fine tutto il ciclo dura 20ms, di conseguenza vado a perdere una lettura del sensore mentre Arduino salva i dati.
sarebbe possibile (ovviamente non avendo un multicore) poter salvare i dati e contemporaneamente leggere i dati del sensore? utilizzo MKR1010
Guardando nel datasheet sembrerebbe possibile impostare anche il "Data Ready Interrupt", il problema è che la libreria che usi non ha alcuna istruzione al riguardo.
grazie mille della tua osservazione, la serie MKR con le sue librerie ufficiali si conferma sempre molto castrata di funzionalità sfortunatamente...... chi fa da sé fa per tre......