IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Cours complet pour apprendre à programmer un Arduino


précédentsommairesuivant

XIX. La petite bête qui a peur

Ce projet vous permettra d'utiliser l'information provenant d'une cellule photo-résistive fixée à un servomoteur afin de créer une « petite bête » simple qui a peur lorsqu'on s'en approche. La résistance électrique d'une cellule photo-résistive varie selon la lumière qu'elle reçoit. Judicieusement placée sous une lampe, cette petite « bête » pourra ainsi « détecter » lorsqu'une main s'en approche, puisque cette dernière fera de l'ombre sur le capteur, la cellule. Une commande sera ensuite envoyée au servomoteur afin de faire reculer la cellule qui y est attachée.

Image non disponible

XIX-A. Éléments nécessaires pour réaliser ce projet

  • une cellule photo-résistive ;
  • une résistance de 10 k ;
  • un servomoteur.
  • deux pinces crocodiles ;
  • quelques fils de connexion.

Si vous n'avez pas accès à un servomoteur, il vous est toutefois possible de réaliser la première partie de ce projet afin de comprendre comment analyser l'information entrante de la cellule photosensible.

XIX-B. Première étape

Dans cette première étape, nous travaillerons sur la partie « capteur » de ce projet. Nous connecterons la cellule photosensible à l'Arduino et afficherons l'information qui y est associée.

XIX-B-1. Schéma et montage

Voici le schéma que nous allons réaliser :

Image non disponible

Pour réaliser ce montage, il vous faut d'abord fixer la cellule sur la tête du servo-moteur, à l'aide de papier collant ou alors en passant les pattes dans les petits trous de la tête du moteur. Ensuite, en utilisant des pinces crocodiles, branchez une des pattes de la cellule sur la pin de 5 V de l'Arduino, et l'autre sur la pin Analog In 0. Pour compléter le montage de la partie « capteur », il faut connecter la patte de la résistance 10 k à la pin Analog In 0, et l'autre patte à la pin GND de l'Arduino. Ce montage électronique correspond en fait à un pont diviseur de tension (voir chapitre « Les bases de l'électroniqueLes bases de l'électronique »).

XIX-B-2. Programme

Copiez maintenant le programme suivant dans la fenêtre de programmation Arduino.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
// **********************
// définition des variables

int pinCapteur = 0; // variable pour désigner quelle pin de l'Arduino est utilisée pour le capteur

int valeurCapteur = 0; // variable pour contenir la valeur du capteur.
void setup()
{
    Serial.begin(9600); // établir la connexion sérielle à 9600 bauds
    pinMode(pinCapteur, INPUT); // définir la pin 0 comme une entrée (pinCapteur)
}

void loop()
{
    montrerValeurCapteur();
    delay(20); // laisser un cours délai pour éviter le trop-plein d'information
}

void montrerValeurCapteur()
{
    valeurCapteur = analogRead(pinCapteur); // lire la pin analogique et mettre la valeur dans valeurCapteur
    Serial.println(valeurCapteur); // communiquer au moniteur sériel la valeur du capteur.
}

Sauvegardez maintenant votre programme et vérifiez-le en cliquant sur le bouton « Verify ». En cas d'erreur (indiquée dans la console) , vérifiez l'orthographe, la casse et la présence appropriée des points-virgules (;). Vous pouvez maintenant télécharger votre programme sur la carte en appuyant sur « Upload ».

Une fois le téléchargement terminé, vous pouvez faire apparaître la fenêtre du moniteur sériel en cliquant sur le bouton « Serial Monitor ». Assurez-vous que la vitesse de transfert des informations (baudrate) du moniteur sériel est identique à celle spécifiée dans le programme, soit 9600. Cette information se trouve dans le bas de la fenêtre et peut être changée.

Après quelques instants, vous devriez voir défiler des chiffres sur le moniteur sériel. Ces chiffres devraient moduler légèrement, et plus amplement lorsque de l'ombre est faite sur la cellule photosensible.

Voyons plus en détail les éléments du code.

