Acquisition de données

Bonjour à trous,

Je viens de réaliser une petite acquisition de données qui me permet d’enregistrer quelques donnes issues de capteurs angulaires (potars), 2 acceleros sur un velo ou tout ce qu’on veux.
Je suis parti d’une carte UNO, et d’un shield groove et capteur grooves par souci de simplicité.

J’ai réussi à réaliser le programme sans problèmes, étant le plus propre possible.
J’ai réalisé une temporisation qui permet de choisir la fréquence d’acquisition (dans les paramètres je choisi Tacqui en ms)
Malheuresement , je n’arrive pas à faire mieux que 100ms (10 Hz). MOn objectif serait d’etre entre 100 et 500 Hz (1KHz le rêve…)

Es-ce que quelqu’un peux expliquer si cela vient de la programmation ou de la carte qui est à sa capacité maximale ?
En joint le programme

Je pense que avec une horloge à 16 MHz on devrait arriver à faire mieux que 10Hz même si il y a quelques lignes à traiter à chaque boucle?

Merci par avance
Emeric

Datalogger-3-12.ino (9.88 KB)

Bonjour,

Je suis un peu étonné par les 100ms. C’est bien 10 mesures par secondes?

Je viens de jouer avec une cartes Uno et un afficheur, et sans rien rajouter (pas de circuits externes, entrées en 0/5V uniquement), je me suis posé la question de faire avec un analyseur digital et un oscilloscope numérique 4 voies. Pour l’analyseur on doit pouvoir monter à 4M ech/s, pour l’oscilloscope la doc du uno me dit qu’elle est capable d’échantillonner à 15000 ech/s en résolution 10 bits et 76000 ech/s en 8 bits. Il y a une sacré différence.

Je n’ai pas analysé ton code, mais je crois que tu utilises analogRead. Cette fonction dure 111µs. avec cette fonction, on devrait pouvoir échantillonner à 9000 ech/s. Problème avec cette fonction: elle est bloquante et elle prend du temps. Pour échantillonner au maximum, il faut demander la conversion et faire le travail en attendant qu’elle soit finie.

Pour comprendre pourquoi cela va lentement, place un chronomètre pour mesurer différentes parties du code. Il doit y avoie une ou plusieurs fonction qui prennent du temps, en particulier les écritures sur la carte SD. Mais je crois que j’écris sur une SD à 20000 octets/s. La carte Sd devrait suivre…

Bonjour,

Oui, c'est bien cela, 10 ech/sec.
Tres bonne idée le chrono.

