Domanda:
Qual è il modo più preciso per contrassegnare i dati analogRead?
Josh de Leeuw
2014-05-29 21:30:13 UTC
view on stackexchange narkive permalink

Desidero campionare un sensore analogico il più velocemente possibile e timbrare ogni campione che prendo nel modo più accurato possibile.

Attualmente sto facendo quanto segue:

  val = analogRead (SENSOR_PIN); clocktime = micros (); writeData (val, clocktime); // scrive i valori su una scheda SD  

Mi chiedo se esista un modo più accurato per contrassegnare l'ora dei dati dalla chiamata analogRead. In altre parole, vorrei registrare l'ora esatta in cui sono stati raccolti i dati analogRead. La mia ipotesi è che questo sia praticamente impossibile su un Arduino, quindi quale tecnica mi permetterà di avvicinarmi il più possibile?

Due risposte:
#1
+5
BrettAM
2014-05-30 02:48:24 UTC
view on stackexchange narkive permalink

Non esiste un modo più preciso per ottenere il tempo su arduino, ma ti suggerirei di utilizzare invece millis ().

micros () restituisce microsecondi, o milionesimi di secondo, poiché arduino era acceso. Il problema è che l'intero senza segno a 32 bit utilizzato per memorizzare il tempo su arduino può contare solo circa 70 minuti di micro prima di overflow e reimpostare a 0. (vedi http://arduino.cc/en/reference/micros)

millis () è in millesimi di secondo dall'accensione di arduino e non si resetterà per circa 50 giorni. Se pensi che un millesimo di secondo sia una risoluzione abbastanza buona, probabilmente sarà la scelta migliore.

Se hai bisogno che il tempo sia assoluto, come nel giorno / ora / minuto correnti, dovrai acquistare un orologio in tempo reale da collegare ad arduino. Costano circa 20 dollari e sono disponibili in tutti i negozi di accessori standard di Arduino come sparkfun, adafruit, ecc.

Sulla tua domanda sull'ordine, entrambi i comandi vengono eseguiti così rapidamente, non riesco a pensare a nessuna ragione per cui sarebbe importante.

Grazie per la risposta. Sto misurando eventi molto veloci con una risoluzione prossima al millisecondo e devo solo eseguire il programma per pochi minuti alla volta.
#2
+3
JRobert
2014-06-01 18:56:34 UTC
view on stackexchange narkive permalink

Per "il più veloce possibile", vorrei

  1. Riscrivere il codice di campionamento in linguaggio assembly (solo quelle due istruzioni, non l'intero programma); e
  2. Memorizza nel buffer le coppie di dati grezzi se ne hai abbastanza, quindi memorizzale sulla scheda dopo il burst di misurazione. Se hai bisogno di più spazio per i dati, considera che la tempistica di un ciclo di assemblaggio stretto sarà coerente (e veloce!) E può essere misurata. Potrebbe non essere necessario leggere l'orologio. Nota che puoi ottenere la stessa coerenza temporale usando C / C ++ se leggi direttamente le porte analogiche e di clock, e forse altrettanto velocemente. È solo che con il linguaggio assembly, WYWIWYG (ciò che scrivi è ciò che ottieni); i generatori di codice e gli ottimizzatori dei compilatori non lo mancheranno.

Un possibile problema con il tuo codice mentre lo hai scritto è che writeData probabilmente memorizza i dati nella maggior parte delle chiamate, ma ogni volta che una chiamata risulta in un buffer pieno, scrive l'intero buffer sulla scheda, introducendo jitter nel campionamento.

Facendo riferimento alla tua modifica del 3 giugno 2014, "vorrei registrare l'ora esatta in cui I dati di analogRead sono stati raccolti ":

Dato che hai proposto di utilizzare micros () (al contrario di un orologio in tempo reale), presumo che tu sia soddisfatto del tempo relativo. Una volta che sai che il tuo codice di raccolta dati è completamente prevedibile, lo scostamento tra la lettura dei dati e il tempo di lettura è costante e, poiché stiamo comunque utilizzando il tempo relativo, può essere scontato o almeno corretto.

Ovviamente non è completamente prevedibile, poiché in questo caso stai usando un orologio mantenuto da interruzioni e puoi aspettarti che a volte l'interruzione si verifichi tra i dati letti e l'orologio read, allungando l'offset per quella tupla. Per essere ancora più accurati, dovresti tenere fuori gli interrupt, leggere tu stesso il timer in modo invariante. f / ex, potresti eseguire il timer a una velocità tale da aspettarti di prendere due o più campioni tra gli overflow del byte di ordine inferiore, leggere e memorizzare solo il byte di ordine inferiore come campione di tempo e postelaborare il tempo dati per ricostruire il byte di ordine elevato rilevando il wrap-around nell'ordine inferiore.

Senza interruzioni in esecuzione e una volta che si conosce la velocità con cui è possibile campionare i dati senza leggere l'orologio, è possibile leggere e salva l'orologio una volta immediatamente prima di prendere il primo campione e deduci i tempi di ogni campione successivo in base alla frequenza di campionamento nota.



Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...