XIX-B-2-a. Déclaration des variables

pinCapteur cette variable est utilisée pour référer, tout au long du programme, à la pin de l'Arduino où est branchée notre capteur, la cellule photosensible. Dans ce projet, nous utilisons la pin analog 0, et donc la valeur de pinCapteur est initialisée à 0 lorsqu'elle est déclarée. Si nous avions connecté le capteur à une autre pin, par exemple analog 5, la valeur de pinCapteur aurait été initialisée à 5.

valeurCapteur cette seconde variable contient la valeur qui sera lue sur la pin de l'Arduino correspondant à notre capteur.

XIX-B-2-b. Configuration (setup)

Deux instructions figurent dans la partie setup () de notre programme.

Serial.begin (9600); Cette fonction établit la connexion sérielle entre la carte Arduino et, dans notre cas particulier, l'interface logicielle Arduino. Le paramètre qui est donné à la fonction est 9600, qui signifie que la connexion sérielle à établir doit rouler à 9600 bauds. Le choix de la vitesse dépend de l'application développée. Dans le cadre de cet exemple, une vitesse plus élevée n'est pas nécessaire.

pinMode (pinCapteur, INPUT); Cette fonction déclare la pin de la carte correspondant à pinCapteur (en l'occurrence, 0), comme un entrée (Input), puisque nous utiliserons cette pin pour recueillir la variation de voltage engendrée par notre circuit comportant la cellule photorésistante.

XIX-B-2-c. Boucle principale (loop)

Notre boucle de programme principal est relativement simple. Il suffit de recueillir la valeur de notre capteur, de l'envoyer au logiciel Arduino par communication sérielle et d'attendre un peu, pour espacer les lectures.

montrerValeurCapteur (); Cette ligne d'instruction appelle la fonction que nous avons définie nous-mêmes et qui sera expliquée ci-après. En l'appelant de la sorte, toutes les instructions qui se trouvent dans la fonction montrerValeurCapteur () seront exécutées. Une fois l'exécution de la fonction terminée, le programme poursuivra pour exécuter la fonction suivante.

delay (20); Cette seconde fonction demande au programme de marquer une courte pause, pour espacer les lectures. Le paramètre qui est spécifié, la valeur 20, indique que le délai a une durée de 20 millisecondes (on retrouve 1000 millisecondes dans une seconde).

XIX-B-2-d. Sous-routines (montrerValeurCapteur)

En plus des fonctions réservées par Arduino setup () et loop (), il est possible de définir soi-même des fonctions que l'on peut également appeler « sous-routines ». L'utilisation de sous-routines permet d'alléger et de mieux structurer le programme. Par exemple, lorsque la fonction principale loop () doit exécuter à plusieurs moments différents la même série d'instructions, il est possible de mettre une fois ces instructions dans une fonction unique, en sous-routines, et d'y référer.

Également, l'utilisation de sous-routine permet une meilleure lisibilité du code principal et de regrouper sous une même appellation, ou une même fonction, une série d'instructions ayant une tâche commune. Par exemple, une série de 10 instructions permettant de faire clignoter une LED de manière non régulière pourraient être regroupées sous une fonction que l'on pourrait nommer faireClignoterLED (). Ensuite, dans le programme principal, pour faire exécuter cette série d'instructions, il ne suffirait plus qu'à appeler la fonction faireClignoterLED ().

montrerValeurCapteur () Dans le cadre de notre projet, la sous-routine que nous avons créée a été nommée montrerValeurCapteur. Il ne s'agit pas d'une fonction préexistante, et nous en avons choisi le nom (qui aurait pu être mangerDesFrites (), par exemple). Jetons un œil en détail à cette fonction :

 
Sélectionnez
1.
2.
3.
4.
void montrerValeurCapteur ()
{
    // instructions à exécuter ici
}

D'abord, le void sert à indiquer que notre fonction ne retourne aucune valeur (voir chapitre « Programmer ArduinoProgrammer Arduino »). Ensuite, nous indiquons le nom donné à la fonction suivi de parenthèses. Comme notre fonction n'utilise pas de paramètres ou n'a pas de variable ou valeur en entrée pour déterminer son fonctionnement, il ne se trouve rien entre les parenthèses. Finalement, nous écrirons les instructions à exécuter pour cette fonction entre les accolades :

 
Sélectionnez
valeurCapteur = analogRead (pinCapteur);

Celle ligne de code contient la fonction analogRead (). Celle-ci permet de lire la pin de la carte Arduino correspondant à la valeur de pinCapteur (0). Puisqu'il s'agit d'une entrée analogique, les valeurs possibles que analogRead () peut retourner se situent entre 0 et 1023, correspondant à un voltage entre 0 et 5 V. L'opérateur « = » permet d'assigner la valeur retournée par analogRead à notre variable valeurCapteur. Ainsi, et pour la suite du programme ou jusqu'à ce qu'il y ait un changement, valeurCapteur contiendra la valeur de la lecture du capteur.

 
Sélectionnez
Serial.println (valeurCapteur);

Notre deuxième instruction permet d'envoyer par communication sérielle la valeur qui est contenue dans notre variable valeurCapteur au logiciel Arduino, à travers le câble USB. La fonction Serial.println () comporte valeurCapteur comme paramètre, ce qui lui spécifie quoi imprimer. Serial.print () et Serial.println () se distingue par le fait que la deuxième fonction ajoute un retour de chariot (CR) dans son message, ce qui fait qu'à chaque envoi de valeur au moniteur sériel, par exemple, un changement de ligne sera effectué. Il est à noter que dans le cas de communication avec d'autres interfaces ou logiciels, il est parfois préférable d'utiliser Serial.print () pour n'envoyer que la donnée demandée, sans le caractère « CR » supplémentaire.

XIX-C. Deuxième étape

Dans cette deuxième étape, nous travaillerons sur la partie « moteur » de ce projet. Nous connecterons le servomoteur à l'Arduino et une valeur de position aléatoire lui sera envoyée afin de vérifier notre montage.

XIX-C-1. Schéma et montage

Voici la suite du schéma que nous allons réaliser :

Image non disponible

Pour réaliser ce montage, il vous faut connecter le servomoteur à la carte Arduino. Celui-ci comporte trois fils de couleurs habituellement rouge, noire et jaune (parfois blanche). Le fil noir doit être connecté à la pin GND, le fil rouge dans la pin 5 V (section power) de la carte et le fil jaune ou blanc doit être connecté à la pin 9 de la carte. Les fils rouge et noir servent à fournir l'alimentation au servomoteur. Le fil jaune sert à recevoir un signal PWM qui sera envoyé par l'Arduino afin de positionner le servomoteur.

Il est important de noter que pour ce projet, il n'y a qu'un seul moteur branché à la carte et utilisant la puissance 5 V qui provient du régulateur de la carte Arduino (qui l'obtient par le port USB). Dans une situation où vous seriez tenté de contrôler plusieurs moteurs, il serait nécessaire de concevoir un système de puissance supplémentaire (voir chapitre « Précautions d'usagePrécautions »).

XIX-C-2. Programme

Copiez maintenant le programme suivant dans la fenêtre de programmation Arduino.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
#include <Servo.h> // inclure la librairie pour l'utilisation des servomoteurs

Servo servo1; // créer l'objet "servo1" pour référer à notre servomoteur
// **********************
// définition des variables

int pinCapteur = 0; // variable pour désigner quelle pin de l'Arduino est utilisée pour le capteur
int valeurCapteur = 0; // variable pour contenir la valeur du capteur.
int servoPos = 0; // variable pour contenir et spécifier la position en degrés (0-180)

void setup()
{
    Serial.begin(9600); // établir la connexion sérielle à 9600 bauds
    pinMode(pinCapteur, INPUT); // définir la pin 0 comme une entrée (pinCapteur)
    servo1.attach(9); // associer la PIN 9 au servomoteur
}

void loop()
{
    // montrerValeurCapteur();
    // delay(20); // laisser un cours délai pour éviter le trop-plein d'informations
    testerServoMoteur();
}

void testerServoMoteur()
{
    while (1==1)
    {
        servoPos = random(181); // attribuer une valeur aléatoire comprise entre 0 et 180 à servoPos
        servo1.write(servoPos); // spécifier la position au servomoteur
        delay(2000); // attendre 2 secondes
    }
}

void montrerValeurCapteur()
{
    valeurCapteur = analogRead(pinCapteur); // lire la pin analogique et mettre la valeur dans valeurCapteur
    Serial.println(valeurCapteur); // communiquer au moniteur sériel la valeur du capteur.
}

Vous pouvez maintenant sauvegarder votre sketch sous un autre nom (afin de conserver le précédent) et télécharger le code sur la carte Arduino. Après quelque temps, le servomoteur devrait se mettre à bouger de manière aléatoire, changeant sa position toutes les deux secondes. Voyons plus en détail les éléments du code qui ont été ajoutés au code existant.

XIX-C-2-a. Inclusion de bibliothèque

La première ligne d'instruction de notre programme est maintenant changée. En effet, pour utiliser des servomoteurs avec l'Arduino, il est possible d'utiliser une bibliothèque (voir chapitre « Bibliothèques externesBibliothèque externes »). Pour inclure une lbibliothèque dans notre programme, nous utilisons la commande suivante :

 
Sélectionnez
#include <Servo.h>

le #include spécifie au programme d'inclure la bibliothèque dont le nom se situe entre les « <> ». L'usage spécifique de Servo.h nécessite la création d'un « objet » qui nous permettra de référer à certaines fonctions de la bibliothèque. Pour notre projet, nous intitulerons cet objet servo1. Encore une fois, ce nom est déterminé par le programmeur et aurait bien pu être maurice.

 
Sélectionnez
Servo servo1;
XIX-C-2-b. Déclaration des variables

servoPos Nous ajoutons à notre code la variable servoPos. Celle-ci contiendra la valeur de position spécifiée pour le servomoteur.

XIX-C-2-c. Configuration (setup)

servo1.attach (9); Une nouvelle instruction de configuration est ajoutée à notre boucle setup (). L'instruction *.attach () permet d'associer une pin de la carte Arduino à un objet servo créé plus haut. Ainsi, notre objet servo1 se voit associer la pin 9 par cette instruction.

XIX-C-2-d. Boucle principale (loop)

Notre boucle de programme principal doit maintenant changer. Nous voulons maintenant attribuer des positions aléatoires à notre moteur. Plutôt que de simplement supprimer les instructions existantes nous permettant de communiquer la valeur du capteur, nous les mettrons sous forme de commentaire. Pour ce faire, il suffit d'ajouter au début de l'instruction « // ».

 
Sélectionnez
// montrerValeurCapteur ();

// delay (20); // laisser un cours délai pour éviter le trop-plein d'informations

Cela rendra inactives les instructions, et au cas où nous voudrions les retrouver, il ne suffirait que de supprimer les « // ». Nous devons également maintenant ajouter une nouvelle fonction que nous définirons plus loin, TesterServoMoteur ();.

XIX-C-2-e. Sous-routines (testerServoMoteur)

Tout comme pour la fonction montrerValeurCapteur de l'étape 1, nous devons définir testerServoMoteur. Nous utilisons encore void en début d'instruction puisque la fonction ne retourne rien. Voyons les instructions qui figurent dans notre nouvelle fonction.

 
Sélectionnez
1.
2.
3.
4.
while (1==1)
{
    xxxx
}

La fonction while est une fonction conditionnelle qui permet de répéter une série d'instructions tant qu'une condition est testée comme vraie. Par exemple, nous pourrions avoir une condition où notre programme fait émettre un bruit d'alarme à l'Arduino tant qu'un bouton d'arrêt n'aurait pas été enclenché : while (bouton==pas enclenché) { faire sonner l'alarme }. La fonction est while (). La condition à tester est un paramètre qui se trouve entre les parenthèses, et la série d'instructions à répéter se trouve entre les accolades (là où se trouvent xxxxx dans notre exemple plus haut).

