Dans cet article nous allons faire varier la puissance électrique d’une charge connectée au Raspberry Pi avec le PWM. Le principe de fonctionnement peut permettre de contrôler par exemple l’intensité d’une lampe ou la vitesse d’un moteur.
Normalement pour effectuer cette tache, nous devrions faire varier le courant ou l’intensité dans sur la charge. Seulement voila, avec un Raspberry Pi capable uniquement d’envoyer un signal en tout ou rien comment on fait?
La réponse la voici : utiliser les deux états de façon alterné et répété. Cette technique se nomme le PWM pour Pulse Width Modulation, ce qui donne modulation de largeur d’impulsion en frenchy.
Au sommaire :
Principe de fonctionnement
La modulation de largeur d’impulsions est une technique couramment utilisée pour synthétiser des signaux continus à l’aide de circuits à fonctionnement tout ou rien. Le principe général est qu’en appliquant une succession d’impulsion (passage de l’état 0 à 1) pendant des durées bien choisies, on peut obtenir en moyenne sur une certaine durée n’importe quelle valeur intermédiaire.
Ce principe repose sur deux paramètres:
-
La fréquence (période)
-
Le rapport cyclique
La fréquence (ou période) est le nombre de fois par seconde ou l’impulsion est générée. Cela se compte entre le moment du début d’une impulsion et le début de la suivante. L’unité de la fréquence est le Hertz (Hz). Le hertz est une pulsation par seconde. Par exemple 50 Hz correspond à 50 impulsions en une secondes, se qui donne une impulsion toute les 0.02 secondes.
Le rapport cyclique est le pourcentage de temps ou le signal est en position 1 pendant le cycle. C’est donc une valeur entre 0 et 100.
Par exemple une fréquence de 50 Hz et un rapport cyclique de 50% signifie que toutes les 0.02 secondes le signal sera à 1 (high) pendant la moitié du temps et à 0 (LOW) pendant l’autre moitié.
Pour une fréquence de 50 Hz et un rapport cyclique de 80% le signal sera à 1(HIGH) pendant 80% du temps du cycle de 0.02 secondes.
Test avec une LED
Pour tester on va se servir du fameux circuit « hello world » qui se compose d’une résistance et d’une LED.
On installe la librairie python si ce n’est pas déjà fait à l’aide du gestionnaire PIP:
1 |
sudo pip3 install RPi.GPIO |
On va commencer par un simple clignotement de la LED. Le code suivant permet de faire clignoter la LED pendant 50% du temps de chaque période. Les périodes durent 0.5 Hz soit une période toutes les 2 secondes.
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 |
import RPi.GPIO as gpio import time from signal import signal, SIGINT from sys import exit def handler(signal_received, frame): # on gère un cleanup propre print('') print('SIGINT or CTRL-C detected. Exiting gracefully') gpio.cleanup() exit(0) def main(): # GPIO init gpio.setmode(gpio.BCM) gpio.setup(4, gpio.OUT) # 0.5 Hz = 1 fois toutes les deux secondes p = gpio.PWM(4, 0.5) # cycle = 50% p.start(50) # une touche pour quitter le programme. input('Appuyez sur une touche pour stopper') # La fonction input est bloquante. Si on arrive ici alors on peut fermer le programme p.stop() gpio.cleanup() if __name__ == '__main__': # On prévient Python d'utiliser la method handler quand un signal SIGINT est reçu signal(SIGINT, handler) main() |
Bon ici rien de foufou, On aurait pu faire aussi bien sans utiliser de PWM avec un simple on/off toute les 2 secondes.
On va ajouter une modulation d’intensité. Dans l’exemple suivant nous allons faire clignoter la LED mais cette fois en contrôlant son niveau d’intensité grâce au rapport de cycle.
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 |
import RPi.GPIO as gpio import time from signal import signal, SIGINT from sys import exit def handler(signal_received, frame): # on gère un cleanup propre print('') print('SIGINT or CTRL-C detected. Exiting gracefully') gpio.cleanup() exit(0) def main(): # GPIO init gpio.setmode(gpio.BCM) gpio.setup(4, gpio.OUT) # 50 Hz p = gpio.PWM(4, 50) # cycle = 0% p.start(0) while 1: for dc in range(0, 101, 1): p.ChangeDutyCycle(dc) time.sleep(0.01) for dc in range(100, -1, -1): p.ChangeDutyCycle(dc) time.sleep(0.01) if __name__ == '__main__': # On prévient Python d'utiliser la method handler quand un signal SIGINT est reçu signal(SIGINT, handler) main() |
Le résultat (sur la vidéo on à l’impression que la LED clignote en plus de monter et descendre en intensité. C’est du au nombre d’images par seconde qu’est capable de prendre ma caméra. Le résultat en réel est bien sur + lisse).
Variation de vitesse d’un moteur via Raspberry
Les ports GPIO du Raspberry n’envoient qu’un signal de 3,3 V. Alors comment faire varier la puissance d’une charge nécessitant bien plus que ces 3,3V comme par exemple un moteur ? Pour cela nous allons utiliser un composant qui fonctionne comme un interrupteur que l’on appel MOSFET. Un MOSFET est un composant électronique permettant de faire de la commande en puissance. Le principe du fonctionnement de ce type de transistor est que lorsque la tension de la Gate atteint une valeur suffisante, le courant passe entre le Drain et la Source. Certains transistors sont commandés en courant, le MOSFET est commandé en tension.
Je vous renvoie à l’article ou je donne une description du fonctionnement du MOSFET.
Donc le MOSFET permet de séparer le circuit ou ce trouve nôtre charge du circuit de commande, en l’occurrence le Rpi.
Voila le schéma avec un moteur éclectique et une alimentation sur batterie de 12V. Notez qu’un diode de roue libre est ajoutée pour protéger le MOSFET des hausses de tension à chaque coupure de courant.Le code à utiliser pour tester est exactement le même que pour le clignotement de la LED avec avec variation d’intensité.
pour les moteurs il module qui marche formidablement bien
http://tsin.langevin-la-seyne.fr/SIN/robot-raspberry-pi-d-inspection.html
https://www.robotshop.com/ca/fr/controleur-deux-moteurs-tb6612fng-v2.html
Bonjour
J’ai mis un commentaire trop rapide
Mettre un pont en H
malheureusement tu utilises en python gpio.pwn() qui est en soft non gestion des timers en hard sorties dédiées sur le pi comme i2c spi,…. (voir la version de ton pi)
Ta pwn n’ai absolument pas stable tu vas faire hurler les puristes comme moi………
Il existe des lib c++ intégrables dans ton python pour avoir une vrai pwm gestion des timers
Bonjour
J’ai mis un commentaire trop rapide
Mettre un pont en H
malheureusement tu utilises en python gpio.pwm() qui est en soft non gestion des timers en hard sorties dédiées sur le pi comme i2c spi,…. (voir la version de ton pi)
Ta pwm n’est absolument pas stable tu vas faire hurler les puristes comme moi………
Il existe des lib c++ intégrables dans ton python pour avoir une vrai pwm gestion des timers
Ps avec ce temps limité ,on n’a pas le temps de ce relire
pas mal ! Dans tous les cas, pour les moteurs, il est pas mal de prendre une carte dédiée avec un driver dédié, ça peut éviter bien des surprises. En général, les drivers sont protégés en courant, surtension, etc. Et ça essaye d’éviter que si un problème arrive, le micro meurt aussi (http://jumpifnotzero.free.fr/auteur/images/pcb-brulant.png)
Et dis donc, t’aurais pas dessiner ton 12V à l’enverse ? 😉
ha non je me réponds, c’est juste que j’ai pas l’habitude de le voir dessiné comme ça 😉
Ping : Variation de puissance électrique via Raspberry – Framboise 314, le Raspberry Pi à la sauce française…. – Jhc Info