analogWrite()
Dans la page précédente, nous avons fait du PWM de façon soft (par logiciel), prétextant que sur l'Arduino, la led LED_BUILTIN était sur une broche qui n'admet pas le PWM hard (fait avec des fonctions câblées dans le microcontrôleur). Mais je voulais montrer dans la page précédente quel mécanisme permet de faire varier la luminosité d'une led.
Les broches PWM
Certaines broches peuvent être des "sorties analogiques". Elles sont repérées par le symbole ~ . Ce sont des broches permettant de faire du PWM beaucoup plus facilement. Pour la Uno ou la Nano, ce sont les broches 3, 5, 6, 9, 10 et 11. Et malheureusement la led LED_BUILTIN se trouve sur la sortie 13. On ne peut pas directement utiliser le PWM hard. Avec une Mega, c'était possible car la led LED_BUILTIN se trouve toujours sur la sortie 13, mais les broches qui permettent le PWM hard sont les broches 2 à 13, 38 à 40 ainsi que la 20.
On va maintenant utiliser la sortie 11 qui est une sortie acceptant le PWM. Mais je voudrais utiliser la led LED_BUILTIN car elle est sur la carte (pas besoin d'acheter du matériel pour cette partie) et elle est reliée à la sortie 13.
Le schéma
Il va falloir faire un câblage, car on va utiliser 2 pins différentes. Et un des moyen de dire ce qu'il faut faire est un schéma de câblage. C'est un dessin normalisé (mais on ne respectera que les grandes lignes), qui est là pour donner les liaisons entre les circuits. Un bon schéma permet rapidement à celui qui a l'habitude, de comprendre rapidement comment cela fonctionne. Voici notre premier schéma:
Si on représente les alimentations, les fils sont dessinés en haut, sauf la masse qui est en bas. Mais si ce n'est pas utile, on ne met pas les alimentations. Pour l'instant on est alimenté par la prise USB, dessiner l'alimentation n'est pas utile.
On a aussi l'habitude de représenter les entrées à gauche et les sorties à droite. Les informations se déplacent globalement de la gauche vers la droite. C'est plus facile à lire si tout le monde a cette convention.
Pour aujourd'hui, on aura les broches 11 et 13 reliées ensembles, la 11 étant une sortie et la 13 une entrée.
Une petite règle: on ne doit pas relier deux sorties ensembles sauf cas exceptionnels. Si on le fait, et que l'une des sortie veut un état bas (0V) et l'autre un état haut (5V), il n'est évidemment pas possible que les deux soient satisfaits. Avoir un état haut, c'est comme si on reliait la sortie au 5V, et avoir un état bas, c'est comme si on reliait la sortie à la masse. Relier les deux sorties ensembles, c'est relier le 0V et le 5V. C'est un court-circuit. Dans la pratique, le courant devrait être limité à 100mA par les résistances internes du microcontrôleur, ce qui n'est pas forcément bon pour lui.
Attention aussi, il existe de beaux logiciels qui font un joli dessin, mais cela est plus une photo qu'un schéma. Évitez donc fritzing et tinkercad pour les schémas. Pensez que ceux qui vous dépanneront auront du mal à lire ces jolis esquisses.
Câblage
Attention: comme deux broches sont reliées ensembles, il ne faut pas qu'elles soient toutes les deux en mode sortie. Ce pourrait être le cas si la carte avait été utilisée pour un autre programme (ce n'est pas le cas avec les leçons précédentes). En cas de doute, on fait fonctionner le programme sans le fil, puis on branche le fil entre 11 et 13.
Pour réaliser le câblage, il vous faut un bout de fil. Si vous avez un fil Dupont, profitez en, sinon prenez n'importe quel fil qui rentre dans le connecteur noir repéré 11 et 13. Si vous n'avez pas de fil électrique prenez une agrafe, un trombone.
Le principe
Pour utiliser le PWM hardware, on a besoin d'une sortie ... PWM! Et comme la broche 13 n'est pas une sortie PWM avec la Uno, nous allons prendre celle qui est la plus proche, la 11. Nous n'allons pas utiliser la sortie 13, mais nous profiterons de la led. C'est la 11 qui va délivrer le signal pour la led LED_BUILTIN qui est câblée. Pour ne pas être gênée par la broche 13 du microcontrôleur, on va la mettre en entrée, ou alors, on compte sur l'initialisation de la carte qui met automatiquement les broches en entrées. Finalement, avec le fil c'est comme si la led était sur la broche 11. Si vous avez une Mega, remplacez les 11 par des 13 et ne mettez pas le fil.
analogWrite()
Cette instruction permet de mettre la broche en sortie et de générer un signal PWM:
analogWrite(11, rapportCyclique);
permet d'avoir du PWM sur la broche 11. La valeur du rapport cyclique est réglé par rapportCyclique, et peut varier de 0% (rapportCyclique=0) à 100% (rapportCyclique=255). La fréquence est de 490Hz ou 980Hz suivant les broches (vous irez voir la référence si besoin), ce qui permet de ne pas avoir de scintillement.
Normalement quand une broche est utilisée en sortie, il faut utiliser pinMode() sinon elle est en entrée. Avec analogWrite() c'est inutile, cette instruction se charge elle même de le faire. Aujourd'hui, on n'utilisera pas pinMode(), mais dans quelques temps vous aurez oublié ce cas très particulier, et vous écrirez un pinMode(11, OUTPUT); qui ne sert à rien. Ce n'est pas grave du tout, c'est un pléonasme, cela fonctionne aussi (consommation de code et augmentation du temps, mais souvent insignifiante).
Pour faire un programme qui ne fait qu'allumer faiblement la led, il suffit de ne mettre que
analogWrite(11, 10); // Éclairage à 4% fixe
dans le setup. Comme alors on n'a rien à mettre dans loop(), elle restera vide. Aide?void setup() { analogWrite(11, 10); // Éclairage à 4% fixe } void loop() { }
Rampe lumineuse
J'entends par là que la lumière de la led part de l'extinction, monte progressivement, atteint son maximum, et que cela recommence sans arrêt.
Pour faire cette rampe ici, nous allons utiliser analogWrite() pour faire un éclairement donné, attendre un peu (grâce à delay()), augmenter le rapport cyclique, le tout en boucle. Pour faire la boucle, loop() peut nous convenir.
Nous avons trois choses à faire cycliquement, mais notez que l'ordre importe peu.
Le rapport cyclique variera de 0% à 100% avec 256 valeurs (0 à 255 admises par la fonction). Si on veut que la rampe dure 2s, il faut que chaque valeur de rapport cyclique dure 2s/256 soit environ 8ms. On mettra donc une attente de 8ms.
loop() va donc contenir:
{ analogWrite(11, rapportCyclique); // Choix de l'éclairement de la led delay(8); // Rampe de 2s sur 256 valeurs rapportCyclique++; // Éclairement suivant }
et le setup() ne contiendra rien. N'oubliez pas de déclarer rapportCyclique comme byte (il va varier naturellement entre 0 et 255).
Quand rapportCyclique atteindra 255, l'éclairement sera maximum. L’incrémentation ne peut pas lui donner la valeur 256 (c'est un byte), la valeur suivante sera de 0 (extinction). Si vous aviez mis un int à la place d'un byte cela ne se verrait pas car l'appel de analogWrite() n'aurait gardé que les 8 bit de poids faible. On aurait juste stocké deux octets au lieu d'un, dont un qui ne servirait strictement à rien.
On peut regrouper la première ligne et la dernière en une seule, en faisant:
{ analogWrite(11,rapportCyclique++); // Pour la led delay(8); // Rampe de 2s sur 256 valeurs }
Faites donc ce programme! Aide?byte rapportCyclique; // De 0 à 255! void setup() { } void loop() { analogWrite(11, rapportCyclique++); // Choix de l'éclairement de la led delay(8); // Rampe de 2s sur 256 valeurs }