Dans notre projet, la fonction while nous sert plutôt ici à créer une boucle infinie, donc qui se répète à tout coup. La condition étant testée est 1==1. Puisque 1 sera toujours égal à 1, notre condition est toujours vraie et les instructions se répéteront à tout coup. Il est à noter que l'opérateur « == » est à distinguer du « = ». L'opérateur « == » sert à faire des comparaisons, et retournera une valeur logique, 1 correspondant à vrai et 0 à faux, tandis que le l'opérateur « = » sert à attribuer une valeur à une variable (dans x = 45, x prendra la valeur 45).

Les trois instructions contenues dans notre boucle while sont les suivantes :

 
Sélectionnez
1.
2.
3.
servoPos = random (181);
servo1.write (servoPos);
delay (2000);

servoPos = random (181); La fonction random () retourne une valeur aléatoire. Celle-ci se situe entre 0 et le paramètre spécifié, de manière exclusive, ce qui signifie, par exemple, qu'un paramètre de 181 fera en sorte que la random () retourne une valeur entre 0 et 180. Comme la position que peut prendre notre servomoteur est comprise entre 0 et 180 en termes de degrés, nous générons dans cette instruction une valeur aléatoire appropriée.

servo1.write (servoPos); Tout comme pour xxx.attach (), la fonction xxxx.write () provient de la bibliothèque Servo.h. Elle nous permet ainsi de spécifier au servomoteur lié à l'objet servo1 la position en degrés qu'il doit atteindre. La variable servoPos fournit ici la valeur de cette position.