Je viens de réaliser un test rapide avec un moniteur :

  • lecture accelero 1 = 1ms ( 3 valeurs)

  • lecture accelero 2 = 4 à 6 ms (7 valeurs)

  • ecriture de toutes les valeurs dans la variable dataString = 2 à 3 ms (utilisation des fct AnalogRead )

  • ouverture du fichier sur la carte SD = 1ms
    (File dataFile = SD.open(DataFileName, FILE_WRITE); )

  • ecriture des résultats = 18 à 39 ms (18 en general, 39 tous les 5 à 6 cycles (??))
    (dataFile.println(dataString):wink:

  • fermeture du fichier 58ms
    (dataFile.close():wink:

  • retour à la boucle suivante 0 à 1 ms

=> Total de 84 ou 105 ms

Donc tout le problème est dans l’écriture des résultats sur la carte SD, soit ces 3 lignes :

File dataFile = SD.open(DataFileName, FILE_WRITE); //--> 1ms
dataFile.println(dataString); //--> 18 à 39 ms
dataFile.close();

Existe-t-il un autre moyen d'écrire cela ?
En attendant j'ai tenté de déplacer l'écriture mais sans résultats.

Emeric

Tu peux stocker tes mesures dans un tableau et écrire au bout de 100 voire 1000 mesures.

Est-il nécessaire de fermer le fichier à chaque fois? Si on écrit une valeur, et qu'on le ferme, il faut écrire un secteur entier (512 octets). Si on écrit un octet à la fois, il est mis dans le buffer de SD, cela ne prend quasiment pas de temps. le buffer on le voit car quand on appelle le bibliothèque la quantité de RAM descend de 800 octets.

Tu peux stocker tes mesures dans un tableau et écrire au bout de 100 voire 1000 mesures.

Cela se fait tout seul si on laisse le fichier ouvert.

Autre question: quand le fichier est-il nécessaire? A quoi il sert?

  • on veut enregistrer sans arrêt et garder toutes les valeurs
  • on veut garder N valeurs
    -...

Merci pour ces réponses ultra rapides.

@lesept Je vais voir pour l'idée du tableau, mais a priori je ne voit pas trop le type de variable à utiliser

@vileroi Le fichier est nécessaire pour récupérer les données et les traiter ultérieurement (excel ou autre)
Il s'agit d'un enregistreur embarqué, d'où le module SD.
On choisi la fréquence suivant les experiences, ou les phénomènes que l'on veut observer. Au premier appui du bouton, on débute l'enregistrement, au second appui, on arrête l'enregistrement.

La loop est composée de 4 blocs en if suivant les conditions du bouton :
Pas d'enregistrement
départ enregistrement
stop enregistrement
et enregistrement (où se trouve la lecture et l'écriture des valeurs de capteurs)

J'ai bien essayé déplacer l'ouverture et la fermeture du fichier dans une autre boucle mais c'est un echec à la compilation.

Emeric

La loop est composée de 4 blocs en if suivant les conditions du bouton :
Pas d'enregistrement
départ enregistrement ------------> C'est à cet endroit qu'il faut placer l'ouverture
stop enregistrement -------------> et ici la fermeture
et enregistrement (où se trouve la lecture et l'écriture des valeurs de capteurs)

Il faut oublier le tableau avec la uno, soit il est plus petit que 500 octets, et le buffer le remplace, soit il est plus grand, et il n'y a pas assez de RAM... En plus la taille du tableau n'est pas connue à l'ouverture. Il faut donc faire un tableau dynamique et faire le test de mémoire libre.

(1KHz le rêve..)
Au premier appui du bouton, on débute l'enregistrement, au second appui, on arrête l'enregistrement.

Donc il y aura plus de 1000 valeurs... mais peut être pas encore aujourd'hui avec les 10 Hz.

Sans fermer le fichier, il y aura de temps en temps une écriture qui va interrompre le déroulement. Il faut peut être penser ou pas, à enregistrer aussi le temps de l'échantillon.

Je pense à autre chose, Est sauvegardé sur la SD un nombre impressionnant de données. Du coup,le buffer doit être rempli en deux ou trois mesures. Donc même en mettant un tableau, en ne fermant pas le fichier... faire une écriture à chaque fois ou faire une écriture quand on a 512 octets ne va pas beaucoup changer.

Il faut penser à revoir le fichier. Pour augmenter le temps, il faut diminuer le nombre de données qui sont enregistrées:

  • quelles sont celles qui sont utiles?
  • quel format de données utiliser? Le format texte utilisé est plus gourmand qu'un format binaire "1234" (chaîne) occupe 4 octets, 1234 (int) n'en occupe que 2
  • y a-t-il la possibilité de faire un fichier ne contenant que les mesures brutes, quitte à rouvrir le fichier pour y inscrire les données mise en forme sous forme de texte?

La chasse aux gaspi est ouvertre

Effectivement je me doutais bien qu'à la fin cela finirai comme cela, mais je n'ai pas encore tous les capteurs désirés (x2 je pense).

Je voulais déja avoir une structure propre avant de rajouter les autres capteurs et être capable de viser du 100hz

Pour la mise en forme, je peux regarder à y mettre des int en place de string.
L'avantage que j'y trouvais c'est que sur une ligne, toutes les donnée à l'instant t étaient écrite et séparées par une virgule (donc simple à ouvrir et traiter avec excel).

Emeric

Rien n'empêche de stocker provisoirement les données sous forme d'int, et au moment de fermer:

  • fermeture du fichier contenant les données brutes avec des int
  • ouverture d'un fichier texte en écriture et du fichier brut en lecture
  • écriture du fichier texte à partir des données du fichier brut
  • fermeture du fichier texte
  • effacement du fichier brut

Ainsi tu récupères la facilité de traitement, et comme tu as déjà l'ossature pour écrire le fichier texte, ce sera plus facile que de les traiter sur l'ordi, sur l'Arduino, la transformation se faisant automatiquement.

OK, bonne idée je vais tester aujourd'hui ou demain.
Bonne journée
Emeric