Capteur de luminosité, photodiode
Ce tutoriel explique comment mettre en œuvre un module capteur de lumière analogique Grove avec MicroPython.
Ce module utilise une photorésistance afin de mesurer l’intensité lumineuse de son environnement, dont la valeur diminue lorsqu’elle est éclairée. Cet exemple est une nouvelle illustration, directe, de la conversion d’un signal en tension variable dans le temps (la réponse de la photodiode) en une réponse numérique, via un ADC.
Si la conversion en une grandeur physique (exprimée en Lux) de l’échantillonnage de l’ADC est en théorie possible, c’est une opération difficile qui nécessite une description complète du capteur de luminosité utilisé, description malheureusement indisponible… Si vous souhaitez un capteur capable de mesurer avec précision l’intensité lumineuse ambiante en Lux, nous vous conseillons le module Grove basé sur le TSL2561.
Les modules Grove capteur de luminosité sont disponibles en au moins deux versions, qui se comportent et se programment de façon identique malgré leur aspect différent :
Grove light sensor v1.0 | Grove light sensor v1.2 |
---|---|
Crédit image : Seeed Studio
Pour commencer
Dans cette première partie nous allons expliquer comment échantillonner l’intensité lumineuse à l’aide du module capteur de lumière analogique.
Matériel requis et montage
- Une carte d’extension de base Grove avec son commutateur d’alimentation positionné sur 5V.
- La carte NUCLEO-WB55
- Un module capteur de luminosité Grove
Connectez le capteur sur la fiche A1.
Le code MicroPython
Vous pouvez télécharger les scripts MicroPython de ce tutoriel (entre autres) en cliquant ici.
Editez le fichier main.py et collez y le code qui suit, avant de l’enregistrer dans le répertoire du périphérique PYBFLASH :
# Lecture et numérisation du signal d'un capteur Grove de luminosité (LS06-S phototransistor)
# Attention : le capteur doit être alimenté en 5V pour donner une réponse entre 0 et 4095.
from pyb import ADC, Pin # Convertisseur analogique-numérique et GPIO
from time import sleep # Pour les temporisations
# Instanciation et démarrage du convertisseur analogique-numérique
adc = ADC(Pin('A1'))
while True:
# Numérise la valeur lue, produit un résultat variable dans le temps
# dans l'intervalle [0 ; 4095]
sampled = adc.read()
print("Luminosité %d (sans unités)" %sampled)
sleep(1) # Temporisation d'une seconde
Manipulation
Lancez le script avec la combinaison de touches [CTRL]-[D] dans votre terminal série.
Une valeur comprise entre 0 et 4095, proportionnelle à la luminosité ambiante, s’affiche toutes les secondes :
MicroPython v1.19.1 on 2022-06-18; NUCLEO-WB55 with STM32WB55RGV6
Type "help()" for more information.
>>>
MPY: sync filesystems
MPY: soft reboot
Luminosité 279 (sans unités)
Luminosité 279 (sans unités)
Luminosité 279 (sans unités)
Luminosité 277 (sans unités)
Luminosité 275 (sans unités)
Luminosité 269 (sans unités)
Luminosité 151 (sans unités)
Luminosité 1907 (sans unités)
Luminosité 2123 (sans unités)
Luminosité 1563 (sans unités)
Luminosité 1221 (sans unités)
Luminosité 1200 (sans unités)
Luminosité 1158 (sans unités)
Luminosité 1138 (sans unités)
Pour aller plus loin
Dans cette partie nous allons voir comment faire une veilleuse automatique. Pour cela nous allons utiliser une LED et une photorésistance.
Matériel requis
- Une carte d’extension de base Grove avec son commutateur d’alimentation positionné sur 5V.
- La carte NUCLEO-WB55
- Un module capteur de luminosité Grove
- Un module Grove LED (peu importe la couleur de la LED). Ne vous trompez pas sur la polarité de la LED lorsque vous la brancherez dans le module ; la patte la plus longue va dans le connecteur “+” !
Moduler l’intensité d’une LED avec un signal PWM
En temps normal, une LED est alimentée par une tension provenant d’une patte numérique qui ne peut fournir que deux niveaux : haut (0V) et bas (3,3V). Par conséquent la LED sera soit éteinte, soit allumée à une intensité fixe. Afin de moduler plus finement l’intensité d’une LED, il faut lui fournir plusieurs niveau de tensions. C’est là qu’intervient l’utilisation d’un timer pour générer un signal PWM, lequel passe de l’état haut à l’état bas à une fréquence élevée. Cette alternance de niveaux de tension (le rapport cyclique) est équivalente à appliquer une tension moyenne comprise entre les deux états.
Pour résumer : changer le rapport cyclique de la PWM permet de changer la luminosité de la LED. Par exemple : on a une PWM alimentée de 0V à 5V avec une fréquence de 1kHz et un rapport cyclique de 50%. On obtient alors 50% de 5V soit 2,5V ; la LED sera alimentée avec une tension équivalente à 2,5V.
Pour réaliser le montage, connectez le capteur de la photorésistance sur la broche A1 et le module LED sur la broche D6. Cette broche n’a pas été choisie arbitrairement, elle doit être multiplexée avec la sortie PWM d’un timer. Pour plus d’explications à ce sujet, consultez ce tutoriel.
Le code MicroPython
Vous pouvez télécharger les scripts MicroPython de ce tutoriel (entre autres) en cliquant ici.
Editez le fichier main.py et collez y le code qui suit, avant de l’enregistrer dans le répertoire du périphérique PYBFLASH :
# Objet du script :
# Conception d'une veilleuse d'obscurité ...
# - Lit l'intensité lumineuse ambiante avec un capteur Grove
# de luminosité (LS06-S phototransistor)
# - Allume une LED (module Grove) avec une intensité
# inversement proportionnelle à la lumière ambiante.
# Alimentation du Grove base shield sur 5V
# LED connectée sur D6 (PWM Timer 1, Channel 1)
# Photodiode connectée sur A1
from time import sleep_ms
from pyb import ADC, Timer
# Photorésistance sur A1 (analogique)
adc = ADC('A1')
# LED sur D6 (sortie PWM)
led = pyb.Pin('D6', pyb.Pin.OUT_PP)
# Configuration du timer : timer 1 channel 1
# sur broche d6 (d'après la cartographie des PWM de la NUCELO-WB55)
d6 = pyb.Pin('D6', pyb.Pin.OUT_PP)
# Fréquence du timer fixée à 100 Hz
tim_d6 = pyb.Timer(1, freq = 100)
# Génération de signal PWM démarrée sur D6
pwm_d6 = tim_d6.channel(1, pyb.Timer.PWM, pin=d6)
# Fonction pour remapper un intervalle de valeurs dans un autre
def map (value, from_min, from_max, to_min, to_max):
return (value-from_min) * (to_max-to_min) / (from_max-from_min) + to_min
while True:
# Récupération de la valeur de la photorésistance
sampled = adc.read()
# Convertit la lecture analogique en pourcentage
ambiant_light_percentage = map(sampled, 0, 4095, 0, 100)
# Change l'intensité de luminosité de la LED via la PWM
pwm_d6.pulse_width_percent(100 - ambiant_light_percentage)
# Temporisation d'une seconde
sleep_ms(1000)
Manipulation
Lancez le script avec la combinaison de touches [CTRL]-[D] dans votre terminal série.
Mettez votre doigt sur le capteur, vous devriez remarquer que la LED devient plus lumineuse. A contrario, si vous approchez une source de lumière du capteur alors la LED s’éteint progressivement.