delay (2000); Afin de laisser un certain intervalle de temps entre chaque mouvement du servomoteur, nous ajoutons un délai de 2 secondes (2000 millisecondes).

XIX-D. Troisième étape

Dans cette troisième étape, nous établirons un lien entre la partie « capteur » et la partie « moteur ». Lorsqu'une main ou un doigt s'approche du capteur, il crée une ombre sur le capteur. Cette ombre devrait faire « fuir » le capteur fixé au servomoteur (si la cellule photo-résistive n'est pas fixée à la tête du moteur, vous devrez le faire maintenant).

Il n'y a pas de montage supplémentaire à exécuter. Le tout se joue au niveau du programme. Quelques ajustements aux valeurs seront peut-être nécessaires afin de « corriger » le comportement de la petite bête qui a peur, puisque la flexibilité du système entraîne également une certaine instabilité (ce qui est recherché pour donner l'impression de la peur !).

XIX-D-1. Programme

Copiez maintenant le programme suivant dans la fenêtre de programmation Arduino.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
#include <Servo.h> // inclure la bibliothèque pour l'utilisation des servomoteurs

Servo servo1; // créer l'objet "servo1" pour référer à notre servomoteur

// **********************
// définition des variables

int pinCapteur = 0; // variable pour désigner quelle pin de l'Arduino est utilisée pour le capteur
int valeurCapteur = 0; // variable pour contenir la valeur du capteur.
int servoPos = 0; // variable pour contenir et spécifier la position en degrés (0-180)
int capteurBase = 0; // variable pour contenir la valeur de base du capteur (sans ombre)

