top of page
ARDUBLOCKLY.png

Le plus simple :
faire clignoter une LED

Nombre de visites :
316
CLIGNOTEMENT LED

 

Tout d'abord, qu'est-ce qu'un programme ?

(Question à l'usage des enfants de 9 à 11 ans... et de 98% des adultes).


 

Si vous posez cette question : «– Quelle est la succession d'actes élémentaires nécessaires pour faire clignoter une LED ? »

... vous aurez presque immanquablement la réponse suivante : «on allume, puis on éteint».

Cela semble simple et évident.

Cependant une réponse sérieuse aurait été :

  • on allume ;

  • on attend ;

  • on éteint ;

  • on attend ;

  • on recommence indéfiniment (ou presque).

 

Ceci est la suite des opérations élémentaires.

... mais ce n'est pas encore la liste complète des opérations à effectuer pour obtenir un vrai programme.



 

Alors finalement, que faut-il pour faire clignoter cette LED ?

Il faut décrire en détails la décomposition du problème en ses actions élémentaires :

  • dire sur quelle sortie de la carte ARDUINO est connectée la LED ;

  • activer cette sortie ;

  • attendre un certain temps ;

  • désactiver la sortie ;

  • attendre de nouveau ;

  • ... et inclure tout cela dans une boucle de répétition infinie.

 


 

... et en « ARDUBLOCKLY »​ ?

Dans ARDUBLOCKLY, chaque fonction est matérialisée par un bloc.

Une fonction peut réaliser plusieurs actions élémentaires.

Les blocs de fonctions s'assemblent comme des LEGO.

Il va donc être très facile de constituer le programme par un assemblage de blocs de fonctions.

 


 

Sur l'image ci-dessous, on peut voir les 4 blocs de fonction nécessaires au clignotement,
juste déposés mais non assemblés.

BLINK-PRINCIPE-2.png
 
Le bloc «set digital pin #» se trouve dans le menu «Input/Output» ;
Le bloc «wait» se trouve dans le menu «Time» ;

Ci-dessous, ces mêmes blocs sont assemblés et enchâssés dans la boucle de répétition infinie «Arduino loop forever».
(Côté blocs, les commentaires ont été masqués, mais on les voit toujours dans la fenêtre du code source ARDUINO, à droite).
BLINK-PRINCIPE-3.png
 
Le code source ARDUINO (fenêtre de droite) est écrit en langage C++.
Finalement ce sera une manière sympa d'apprendre les bases du langage C++, sans trop de douleur !

Remarque :

Pour obtenir un clignotement plus ou moins rapide, il suffit de changer les valeurs des temporisations dans les 2 blocs 

Avec 500 / 500 on aura un clignotement plus rapide.

Avec 500 / 1000 on aura un clignotement dissymétrique.

Bloc-WAIT-1000.png
 
Schéma de branchement en utilisant un breadboard (plaque d'essai)
ARDUBLOCKLY_num-103_(2020-02-28_18-22).p
La résistance en série avec la LED est indispensable.
On choisira une valeur entre 220 Ω et 3,3 kΩ.
 
 
Transférer le code C++ depuis ARDUBLOCKLY dans L'IDE ARDUINO
Sur l'image ci-dessus on voit une petite icône  en haut à droite de la fenêtre des blocs.
Icone-ARD-1.png

Un «clic» sur cette icône ouvre l'IDE de l'ARDUINO  c'est à dire l'environnement de programmation ARDUINO «en lignes de code» et affiche le texte du programme en langage C++.

C'est à partir de cet IDE que le programme sera compilé puis téléversé dans la carte ARDUINO.

Il semble que dans certains cas cette icône jaune refuse de fonctionner.
Il suffit alors de transférer le code du programme par copier/coller, depuis ARDUBLOCKLY vers L'IDE ARDUINO.

La petite video ci-dessous montre cette manip finalement très simple :


Flash periodique

Flash périodique

 
 
 
Qu'y a-t-il de différent avec le précédent programme de clignotement d'une LED ?
Peu de choses :
  • on allume la LED ;
  • on attend très peu de temps ;
  • on éteint ;
  • on attend longtemps ;
  • on recommence indéfiniment.
FLASH-1.png
 
L'assemblage de blocs est le même que dans l'article précédent.

Seules les valeurs de temps d'allumage et d'extinction ont été modifiées.

void setup() {

  pinMode(3, OUTPUT);

}

 

void loop() {

  // Déclarer que la LED est branchée sur la sortie n°3...

  // ... et allumer la LED (sortie=état "HAUT")

  digitalWrite(3, HIGH);

  // La LED reste allumée pendant 20 millisecondes.

  delay(20);

  // Eteindre la LED (sortie3 = état "BAS")

  digitalWrite(3, LOW);

  // LED éteinte pendant 3 secondes.

  delay(3000);

 

}

Intensité atténuée

Intensité atténuée

 
 
Le programme de base est le même que celui du clignotant.
Pensez à régler la définition de la video sur « 720 p » pour une meilleure définition de l'image.
 
AMUSEZ-VOUS !
PWM intensité variable

PWM et intensité variable

CLIGNOTANT AVEC EXTINCTIONS ET ALLUMAGES PROGRESSIFS
(Construction du programme pas à pas)
 
 
Dans le programme précédent «03-INTENSITÉ ATTÉNUÉE» le fonctionnement de la LED avec une intensité atténuée nécessitait 4 blocs.
Or il existe une fonction qui fait la même chose de façon plus élégante, avec un seul bloc : 
BLOC-PWM-0.png
 
 
Associée à une valeur numérique comprise entre 0 et 254, elle fournit sur la sortie PWM choisie un rapport cyclique compris entre 0 et 100% !
BLOC-PWM-1.png
 
 
Ici, avec la valeur numérique «100», on obtiendra un rapport cyclique de 100/254 ≈ 39% ⇒ la LED s'éclairera avec 39% de l'intensité maximale.
Si à la place de cette valeur numérique fixe on utilise une valeur variable, on peut faire varier par programme la valeur de l'éclairement de la LED.
 
Pour faire varier automatiquement le fameux rapport cyclique depuis 0 jusqu'à 254 (par exemple) on va utiliser une boucle de comptage.
 
Mise en place de la boucle de comptage
 
Le microcontrôleur de l'ARDUINO est très rapide et dans ces conditions les boucles
«count with...do... by...» sont parcourues tellement vite qu'on n'a pas le temps de voir une quelconque progression du niveau de luminosité.
Il faut donc accorder du temps à chaque palier d'intensité en insérant une temporisation à l'intérieur de chacune des deux boucles de comptage.
C'est le rôle du bloc «wait» en ARDUBLOCKLY («delay» en langage C++ ).
Décodage du fonctionnement :
  • à chaque tour de la boucle de comptage, la fonction «set analog pin # 3» augmente la luminosité de la LED d'un cran de durée 5 millisecondes, pour partir d'un état «éteint» à un état «allumé au maximum» ;
  • quand le compteur « luminosite » ou «INTENSITE» – suivant notre choix de nom de variable – atteint la valeur «254», le programme sort de la boucle «count with... do... by...» ;
  • ... et la boucle reprend le comptage à partir du début.
Calcul de la durée du cycle de croissance de la luminosité :
nbr de paliers x durée de la temporisation
Pour 254 paliers de 20 millisecondes le cycle dure 5,08 secondes
Si on utilise une temporisation « wait » de 5 millisecondes, le cycle dure 1,27 secondes.
bravo.gif
​Ça y est, le programme
est complet !
informatik.gif
Que nenni !
 
 
Bien entendu, ceci ne suffit pas à obtenir le résultat recherché, à savoir un allumage progressif suivi d'une extinction progressive.
Que manque-t-il ?
La partie «extinction progressive» de la LED.
Duplication de la boucle de comptage
La deuxième boucle fait varier la valeur du compteur, donc de la variable «INTENSITE», de la valeur 254 (éclairé à fond) à la valeur 1 (éteint).
 
Premières variables
Un tel programme est opérationnel.
Cependant, quand on modifie les valeurs mini et maxi dans LES boucles de comptage, il faut faire attention que les deux maxima soient identiques et les deux minima aussi.
C'est ce que montre la video ci-dessus.
La video montre aussi la mise en place des deux variables qui vont résoudre ce problème avec élégance.
Grâce à ces deux variables on est sûr que lorsqu'on modifie dans le setup (Arduino run first) l'une ou l'autre des valeurs de luminosité, cette valeur sera prise en compte sans erreur dans les deux boucles de comptage, càd dans la totalité du programme.
Note :
Peu importe les noms qu'on attribue aux variables, du moment qu'ils sont explicites.
Une variable est un récipient qui contient une valeur, comme une bouteille contient de l'eau en quantité variable.
bravo.gif
​Ça y est, c'est fini maintenant ?
informatik.gif
​Quelle impatience !
Tant qu'on y est, on ajoute deux autres temporisations...
 
juste après chaque boucle «count with...do... by...» :
  • la première fixe la durée pendant laquelle la LED reste allumée à pleine intensité ;
  • la deuxième fixe la durée pendant laquelle la LED reste éteinte
... et aussi deux variables de plus...
 
 
 
Voici à quoi ressemble le programme une fois terminé.
Note :
Sur la copie d'écran ci-dessous, les noms des variables sont différents de ceux visibles dans les videos.
Ils sont un peu plus explicites, mais nous l'avons dit : peu importe le nom des variables, du moment que ce nom nous parle.
LED-PWM-1b.png
 
 
Je vous rassure : un tel programme, une fois compilé et téléversé, ne prend pas plus de place mémoire dans L'ARDUINO que la version sans les 6 variables supplémentaires.
Il n'y a qu'à l'écran, dans la présentation blocs ou C++, qu'il est plus... encombrant.
 
Il suffit maintenant, dans le setup du programme, de jouer avec les différentes valeurs des variables pour obtenir des effets variés d'éclairages de la LED.
Il est d'ailleurs plus rapide de modifier les valeurs directement dans le code C++ depuis L'IDE ARDUINO puisque de toutes façons c'est depuis L'IDE que le programme sera téléversé dans la carte ARDUINO.
 
informatik.gif
 
... et puis va bien falloir vous y mettre, à la ligne de code,
non mais sans blague !
 
 
QUELQUES EXEMPLES EXTRÊMES...
Si on règle la durée des 2 paliers à «0», on obtient un clignotant comme celui de l'article «01-DEBUTER EN DOUCEUR», sans progressivité.
Avec le réglage ci-dessus, on obtient un flash dont la période est 1,6 secondes et avec allumage et extinctions progressifs rapides.
Avec INTENSITE_MINI = 50, la LED ne s'éteint pas complètement.
LED-PWM-2r.png
LED-PWM-2s.png
LED-PWM-2t.png
 
 
Le programme élaboré dans cet article possède donc une sorte d'universalité puisqu'il permet
d'obtenir toute une gamme d'effets en modifiant quelques paramètres.
On pourra utiliser ce programme pour :
  • clignoteur simple, plus ou moins rapide ;
  • feux de P.N. avec simulation de l'inertie thermique du filament des lampes ;
  • flash périodique ;
  • simple fluctuation d'intensité d'une LED pour un éclairage intérieur d'un bâtiment ;
Ça, c'est de la programmation intelligente et organisée :
  • pas besoin de chercher partout dans le programme les bons endroits pour modifier telle valeur de temporisation ou telle valeur de seuil d'intensité... ;
  • ⇒ toutes les variables sont déclarées dans un endroit unique, en tête du programme ;
  • ⇒ le nom des variables est explicite et facilite la compréhension du fonctionnement du programme.
Servo-moteur 1
 
 
PETIT TOPO SUR LES NOMS DE VARIABLES
ou
«Autant prendre tout de suite des bonnes habitudes»
 
Il est indispensable que les noms de variables que l'on créé soient explicites.
Un nom comme «INTENSITE» ne pose aucun problème.
 
Par contre, si on désire créer une variable pour la durée du palier d'allumage, il faut respecter quelques règles.
 
Le nom de la variable peut contenir :
  • des minuscules ;
  • des majuscules ;
  • des chiffres ;
  • le signe «_» (qui est la minuscule du «8» sur la plupart des claviers).
... mais PAS D'ESPACES.
 
Disons que l'on va se contenter de cela.
 
Sont interdits :
  • les signes «-», «+», «*», «/», «^», «=» qui seraient interprétés comme des opérateurs mathématiques ;
  • les signes «&», «|»,  «!» qui sont des opérateurs booléens ou compound ;
  • les signes «>», «<», «==», «%» qui seraient interprétés comme des opérateurs logiques ;
  • les caractères «{», «}», le point-virgule, «#», les parenthèses ( et ), qui sont utilisés pour structurer le code C++ ;
  • le signe «/» marque aussi les lignes de commentaires, en association avec «*» ou doublé «//» ;
  • le signe «\» qui est utilisé par le système ;
  • les lettres accentuées, qu'elles soient minuscules ou majuscules ;
  • les guillemets «, », ou " ;
  • l'apostrophe «'», les espaces ;
 
Donc, faisons simple : dans le cas de la variable durée du palier d'allumage, on aura droit à ;
  • dureedupalierdallumage ;
  • DureeDuPalierDallumage  (c'est mieux) ;
  • DUREEDUPALIERDALLUMAGE (... pas très facile à lire) ;
  • DUREEduPALIERdALLUMAGE (pourquoi pas) ;
 
... ou encore :
  • duree_du_palier_d_allumage ;
 
et ses variantes :
  • DUREE_PALIER_ALLUMAGE ;
  • Duree_Palier_Allumage ;
  • ...
 
... beaucoup plus faciles à lire.
L'utilisation du signe «_» comme séparateur de mots à la place de l'espace, est une convention universellement utilisée dans le monde de la programmation, quel que soit le langage.
 
En effet, «_» est un caractère qui existe dans tous les alphabets informatiques – y compris anglo-saxon – et qui n'est jamais employé comme opérateur ou caractère structurant.
 
Les lettres accentuées ne sont pas présentes dans l'alphabet anglo-saxon, seule langue utilisée dans les langages de programmation.
 
C'est ce qui explique qu'elles peuvent poser des problèmes si on les utilise dans les noms de variables.
Amusement avec un
servo-moteur
 
 
POUR COMMENCER EN DOUCEUR :
un petit programme tout simple qui fait «gigoter» le servomoteur entre 2 angles choisis.
Préambule
De nombreux modèles de servomoteurs peuvent être utilisés avec ce programme, sauf les servos digitaux.
Ci-dessous, un modèle peu coûteux (moins de 3,00 € sur le net) et qui rend de grands services en modélisme grâce à sa petite taille :
SERVO-9G.jpg
 
 
Le brochage est normalisé, mais la couleur des fils varie d'un fabricant à l'autre.
  • le «+» est rouge. Toujours ;
  • le «-» est souvent noir, jamais bleu, mais l'image ci-dessous prouve qu'il y a des cas particuliers ;
  • le fil pour le «signal» est souvent jaune ou orange... mais pas toujours (bleu sur le connecteur de droite, mais c'est une exception).
SERVO-9G_Connexionx.jpg
 
 
Ce petit préambule n'est destiné qu'à vous éviter des déboires au moment des branchements.
 
BRANCHEMENT DU SERVOMOTEUR SUR LA CARTE ARDUINO
ARDUINO-SERVO_1.png
 
 
Le fil «signal» jaune sera connecté à la broche «~9» de la carte ARDUINO UNO.
Les broches marquées «~x» sont les seules qui ont la possibilité de générer un signal PWM.

 
POUR COMMANDER FACILEMENT LE SERVO...

 
Pas besoin d'écrire nous-même un programme (compliqué) qui génère les impulsions de commande du servo.
Un bloc tout prêt le fait à notre place. Il se trouve dans la rubrique «Motors» :
 
 
Voyons cela avec une toute petite video...
 
 
LE PROGRAMME
Pas plus compliqué que de faire clignoter une LED !
D'ailleurs, les deux programmes se ressemblent étrangement :
 
 
  • positionner le palonnier à 45° ;
  • attendre ;
  • positionner le palonnier à 135° ;
  • attendre ;
  • ... et recommencer.
Plus simple, ce n'est pas possible !
ARDUBLOCKLY-SERVO-3.png
 
 
Le CODE en C++
 
La fenêtre «Arduino Source Code» à droite ci-dessus retranscrit le code en langage C++.
On y retrouve les 4 lignes de code qui positionnent le servo à 45° puis à 135°, avec un temps d'attente après chaque mouvement.
Plus intéressant :
Le bloc 
a automatiquement mis en place :
  • #include <Servo.h> la librairie qui gère la commande des servos en nous facilitant le paramétrage de l'angle en «°» (entre autre) ;
  • Servo myServo9; qui déclare le servomoteur en lui donnant un nom, de façon à pouvoir disposer de fonctions spécifiques à ce servo, telle que la fonction «myServo9.write(45) ; »
Remarque : si on avait connecté et utilisé des servos sur les sorties PWM 3,5,6,9,10 et 11 la librairie «Servo.h» aurait créé 6 instances pour les 6 servos :
  • Servo myServo3 ;
  • Servo myServo5 ;
  • Servo myServo6 ;
  • Servo myServo9 ;
  • Servo myServo10 ;
  • Servo myServo11 ;
... chacune de ses instances donnant par exemple accès au fonctions «myServo3.write(xx)», «myServo5.write(xx)»,... , «myServo11.write(xx)», sans qu'il soit nécessaire de programmer nous-même ces fonctions.
Merci «Servo.h» ! 
Merci surtout à son créateur.

 
... et pour jouer un peu...
 
Oh, ce programme est si simple que les possibilités de paramétrages sont peu nombreuses :
  • la modification des 2 angles, en respectant la plage 0 - 180 °, modifie l'amplitude de déplacement ;
  • la modification des temporisations «wait...» changera la cadence du «gigotage».
Rien de bien extraordinaire.
Cependant, on a appris qu'un servo peut être positionné à un angle précis, et cela avec simplicité.
ARDUBLOCKLY-SERVO-2 (1).png
Servo et mouvement lent

Servo et mouvement lent

En modélisme ferroviaire (entre autre) les les projets d'animations qui nécessitent des mouvements lents ne manquent pas :
  • commandes réalistes d'aiguillages ;
  • ouverture / fermetures de portes de bâtiments industriels ;
  • chute d'arbre ;
  • mouvements d'une grue ;
  • commande de passage à niveau ;
  • pilotage d'une caméra de surveillance (dans une gare cachée par exemple) ;
  • ...
 
 
RACCORDEMENT DU SERVO A LA CARTE ARDUINO
Identique à celui du chapitre précédent
Servo et mouvement lent
ARDUINO-SERVO_1.png
 
 
PREMIÈRE VERSION
SERVO_LENT_0.png
 
 
Le débattement choisi est «1° à 175°» et retour.
La première boucle fait varier «ANGLE» de 1° à chaque tour de boucle, en partant de 1° pour atteindre 175°.
 
Pour obtenir un mouvement lent, on introduit une temporisation de 5 millisecondes avant de calculer la valeur d'angle suivante.
 
La deuxième boucle fonctionne de la même façon, mais de 175° vers 1°.
 
A droite, le code C++.
 
Note :
 
Le servo parcourt 176 pas dans chaque sens.
Chaque pas dure 5 ms.
 
⇒ le cycle «aller» dure 176 x 5 = 880ms, soit un peu moins d'une seconde. Le cycle de retour aussi.
Amusez-vous à modifier la valeur des deux temporisations et constatez les effets.
 
Si les deux temporisations sont différentes, les vitesses aller et retour seront différentes.
 
On peut aussi modifier la valeur du débattement.
 
 

 
DEUXIÈME PROGRAMME
Le défaut de ce premier programme est que, pour savoir où modifier les valeurs de débattement et de rapidité, il faut examiner tous les blocs et les comprendre.
 
La bonne idée consiste alors à créer des variables avec un libellé explicite, lesquelles qui seront déclarées en tête du code, blocs ou C++.
SERVO-LENT-1.png
SERVO-LENT-2.png
 
 
Cette fois, tous les paramètres sont regroupés au début.
Si par exemple on doit modifier «ANGLE_MINI» il suffit de le faire une seule fois dans l'instruction «set ANGLE_MINI to...», alors que la variable «ANGLE_MINI» est utilisée 2 fois.
Imaginez le bazar si le programme comporte plusieurs centaines de lignes (ne rigolez pas, cela arrive plus vite qu'on ne croit ! ) et qu'un même paramètre soit utilisé à dix endroits différents ⇒ comment être sûr de les corriger tous, sans en oublier, si on s'est contenté de les écrire sous forme de valeur chiffrée ?
confused-smiley.png
Ben ! J'avais pas pensé à ça !
Servomoteur et contact
Servomoteur et contact
  • le contact met l'entrée de commande à la masse
    (0 volts = état «LOW»)
    ⇒ le servo se déplace rapidement vers sa position angulaire maximale ;
  • le contact est relâché
    ⇒ le servo revient rapidement à sa position d'origine.
 
Juste une petite video de 2 minutes...
 
Servo, mouvement lent et switch
 
Pensez à mettre la video en « 720p » pour une meilleure netteté.
(il n'est pas nécessaire de la mettre en mode « plein écran » ).
 
Icone_Video_1.png
720p
Servo, mouvement lent et switch
  • le contact met l'entrée de commande à la masse (0 volts = état «LOW») ⇒ le servo se déplace lentement vers sa position angulaire maximale ;
  • le contact est relâché ⇒ le servo revient lentement à sa position d'origine.
On veut pouvoir paramétrer :
  • la vitesse de déplacement «aller» ;
  • la vitesse de déplacement «retour» ;
  • les consignes d'angle mini et maxi du servo.
RACCORDEMENT DU SERVO ET DU CONTACT
ARDUBLOCKLY_num-591_(2020-06-03_15-16).p
ARDUBLOCKLY_num-592_(2020-06-03_15-18).p
 
À gauche : le switch est relâché ⇒ le servo est en position initiale.
À droite, le switch est actionné ⇒ le servo est en position finale.
 
La broche «commande» du servo est connectée à la broche «~3».
Le contact est raccordé entre «Gnd» et la broche «5».
La résistance PULL UP est raccordée entre « +5V » et la broche «5».
 
Petite video de 11 minutes.
 
 
Pour finir, une petite simulation du résultat :
 
Fache.png

OUPS !
Le programme ARDUBLOCKLY tel qu'il est visible à partir de la minute 9:30 de la video comporte une erreur stupide : le test de la 2e boucle «repeat while» (celle tout en bas) doit se terminer par «HIGH», bien évidemment !
Mea culpa.

 
Commande d'aiguillage
SERVO 2 CONTACTS-6.png
1 SERVO + 2 CONTACTS
+ MÉMOIRE DE POSITION
Ce programme est destiné à piloter un servomoteur pour actionner un aiguillage .
Les mouvements du servo sont déclenchés grâce à 2 contacts fugitifs ;

PETIT CAHIER DES CHARGES
 
Le but est de piloter un servomoteur pour commander un aiguillage.
  • chaque sens de rotation du servo est déclenché par un contact fugitif différent ;
  • les contacts de déclenchement peuvent être non fugitifs, à condition de ne pas être enclenchés en même temps : utilisation du contact ON-OFF d'un relais ou d'un switch ;
  • les lames de l'aiguillage se déplacent avec un mouvement lent, de rapidité réglable ;
  • 2 LED-témoins indiquent que le servo a atteint l'une ou l'autre position finale.
    (Ces LED de contrôle peuvent être installées sur un TCO).
  • le programme peut être étendu à 4 servo-moteurs (pour actionner 4 aiguillages) ;
  • à la place des LED, on peut actionner des relais.

CÂBLAGE DU MONTAGE D'ESSAIS
 
SCHEMA_3.png
 
Ci-contre : le schéma électrique des contacts fugitifs, uniquement (avec les deux résistances «pullup» de 10 kΩ).
Le servo n'est volontairement pas représenté.

Note : ne pas tenir compte des numéros «11», «12»... «18», etc. notés à l'extérieur du rectangle de l'ARDUINO UNO.
 
Seuls sont à considérer les labels «intérieurs» qui correspondent aux indications sérigraphiées sur la carte elle-même.

 
SERVO 2 CONTACTS-8.png
SERVO 2 CONTACTS-7.png
 
Une petite platine d'essai (Breadboard) de 170 points suffira.​
  • à gauche : câblage du servomoteur seul, sur la sortie «3» :
  • à droite : on a ajouté les deux contacts fugitifs (poussoirs) avec leurs résistances «PullUp» de 10 kΩ.
LES VARIABLES


Petit préambule...

Les questions qu'on doit se poser chaque fois nos application sont les suivantes :
– quelles sont les valeurs que le programme va faire évoluer au cours de son  fonctionnement ?
– quelles sont les valeurs qui sont susceptibles d'être ajustées ou modifiées au cours de la mise au point du programme, mais qui ne seront pas modifiées par le programme : paramétrage ?

Dans le premier cas, la création de variables est indispensable.
Dans le deuxième cas on pourrait effectivement ne pas créer de variables et se contenter d'écrire la valeur numérique du paramètre là où on en a besoin. Pourtant, la création de variables donne une meilleure lisibilité au programme, et les interventions sur ces paramètres sont plus aisées et plus sûres.
 

1.– Variables pour les valeurs qui évoluent au cours du fonctionnement :
«Position_palonnier» : position angulaire du palonnier du servomoteur
  • dans ce programme, c'est la seule variable absolument indispensable ;
  • varie de 0 à 180° ;​
  • initialisée à «Position_repos = 90°» (voir ci-dessous) ;
 
2.– Variables de paramétrages :
 
«Position_repos» : position angulaire du palonnier, imposée au démarrage du programme
  • fixée à «90°» ;
  • utilisée pour recaler le servomoteur sur une position médiane ;
«Angle_de_depart» : position angulaire du servomoteur correspondant à l'aiguillage dévié à gauche
  • fixé à une valeur qui permet à la lame de l'aiguillage de plaquer correctement, mais sans plus ;
  • cette valeur dépend de la transmission mécanique entre le palonnier et la barre de commande de l'aiguillage ;
«Angle_d_arrivee» : position angulaire du servomoteur correspondant à l'aiguillage dévié à droite
  • fixé à une valeur qui permet à la lame de l'aiguillage de plaquer correctement, mais sans plus ;
  • cette valeur dépend de la transmission mécanique entre le palonnier et la barre de commande de l'aiguillage ;
«Duree_du_pas» : temps entre 2 position successives du palonnier lors des rotations lentes
  • fixé arbitrairement à 10 millisecondes ;
  • sera ajusté en fonction de la rapidité désirée pour le déplacement des lames d'aiguillage.
STRUCTURE DU PROGRAMME
Que doit faire le programme ?
  1. initialiser la variable et les paramètres ;
  2. amener le servomoteur à une position neutre ;
  3. amener le servomoteur à sa position de départ, càd à la position de départ souhaitée pour l'aiguillage ;
  4. tester en permanence (presque) les contacts fugitifs pour savoir lequel est actif ;
  5. faire tourner le servomoteur à droite ou à gauche, en fonction du contact qui est actionné ;
  6. conserver la position du servomoteur si on relâche le contact ;
  7. ne rien faire si un contact donné reste appuyé longtemps ;
  8. ne rien faire si on relâche un contact et qu'on l'actionne de nouveau (sans avoir actionné l'autre contact).
 
Pour les occurrences «6» à «8», il faudra donc mémoriser dans quelle position le servomoteur s'est arrêté.
 
1.– Installer et initialiser les variables
 
SERVO_variables_1.png
Toutes les variables sont déclarées dans
«Arduino run first».
 
On pourrait ne pas affecter de valeur à «Position_palonnier» puisque cette valeur est constamment calculée par le programme.



 

2.– Amener le servomoteur à une position neutre «Position_repos»
 
SERVO 2 CONTACTS-5.png
Dans «Arduino run first» on insère la commande
«set SERVO...» qui va forcer le servomoteur à se positionner à «Position_repos» que l'on a paramétrée à la valeur 90°.



3.– Amener le servomoteur à sa position de départ : «Angle _de_depart»
 
SERVO 2 CONTACTS-4.png
On créé une fonction personnelle :
«Aller_a_la_position_de_depart».

Grâce à la boucle «count with [Position_palonnier]...», elle va commander commander le déplacement lent du palonnier depuis l'angle «Position_repos» – fixé et atteint dans «Arduino run first» –, jusqu'à l'angle «Angle_de_depart», par pas de 1°.

Entre chaque déplacement de 1°, on attend pendant «Duree_du_pas» fixé a priori à 10 millisecondes.
Ce paramètre sera ajusté en fonction de la vitesse désirée du déplacement des lames de l'aiguillage.
 
Important !

En sortant de la boucle «count with Position_palonnier...» on insère l'instruction «set [Position_servo] to [Angle_de_depart]». 

Cette nouvelle variable «Position_servo» va stocker la position angulaire du servomoteur dans laquelle il s'est arrêté.

Note : avant la boucle de comptage figure une instruction «wait 1000 milliseconds».Cette temporisation n'est pas indispensable.


4.– Tester les contacts dans «Arduino loop forever».
C'est le corps principal du programme.

 
SERVO 2 CONTACTS-1.png
La boucle principale contient 2 fonctions de test :
  • la première teste l'état du contact sur l'entrée «7» ;
  • la deuxième teste l'état du contact sur l'entrée «8».
Si aucun contact n'est appuyé, aucun des 2 tests n'est vrai ⇒ les fonctions «Aiguille_deviee_a_droite» et
«Aiguille_deviee_a_gauche» ne sont pas appelées.
La boucle principale contient seulement les 2 fonctions de test :
  • la première teste l'état du contact sur l'entrée «7» ;
  • la deuxième teste l'état du contact sur l'entrée «8».
Si aucun contact n'est appuyé, aucun des 2 tests n'est vrai :
⇒ les fonctions «Aiguille_deviee_a_droite» et «Aiguille_deviee_a_gauche» ne sont pas appelées.
Analysons maintenant comment sont constituées les deux fonctions personnelles «Aiguille_deviee_a_droite» et «Aiguille_deviee_a_gauche», et comment elles fonctionnent.

5.– Faire tourner le servomoteur à droite ou à gauche
 
SERVO 2 CONTACTS-2.png
On créé deux fonctions personnelles :

«Aiguille_1_deviee_a_droite»

«Aiguille_1_deviee_a_gauche».

 

Fonctionnement : 
 
Les initialisations ont eu lieu et le servomoteur est en position «Angle_de_depart».
La position mémorisée dans «Position servo» est «Angle_de_depart» (voir alinea 3 ci-dessus)

1.– On actionne et on relâche le contact sur l'entrée «7» pour dévier l'aiguille à droite :
  • le test «if read digital pin # [7] = [LOW]» est vrai ⇒ appel de la fonction personnelle «Aiguille_1_deviee_a_droite» ;
  • «Position servo» est différente de «Angle_d_arrivee».
⇒ la boucle fonctionne et amène le palonnier à «Angle_d_arrivee» ;
  • «set [Position_servo] to [Angle_d_arrivee]»  mémorise la nouvelle «Position_servo».
2.– On actionne une nouvelle fois le contact sur l'entrée «7» :
  • «Position_servo» = «Angle_d_arrivee» ⇒ les deux bornes de la boucle sont identiques
    ⇒ la boucle n'est donc pas utilisée.
  • «set [Position_servo] to [Angle_d_arrivee]»  ne fait que confirmer la valeur de «Position_servo».
 
3.– On actionne et on relâche le contact sur l'entrée «8» pour dévier l'aiguille à gauche:
  • le test «if read digital pin # [8] = [LOW]» est vrai ⇒ appel de la fonction personnelle «Aiguille_1_deviee_a_gauche» ;
  • «Position servo» = «Angle_d_arrivee», donc différente de «Angle_de_depart».
⇒ la boucle fonctionne et amène le palonnier à «Angle_de_depart» ;
  • «set [Position_servo] to [Angle_de_depart]»  mémorise la nouvelle «Position_servo».
 
 
4.– On actionne une nouvelle fois le contact sur l'entrée «8» :
  • «Position_servo» = «Angle_de_depart» ⇒ les deux bornes de la boucle sont identiques
    ⇒ la boucle n'est donc pas utilisée.
  • «set [Position_servo] to [Angle_de_depart]»  ne fait que confirmer la valeur de «Position_servo».

 
LE PROGRAMME COMPLET
SERVO_2 CONTACTS_2_LED_COMPLET.png




 
SERVO+2 contacts+2 LED
SERVO 2 CONTACTS-6.png
1 SERVO + 2 CONTACTS
+ 2 TÉMOINS LUMINEUX
+ MÉMOIRE DE POSITION
Ce programme est destiné à piloter un servomoteur pour actionner un aiguillage .
  • les mouvements du servo sont déclenchés grâce à 2 contacts fugitifs ;
  • 2 LED-témoins indiquent que le servo a atteint l'une ou l'autre position finale ;
  • le programme peut être étendu à 4 servomoteurs.

Qu'y a-t-il de différent avec le programme précédent ?

Pas grand chose.

On veut qu'un témoin s'allume à la fin de chaque cycle de déplacement des lames d'aiguillage, différent pour chaque fin de course.

 
CABLAGE
SERVO 2 CONTACTS-6.png
On ajoute 2 LED avec leurs résistances (environ 330 Ω).

Elles seront commandées par les sorties «4» et «5».








 
LES MODIFICATIONS
On ajoute 2 LED avec leurs résistances (environ 330 Ω).

Elles seront commandées par les sorties «4» et «5».
  • la LED sur la sortie «4» indiquera que l'aiguillage est arrivé à sa position «déviée à droite» ;
  • la LED sur la sortie «5» indiquera que l'aiguillage est arrivé à sa position «déviée à gauche» ;

Les instructions pour commander ces LED seront ajoutées dans les fonctions personnelle :
  • «Position_de_depart» ;
  • «Aiguille_deviee_a_droite» ;
  • «Aiguille_deviee_a_gauche».
SERVO 2 CONTACTS-9A.png
SERVO 2 CONTACTS-9B.png
SERVO 2 CONTACTS-9C.png


Note :

À la place des LED, on peut connecter des relais.

On disposes ainsi de 2 relais, c'est à dire de 2 jeux de contacts «2RT».


On peut ainsi commuter le cœur de l'aiguillage ou commander un signal...



 
... ET SI ON VEUT LES LED ET UN RELAIS ?
SERVO 2 CONTACTS-10C.png
SERVO 2 CONTACTS-10B.png
Le relais est connecté sur la sortie «2» (par exemple).

Dans «Position-de-depart» le relais est coupé tout de suite au début de la séquence.

Dans «Aiguille_deviee_a_droite» et dans «Aiguille_deviee_a_gauche», on attend la fin de la séquence pour commuter le relais.

Le programme principal n'a pas été modifié.
Seules les actions ont été retouchées.
 
SERVO 2 CONTACTS-10A.png
Ah ! Vous voulez commuter le relais
«en cours de cycle» !
Saperlipopette ! Et puis quoi encore ?
Tournesol-2.jpg
Bon. Allons-y.

On peut avoir une très bonne raison pour que la commutation du relais se fasse à mi-course.

Le problème se complique un peu, mais pas tant que cela.

Au lieu d'avoir une seule boucle qui réalise le déplacement complet du servomoteur, il suffit d'en avoir deux :
– une qui réalise la première moitié du cycle ;
– une autre qui termine le cycle.
– entre les deux on insère la commutation du relais.
 
Voici ce que cela donnerait sur une des fonctions personnelles précédentes :
 
SERVO 2 CONTACTS-10B.png
SERVO 2 CONTACTS-10D.png
Au lieu de ceci...









... on aurait cela.

 
Fonctions personnelles
Feux de carrefour : comment utiliser les fonctions personnelles
  • La mise au point d'un petit programme pour commander les feux de carrefour est le prétexte  pour apprendre à créer des fonctions personnelles.
  • Ces fonctions personnelles sont parfois appelées «sous-programmes».

    Dans ARDUINO (Blockly ou ligne de code), elles sont tout simplement appelées «fonctions».
CYCLE D'ALLUMAGE DES FEUX
FEUX_de_CARREFOUR_1.png
6 phases ; 2x3 LED ⇒ 6 sorties


 
PREMIÈRE VERSION
FEUX_de_CARREFOUR_2.png
FEUX_de_CARREFOUR_2b.png
 
À gauche : le programme complet. À droite : le détail du début.
Bof !
 
Peut-on appeler cela «un programme» ?
 
C'est plutôt une liste de commissions : pain, beurre, chocolat...
 
Il fonctionne parfaitement bien, mais il est illisible.
 
En effet, aucune indication ne permet de savoir quelle LED est connectée sur quelle sortie.
 


 
DEUXIÈME VERSION
(Première fonction personnelle)

 
On obtiendrait des programmes bien plus élégants avec les fonctionnalités de CocoBLOCKLY ou de BLOCKLY@RDUINO.
Cependant ARDUBLOCKLY, malgré des capacités plus limitées que ses proches cousins, permet d'améliorer grandement le sketch de départ.
 
Dans cette deuxième version, on a une vraie vision de l'organisation des LED :
FEUX_de_CARREFOUR_3.png
FEUX_de_CARREFOUR_3c.png
 
On a créé :
  • 6 variables représentent les 6 sorties. («ROUGE_NORD_SUD» etc.)
    Ces variables ne contiennent pas le numéro des sorties mais seulement leur état, «HIGH» ou «LOW» ;
  • 1 fonction personnelle «CMD_SORTIES» qui se charge d'actionner, pour chaque phase, les différentes sorties en fonction de l'état des 6 sorties ci-dessus.
Le corps du programme comporte 6 groupes de blocs qui représentent les 6 phases.
Chaque groupe comporte :
  • la déclaration de l'état de chacune des LED de sortie : « set ROUGE_NORD_SUD to HIGH » par exemple.
  • l'appel à la fonction personnelle qui commande les sorties ;
  • la temporisation qui donne la durée de la phase en cours.
Par comparaison avec la première version, la création de la fonction personnelle «CMD_SORTIES» offre plusieurs avantages :
  • la fonction personnelle, telle qu'elle est construite, permet instantanément de savoir sur quel numéro de sortie est connectée chaque LED des feux nord-sud et est-ouest ;
  • cette fonction est écrite une seule fois, mais elle est utilisée 6 fois ;
  • dans chaque groupe de blocs représentant une phase, les états attribués aux sorties sont faciles à établir, facile à relire et faciles à contrôler ;
  • si pour une raison pratique, on désire utiliser d'autres sorties que les sorties 2 à 7, il suffit uniquement de modifier les affectations dans cette seule fonction personnelle.
    Les numéros de sorties n'ont d'ailleurs pas besoin d'être consécutifs.
    Une série comme par exemple 2, 4, 5, 9, 11, 12 ne posera aucun problème.
 
 

 
TROISIÈME VERSION
FEUX_de_CARREFOUR_4d.png
FEUX_de_CARREFOUR_4e.png
 
Chacun des 6 groupes de blocs «état de chaque LED / appel à la fonction de commande des sorties / durée de la phase» est installé dans une fonction personnelle comme «PHASE_1» ci-dessus à gauche.

Chaque nouvelle fonction ainsi obtenue doit être renommée «PHASE_1» ... «PHASE_6».

Le corps du programme s'en trouve extrêmement simplifié puisqu'il ne comporte QUE l'appel à ces 6 fonctions personnelles :
 
FEUX_de_CARREFOUR_4c.png
  • dans «Arduino run first : », les déclatations des durées des 6 phases ;
     
  • dans «Arduino loop forever : », les appels aux 6 fonctions «PHASE_1» à «PHASE_6».
 
Ci-dessous, synoptique du programme complet. En résumé :
  • 6 fonctions personnelles établissant l'état des sorties pour chaque phase ;
  • 1 corps de programme qui ne contient que les appels à ces 6 fonctions ;
  • 1 fonction personnelle qui actionne les sorties.
Schéma des interactions :
FEUX_de_CARREFOUR_4b.png
 
Cette structuration est très pratique, aussi bien en BLOCKLY qu'en lignes de code C++ :
  • chaque bloc peut être documenté avec un commentaire ;
  • chaque fonction personnelle peut être «collapse», càd réduite, pour améliorer la visibilité et la conception (sauf le programme principal) ;
  • les fonctions qui sont au point et sur lesquelles on ne travaille plus peuvent être «poussées» plus loin sur l'écran de façon à dégager l'espace de travail ;
Il subsiste malgré tout un petit... défaut :
 
Dans chaque fonction «PHASE_n» on traite chaque fois toutes les 6 variables d'états des sorties.
 
Or seulement deux d'entre elles sont «HIGH» dans chaque fonction. Les autres sont toutes à «LOW».
 
En phase de mise au point, il faut donc lire tous les blocs d'une fonction «PHASE_n» pour vérifier lesquels sont «HIGH», càd quelles sorties sont allumées.

 
 

 
QUATRIÈME VERSION
 
Et si on se contentait de :
  • au début de chaque phase ⇒ éteindre toutes les sorties.
  • dans chaque fonction «PHASE_n», mettre à l'état «HIGH» seulement les deux sorties concernées ;
Pour cela, créer une nouvelle fonction personnelle dont le rôle est d'éteindre toutes les sorties
⇒ créée une fois, utilisée 6 fois.
L'ARDUINO est suffisamment rapide pour que cette extinction générale des LED en début de chaque phase passe inaperçue.


Voyons cela :
FEUX_de_CARREFOUR_5a.png
La nouvelle version du programme comporte :
  • 1 fonction «TOUT_ETEINDRE» ;
  • 1 fonction «CMD_SORTIES» ;
  • 6 fonctions «PHASE_n» ;
  • 1 programme principal

Chaque fonction personnelle «PHASE_n» devient beaucoup plus légère, plus facile à fabriquer, à relire et à comprendre.
Elle ne traite que les deux sorties concernées dans chaque phase.
 
Ci-dessous, le programme complet :
FEUX_de_CARREFOUR_5.png
 
Pas mal, non ?

 
Ce n'est pas tout à fait fini !
CINQUIÈME VERSION

 
On peut remarquer que les phases 3 et 6 sont parfaitement identiques : les feux rouges des deux directions sont allumés ensemble pendant la même durée.
On peut donc se passer d'une des deux fonctions correspondantes et ne garder par exemple que la fonction «PHASE_3».
Cette fonction «PHASE_3» sera appelée 2 fois dans le programme.
FEUX_de_CARREFOUR_6.png
 
À la rigueur, «PHASE_3» pourrait être renommée «PHASE_3_6», histoire d'éviter (plus tard, quand on aura oublié qu'on avait été astucieux et futé) de se poser la question angoissante :

«... mais où est passée la fonction PHASE_6 ? ».

 
Ça, c'est de la belle programmation !
Looney_tunes.png
Thats's all Folks !
PN américain
Feux de P.N. américains
Deux feux qui s'allument et s'éteignent en opposition, avec simulation de l'inertie thermique du filament des lampes.
 
LE PROGRAMME
 
FEUX_PN_US_1.png
 
6 variables ; 2 boucles ; 2 calculs
  • INTENSITE_MAX permet de limiter par programme la luminosité maximale des LED ;
  • INTENSITE_MIN pourrait être utilisée pour empêcher l'extinction complète des LED ;
  • DUREE_PALIER règle le temps pendant lequel l'une ou l'autre LED reste éclairée avec l'intensité max ;
  • VITESSE_VARIATION : c'est le paramètre qui caractérise la lenteur de l'établissement de l'éclairage maximal du feu, et la rémanence à l'extinction.
    Attention : ici on a VITESSE_VARIATION = 5 avec INTENSITE_MAX = 30.
    Si par exemple on règle INTENSITE_MAX = 150 il faudra réduire VITESSE_VARIATION
    à «2» ou même «1».
  • INTENSITE_DROITE : contient la valeur analogique instantannée de la luminosité du feu de droite ;
  • INTENSITE_GAUCHE : contient la valeur analogique instantannée de la luminosité du feu de gauche ;
  • les LED sont connectée sur les sorties «3» et «5». Ce sont deux sorties qui acceptent d'être commandées en analogique, càd en PWM.
 

Une des boucle expliquée :
 
FEUX_PN_US_2.png
 
La luminosité des deux feux varie en même temps : pendant qu'un feu s'éteint progressivement, l'autre s'allume progressivement.
On n'aurait donc pas pu traiter indépendamment chaque feu dans une boucle indépendante.
 
C'est la raison pour laquelle «INTENSITE_GAUCHE» (l'intensité du feu de gauche) est calculée à partie de «INTENSITE_DROITE» (l'intensité du feu de droite) grâce à la formule :
 
INTENSITE_GAUCHE = INTENSITE_MAX – INTENSITE_DROITE
 
Cette formule est valable aussi pour la deuxième boucle qui traite la variation inverse des deux luminosités.
 
Download_1.png
Pour télécharger les codes
ARDUBLOCKLY et C++
Looney_tunes.png
Thats's all Folks !
2 contacts - 1 action
2 contacts ⇒ 1 action
opérateur logique «and»
Déclencher une action si et seulement si 2 contacts sont actifs en même temps ou, plus précisément, si deux entrées de l'ARDUINO sont mises à l'état «LOW» en même temps.


En termes choisis : «une action est déclenchée, si une double condition est vérifiée».

Ce petit programme est surtout le prétexte à étudier la façon de combiner 2 tests dans la même fonction «if».
Créé le 21/08/2020 ; modifié le 12/12/2021


LE PROGRAMME
  • la LED est connectée sur la pin n°2 ;
  • un premier switch est connecté sur la pin n°3 ;
  • un deuxième switch est connecté sur la pin n°4 ;

Dans cet exemple, «l'action» consiste à faire clignoter la LED sur la pin 2.

Cette action est matérialisée par la fonction personnelle BLINK_LED_2.
TEST_DOUBLE_3.png
 
La double condition est assez simple à comprendre :
la fonction if... do... else teste si la pin 3 ET (and) la pin 4 sont à l'état «LOW».


 
_____________

 
INPUT_PULLUP
 
A la fin de la page «MAISON VIVANTE 2» accessible ICI, sont expliqués les risques et le remèdes lorsqu'on utilise un contact comme capteur sur une entrée de l'ARDUINO.

ARDUBLOCKLY ne possède pas de bloc permettant de déclarer une entrée avec le paramètre «PULLUP».

Une astuce permet malgré tout d'actionner cette résistance PULLUP :
  • créer une variable factice, peu importe son nom ( «INITIAL» par exemple) ;
  • attribuer à cette variable la valeur Read digital pin 3 and Read digital pin 4. ;
  • placer ce groupe de blocs dans Arduino run first ;
  • ajouter tout de suite après les deux blocs Set digital pin 3 to HIGH ; et Set digital pin 4 to HIGH ;
Ceci n'a qu'un seul but : forcer ARDUBLOCKLY à générer le code source dans l'ordre ci-dessous :
TEST_DOUBLE_2.png
  • l'instruction INITIAL = digitalRead(3) && digitalRead(4); dans « Arduino run first » force à déclarer les pin 3 et 4 en entrées donc à générer les déclarations suivantes dans void setup() :

    pinMode(3, INPUT); et  pinMode(4, INPUT);
    ⇒ c'est précisément l'usage qu'on a prévu pour les pin 3 et 4.
     
  • avec les 2 instructions digitalWrite(3, HIGH); et  digitalWrite(3, HIGH); on force volontairement pin 3 et pin 4 à l'état « HIGH » en tant que sorties. 
    ⇒ on active ainsi les résistances «PULLUP» internes des pins 3 et 4 de L'ARDUINO ;

     
Or, dans le code C++, ces deux déclarations sont automatiquement placées APRÈS les 2 instructions 
pinMode(3, INPUT); et  pinMode(4, INPUT);
... et en conséquence ne génèrent pas d'instructions 
pinMode(3, OUTPUT); et  pinMode(4, OUTPUT);
Cela semble un peu compliqué, mais avec ARDUBLOCKLY ce groupe de blocs (donc d'instructions C++) est le seul moyen d'activer les résistances PULLUP des entrées, en l'absence d'un bloc supplémentaire de fonction permettant ce paramétrage.

À ma connaissance, seul BLOCKLYDUINO de Greich dispose d'un tel bloc.
Sinon il faut câbler physiquement les résistances PULL UP (10 k).
Ci-dessous, les deux câblages :
  • à gauche, câblage pour PULL UP par programme (comme décrit ci-dessus) ;
  • à droite, résistances PULL UP physiquement câblées.
ARDUBLOCKLY_num-590_(2020-06-03_15-12).p
ARDUBLOCKLY_num-589_(2020-06-03_15-11).p
Boucle « repeat... »
Boucle « repeat... »
La petite application ci-dessous, «Feux de pénétration», est le prétexte à l'apprentissage des boucles de programmation.
Créé le 21/11/2021 ; modifié le 21/11/2021
 
 
ARDUBLOCKLY propose 3 types de boucles :
Boucles_1.png
 
«repeat 10 times» est redondante avec la boucle «count with...».

Cependant, dans des cas très simples comme celui-ci, elle est plus légère et plus simple à utiliser.
 


OBJECTIF

Simuler le fonctionnement des feux de pénétration des véhicules de police (par exemple) en utilisant une boucle de répétition :
  • x4 flashs rapides sur le feu de droite ;
  • x4 flashs rapides sur le feu de gauche ;
... les deux séries de flashs étant séparées par un temps d'attente.
 
 

 
CÂBLAGE

Le feu de droite est connecté à la pin 3.
Le feu de gauche est connecté à la pin 4.
ARDUBLOCKLY_num-572_(2020-06-03_10-40).p
La petite video ci-dessous montre une simulation du fonctionnement des feux.
Le simulateur n'a pas la rapidité de réaction de l'ARDUINO.
Pour cette raison, l'intervalle entre les éclats et l'intervalle entre les salves des 4 éclats ont été artificiellement rallongés respectivement à 200 ms et 500 ms, au lieu de 50 et 300 ms de façon à visualiser correctement les séquences. 
Un ralenti, en quelque sorte...
 
ÉLABORATION DU PROGRAMME
 
On pourrait, pour chaque feu, écrire 4 fois la succession de 4 blocs comme ceux-ci 





... et obtenir ceci pour la LED sur la pin 3 :
Feux_penetration_3.png
fleche-triple.png
Feux_penetration_1.png
MDR2.gif
Oui, bon, ça va !
informatik.gif
 

 

... ou alors demander au programme qu'il le fasse pour nous grâce à la boucle 
repeat 4 times.


 
fleche-triple.png
Feux_penetration_2.png
Feux_penetration_4.png
... et ensuite :
  • on duplique la boucle
     «repeat 4 times» ;
  • dans la 2e boucle, on remplace la sortie «3» par la sortie «4» ;
 
  • on ajoute les temps d'attente de 300 millisecondes après chacune des deux boucles «repeat 4 times» ;
 
  • on inclut cet ensemble dans la fonction : Arduino loop forever


⇒ le programme est complet.

Il ne reste plus qu'à le téléverser dans la carte ARDUINO pour admirer le résultat.

 
Emoticone_doute.jpg
 
On n'aurait pas pu
faire... plus élégant ?
informatik.gif
 
OOOOKAAAYYY !
On y va...
ÉCRITURES ALTERNATIVES
Feux_penetration_5.png
 
  • la variable NB_FLASH contient le nombre d'éclats de flash par salve ;
  • la variable INTERVALLE indique le temps d'attente entre salves ;
  • ECART_ECLATS détermine avec quelle rapidité les éclats d'une salve se succèdent.
Il est ainsi beaucoup plus facile de paramétrer le fonctionnement des feux de pénétration, parce tout changement se fait dans ces trois variables, déclarées dans Arduino run first, et uniquement là.
Feux_penetration_6.png
 
La partie déclarative des variables est inchangée.

Le programme, lui, ne contient que 2 lignes.
Elles appellent 2 fonctions personnelles (ou sous-programmes).

La première de ces fonctions traite complètement le feu de droite (sortie «3»).
La deuxième s'occupe du feu de gauche (sortie «4»).

Certes, on n'a rien gagné en terme de taille du programme (ni sous forme «blocs», ni sous forme «code C++» ).
Par contre, la lisibilité est nettement meilleure :
  • le cœur du programme est simple ;
  • chaque fonction personnelle est claire et simple.
... et pour finir, une video « non stop »
de l'élaboration de ce programme
« Maison vivante »
Maison_vivante.jpg
« Maison vivante »
Éclairer 1 à 4 pièces d'un bâtiment de façon aléatoire en utilisant la fonction «random» .
Utilisation de la fonction «random integer».
 
BRANCHEMENT et SIMULATION
Tel qu'il est représenté ci-dessous, le branchement convient pour 1 à 4 pièces.
La simulation utilise des créneaux horaires de 1 seconde.
ARDUBLOCKLY_num-580_(2020-06-03_11-38).p
 
SOLUTION POUR DÉBUTANT
La solution en video​
Pensez à régler la résolution en 720p à partir des paramètres : engrenage en bas à droite.
Il arrive parfois que la définition 1080p ne fonctionne pas bien.
Le gain en qualité est modeste, donc 720p convient très bien.
Il n'est pas nécessaire de passer en mode plein écran.
Il est même recommandé de ne pas le faire.
 
La solution en image pour éclairer 2 pièces
Voici comment se présente le programme terminé :
MAISON_VIVANTE_num-850_(2020-07-20_16-49
 
Le corps du programme :
Il appelle successivement les deux fonctions personnelles qui traitent l'éclairage des deux pièces puis attend pendant «une heure fictive».
(Pendant la période de mise au point, la valeur de l'«heure fictive» est fixée à 1000 millisecondes).
Les fonctions personnelles :
Chacune d'entre elles calcule l'état allumé ou éteint de la pièce :
  • «1» : la variable «PIECE_1» reçoit la valeur «0» ou «1» de façon aléatoire grâce à la fonction
    «random integer from 0 to 1» ;
  • «2» : si la variable «PIECE_1» vaut «1», alors la sortie «3» devient «HIGH» donc la pièce s'éclaire.
    Sinon la sortie «3» devient «LOW» et la pièce s'éteint. 
 
Même chose pour la «PIECE_2» et la sortie «4».
La solution pour éclairer 4 pièces
MAISON_VIVANTE_num-848_(2020-07-20_16-35
 
  • créer 2 autres fonctions personnelles, «troisieme_piece» et «quatrieme_piece», grâce à «duplicate» ;
  • créer et renommer deux autres variables : «PIECE_3» et «PIECE_4» ;
  • changer le nom des variables dans les fonctions de test «if...» ;
  • changer le numéros des sorties :
    Dans l'exemple : sortie «5» pour «PIECE_3» et sortie «6» pour «PIECE_4».
  • dans le corps du programme, ajouter l'appel aux deux nouvelles fonctions personnelles.
La solution pour éclairer 6 pièces
MAISON_VIVANTE_num-849_(2020-07-20_16-38
 
Évident !​
  • 2 nouvelles fonctions personnelles ;
  • 2 nouvelles variables ;
  • 2 nouvelles sorties utilisées sur l'ARDUINO ;
  • 2 nouvelles lignes dans le corps du programme pour appeler les fonctions personnelles.
⇒ on peut donc très facilement étendre le nombre de pièces à traiter.
La limite, c'est le nombre de sorties disponibles sur la carte ARDUINO.
Remarque​
Les fonctions personnelles sont exécutées successivement.
⇒ le résultat de la fonction «random...» de l'une d'elles n'influe donc absolument pas sur le résultat renvoyé par les fonctions «random...» des autres.
⇒ on peut alors éviter d'avoir la série de variables «PIECE_1», «PIECE_2», etc., et les remplacer par une seule variable : «ECLAIRAGE» (par exemple).
 
Voici ce que devient le programme :​​
MAISON_VIVANTE_num-851_(2020-07-20_18-07
 
La duplication des fonctions personnelles est facilitée : seul le numéro de la sortie est à modifier.
emoticone_j_aime.png
 
Voilà, c'est fini !
ordi.gif
 
Ben, moi, j'aimerais bien améliorer un peu...

CLARIFIER LA LECTURE
Juste pour s'amuser un peu.


Si au lieu de «HIGH» et «LOW» on lisait «ALLUMEE» ou  «ETEINTE» ?

Aussitôt dit, aussitôt fait :
  • créer 2 variables «ALLUMEE» et «ETEINTE» ;
  • attribuer la valeur «HIGH» à «ALLUMEE» et «LOW» à «ETEINTE» ;
  • dans les fonctions personnelles, remplacer «HIGH» par «ALLUMEE» et «LOW» par «ETEINTE».
MAISON_VIVANTE_num-852_(2020-07-20_18-21

Pas mal, non ?
bravo.gif
 
SOLUTION POUR MATHEUX
On part de la constatation que ALLUMEE = HIGH = «1» et ETEINTE = LOW = «0».
En effet, :
  • «HIGH» est une façon officielle d'exprimer la valeur logique «1» ;
  • «ALLUMEE» n'est qu'une façon personnelle de remplacer «HIGH» dans le programme pour le clarifier.
 
MAISON_VIVANTE_num-854_(2020-07-21_09-10
Dans cette application, la fonction «random...» renvoie la valeur «0» ou «1».
Or «0» ou «1» sont précisément les deux états possibles de la sortie «digital pin # 3».
«ECLAIRAGE» est une variable à laquelle on attribue la valeur «0» ou «1» et qui sert d'intermédiaire de calcul dans la fonction «if...».
MAISON_VIVANTE_num-855_(2020-07-21_09-11
On peut donc se passer de la fonction de test «if...» et affecter directement la variable «ECLAIRAGE» à la sortie «digital pin # 3».
Et si on se passait aussi de la variable intermédiaire «ECLAIRAGE» ?
MAISON_VIVANTE_num-856_(2020-07-21_09-13
Il suffit de greffer le générateur de nombres aléatoires directement sur la commande de la sortie n°3, la sortie prendra bien les valeurs «0» ou «1».
MAISON_VIVANTE_num-857_(2020-07-21_09-37
Pas tout à fait : la fonction «random...» refuse de s'accrocher à la fonction «set digital pin...».
Pourquoi ?
Tout simplement parce que, la fonction «random» n'est pas destinée à générer un niveau logique «0» ou «1», «HIGH» ou «LOW», mais un nombre.
Eh oui : il y a une différence fondamentale entre les nombres «0» et «1» d'une part, et les niveaux logiques (booléens) «0» et «1» d'autre part.
Il faut donc transformer en niveau logique le nombre généré par la fonction «random».
MAISON_VIVANTE_num-862_(2020-07-21_12-09
Pour cela on utilise la fonction «... as Character» qui se trouve dans la catégorie «Variables».
Dans la liste déroulante on choisit «Boolean» qui transformera le résultat de la fonction «random...» en un niveau logique «1» ou «0».
Note :
Précédemment on n'avait pas besoin d'utiliser «Boolean» parce que la fonction «Set ECLAIRAGE = ... » le faisait naturellement.
MAISON_VIVANTE_num-858_(2020-07-21_09-38
◄◄◄ finalement on obtient ceci.
 
En fait, à ce stade, on se demande à quoi sert une fonction personnelle qui ne contient qu'un seul groupe de fonctions ?
MAISON_VIVANTE_num-861_(2020-07-21_09-41
On supprime donc toutes les fonctions personnelles et on regroupe tous les traitements directement dans le corps du programme.
Ouahouhh​ !
Ça c'est champion !
Smiley-Prof-1.png
 
On a conservé la variable «HEURE_FICTIVE» qui nous permet d'ajuster la durée du cycle de traitement en fonction des besoins.
Pour ajouter une pièce il suffit de dupliquer un groupe quelconque et de le glisser à la suite des autres.
On change le numéro de la sortie et c'est tout.
Plus simple, on ne peut pas.
Plus clair, on ne peut pas.
Remarque​
Pour le fun, essayez de modifier les bornes de la fonction «random...».
Par exemple, pour la sortie n°3, au lieu des bornes «0» et «1», choisissez «0» et «5».
⇒ le fonctionnement reste le même : «5» est considéré comme étant un «booléen non zéro», donc «1».
Avec  une petite différence de fonctionnement tout de même : statistiquement chaque nombre de 1 à 5 sort aussi souvent que le «0» :
⇒ à eux tous, les nombres de 1 à 5 sortent donc 5 fois plus souvent que le «0» ;
⇒ statistiquement la sortie n° 3 est allumée 5 fois plus longtemps qu'elle n'est éteinte.
Cette propriété peut être mise (doit être mise) à profit pour agir sur les durées relatives d'allumage et d'extinction de chaque pièce.
 
UNE SEULE PIÈCE À LA FOIS​
Il ne vous a pas échappé qu'avec le programme ci-dessus il arrive très souvent – pour ne pas dire de façon systématique – que plusieurs pièces s'éclairent ou s'éteignent en même temps.
Dans la réalité il est assez rare que cela arrive.
C'est même théoriquement impossible s'il s'agit de pièces ou de locaux indépendants.
Alors que faire ?
MAISON_VIVANTE_num-863_(2020-07-21_16-16
On fait suivre le traitement de chaque sortie par une temporisation.
Ici on ré-utilise la temporisation «HEURE_FICTIVE».
Le programme précédent traite toutes les pièces à chaque «HEURE_FICTIVE».
Le nouveau programme traite une pièce différente à chaque «HEURE_FICTIVE».
⇒ le fonctionnement est beaucoup plus réaliste et le programme est toujours aussi simple.
MAISON_VIVANTE_num-866_(2020-07-21_16-31
◄◄◄ une configuration définitive ressemblera à ceci.
En mode «mise au point» la durée de «HEURE_FICTIVE» est ramenée à 200 ms.
En mode réel, «HEURE_FICTIVE» prendra des valeurs comprises entre 10 000 et 64 000.
Note : 
Il faut avoir présent à l'esprit que :
  • un changement peut intervenir à chaque «HEURE_FICTIVE» ;
  • il peut s'écouler plusieurs «HEURES_FICTIVE» sans qu'aucun changement ne survienne.
 
C'est la glorieuse incertitude du hasard (random).
Moniteur série
Moniteur série
Premier contact
PRÉAMBULE
 
L'IDE de l'ARDUINO permet d'afficher un moniteur série.

Un moniteur série ça sert à quoi ?

La communication série permet d'établir une liaison entre le PC et la carte ARDUINO.

Très utile pour avoir un retour de données et ainsi permettre de déboguer les dysfonctionnements de nos programmes par des affichages séquencés des données.


L'icône d'activation du moniteur série est située en haut à droite de l'écran de l'IDE :
 
lanceur-moniteur-seerie.png
 
 
PETIT PROGRAMME D'ESSAI


Ce petit programme utilise la liaison série
pour afficher l'état ouvert ou fermé d'un contact.
 
  • Setup serial sert à initialiser la liaison série, en fixant la vitesse à 9600 bauds ;
     
  • set digital pin #7 to HIGH sert à activer la résistance PULLUP interne pour la pin n°7 ;
     
  • la fonction «ACTION» est appelé uniquement lorsque l'entrée n°7 est mise à zéro ;
     
  • serial print "Contact fermé" : 
    Si on met l'entrée n°7 à zéro, le moniteur – qu'on aura préalablement activé – affichera le message «Contact fermé», suivi d'un retour à la ligne en vue du prochain affichage.

     
  • le programme attend 1 seconde avant d'effectuer un nouveau test ;
     
  • tant que l'entrée n°7 n'est pas mise à zéro, le moniteur série n'affiche rien.
 
Test_moniteur_serie.png
 
 
UN PEU PLUS SÉRIEUX (... et même beaucoup plus sérieux) :
AFFICHER LA DURÉE D'APPUI SUR UN CONTACT



En vue d'écrire un programme qui effectuera des actions conditionnées à la durée d'appui sur un contact, on créé un petit programme préparatoire.

Grâce à ce programme nous allons apprendre :
  • l'utilisation de la fonction current elapsed Time (l'horloge interne de l'ARDUINO) ;
  • la boucle while... (test) ;
  • la déclaration d'une variable avec le type nombre entier long ;
  • l'affichage sur le moniteur série des résultats sous forme structurée.
 
emoticon_sueur.jpg
Tout ça !
Ben, dis donc...
 

LE PROGRAMME COMPLET (pour attaquer directement dans le dur...)
 
DUREE_IMPULSION_b.png
Mal_de_tete_3.jpg
 
Meuhh non !
... ET SON ANALYSE DÉTAILLÉE

La boucle while... (tant que...)

DUREE_IMPULSION_g.png
Cette première boucle «tourne» et mémorise le temps courant current elapsed Time, qui est l'heure interne de l'ARDUINO (compté à partir de la mise sous tension de l'ARDUINO).

TIME_START stocke donc l'heure courante.

À l'instant où l'entrée n°7 est mise à zéro («LOW»), on sort de la boucle
 l'heure de départ est alors figée dans TIME_START.
 
Tant que l'entrée n° 7 est maintenue à l'état «LOW», la boucle tourne et stocke l'heure courante dans la variable TIME_STOP.

Dès que l'entrée n°7 retourne à l'état «HIGH» on quitte la boucle et l'heure de fin est figée dans TIME_STOP.
DUREE_IMPULSION_g.png

Fonction MESURE_IMPULSION 

DUREE_IMPULSION_f.png
Cette fonction personnelle est l'assemblage de trois entités :
  • la boucle while qui enregistre l'heure à laquelle l'entrée n°7 passe à l'état «LOW» ;
  • la boucle while qui enregistre l'heure à laquelle l'entrée n°7 repasse à l'état «HIGH» ;
  • le calcul de la durée de l'impulsion par différence de l'heure de fin et de l'heure de début.

Affichage sur le moniteur série

DUREE_IMPULSION_c.png
Setup serial initialise la liaison série avec le PC.
DUREE_IMPULSION_e.png
Fonction AFFICHAGE_1

Elle comprend 3 lignes :
  • la première écrira le mot «Durée = » ;
  • la seconde écrira la valeur de la durée d'impulsion, càd la valeur contenue dans la variable «DUREE» ;
  • la troisième écrira « millisecondes».
DUREE_IMPULSION_j.png
... tout cela sur une seule ligne.

En effet, seule la troisième ligne impose un retour ligne
«add new line».

Remarque : le message «Durée = » est suivi d'un espace, et « millisecondes» est précédé d'un espace, de façon à éviter que les trois affichages soient collées ensemble.

Le corps du programme

DUREE_IMPULSION_d.png
Arduino run first contient la déclaration de la variable «DUREE».

(Voir la note ci-dessous).

Le corps du programme est ultra-simple.

Il ne contient QUE les appels aux deux fonctions personnelles.
Note :
La variable «DUREE» est déclarée comme un nombre «Large Number», càd un entier long, appelé unsigned long dans le langage C++.

Dans le cas présent, il est absolument indispensable de déclarer la variable «DUREE» avec le type «Large Number».

En effet, current elapsed Time est stockée sur 32 bits, ce qui permet de compter de 
0 à 4 294 967 294 millisecondes ou, pour simplifier, (2^32 – 1) millisecondes.

... ce qui correspond à environ 50 jours !
DUREE_IMPULSION_a.png
Ci-contre l'affichage obtenu sur le moniteur série.


On constate que ce petit programme préparatoire mesure avec précision les durées d'appui sur le contact connecté à la broche n°7.

La fonction «MESURE_IMPULSION» ainsi constituée pourra être utilisée dans un autre programme, si on a besoin de déclencher l'une ou l'autre action en fonction d'une durée d'impulsion.
Looney_tunes.png
That's all Folk's !
... for real.

ARDUBLOCKLY : vraiment simple

bottom of page