08) 17/09/2017 : Dialoguer et … ACTION ! (MJD 58013)

Première brique de l’édifice logiciel : Rédiger une procédure qui pilote en toute sécurité un moteur avec des paramètres « naturels » constitue la fondation sur laquelle sera architecturée l’ensemble du programme. Tout mouvement de la sonde ne sera par la suite qu’une cascade de rotations élémentaires plus ou moins combinées. Écrire une subroutine évidente à utiliser qui se charge de gérer les butées logicielle est donc fondamental. Le démonstrateur P04_Piloter_un_moteur.ino s’avère incontournable, car non seulement il intègre la procédure de base Traite_moteur() mais il se charge également de l’aiguillage logiciel en fonction du fait que la consigne est de type « m » ou de nature « p« . Enfin, pour vérifier le bien-fondé des choix effectués à ce stade du développement logiciel, le programme P01 est émulé. Cette fonction ramène les douze moteurs à leurs neutres opérationnels en tenant compte des paramètres du tableau de la Fig.26 qui précise les dispersions de caractéristiques de chaque individu.
ATTENTION : Pour pouvoir tirer le meilleur parti de ce démonstrateur, les moteurs sont branchés par ordre croissant de leur ordre de traçabilité, c’est à dire le n°1 sur la sortie S0, le n°2 sur la sortie S1 … le n°12 sur la sortie S11. Si vous possédez plus de douze moteurs, vous pouvez en brancher seize, le programme tolère ce nombre. (En réalité la limite va jusqu’à 18 car c’est le nombre d’individus disponibles ici et tous ont été passés au crible pour valider la table des valeurs.)
Comme vous le constaterez en observant le listage de ce petit programme, les butées « électroniques » sont consignées dans un tableau[]. À partir du tableau Fig.26 il est assez indigeste de copier toutes ces valeurs, les risques d’erreurs sont importants. Dans le but de pouvoir vérifier intégralement les données relatives aux butées logicielles, chaque consigne de mouvement s’accompagne d’un compte-rendu à l’écran. Vérifier toutes les valeurs devient alors tout à fait convivial. Par exemple sur la Fig.31 le programme en 1 nous fait un petit rappel du genre :

– N’oubliez-pas de terminer avec « * » avant de valider votre consigne.

 

 

 

Puis en 2 et 3 on a positionné deux moteurs. Observez au passage que le programme fait la distinction entre la référence d’un moteur et l’ordre de la sortie sur laquelle il est branché. Enfin en 4 n’oubliez pas de terminer vos manipulations par l’appel du programme P01 comme nous en avions mentionné l’importance dans les chapitres précédents. Sans qu’il ne soit indispensable d’immobiliser tous les moteurs sur un quelconque support, la Fig.32 présente le banc de test sur lequel quatre individus étaient assemblés avec des cadrans de repérage. Les autres dispersés en vrac se voyaient complétés chacun à son tour d’un disque gradué dans l’ordre où les butées étaient vérifiées. Toutefois, avoir plusieurs moteurs bien stables avec leurs disques de repérage s’avère très utile pour vraiment tester le démonstrateur P04_Piloter_un_moteur.ino et en valider la procédure de base.
Pour finir, nous sommes dans le monde réel, et pas dans de la théorie. Il ne faudra pas s’offusquer si le positionnement consigné est affecté d’une imprécision pouvant aller jusqu’à de ±5° au cours du temps.

La crise du logement.

L‘avancement du projet est conforme aux prédictions du planning. Tout va pour le mieux, car le dialogue Homme/Machine est en place, la sonde est sous contrôle. L’interface de puissance ainsi que la centrale électrique sont validées. La procédure de gestion des moteurs semble avoir fait ses preuves. Bref la sérénité devrait prendre le devant de la scène … et pourtant une ombre maléfique plane. En effet, si l’on résume la situation, pour le moment JEKERT n’est pas en mesure de se déplacer. Tout juste si ce petit robot est capable de mouvoir une articulation alors qu’il reste tant à programmer. Quand on consulte le listage de P04_Piloter_un_moteur.ino on constate que ce trois fois rien opérationnel consomme déjà 10698 octet dans la mémoire de programme soit environ 34% de la place disponible. Quand aux variables dynamiques, avec 595 octets on dilapide déjà 29% de l’espace vital. À ce régime la saturation va se précipiter et l’on ne pourra pas engager notre belle sonde dans les actions qui encombrent notre rêve.
Pondérons ce pessimisme. L’expérience prouve depuis longtemps que dans un programme compilé, ce sont généralement les premières lignes du code source qui amassent beaucoup d’instructions. On ne s’en rend pas compte, car c’est transparent utilisateur. Par exemple :
void setup() {} suivi de void loop() {} consomment déjà 450 octets soit 1%. Pourtant nous avons là un programme qui ne fait strictement rien … en apparence. En réalité le compilateur se charge sans nous le dire d’initialiser la PILE, le TAS, les interruptions, les broches d’E/S …
Ajoutons dans void setup() {} les deux lignes :
  Serial.begin(115200);
  Serial.print(« Bonjour« );
Le programme passe à 1736 octets soit 5% de l’espace disponible et 190 octets en mémoire dynamique. Pourtant ce démonstrateur ne fait qu’afficher « Bonjour » sur la ligne USB. C’est normal, car il faut intégrer toutes les routines qui permettent des échanges sur la ligne série.
On enlève les instructions de la ligne de dialogue USB et l’on ajoute à peine de quoi faire bouger un moteur soit, toujours dans void setup() {} on place :
  pwm.begin(); // Initialise le module multiplexeur  
  pwm.setPWMFreq(50);
  pwm.setPWM(2, 0, 1000);
précédé des déclarations :
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
Ces quelques directives et instructions consomment à elles seules 3532 octets de programme et 218 octets de RAM dynamique. On ajoute un petit « Bonjour » et le programme passe à 5214 octets soit 16% de l’espace disponible  avec 399 emplacements dans la PILE soit 19%. Autant dire que dans ce contexte « un trois fois rien c’est déjà quelque chose » est particulièrement d’actualité.
Restons sereins, car une fois que les procédures et fonctions de services sont compilées, s’en servir ne consomme plus que quelques octets pour y faire appel et quelques emplacements pour les passages de paramètres. C’est généralement dans la mise en place du noyau que l’on doit déclarer les variables qui seront utilisées. Elles se taillent également une bonne partie de l’espace possible. Plus le projet avance, moins on aura besoin de nouvelles variables.

CONCLUSION : Statistiquement les premières briques de l’édifice gloutonnent les octets par paquets de cent. L’expérience prouve qu’ensuite la boulimie va en diminuant, alors que le travail effectué par le logiciel semble de plus en plus conséquent. Il n’y a donc pas lieu de s’alarmer pour le moment, les événements devraient logiquement se conformer « aux statistiques ».

Perspectives : Les précisions qui précèdent, issues d’une expérience personnelle découlent, il faut le préciser, d’une optimisation à outrance de mes programmes. Optimisation pour choisir au mieux le type des variables et des constantes pour minimiser leurs tailles en mémoire. Les procédures et les fonctions sont optimisées également dans ce but. Par exemple vous pouvez observer la présence de void Espace() {Serial.print( » « );} dans les démonstrateurs. Une procédure pour afficher un espace !
Et bien oui, car à chaque appel on gagnera quelques octets …

La suite est ici.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *