21) Une dernière petite surprise avant de se quitter.

Observant le thermomètre de la Fig.148 on constate une fois de plus qu’ajouter une fonction pourtant « cossue » avec gaspillage de place en mémoire, l’augmentation rouge reste dérisoire. À peine 1%. À ce taux d’inflation on pourrait encore en ajouter 28 de consistance analogue. (Sauf qu’il ne faudrait pas trop de tableaux ou le ratio PILE moins le TAS deviendrait négatif.) On constate à chaque ajout de fonctions dans le programme que l’on s’approche de moins en moins rapidement de la saturation. Il faut vraiment un projet très complexe pour arriver à consommer les 100% de la zone programme. Avec P19_Version_UTILISATION.ino on termine notre cheminement dont le but était d’explorer avec méthode diverses facettes du développement en C++. Il y a toutefois un chapitre pourtant fondamental qui n’a pas été abordé : L’utilisation des opérations avec masques LOGIQUES. Aussi je vous propose un exemple ludique, car une petite surprise vous attend si dans le Menu du RESET vous activez la touche HAUT avec un clic long. (Ben allez-y, faites-le !)

Le domaine des MASQUES LOGIQUES.

Fréquentant depuis de longues années des programmeurs amateurs, force est de constater que les si les opérateurs booléens tel que le OU et le ET sont bien assimilés, il en est autrement pour l’usage des masques logiques. C’est particulièrement vrai quand on programme en langage évolué comme BASIC, PASCAL ou C++ etc. Généralement des expressions comme :
                • Si (Condition 1) OU (Condition 2 ) faire Action 1 Sinon faire Action 2.
                • Si (Condition 1) ET (Condition 2 ) faire Action 1 Sinon faire Action 2.
sont bien assimilées.
Il en est tout autrement de l’usage du OU Exclusif. Par exemple que signifie ?
• Si (Condition 1) OU Exclusif (Condition 2 ) faire Action 1 Sinon faire Action 2 ? ? ?
C’est la pratique de la programmation « au raz de la machine » notamment en ASSEMBLEUR qui généralise l’usage des opérateurs LOGIQUES BIT à BIT et tout particulièrement l’intervention des masques logiques. Pourtant, comme on va le voir dans l’exemple de P19 ce type de programmation peut rendre de signalés services également dans les langages évolués. (On oubliera ici les opérateurs de décalage dont on a fait appel plusieurs fois dans ce petit projet. Ils permettent facilement de multiplier ou diviser rapidement par des multiples de deux.) Nous allons dans ce chapitre passer en revue le domaine d’application des masques logiques et des opérateurs associés. On peut déjà noter que :

La modification d’un OCTET BIT à BIT.

Bien que ce chapitre prend en exemple des données de huit BITs, on peut généraliser sans autre forme de procès à des variables entières de taille quelconque. Par exemple on va raisonner sur une variable OCTET qui dans une procédure adaptée sert à lire ou écrire directement les huit BITs des broches binaires allant de D2 à D9 comme montré sur la Fig.149 donnée ci-contre. L’instruction suivante OCTET = DATA recopiera dans les huit BITs de sortie d’OCTET ceux de la variable DATA. Réciproquement DATA = OCTET recopiera dans DATA les huit BITs des entrées BINAIRES d’OCTET. Ici l’opérateur « = » agit d’un seul coup sur l’intégralité du groupement nommé OCTET. On va maintenant voir comment à l’aide des opérateurs et des Masques LOGIQUES on peut agir sur des BITs individuels.


Le tableau de la Fig.150 propose trois exemples, mais pour bien saisir les transformations qui résultent de ces opérateurs reportez-vous sur la Fig.151 au résumé de l’emploi des Masque LOGIQUE :

Sur la Fig.150 la ligne A correspond à un Masque LOGIQUE commun affecté aux trois exemples. Sur la ligne B trois fois la même données sur laquelle est appliqué l’opérateur. En C est affiché le résultat de l’opération. Dans l’exemple avec le ET, supposons que les huit sorties BINAIRES de OCTET pilotent des LEDs. Et bien cette instruction va éteindre D2, D4, D8 et D9 sans modifier les autres sorties. Si on exécute une deuxième fois l’opération sur cette donnée OCTET modifiée en C, avec le même Masque LOGIQUE on constate sur la ligne D que l’on ne retrouve pas l’état initial du BIT concerné.

La donnée initiale est définitivement perdue car il est impossible d’en retrouver la combinaison de départ. Le ET associé à un Masque LOGIQUE sert également à tester un BIT individuel sur une donnée globale. Supposons par exemple qu’OCTET a été initialisé en huit entrées binaires reliées à des capteurs. On désire savoir dans quel état se trouve celui qui est branché sur D5 par exemple. Il suffit dans la donnée lue de forcer tous les autres BITs à « 0« . L’instruction devient : Entrees = OCTET; if (Entrees && B00010000) then

