XVII. Projet 9 : les inputs analogiques▲
Un signal analogique(10) varie de façon continue au cours du temps. Sa valeur est donc un nombre réel. On trouve des signaux analogiques constamment, comme la température, la vitesse…
L'Arduino Uno possède six entrées analogiques, numérotées A0 à A5. En réalité, le microcontrôleur n'est pas capable de comprendre un signal analogique. Il faut donc d'abord le convertir en signal numérique par un circuit spécial appelé convertisseur analogique/numérique. Ce convertisseur va échantillonner le signal reçu sous la forme d'une variation de tension et le transformer en valeurs comprises entre 0 et 1023. Attention à ne pas faire entrer une tension supérieure à 5 V, ce qui détruirait l'Arduino.
XVII-A. La photorésistance▲
Une photorésistance est un composant électronique dont la résistance (en Ohm Ω) varie en fonction de l'intensité lumineuse. Plus la luminosité est élevée, plus la résistance est basse. On peut donc l'utiliser comme capteur lumineux pour :
- mesurer la lumière ambiante pour une station météo ;
- détecter la lumière dans une pièce ;
- suivre la lumière dans un robot ;
- détecter un passage ;
- …
Ses symboles électroniques sont les suivants :
L'avantage des photorésistances est qu'elles sont très bon marché. Par contre, leur réaction à la lumière est différente pour chaque photorésistance, même quand elles ont été produites dans le même lot. On peut ainsi noter une différence de résistance de plus de 50 % entre deux photorésistances du même modèle pour la même luminosité. On ne peut donc pas l'utiliser pour une mesure précise de la lumière. Par contre, elles sont idéales pour mesurer des changements simples de la luminosité.
XVII-B. Circuit 11 : diviseur de tension▲
Pour le circuit 11, nous aurons besoin d'une photorésistance que nous connecterons à la broche A0.
Le montage résistance fixe – photorésistance constitue ce qu'on appelle un diviseur de tension. 5 V sont introduits dans le circuit depuis l'Arduino. On relie le point entre les deux résistances à une broche analogique de l'Arduino et on mesure la tension par la fonction analogRead
(broche). Tout changement de la tension mesurée est dû à la photorésistance puisque c'est la seule qui change dans ce circuit, en fonction de la lumière.
Liste des composants
- 1 LED ;
- 1 résistance de 220 Ω ;
- 1 résistance de 10 kΩ ;
- 1 photorésistance.
XVII-C. Code 16 : valeur de seuil▲
L'objectif de ce code est de définir un seuil de luminosité au-delà duquel on éteint une LED. Nous allons pour cela utiliser une nouvelle instruction : if
… else
(si … sinon). C'est donc une condition.
Voici ce qui va se passer :
Si la luminosité dépasse le seuil (if
(analogRead
(lightPin)>
seuil)), éteindre la LED (digitalWrite
(ledPin, LOW
)) ; sinon (else
), allumer la LED (digitalWrite
(ledPin, HIGH
)).
L'instruction ==
vérifie si deux expressions sont égales. Si elles le sont, alors le résultat sera vrai (true
) sinon le résultat sera faux (false
).
Dans ce cas, le seuil est fixé à 900 (sur 1023). En variant la valeur du seuil, on modifie la sensibilité de détection de la luminosité.
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.
/*
Code 16 - Edurobot.ch, destiné à l'Arduino
Objectif: Éteindre une LED dès que la luminosité est suffisante
*/
//***** EN-TÊTE DÉCLARATIF *****
int
lightPin =
0
; //On renomme la broche A0 en "lightPin"
int
ledPin =
9
; //On renomme la broche 9 en "ledPin"
//***** FONCTION SETUP = Code d'initialisation *****
// La fonction setup() est exécutée en premier et une seule fois, au démarrage du programme
void
setup()
{
pinMode
(ledPin, OUTPUT
);
Serial
.begin(9600
);
}
void
loop()
{
int
seuil =
900
; //On définit un seuil de luminosité (sur 1023) à partir duquel la LED s'éteint
if
(analogRead
(lightPin)>
seuil) //Si la luminosité est plus élevée que le seuil.. .
{
digitalWrite
(ledPin, LOW
); //... alors on éteint la LED.
}
else
//Sinon...
{
digitalWrite
(ledPin, HIGH
); //...on allume la LED
}
}
XVII-D. Code 17 : variation de la luminosité d'une LED en fonction de la lumière ambiante▲
Imaginons maintenant que l'on veut faire varier la luminosité d'une LED en fonction de la luminosité de la pièce dans laquelle elle se trouve : plus il fait jour, moins la LED est lumineuse.
Théoriquement, cela n'a rien de compliqué : il suffit de combiner le signal de la photorésistance avec la valeur PWM de la LED. Pratiquement, on se retrouve avec un signal en entrée (la photorésistance) découpé en 1024 paliers, alors que ceux du signal PWM comptent 256 paliers. Seulement, 1024, c'est 256 x 4. En divisant la valeur de la variable lightReading par 4, on la rend compatible avec les 256 paliers de variation de luminosité de la LED.
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.
/*
Code 17 - Edurobot.ch, destiné à l'Arduino
Objectif: Faire varier la luminosité de la LED en fonction de la luminosité de la pièce
Source: http://learn.adafruit.com/lights
*/
int
lightPin =
0
;
int
lightReading;
int
ledPin =
9
;
int
ledBrightness;
void
setup() {
Serial
.begin(9600
);
}
void
loop() {
lightReading =
analogRead
(lightPin);
Serial
.print("Lecture analogique = "
);
Serial
.println(lightReading);
lightReading =
1023
-
lightReading;
ledBrightness =
lightReading /
4
;
analogWrite
(ledPin, ledBrightness);
delay
(100
);
}
Analyse du code
Premièrement, on va définir nos constantes et nos variables. Ainsi, la broche A0, sur laquelle la photorésistance (couplée à la résistance pull-down) est connectée est renommée lightPin. On crée ensuite une variable nommée lightReading pour y stocker la valeur analogique (comprise entre 0 et 1023) de la valeur de la photorésistance avec le diviseur de tension. Naturellement, la broche 9, sur laquelle est connectée la LED est appelée ledPin. À noter que la broche 9 est compatible PWM. Enfin, on crée une variable ledBrightness pour y stocker la valeur de luminosité de la LED (comprise entre 0 et 255).
8.
9.
10.
int
lightPin =
0
;
int
lightReading;
int
ledPin =
9
;
int
ledBrightness;
Ensuite, on stocke la valeur de la photorésistance avec un analogRead dans la variable lightReading.
lightReading =
analogRead
(lightPin);
Petit aparté : on peut contrôler le bon fonctionnement de la photorésistance en envoyant à la console d'Arduino IDE les valeurs mesurées grâce à Serial.print, qui se trouve dans Menu Outils -> Moniteur série. Ce code est donc facultatif.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
Serial
.print("Lecture analogique = "
);
Serial
.println(lightReading);
// Plus il fait sombre, plus la LED doit être brillante.
// Cela signifie qu'il faut inverser la valeur lue de 0-1023 à 1023-0, avec une soustraction.
lightReading =
1023
-
lightReading;
//Enfin il faut faire correspondre les valeurs lues de 0-1023 à 0-255 qui sont les valeurs utilisées par analogWrite.
// Pour cela, on convertit la valeur de la variable "lightReading" en la divisant par 4.
ledBrightness =
lightReading /
4
;
analogWrite
(ledPin, ledBrightness); // On allume enfin la LED avec la luminosité stockée dans la variable "ledBrightness".
delay
(100
);
}
La variation de luminosité est souvent inversée. Ainsi, un radioréveil est très lumineux lorsqu'il fait jour et peu lumineux durant la nuit. Pour simuler cela, il suffit de supprimer la ligne suivante :
lightReading =
1023
-
lightReading;
XVII-E. Code 18 : mappage de données▲
Le mappage des données est l'association des données appartenant à un ensemble avec les données appartenant à un autre ensemble, de manière que l'on puisse passer harmonieusement des premières aux secondes(11). Dans notre cas, nous avons des données inscrites dans une plage située entre 0 et 1023 que nous devons convertir dans une plage entre 0 et 255, qui correspond à 8 bits.
Si on reprend l'exercice précédent, une petite modification permet de faire le mappage des données.
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.
/*
Code 18 - Edurobot.ch, destiné à l'Arduino
Objectif : Faire varier la luminosité de la LED en fonction de la luminosité de la pièce avec mappage de données
Source : http://learn.adafruit.com/lights
*/
int
lightPin =
0
; // La photorésistance et la résistance pulldown de 1 à 10K sont connectées à A0
int
lightReading; // Lecture analogique de la valeur de la photorésistance avec le diviseur de tension
int
ledPin =
9
; // LED en PWM sur la broche 9
int
ledBrightness; // Variable pour stocker la valeur de luminosité de la LED
void
setup() {
Serial
.begin(9600
);
}
void
loop() {
lightReading =
analogRead
(lightPin);
// Affichage de la valeur de "lightReading" dans la console
Serial
.print("Lecture analogique = "
);
Serial
.println(lightReading); // Affichage de la valeur brute issue de la photorésistance.
// Plus il fait sombre, plus la LED doit être brillante.
// Cela signifie qu'il faut inverser la valeur lue de 0-1023 à 1023-0, avec une soustraction.
lightReading =
1023
-
lightReading;
// Enfin il faut faire correspondre avec la fonction "map" les valeurs lues de 0-1023 à 0-255 qui sont les valeurs utilisées par analogWrite.
ledBrightness =
map
(lightReading, 0
, 1023
, 0
, 255
);
analogWrite
(ledPin, ledBrightness); // On allume enfin la LED avec la luminosité stockée dans la variable "ledBrightness".
delay
(100
);
}
On voit à la ligne suivante le mappage :
ledBrightness =
map
(lightReading, 0
, 1023
, 0
, 255
);
la fonction map fonctionne sous la forme suivante :
Variable1 est l'origine des données. Variable2 est la destination des données.