Gestion du PWM

D’abord, c’est quoi le PWM, à quoi ça sert ?

Lorsqu’on veut faire varier l’intensité d’une lampe ou la vitesse d’un moteur par exemple, il y a deux façons de faire :

-          Soit on modifie la tension aux bornes du composant, on lui met plus de volts et ça tourne plus vite ou ça s’allume plus. Si on met deux piles de 1.5V en série, ça ira plus vite ou ça éclairera plus que si il n’y en a qu’une…

-          Soit on découpe la tension d’alimentation pour faire clignoter très rapidement la lampe ou donner des impulsions très rapide au moteur.

Avec notre Raspberry, la première solution est impossible à appliquer. Les sorties du Raspberry donnent du 0V ou du 3.3V, impossible de leurs dire donnez-moi 1V ou 2V. En plus notre LED doit être alimentée à sa tension de seuil, si on met moins, elle s’éteint, si on met plus, elle risque de griller.

On va donc essayer la deuxième solution.

Si vous avez bien tout suivi, on l’a déjà fait. Notre programme de clignotement de LED pouvait modifier le temps pendant lequel la LED était éteinte et allumée.

Si on met en temps d’allumage time.sleep(0.001) en Python ou delay(1) en C et un temps d’extinction à time.sleep(0.009) en Python ou delay(9) en C, notre LED sera allumée pendant 1 ms et éteinte pendant 9 ms, on pourra donc dire que notre LED est allumé à 10%, si on inverse les temps d’allumage et d’extinction, elle sera allumée à 90%. (Listing dans les fichiers blink10.py, blink10.c, blink90.py et blink90.c en fin de document avec la broche GPIO18)

Afficher l'image d'origine

Là, on le fait via un programme qui consomme beaucoup de temps machine, alors que le Raspberry peut le faire lui-même via l’une de ses broches, la GPIO18 et elle seule.

Au fait, ça veut dire quoi PWM ?

C’est Pulse Width Modulation en anglais, soit modulation de largeur d'impulsions en français.

Avant toute modification éteignez et débranchez le Raspberry et refaire le câblage de la cathode de la LED de la broche physique 22 à la 12 (GPIO25 à GPIO18).

               Avant (GPIO 25)                                     Après (GPIO 18)


 

1.1        Programme C

 

#include <iostream>        // Include pour affichage et clavier

#include <wiringPi.h> // Include WiringPi library!

 

using namespace std;

 

// Pin number declarations. We're using the Broadcom chip pin numbers.

const int pwmPin = 18; // PWM LED - Broadcom pin 18, P1 pin 12

 

int pwmValue = 0; // Use this to set an LED brightness

 

int main(void)

{

    // Setup stuff:

    wiringPiSetupGpio(); // Initialize wiringPi -- using Broadcom pin numbers

 

    pinMode(pwmPin, PWM_OUTPUT); // Set PWM LED as PWM output

 

    cout << "PWM is running! Press CTRL+C to quit" << endl;

 

    // Loop (while(1)):

    while(1)

    {

             cout << "Rapport cyclique actuel: " << pwmValue << endl;

             cout << "Rapport cyclique désiré: ";

             cin >> pwmValue;

             pwmWrite(pwmPin, pwmValue); // Entre 0 et 1024

    }

 

    return 0;

}

Nommez le par exemple pwm.cpp (mettez bien cpp en extension car on commence à faire du C++)

On utilise quelques nouvelles fonctions :

-          cout pour afficher.

-          cin pour récupérer une valeur au clavier

-          endl pour un saut de ligne

-          using namespace std permet d’utiliser ces fonctions sans les préfixer (on devrait écrire std::cout)

La compilation « g++ -o pwm pwm.cpp -l wiringPi ». Non, ce n’est pas une erreur, c’est bien g++, on ajoute une extension au C et on fait du C++.

L’exécution sudo ./pwm

Plusieurs remarques :

-          Le rapport cyclique est entre 0 et 1024, si on veut éclairer notre LED à moitié, il faut indiquer 512.

-          Une valeur qui n’est pas dans la plage 0 à 1024 est ignorée.

-          Quand on fait un CTRL-C pour arrêter le programme, l’invite de commande est au milieu de l’écran, appuyer sur la touche « Entrée » pour le remettre à gauche.


 

1.2        Programme python

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import RPi.GPIO as GPIO

servo_pin = 18  # équivalent de GPIO 18

GPIO.setmode(GPIO.BCM)  # notation BCM

GPIO.setup(servo_pin, GPIO.OUT)  # pin configurée en sortie

pwm = GPIO.PWM(servo_pin, 50)  # pwm à une fréquence de 50 Hz

rapport = 7       # rapport cyclique initial de 7%

pwm.start(rapport) 

while True:

    print "Rapport cyclique actuel: " , rapport

    rapport = raw_input ("Rapport cyclique désiré:  ")

    pwm.ChangeDutyCycle(float(rapport))

 

Sauvegarde dans un fichier « pwm.py » et démarrage par « python pwm.py »

On a des résultats comme ceci, avec des variations d’intensité lumineuse de la LED

 

Plusieurs remarques :

-          Cette fois, le rapport cyclique est en pourcentage, soit de 0 à 100.

-          Une valeur qui n’est pas dans la plage 0 à 100 fait planter le programme.

-          Un CTRL-C arrête le programme au bon endroit.

-          Si la broche utilisée est déjà programmé, python vous l’indique.

Si vous avez comme moi, des caractères bizarres à la place des caractères accentuées, c’est que l’encodage n’est pas bon. Vous avez déclaré en tête un encodage utf-8 mais votre fichier est encodé en autre chose. Dans ce cas, utilisé un éditeur de texte performant comme Notepad++ qui vous permettra d’avoir le bon encodage (Sur Linux, tout se passe bien, cela pose problème avec Notepad Windows par exemple).

Allez dans le menu Encodage, sélectionnez « Encoder en UTF-8 » et sauvegardez votre fichier.

En plus, Notepad++ fait de la coloration syntaxique, c’est plus sympa à lire.

On a bien les accents.


 

1.3        Liste des programmes

https://github.com/montotof123/raspberry/blob/master/030_Pwm/blink10.c

https://github.com/montotof123/raspberry/blob/master/030_Pwm/blink90.c

https://github.com/montotof123/raspberry/blob/master/030_Pwm/blink10.py

https://github.com/montotof123/raspberry/blob/master/030_Pwm/blink90.py

https://github.com/montotof123/raspberry/blob/master/030_Pwm/pwm.cpp

https://github.com/montotof123/raspberry/blob/master/030_Pwm/pwm.py

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Lien vers la base du site.