Bonjour, il nous faut maintenant, consolider le peu qu'on a appris du C, en faisant quelques programmes simples. Bien voir la différence entre le if et le while, entre le binaire et le BCD, et comment on peut faire des conversions. On a vu comment lire un poussoir et écrire sur une led. On va un tout petit peu compliquer le problème en ayant deux poussoirs et deux leds, et chercher à programmer différentes fonctionnalités. Ces fonctionnalités interagissent avec des poussoirs et des leds qui sont allumées ou éteintes, des poussoirs qui sont pressés ou relâchés, et la façon dont ça a été câblé est un autre niveau. Donc, c'est comme on l'avait vu la dernière fois, dans le define que l'on va dire. Et bien, pour ce câblage, dans pour ce programme, et pour, euh, ce câblage dans lequel on va tester le programme. Et bien, la led un est dans la pin cinq, la led deux sur la pin six, euh, la fonction poussoir on, et bien, c'est quand on lit un zéro, il y a le point d'exclamation. Euh, quand on veut activer la led, et bien, on doit mettre low sur la led qui est sur la pin un. Une fois qu'on a défini ça, et bien, on peut oublier le câblage, et ne se préoccuper que de la fonctionnalité. Alors, première fonctionnalité, et bien, c'est ce qu'on avait déjà vu. On copie le poussoir un sur la led un, le poussoir deux sur la led deux, et là , avec un if, notre problème, si le poussoir un est à un, on allume la led, autrement, on l'éteint, et le programme, après, en if, continue, va s'occuper du poussoir deux, et ensuite, recommence. Vous avez une réaction immédiate du processeur, aux actions d'entrées On peut s'amuser à compliquer un tout petit peu la règle du jeu, en disant, mais la led un, j'aimerais qu'elle s'allume si le poussoir un est actif, ou si le poussoir deux est actif. Et là , on a fait un tout petit peu de logique, ça peut se convertir directement dans le symbole logique du Ou, et on peut également, euh, faire une table de vérité, et puis, euh, voir, euh, les différents cas exprimés avec des uns, des zéros. Alors, ici, on a la fonction Ou, et puis là , de l'autre côté, et bien on va changer un petit peu la règle, et on va dire la led deux, elle s'allume quand on agit sur le poussoir deux. Mais elle ne doit pas s'allumer si on ajoute, en même temps, sur le poussoir un. Donc, là , c'est une condition ET. Pour que la led deux soit allumée, il faut que le poussoir deux soit actif, et il faut que le poussoir un ne soit pas actif. Ce petit rond d'inversion, euh, remplace le, l'inverseur qu'on avait eu, dessiné. Donc maintenant, comment programmer ça? Alors, au niveau du C, vous avez le OU logique qui est une barre verticale, et on verra que comme pour le signe égal, la simple barre verticale agit sur des Mo binaires, et la double barre verticale agit sur des conditions, condition de poussoir un on, condition de poussoir deux on. Si l'une de ces deux conditions est réalisée, on allume la led un; autrement, on l'éteint. Et puis, dans le cas du ET logique, et bien on a le symbole du ET qui est facile à reconnaître. Si le poussoir deux est actif, et que on n'agit pas avec le poussoir un, et bien, on va allumer la led. Donc, pour tester ces programmes, on utilise des définitions qui ont été, euh, listées au lien précédent. Avec toujours le même schéma, mais on a un seul poussoir et puis une seule led, on se dit, tiens, mais ça peut être amusant de clignoter un nombre de fois, en fonction de la durée d'un poussoir. Hein, vous pressez rapidement, ça clignote une fois. Vous pressez très longuement, ça va clignoter plusieurs fois. Comment est-ce qu'on peut programmer ça? Et bien, on va dire, tant que je presse sur le bouton, je vais incrémenter un compteur, augmenter, euh, toutes les 20 millisecondes, par exemple. En fait, on a les petits escaliers, ici. Et puis, une fois qu'on a relâché, et bien, on va décompter, mais on peut décompter, dans le fond, on veut pas décompter autant de fois qu'ici, ça ferait trop de clignotements. Donc, on va faire des paliers. Là , on a incrémenté de un. Maintenant, on va décrémenter, par exemple, de 25. Donc, au niveau du programme, il faut définir une variable cTime qui est le compteur de temps du poussoir. Dans la boucle, et bien, on va commencer par mettre le compteur à zéro. Et puis ensuite, on dira, et bien, tant que le poussoir est à un, on va augmenter le temps toutes les 20 millisecondes. Et là , ça doit être un while, aussi longtemps, on va rester dans cette partie du programme. Si on l'avait mis en if, et bien, on aurait tout de suite été, regarder ce qu'il fallait faire plus loin, et, euh, vous auriez eu un clignotement, euh, à chaque pression, et un seul. Verifiez. Alors, une fois qu'on relâche le bouton, et bien, le while, euh, va nous faire sortir, dans le fond, de cette boucle. Et puis, on va dire, et bien, tant que le compteur de temps cTime est supérieur à zéro, on fait un clignotement, on diminue de 25, et on reste dans cette boucle, à faire des impulsions jusqu'à ce que ça soit en négatif. Voilà . Et puis, ensuite, et bien, on va recommencer à attendre sur le poussoir et refaire le petit jeu. Donc là , vous voyez bien la différence entre un while qui attend la fin d'un événement, et le if qui teste une chose et continue plus loin. Alors, on parlera beaucoup de pwm, euh, pour faire des impulsions de longueurs variables, et changer la vitesse d'un moteur, ou changer l'intensité d'une led. Bon, on a, on a une led, ici, euh, en sortie de notre circuit qui a été déclaré led un on. Et bien, on va l'allumer un certain temps, l'éteindre un certain temps. En répétant toutes les 20 millisecondes, et bien, la persistance rétinienne intégrera cette intensité lumineuse, et on verra, euh, si on définit une valeur deux. Et bien, on aura deux-vingtième d'intensité, 10% d'intensité sur la led. Donc, on définit une durée, led un on, un délai, la durée, led un on ET. Et puis, après, ensuite on éteint, et attend la durée complémentaire à 20, puisqu'on a une tranche, ici, de 20 millisecondes. Alors, il y a un petit problème auquel il faut faire attention, c'est que le delay duréeOn, si vous mettez une durée de zéro, vous n'aurez pas du tout une durée de zéro, mais une durée de 65 secondes, à cause du décomptage qui se fait, et si on décompte de zéro, et bien, on a la valeur maximum. De même, la valeur 20 doit être exclue puisque ça correspondrait, de ce côté, à une attente de zéro. On peut naturellement, maintenant, perfectionner le programme, et dire, et bien, si c'est zéro, je ne passe pas par ces instructions, j'active le on. Si c'est 20, je ne passe pas par ces instructions, j'active en permanence le on. Et maintenant, si vous voulez vraiment pouvoir éteindre totalement et allumer sans perte d'intensité, il vous faut, décoder, ici, au début du programme. Si la durée est à zéro, alors, il faut ne pas passer par ces instructions, et uniquement éteindre. Si c'est 20, il ne faut pas passer ces instructions et uniquement allumer, et ça coûte, euh, plusieurs instructions que vous avez peut-être encore de la peine à bien écrire, mais essayez. Ce qu'on va plutôt faire, c'est de varier cette intensité pour avoir une led qui s'allume de plus en plus longtemps. Et là , on peut dire, et bien c'est facile, il suffit de, euh, j'avais le temps, euh, deux, ici. Je peux mettre la valeur trois dans la proche, pro, prochaine boucle. Mais, ça veut dire que, 20 fois 20 millisecondes, zéro quatre secondes, on aura passé de l'intentité minimum à maximum. Donc, pour ralentir cette évolution, il nous faut répéter plusieurs fois la même configuration de, d'impulsions, et pour cela, et bien, on va, en plus de la durée qui va varier, maintenant, et qui va commencer à un. On va introduire un nombre de répétitions qui sera un compteur, et on va définir un nombre maximum de ces répétitions, et si on prend par exemple la valeur 10, ça veut dire que l'on va, maintenant, euh, répéter 10 fois chaque impulsion. Donc, ça va durer zéro deux secondes, et toutes les zéro deux secondes, on va modifier la valeur et le cycle va prendre dans les trois, quatre secondes. Donc, au niveau de la boucle, on part avec un nombre de répétitions qui vaut zéro, on vérifie si ce nombre est inférieur au maximum. Si oui, on active et désactive la led, et on incrémente le compteur de répétitions pour sortir de cette boucle quand la condition, ici, ne sera plus satisfaite. Quand on sort de cette boucle, on modifie la durée, puisqu'on veut augmenter l'intensité, et si la durée on est égale à 20, hein, on était à 19, c'était accepté. Mais quand, ici, on a rajouté un, et bien, ça n'est plus acceptable, c'est pour ça que j'ai préféré écrire 19 plus un. On remet l'état un. Quand on a ces derniers cycles à 19, Que l'on a anticipé une évolution qui n'a pas eu lieu et bien on remet le compteur à 1. Donc voila quelques exemples. Si maintenant on s'intéresse à incrémenter, augmenter de 1 un compteur BCD. La repésentation en BCD, et bien c'est chaque fois, comme on a vu, 4 bits et on ne doit pas utiliser toutes les combinaisons possibles de ce mot binaire. Donc je pars d'un exemple qui est 399, j'aimerais ajouter 1, et bien en binaire je dois ajouter 1. 1 plus 1 ça fait 0. Il y a un report. 1 plus 0 ça fait 1. Il n'y a pas de report. 0 plus 0, c'est copié. 1. Et voilà , le résultat ben c'est en fait le chiffre hexadécimal A. Alors qu'on voudrait avoir des 0 ici et puis un report pour le bit suivant. Alors cette différence elle est de 6. Donc au niveau de l'algorithme et bien on va dire si le résultat dépassait 9, on ajoute 6, ce qui amène le résultat à la valeur 0 et incrémente l'étage suivant. Donc ce raisonnement peut se continuer, et au niveau de la programmation, puisque c’est ça qui nous intéresse, il nous faut définir un nombre de 16 bits, que l’on va appeler bcd. C’est important de remarquer que quand vous avez ici 8,000 ou 9,000 et bien vous avez le premier bit qui est le bit de signe, qui pourrait faire croire à certaines parties du programme que l’on manipule un nombre négatif. Donc il faut bien définir unsigned int bcd. Et maintenant on incrémente bcd en binaire. Donc, on va trouver dans ce cas-là , A, heu 9. Et puis on dit ben si le résultat est supérieur à 9, on ajoute 6, ce qui veux dire que le résultat va devenir 0 A. Et la ligne suivante, et bien on dit si c’est supérieur à 90, ce qui est le cas ici, et bien on ajoute 60. Le résultat va devenir 0 0 4 puisqu’on a ajouté 1. Et on va passer à travers les deux instructions suivantes sans rien faire puisque ce n’est pas supérieur à 900 ni supérieur à 9,000. Alors quand c’est supérieur à 9,000, il y a en fait un débordement, qui ne sera pas signalé (par) le programme. Vous allez obtenir la valeur 0. Donc si vous voulez signaler le débordement, il vous faudra rajouter des instructions supplémentaires, activer une variable qui dit ça a débordé. Pour faire un décompteur BCD, c’est extrêmement proche et même plus simple. Vous devez soustraire 1. Donc 0 moins 1 ça fait 1 et il y a un emprunt. 0 moins l’emprunt ça fait 1 moins l’emprunt, ça fait 1. Donc on trouve la valeur F alors qu’on devrait avoir la valeur 9. Et puis il n’y a pas d’emprunt qui a été propagé donc la règle est très simple c’est de dire ben si on a 9, on met F et il suffit de regarder, comme on l’a fait avant, un digit après l’autre avec des masques pour avoir le résultat. Voilà en plus propre ce que je viens d’expliquer. On pourrait soustraire 6 ou bien comme on vient de l’expliquer simplement forcer un 9. On a souvent l’implication où une variable doit rester en fait dans un certain intervalle Alors si cette variable x est plus grande que a et bien on ramène la valeur à a Si elle est plus petite que b, on ramène la valeur à b Et cela nous coûte 2 instructions enfin 4 instructions, heu 5 hm Et cela nous coûte 2 instructions. Arduino vous offre cette fonction qui est constrain avec 3 paramètres : x, l’entrée, le maximum et le minimum. Adruino vous offre cette fonction si vous ne voulez pas réfléchir. Constrain if x doit rester dans l’intervalle entre a et b et le résultat donc sera confiné, constrain, dans cet intervalle On peut aussi s’intéresser à définir un maximum et un minimum. Vous avez une variable, est-ce qu’elle est plus grande que a, plus petite que b? Donc c’est aussi une, des fonctions qu’Arduino vous offre mais qui ne sont pas vraiment essentielles. Minimum de a, b. Maximum de a, b. Un cas plus intéressant c’est une conversion dans le fond d’échelle. On verra dans les convertisseurs analogiques numériques que vous obtenez à partir d’une tension sur une entrée du microcontrôleur, une valeur entre 0 et 1023. Souvent cela nous arrangerait d’avoir seulement cette valeur entre 0 et 255. Donc là il suffit de la diviser par 4, ce qui revient, vous avez une valeur qui en fait est 10 bits. Ce qu’on voudrait c’est ne garder que 8 bits et on va garder naturellement les bits de poids forts et on va couper les 8 derniers bits ce qui se fait, en fait, dans la pratique, en décalant de 2 et, on en reparlera plus tard, il y a le signe supérieur, supérieur, 2 pour dire qu’on décale le mot de 2 positions. Donc il y en avait 10 avant, on a éjecté des zéros, il n’y a pas plus que 8 positions successives. C’est un peu plus compliqué si maintenant on va vous, vous voudriez que le 1023 corresponde à la valeur de somme. Alors, au lieu de diviser 256 par 1023, qui était le x sur 4, il nous faut maintenant diviser 200 par 1024 et puis multiplier par x. Alors là il faut quand même faire attention parce 200 sur 1024 ça fait 0. Le microcontrôleur travaille avec des nombres entiers et il va vous signaler que ça fait 0 et qu’il y a peut-être un reste à cette division que vous pouvez récupérer d’une certaine façon mais ce produit vous donnera toujours 0. Donc ce qui faut écrire ben c’est x fois 200, en se méfiant que cela pourrait devenir trop grand par rapport à la taille mémoire que l’on a réservé et on divise par 1024. Diviser par 1024, comme on vient de le dire, ça peut être des décalages. C’est une puissance de 2, donc si on décale 10 fois et bien vous aurez votre résultat. On peut encore s’amuser à dire mais 200 multiplié par 200 c’est multiplier par 128, par 64, par 8 et ajouter le tout. Ces multiplications par 128, 64 et 8, c’est le décalage dans l’autre sens. Donc la valeur y on l’obtient avec des instructions qui ne sont pas des divisions ou des multiplications qui prennent beaucoup de temps au processeur mais de simples décalages dans un sens et puis ensuite le résultat est décalé dans l’autre sens. Et maintenant si on réfléchissait encore, on pourrait dire mais on pourrait enlever 3 décalages ici et puis compenser en les enlevant ici aussi. Ce sont des petits trucs qui accélèrent encore l’exécution. Bien regardons un autre exemple. Vous avez un thermomètre médical qui travaille entre 32 et 35 degrés. Et le capteur donne des valeurs entre 240 et 680. Alors le programme est un peu plus long puisqu’il faut commencer par définir des coordonnées, ici en soustrayant ces valeurs et ensuite appliquer la multiplication et division que l’on vient de voir. Là heureusement, Arduino nous fournit une fonction qui s’appelle map, qui est très bien documentée puisqu’on dit ben c’est map d’une valeur, la valeur x, fromLow, fromHigh. Donc on avait une échelle qu’ils appellent from puisqu’on veut convertir cette valeur x en y. Donc fromLow fromHigh, toLow, toHigh et vous obtenez la valeur y en appelant cette fonction. Donc dans le cas particulier, ben voilà les valeurs numériques qui correspondent à mon dessin. Donc tant mieux quand on trouve des fonctions qui font exactement ce que l’on veut pour autant qu’elles existent dans l’environnement que l’on utilise. Ça c’est pas du C, c’est les facilités d’Arduino qui existent peut-être aussi dans d’autres compilateurs. Avec ces quelques exemples, on a clairement vu la différence entre le if et le while, entre le binaire et le décimal. On a appris que les calculs se faisaient en nombre entiers uniquement. Et puis avec des comparaisons, on peut vérifier des valeurs, transformer linéairement des variables et on verra naturellement d’autres solutions dans le futur.