void setup()
{
    Serial.begin(9600);// établir la connexion sérielle à 9600 bauds
    pinMode(pinCapteur, INPUT); // définir la pin 0 comme une entrée (pinCapteur)
    servo1.attach(9); // associer la PIN 9 au servomoteur
    determinerCapteurBase(); // trouver la valeur de base du capteur.
}

void loop()
{
    // montrerValeurCapteur();
    // testerServoMoteur();

    modifierPosSelonCapteur(); // lire la pin du capteur et mettre dans valeurCapteur.
    decroitreServoPos(); // faire décroître "la peur" de la petite bête.
    servo1.write(servoPos); // assigner la position du servomoteur qui a été changée
    delay(20);
}

void modifierPosSelonCapteur()
{
    int difference = 0; // déclarer variable locale pour calculer la différence

    valeurCapteur = analogRead(pinCapteur); // lire la pin du capteur et mettre dans valeurCapteur
    difference = capteurBase - valeurCapteur; // calculer l'écart entre valeur actuelle et la base
    difference = max(difference, 0); // limiter différence à 0 (pas de chiffre négatif)

    /* pour déboguer les valeurs et comprendre ce qui se passe
    Serial.print(valeurCapteur);
    Serial.print(" - ");
    Serial.print(capteurBase);
    Serial.print(" -- ");
    Serial.println(difference); // imprimer différence pour debug
    */

    servoPos = min ( servoPos + difference, 180); // modifier la valeur de position du servo
}