Vous avez certainement compris que l’opérateur OU qui force des « 1 » individuellement va servir à piloter des sorties binaires individuellement. Si on désire mettre en marche le moteur (Ou la LED etc.) branché sur D7 il suffit d’un OU avec 00000100. Pour le stopper c’est ET associé à 11111011 qui servira de masque. Il nous reste encore à passer en revue le domaine d’exploitation classique du OU Exclusif. On a vu en Fig.151, ce que confirme l’exemple de droite de la Fig.150 que cet opérateur sert à inverser les BITs correspondant lorsque dans le Masque LOGIQUE on a placé des « 1« . Du coup on peut inverser l’état d’un système sans se préoccuper de son état initial. C’est exactement ce que font sans que nous le sachions des instructions de type :

La première instruction inverse l’état de la LED de D13 une fois par seconde. Concrètement, dans ces deux instructions, l’opérateur d’inversion d’état qui en C++ est symbolisé par « ! » génère pour le microcontrôleur une opération élémentaire avec un OU Exclusif et un masque logique. Il me semble important de vous faire remarquer que la ligne relative au clignotement de la LED d’Arduino ne fonctionne correctement que par le fait qu’un OU Exclusif appliqué deux fois sur la même donnée avec un Masque LOGIQUE identique restitue cette dernière. Du coup on obtient bien une alternance d’état sur une paire d’exécution puis le cycle se poursuit.

Avant de passer à la suite, examinons ensembles une application banale en informatique de l’opérateur ET pour transformer un texte saisi en minuscules en majuscules. Par exemple vous développez un projet pour lequel les directives sont envoyées au dispositif par l’usage du Moniteur de l’IDE. Chaque commande est obtenue par un caractère. Par exemple si l’usager frappe ‘E‘ il effacera ses données. Vous désirez que cet usagé ne soit pas forcément obligé d’enfoncer la touche [MAJ]. Si il frappe ‘e‘, votre programme devra le transformer en ‘E‘. En codage ASCII c’est le BIT n°5 qui à « 1 » correspond à une minuscule, et à « 0 » donne son équivalent majuscule. L’instruction du genre Caractere = Caractere & 32; transformera toute minuscule en majuscule. ATTENTION : cette transformation n’est correcte que si le clavier utilisé retourne des codes ASCII et non de l’EBCDIC ou des codes clavier « IBM » …

Un tout petit « chouilla de cryptographie.

Domaine tellement vaste que des dizaines de didacticiels ne feraient qu’à peine l’aborder, on va ici cacher dans le programme du texte qui sera crypté. Le but de cette approche était de justifier ce chapitre sur les opérateurs logiques. N’oublions pas que ce n’est pas tellement la possession de ce petit oscilloscope aux performances modestes qui constitue le facteur déclenchant de ce projet, mais le plaisir de la programmation sur Arduino en C++. Aussi, lorsque vous allez déclencher la petite surprise avec la touche HAUT clic long du Menu du RESET, la page écran va afficher un texte comme pour tous les autres menus. Pour ces derniers, les textes affichés sont directement écrits dans le programme ou en EEPROM. par contre, pour cette page écran inutile de chercher les chaînes de caractère dans le croquis. Les lettres ont été cryptées de façon simple. Pour la substitution j’ai utilisé un simple opérateur OU Exclusif associé au Masque_LOGIQUE suivant :

Pour pouvoir appliquer sur les caractères affichés le masque logique caractère par caractère, les textes sont fournis sous forme du tableau de char de la Fig.153 nommé Texte_CRYPTE. Ainsi pour générer la page OLED on va extraire caractère par caractère et appliquer l’opération :
Caractere = char(Caractere ^ Masque_LOGIQUE);
En C++ le OU Exclusif se code ‘^‘. Profitant du fait que cet opérateur fonctionne « dans les deux sens », dans un premier temps j’ai rempli le tableau Texte_CRYPTE avec le texte en clair. L’écran OLED a alors affiché un texte correspondant à celui de la Fig.154 avec certains comme l’espace ou le point qui étaient non affichés. C’est la raison pour laquelle l’opérateur ‘^’ n’est pas appliqué sur cinq caractères Particuliers. Il m’a suffi de remplacer dans le tableau les textes en clair par ceux de la Fig.154 affichés sur OLED et le cryptage était effectué sans se tordre les méninges. Du reste, pour que vous puissiez voir ce que donne l’opérateur sur n’importe quel caractère, avec le Moniteur de l’IDE je vous propose Transcodage_par_masque_logique.ino ajouté aux autre démonstrateurs. Finalement, nous ne sommes pas encore au terme de ce petit cheminement ludique dans les sentiers du C++ et le thermomètre montre que cette version n’arrive pas à 80% d’espace programme utilisé. La zone verte disponible est encore scandaleusement grande. Il se trouve qu’en rédigeant ce chapitre, une idée intéressante a émergé avec l’espoir d’améliorer encore la « rentabilité du projet ». Alors sur le métier on replace l’ouvrage et l’on reprend le joug. C’est d’autant plus « émoustillant » que cet ajout va vraiment améliorer les performances de notre petit joujou.

La suite est ici.