Avec un investissement en matériel presque dérisoire, nous allons pas à pas aborder toutes les notion précédentes pour qu’elle deviennent des évidences. Puis on va enrichir notre expérience en ajoutant à notre démonstrateur de base des fonctions présentes sur tous les oscilloscopes numériques digne de ce nom. Bref, nous allons nous amuser avec Arduino, et nous construire une culture technique qui ne pourra que nous servir ultérieurement dans nos loisirs informatiques.
L’optimisation logicielle.
Avant de définir le matériel et le cahier des charge fonctionnel du futur prototype, il nous faut évaluer la faisabilité et en particulier « dégrossir » la saisie des enregistrement pour évaluer la fréquence d’échantillonnage possible, donc la BANDE PASSANTE que l’on pourra espérer. La façon dont vont être saisies les CAN influencera également la quantité des échantillons qui seront mémorisés. Bref, il va falloir donner dans l’optimisation et les compromis. C’est l’objet de ce chapitre.
Philosophiquement, je considère qu’un petit démonstrateur comme P02 par exemple n’est pas vraiment un programme. C’est avec ses 3078 Octets un petit « bricolage ». (Même si pour le développer je me suis s’est cogné à des séquences pouvant se montrer réticentes de façon agassive.) À mon sens, je parle de vrai programme quand il va falloir aligner on nombre considérable d’instructions, et que le code finira par saturer la mémoire disponible et qu’il faudra chercher désespérément de la place. Ce n’est pas quand le bateau coule qu’il faut apprendre à nager. Aussi, y compris pour des tout petits démonstrateurs, il faut optimiser l’optimalisation des séquences déjà ultra condensées.
En résumé, optimiser le code est plus qu’un réflexe de programmeur et cette facette doit virer à l’obsession. En fonction de la séquence en cours de rédaction, le programmeur peut privilégier :
• Une taille minimale du code objet qui encombrera la mémoire,
• Un temps d’exécution minimal d’une séquence car c’est un critère prioritaire dans le contexte.
Optimiser l’enregistrement des échantillons.
Sachant que les CAN des entrés analogiques de l’ATmega328 fonctionnent sur 10 BITs, les valeurs échantillonnées vont s’échelonner entre 0 et 1023. Pour les stocker on va devoir utiliser des int consommant deux OCTETs par valeur. C’est un peu du gaspillage, car l’écran graphique ne présente que 64 PIXELs en vertical. Aussi, pour ranger les valeurs sous forme de byte il suffit de diviser la valeur de la CAN par quatre avant de la stocker. Les valeurs seront ainsi comprises entre 0 et 255. La façon la plus rapide pour réaliser cette division consiste à effectuer deux décalages à gauche. (Opérateur SHIFT left codé par << 2 en langage C++.) Toutefois il est légitime de se demander si cette opération de deux décalages à gauche ne dégradera pas la rapidité d’échantillonnage. C’est ici qu’il faut expérimenter pour trouver le meilleur compromis entre taille et rapidité.
Téléverser le démonstrateur nommé Teste_Echantillonnage.ino pour effectuer les essais qui s’imposent. Une partie du listage en Fig.16 présente la boucle de base (2) qui effectue l’enregistrement des échantillons. Plus leur nombre sera important, plus la trace contiendra de l’information. Toutefois, avec une largeur d’écran de 128 PIXELs, si l’étendue de la mémoire dépasse cette valeur, il faudra « fenêtrer » la visualisation. Comme à ce stade du tutoriel cette option est envisagée, dans la
déclaration en (1) on réserve 512 cellules. Inutile de tenter plus, car avec 1024 par exemple, le compilateur refuse une saturation de la mémoire dynamique. Lorsque le démonstrateur est chargé, la ligne (5) est en remarque et n’intervient pas. La boucle for en (3) se contente de lire la CAN et de la stocker les 512 valeurs le plus rapidement possible dans le TAMPON. En ligne (4) on crée une impulsion très courte sur la sortie D13, signal qui sert à mesurer la fréquence d’échantillonnage avec un appareil très précis. On trouve une cadence de 8301Hz.
C’est tout de même bien meilleur qu’avec le circuit intégré MCP3208 dont la cadence talonnait à 2582 échantillons par seconde bien qu’il soit susceptible de fonctionner à 100 ksps. La lenteur constatée vient de la séquence Arduino qui enchaîne une foule d’instructions qui ralentissent le processus. En conclusion on élimine la présence de ce circuit intégré et on utilisera une entrée analogique de l’ATmega328. Enfin nous n’avons plus besoin de la fonction Lire_valeur(byte Canal) ce qui fait économiser 212 octet qui seront certainement les bienvenus à la fin du développement.
Deuxième essai, on va tenter la division par quatre pour voir si cette dernière est pénalisante en terme de rapidité de traitement. Le but étant de ne manipuler que des données sur huit BITs pour diminuer la place occupée par le TAMPON, il faut au préalable changer la déclaration de la ligne (1) par unsigned byte TAMPON[512]. Il importe de déclarer les données en « non signées » pour obtenir un SHIFT pur. Si on oublie ce détail, le décalage ne remplit pas les deux BITs de poids faible par un « 0 », mais par le BIT de poids faible initial. Puis, on fait passer la ligne † en remarque et l’on valide la ligne …. À partir d’ici le croquis téléversé va diviser par quatre chaque valeur fournie par le CAN avant de la ranger dans TAMPON. On réactive le logiciel pour mesurer une fréquence d’échantillonnage de la même valeur de 8301Hz.
EXPLICATION : Dans la boucle for de la ligne (3), le traitement (4) prend une durée dérisoire. Par ailleurs, les deux décalages à gauche de la ligne (5) ne prennent que quelques microsecondes. C’est le traitement de la boucle for en (3) qui pénalise un peu le processus car il intègre la gestion d’un compteur, ainsi que le stockage de la valeur dans TAMPON qui impose la gestion d’un pointeur en mémoire dynamique. Et puis c’est surtout la numérisation qui se taille la part du lion, elle prend 100µS durée indiquée dans la documentation sur Arduino.
CONCLUSION : Comme translater les valeurs en les limitant à des byte ne pénalise rigoureusement pas la rapidité d’échantillonnage on pourra se permettre un TAMPON[512] qui autorisera de sauvegarder « quatre écrans de large ». De plus, la sauvegarde en mémoire non volatile est envisagée et se justifie totalement dans l’optique expérimentale de ce petit projet. Il restera de ce fait encore 512 autres emplacements en EEPROM, probablement pour y loger des textes du dialogue Homme/Machine affichés sur l’écran OLED. Nous pouvons Sereinement envisager l’avenir …
La suite est ici.