void determinerCapteurBase()
{
    servo1.write(0); // positionner le moteur à la position de départ
    delay(2000); // laisser le temps au moteur de se placer
    capteurBase = analogRead(pinCapteur); // assigner la lecture actuelle à capteurBase
}

void decroitreServoPos()
{
    servoPos = max ( servoPos - 10, 0); // faire décroître servoPos
}

void testerServoMoteur()
{
    while (1==1)
        {
        servoPos = random(181); // attribuer une valeur aléatoire comprise entre 0 et 180 à servoPos
        servo1.write(servoPos); // spécifier la position au servomoteur
        delay(2000); // attendre 2 secondes
    }
}

void montrerValeurCapteur()
{
    while (1==1)
        {
        valeurCapteur = analogRead(pinCapteur); // lire la pin analogique et mettre la valeur dans valeurCapteur
        Serial.println(valeurCapteur); // communiquer au moniteur sériel la valeur du capteur.
    }
}

Voici les ajouts faits à ce programme.

XIX-D-1-a. Déclaration des variables

capteurBase Nous ajoutons à notre code cette variable qui nous permettra de garder en mémoire la valeur de base du capteur. Celle-ci nous sera utile pour calculer l'écart entre la valeur mesurée en temps réel (donc affectée par l'ombre que crée le doigt ou la main qui s'approche) et celle de base, sans ombre.

XIX-D-1-b. Configuration (setup)

determinerCapteurBase () Il s'agit d'une nouvelle fonction créée pour initialiser les éléments de base de notre projet. Comme elle ne doit s'exécuter qu'une seule fois, la fonction est placée dans la configuration du programme.

XIX-D-1-c. Boucle principale (loop)

Notre boucle de programme principal doit encore une fois changer. Nous mettons d'abord sous commentaires les fonctions liées à la prise d'information et au test moteur, soit montrerValeurCapteur () et testerServoMoteur (). Ensuite, nous ajoutons les fonctions qui nous servirons à analyser le capteur et modifier la position du servomoteur en fonction de celui-ci, soit modifierPosSelonCapteur () et decroitreServoPos ().

Finalement, nous ajoutons l'instruction servo1.write (servoPos) afin de spécifier à l'objet servo1 la position telle qu'elle a été modifiée par le programme. L'instruction du delay (20) permet un certain espacement entre les lectures et assignations moteur.

XIX-D-1-d. Sous-routines

Nous ajoutons trois sous-routines à notre programme :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
void determinerCapteurBase()
{
    servo1.write(0);
    delay(2000);
    capteurBase = analogRead(pinCapteur);
}

Cette fonction sert d'abord à initialiser la position du moteur avec servo1.write (0). Ensuite, il faut faire attendre le programme deux secondes avec delay (2000) pour laisser le temps au moteur de se positionner. Finalement, le programme fera une lecture du capteur avec analogRead (pinCapteur) pour assigner cette valeur à la variable capteurBase. Nous utiliserons cette variable pour calculer l'écart entre une lecture « sans ombre » et une lecture avec l'ombre projetée par la main ou le doigt.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
void modifierPosSelonCapteur()
{
    int difference = 0;
    valeurCapteur = analogRead(pinCapteur);
    difference = capteurBase - valeurCapteur;
    difference = max(difference, 0);
    servoPos = min ( servoPos + difference, 180);
}

Cette fonction a la particularité de contenir une déclaration de variable, l'instruction int difference = 0. Habituellement réservée à la première section du programme, une déclaration de variable faite à l'intérieur d'une sous-routine crée ce qu'on appelle une variable locale. Cela signifie que la variable « n'existera » que dans le contexte d'exécution de la fonction ou sous-routine dans lequel elle se situe. Par conséquent, aucune autre fonction ou sous-routine ne pourrait faire usage de la variable difference. Par opposition, les variables qui sont déclarées au tout début du programme sont considérées comme globale, c'est-à-dire qu'elles « existent » et sont accessible à toutes les fonctions ou autre routines.

La seconde instruction de cette sous-routine assigne à valeurCapteur la lecture de la pin liée au capteur. Ensuite, nous calculons la différence entre la valeur du capteur « sans ombre » contenu dans capteurBase et celle « avec ombre » (ou sans) de valeurCapteur.

Finalement, comme il est possible que la différence nous retourne une valeur négative (dans le cas où il y aurait eu une illumination, par exemple, nous limitons la valeur de différence à un minimum de 0. Bien que cela semble contre-intuitif, nous utilisons dans ce cas la fonction max (). Celle-ci prend en paramètre deux valeurs (en l'occurrence difference et 0) et retournera celle des deux qui sera la plus élevée. Ainsi, si difference = -5, max (difference, 0) retournera 0, puisque ce chiffre est plus élevé que -5. Par contre, si difference = 10, la fonction retournera 10. Nous assignons la valeur retournée par max () à difference.

La dernière instruction de cette sous-routine nous sert à incrémenter, si c'est le cas, la valeur de servoPos. Nous assignons ainsi à servoPos sa valeur actuelle en y ajoutant la différence calculée précédemment : servoPos + difference. La raison pour laquelle nous ajoutons la différence à la valeur actuelle est pour conserver une certaine continuité dans la position du moteur et une accumulation de la valeur de celle-ci à travers le temps. Ce code, puisqu'il prend en compte la différence, fait en sorte qu'un mouvement brusque, traduit comme une grande différence entre les deux lectures, augmentera grandement la position du servomoteur, générant une impression de « peur ». À l'inverse, une approche très « douce » et lente représentant une faible différence n'aura qu'un impact mineur sur la position du servomoteur, qui semblera plus « calme ».

Comme il n'est pas possible de donner une valeur supérieure à 180 au servomoteur (ou à la fonction servo1.write ()), nous devons limiter l'incrémentation de servoPos. Pour ce faire, nous utilisons la fonction min () qui s'exécute à l'inverse de max (). Ainsi, elle prendra le plus bas des deux chiffres en paramètres pour le retourner. Donc, dans min (servoPos + difference, 180), si l'addition de servoPos et différence est supérieure à 180, le chiffre 180 sera retourné, autrement ce sera le résultat de l'addition qui sera pris en compte.

 
Sélectionnez
1.
2.
3.
4.
void decroitreServoPos ()
{
    servoPos = max (servoPos - 10, 0);
}

La dernière sous-routine que comporte notre programme permet au servomoteur de retourner vers son point de base, le degré 0. Comme servoPos s'incrémente graduellement avec les ombres, il faut également doter notre petite bête d'une « tendance » à revenir, ou dit autrement, à faire décroître servoPos. L'instruction qui accomplit cela est servoPos = servoPos - 10. La valeur 10 est soustraite de servoPos et le résultat est stocké dans la même variable. Le choix de « 10 » ici est plus ou moins arbitraire et peut être ajusté, dans la mesure où une valeur plus faible (3, par exemple) fera décroître beaucoup plus lentement servoPos et une valeur plus élevée fera revenir à l'inverse la petite bête beaucoup plus rapidement.

Nous devons également nous assurer de ne pas aller en dessous de 0, puisqu'il s'agit de la position en degrés du servomoteur. Il faut donc utiliser, comme décrit précédemment, la fonction max ().


précédentsommairesuivant

Ce cours est publié sous licence GPLv2, peut être lu et copié librement.