Je dis toujours : « Avant de vous lancer dans un projet de tondeuse à gazon guidée par GPS avec évitement d’obstacles à laser et retour vidéo, apprenez déjà à allumer une LED ? » …
Enfin, vous faites comme vous voulez, ce n’est que mon avis… Patrice nous propose dans son premier article pour framboise314 de faire clignoter une LED avec un Raspberry Pi … Un tracteur pour déplacer un œuf me direz vous !
Mais La Saga Blink aborde de nombreuse façons de le faire. Au menu: bash, Python, nodejs, wiringpi, pigpio, Rpi.GPIO …
Au sommaire :
Introduction
Rien de neuf sous les tropiques car il existe une multitude de tutoriels, de présentations et autres billets sur le sujet. La présentation s’adresse aux débutants expérimentés c’est à dire ceux qui disposent d’un Raspberry Pi opérationnel et qui n’ont pas peur d’utiliser la console pour l’élaboration des programmes. Les experts n’ont pas besoin de cette présentation et la trouveront certainement inutile.
Il faut, à un moment donné, un début.
Faire clignoter une LED sur le Raspberry Pi ou autres cartes consœurs (Arduino, ChipKit, LaunchPad, etc…) est le pendant du traditionnel « Hello World ! » de l’apprentissage d’un langage de programmation.
Base d’expérimentation.
Pour notre expérimentation, il nous faut :
- Un raspberry Pi opérationnel,
- Une LED,
- Une résistance de 330 Ω (ou entre 330 et 470 Ω).
Schéma électronique
L’anode de la diode LED (patte longue) est raccordée à la sortie GPIO23 (broche 16 du connecteur P5).
La cathode (patte courte) est reliée à la masse du Raspberry Pi (Ground), par exemple la pin 20 du connecteur P5.
La résistance R1 sert à limiter le courant traversant la LED. Plus cette résistance est élevée et moins le courant sera élevé. Attention, une résistance trop faible risque de détruire la sortie GPIO par dépassement du courant maximal.
Schéma de câblage
Le câblage est simple et demande que peu de composants. On peut le réaliser avec un cobbler comme sur la photo de la figure 1 ou par une connexion directe sur le port GPIO du raspberry (voir figure 3).
Le cobbler est un accessoire qui permet de déporter les pins du GPIO vers une plaque d’essai (breadboard).
Remarque : Le RPI3 de la photo figure 3 est équipé de l’écran officiel de la Fondation mais non utilisé dans les expérimentations qui suivent.
Cahier des charges.
Tout programmeur qui se respecte doit disposer ou établir un cahier des charges qui défini les différentes opérations à réaliser. Dans notre cas, il sera très simple.
Notre cahier des charges :
- allumer la led,
- attendre 1 seconde,
- éteindre la led,
- attendre 1 seconde,
- continuer en 1) (on répète indéfiniment la boucle)
Organigramme
L’organigramme est une représentation graphique du déroulement de notre programme. Il comporte les différentes étapes qui permettront une transcription dans un langage donné.
Le premier pavé, qui nous intéresse, est « Initialisation » qui consiste à préparer la pin GPIO23 pour qu’elle puisse piloter la led.
Après cette phase, il faut allumer la LED.
Puis attendre x secondes (dans notre cas 1 sec.).
Après cette attente, on éteint la LED.
Suivi d’une nouvelle attente de x secondes (1 sec. pour notre exemple).
Et finalement, on reprend le cycle en allumant la LED et cela indéfiniment (boucle infinie).
Programmation.
Les différents programmes abordés dans la suite peuvent être exécutés sur toutes les versions du Raspberry Pi (type A, B, jusqu’au RPI3 y compris le Zero).
La saisie des programmes se fait via un éditeur de texte graphique (par exemple geany) ou en mode console (par exemple nano).
L’accès au Raspberry Pi peut se faire via son interface écran HDMI / clavier ou bien par l’intermédiaire d’un connexion à distance (mode console ou graphique).
Pour ma part, j’utilise une connexion console via une liaison SSH.
Dans la suite, nous verrons quelques programmes qui effectuent tous les mêmes actions (allumer / éteindre la LED) mais dans des langages différents.
Bash
Dans l’os Linux tout est « fichier » donc nous ferons des opérations de création, lecture, écriture et suppression de fichiers.
Programme
Pour saisir ce programme, il faut faire dans la console :
nano blink90.sh
Cette commande ouvre un fichier texte vide appelé blink90.sh (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
La combinaison Ctrl+o signifie l’appuie sur la touche Ctrl ainsi que la touche o.
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
#!/bin/bash #Programme classique LED clignotante #Led rouge sur GPIO23 via une résistance de 330 Ohms #logiciel : bash #cible : raspberry Pi #date de création : 17/06/2016 #date de mise à jour : 18/06/2016 #version : 1.0 #auteur : icarePetibles #référence : #Remarques : Pour fonctionner, il faut être sous super utilisateur # Il faut rendre le fichier exécutable avec # sudo chmod +x blink90.sh # Pour exécuter le fichier, il faut faire # sudo ./blink90.sh # #Attention : Ce script à des effets de bord lorsqu'on interrompt la boucle # infinie par Ctrl-C. On a des messages d'errreur lors de la relance # du script mais fonctionne néanmoins # echo "23" > /sys/class/gpio/export #assigne pin echo "out" > /sys/class/gpio/gpio23/direction #en sortie while true; #boucle infinie do echo "1" > /sys/class/gpio/gpio23/value #allume led # echo "Led allumée" #message IHM sleep 1; #attente 1 sec echo "0" > /sys/class/gpio/gpio23/value #éteint led # echo "Led éteinte" #message IHM sleep 1; #attente 1 sec done #fin script
Si l’on supprime les lignes de commentaires, il ne reste plus que 9 lignes.
Les commentaires sont importants si l’on souhaite reprendre un programme après quelques jours car notre mémoire n’est pas fiable. Ce qui était évident lors de l’écriture du programme devient incompréhensible. On peut également insérer des remarques concernant l’utilisation du programme (lignes 11 à 20).
Les lignes 21 et 22 correspondent à la phase « Initialisation« .
L’allumage de la LED se fait ligne 25 suivi d’une attente d’une seconde ligne 27.
L’extinction de la led se fait ligne 28 suivi de l’attente ligne 30.
Si l’on dé-commandante les lignes 26 et 29, le programme affiche également l’état de la LED dans la console.
Exécution du programme.
Pour exécuter ce programme bash, il faut le rendre exécutable avec la commande :
sudo chmod +x blink90.sh
Et pour l’exécuter :
sudo ./blink90.sh
Pour sortir de la boucle infinie, il suffit de faire un Ctrl+c au clavier (voir la remarque lignes 17 à 19 du programme).
Python
Le pilotage des ports GPIO, sous Python s’appuie sur des bibliothèques. Les bibliothèques RPi.GPIO et gpiozero sont incluses dans les versions de Python. Nous utiliserons également les bibliothèques pigpio et wiringpi qui devront être installées sous Python.
Rpi.GPIO
Programme
Pour saisir ce programme, il faut faire dans la console :
nano blink01.py
Cette commande ouvre un fichier texte vide appelé blink01.py (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
#!/usr/bin/python3 # -*- coding:utf-8 -*- """ Programme classique LED clignotante Led rouge sur GPIO23 via une résistance de 330 Ohms logiciel : python 3.4.2 cible : raspberry Pi date de création : 08/06/2016 date de mise à jour : 08/06/2016 version : 1.0 auteur : icarePetibles référence : """ #------------------------------------------------------------------------------- # Bibliothèques #------------------------------------------------------------------------------- import RPi.GPIO as GPIO #bibliothèque RPi.GPIO import time #bibliothèque time #------------------------------------------------------------------------------- GPIO.setwarnings(False) #désactive le mode warning GPIO.setmode(GPIO.BCM) #utilisation des numéros de ports du #processeur GPIO.setup(23, GPIO.OUT) #mise en sortie du port GPIO 23 (broche #16 du connecteur) if __name__ == '__main__': """ Programme par défaut """ # print(sys.version) #affiche version python print("Début du programme LED clignotante") #message IHM while True : #boucle infinie GPIO.output(23, GPIO.HIGH) #sortie 23 high time.sleep(1) #attente 1 seconde GPIO.output(23, GPIO.LOW) #sortie 23 low time.sleep(1) #attente 1 seconde #-------------------------------------------------------------------------------
Les lignes 20 à 24 correspondent à la phase « Initialisation ».
L’allumage de la LED se fait ligne 34 suivi d’une attente d’une seconde ligne 35.
L’extinction de la LED se fait ligne 36 suivie de l’attente ligne 37.
La ligne 31 transmet un message console signalant le démarrage du programme.
Exécution du programme
Pour exécuter ce programme, il faut lancer la commande suivante dans la console Linux :
python3 blink01.py
Pour sortir de la boucle infinie, il suffit de faire un Ctrl+c au clavier.
Commentaire bibliothèque
La documentation concernant cette librairie est faible au niveau de la toile. On trouvera quelques informations sur le site :
https://sourceforge.net/p/raspberry-gpio-python/wiki/Home/
On peut également avoir des informations sous Python par les commandes suivantes :
python3 >>> import Rpi.GPIO as gp >>> help(gp)
Rappel : pour sortir de l’interpréteur python, il suffit de faire Ctrl+d
Remarque : le contenu de cette librairie est étique et ne gère pas les bus I²C ou SPI.
gpiozero
Programme
Pour saisir ce programme, il faut faire dans la console :
nano blink20.py
Cette commande ouvre un fichier texte vide appelé blink20.py (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
#!/usr/bin/python3 # -*- coding:utf-8 -*- """ Programme classique LED clignotante Led rouge sur GPIO23 via une résistance de 330 Ohms logiciel : python 3.4.2 cible : raspberry Pi date de création : 09/06/2016 date de mise à jour : 09/06/2016 version : 1.0 auteur : icarePetibles référence : https://gpiozero.readthedoc.io/en/v1.2.0/ """ #------------------------------------------------------------------------------- # Bibliothèques #------------------------------------------------------------------------------- from gpiozero import LED #bibliothèque gpiozero from time import sleep #sleep de la bibliothèque time #------------------------------------------------------------------------------- if __name__ == '__main__': """ Programme par défaut """ led = LED(23) #instance LED sur GPIO23 while True: #boucle infinie led.on() #allume led sleep(0.5) #pause 0.5 sec led.off() #éteind led sleep(0.5) #pause 0.5 sec #-------------------------------------------------------------------------------
La ligne 24 correspond à la phase « Initialisation ».
L’allumage de la LED se fait ligne 26 suivi d’une attente d’une demi-seconde ligne 27. L’extinction de la LED se fait ligne 28 suivi de l’attente ligne 29.
Exécution du programme
Pour exécuter ce programme, il faut lancer la commande suivante dans la console Linux :
python3 blink20.py
Pour sortir de la boucle infinie, il suffit de faire un Ctrl+c au clavier.
Commentaire bibliothèque
La documentation pour cette librairie peut être consultée sur le site :
https://gpiozero.readthedocs.io/en/v1.2.0/
On peut également avoir quelques informations supplémentaires par les commandes suivantes :
python3 >>> import gpiozero >>> help(gpiozero)
Rappel : pour sortir de l’interpréteur Python, il suffit de faire Ctrl+d
Remarque : le contenu de cette librairie est nettement plus riche en méthodes que la précédente et gère le bus I²C ou SPI.
wiringpi
Programme
Pour utiliser la bibliothèque wiringpi, il faut l’installer au préalable. On trouvera la procédure l’installation sous le lien :
https://github.com/WiringPi/WiringPi-Python/
Pour saisir ce programme, il faut faire dans la console :
nano blink60.py
Cette commande ouvre un fichier texte vide appelé blink60.py (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
#!/usr/bin/python3 # -*- coding:utf-8 -*- """ Programme classique LED clignotante Led rouge sur GPIO23 via une résistance de 330 Ohms logiciel : python 3.4.2 cible : raspberry Pi date de création : 21/06/2016 date de mise à jour : 21/06/2016 version : 1.0 auteur : icarePetibles référence : wiringpi.com Remarques : """ #------------------------------------------------------------------------------- # Bibliothèques #------------------------------------------------------------------------------- import wiringpi #bibliothèque wiringpi #------------------------------------------------------------------------------- if __name__ == '__main__': """ Programme par défaut """ print("\nDébut du programme LED clignotante") #messages IHM LED = 4 #sortie LED sur GPIO23 = 4 mode wiringpi DUREE = 1000 #durée demi période = 1 sec ON = 1 OFF = 0 wiringpi.wiringPiSetup() #mode wiringpi ou "pseudo Arduino" wiringpi.pinMode(LED, 1) #pi en sortie sortie wiringpi.digitalWrite(LED, OFF) #led éteinte while True: #boucle infinie wiringpi.digitalWrite(LED, ON) #allume led wiringpi.delay(DUREE) #attente DUREE wiringpi.digitalWrite(LED, OFF) #éteind led wiringpi.delay(DUREE) #attente DUREE #-------------------------------------------------------------------------------
Les lignes 30 à 32 correspondent à la phase « Initialisation ».
L’allumage de la LED se fait ligne 34 suivi d’une attente d’une seconde ligne 35.
L’extinction de la LED se fait ligne 36 suivi de l’attente ligne 37.
La ligne 24 transmet un message console signalant le démarrage du programme.
Exécution du programme
Pour exécuter ce programme, il faut lancer la commande suivante dans la console Linux avec les privilèges root :
sudo python3 blink60.py
Pour sortir de la boucle infinie, il suffit de faire un Ctrl+c au clavier.
Commentaire bibliothèque
La documentation pour cette librairie peut être consultée sur le site :
http://wiringpi.com/reference/
On peut également avoir quelques informations supplémentaires par les commandes suivantes :
python3 >>> import wiringpi >>> help(wiringpi)
Rappel : pour sortir de l’interpréteur python, il suffit de faire Ctrl+d
Remarque : le contenu de cette librairie est également très riche en méthodes et gère le bus I²C ou SPI.
Langage C
Le pilotage des ports GPIO, sous C s’appuie sur la bibliothèque wiringPi. L’installation de cette bibliothèque et décrite sur le site de wiringPi sous le lien : http://wiringpi.com/download-and-install/
wiringPi
Programme
Pour saisir ce programme, il faut faire dans la console :
nano blink80.c
Cette commande ouvre un fichier texte vide appelé blink80.c (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
/* ----------------------------------------------------------------------------- Programme classique LED clignotante Led rouge sur GPIO23 (4) via une résistance de 330 ohms os : RPi Linux 4.4.13+ logiciel : gcc (Raspbian 4.9.2-10) 4.9.2 cible : raspberry Pi date de création : 21/06/2016 date de mise à jour : 22/06/2016 version : 1.0 auteur : icarePetibles référence : www.wiringpi.com Remarques : ----------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------- Bibliothèques ----------------------------------------------------------------------------- */ #include <stdio.h> //utilisé pour printf() #include <wiringPi.h> //bibliothèque wiringPi //------------------------------------------------------------------------------ #define LED 4 //numéro led = GPIO23 int main(void){ //programme principale printf("Led clignotante\n"); //IHM wiringPiSetup(); //numérotation wiringPi ou "pseudo Arduino" pinMode(LED, OUTPUT); //pin en sortie for(;;){ //boucle infinie digitalWrite(LED, HIGH); //allume led delay (500); //attente 0.5 sec digitalWrite(LED, LOW); //éteint led delay (500); //attente 0.5 sec } return(0); //code sortie } //------------------------------------------------------------------------------
Les lignes 23 et 24 correspondent à la phase « Initialisation ».
L’allumage de la LED se fait ligne 26 suivi d’une attente de 0.5 seconde ligne 27.
L’extinction de la LED se fait ligne 28 suivie de l’attente ligne 29.
La ligne 22 transmet un message console signalant le démarrage du programme.
Exécution du programme
Pour exécuter se programme, il faut d’abord le compiler. La compilation se fait par la commande ci-dessous (en mode console) :
gcc -Wall -o blink80 blink80.c -lwiringPi
Le résultat de la compilation est un fichier : blink80
Lancement du programme :
sudo ./blink80
Pour sortir de la boucle infinie, il suffit de faire un Ctrl+c au clavier.
Commentaire bibliothèque
La documentation pour cette librairie peut être consultée sur le site :
http://wiringpi.com/reference/
Cette bibliothèque est la même que celle utilisée au paragraphe 4.3 mais qui elle était adaptée à Python.
Perso
Une petite récréation avec une bibliothèque GPIO personnelle qui n’apporte rien de particulier et elle est même un tantinet « capillotracté ».
La bibliothèque se compose de 2 fichiers ipsGPIO.h (fichier entête) et ipsGPIO.c (fichier fonctions) qui sont utilisés dans le programme blink50.c pour piloter le port GPIO du Raspberry Pi.
Programme
Bibliothèque perso
Pour saisir ce programme ipsGPIO.h, il faut faire dans la console :
nano ipsGPIO.h
Cette commande ouvre un fichier texte vide appelé ipsGPIO.h (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
/* ----------------------------------------------------------------------------- Programme classique LED clignotante Fichier entête de ipsGPIO.c os : RPi Linux 4.4.13+ (Jessie) logiciel : gcc (Raspbian 4.9.2-10) 4.9.2 cible : raspberry Pi date de création : 26/06/2016 date de mise à jour : 28/06/2016 version : 1.0 auteur : icarePetibles référence : Remarques : ----------------------------------------------------------------------------- */ #ifndef IPS_H #define IPS_H //directives constantes #define ENTREE 0 #define SORTIE 1 #define DESACTIVE 2 #define HAUT 1 #define BAS 0 #define VRAI 1 #define FAUX 0 //prototypes fonctions void afficheLn(const char * nom); //eq. println() void affiche(const char * nom); //eq. print() void modeBroche(int, int); //eq. pinMode() void ecritureDigitale(int, int); //eq. digitalWrite() void dormir(unsigned int); //eq. delay() unsigned long int mTemps(void); //eq. millis() #endif
Ce fichier contient les définitions des constantes et les prototypes des fonctions.
Pour saisir ce programme ipsGPIO.c, il faut faire dans la console :
nano ipsGPIO.c
Cette commande ouvre un fichier texte vide appelé ipsGPIO.c (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
/* ----------------------------------------------------------------------------- Programme classique LED clignotante Fichier bibliothèque ipsGPIO.c os : RPi Linux 4.4.13+ (Jessie) logiciel : gcc (Raspbian 4.9.2-10) 4.9.2 cible : raspberry Pi date de création : 26/06/2016 date de mise à jour : 28/06/2016 version : 1.0 auteur : icarePetibles référence : Remarques : ----------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------- Bibliothèques ----------------------------------------------------------------------------- */ #include <stdio.h> //bibliothèque entrées/sorties #include <string.h> //manipulation chaîne #include <stdlib.h> //conversion nombre et autres #include <unistd.h> //types et constantes #include "ipsGPIO.h" //bibliothèque ipsGPIO /* ---------------------------------------------------------------------------- Fonction affichage avec retour ligne suivant SYNTAXE : afficheLn("texte") eq. println() ---------------------------------------------------------------------------- */ void afficheLn(const char * nom){ printf("%s\n", nom); //IHM } /* ---------------------------------------------------------------------------- Fonction affichage sans retour ligne suivant SYNTAXE : affiche("texte") eq. print() ---------------------------------------------------------------------------- */ void affiche(const char * nom){ printf("%s", nom); //IHM } /* ---------------------------------------------------------------------------- Fonction définition du mode de fonctionnement de la broche SYNTAXE : modeBroche(BROCHE, MODE) BROCHE : Port GPIOXX MODE : ENTREE = 0, SORTIE = 1 ou DESACTIVEE = 2 eq. pinMode() ---------------------------------------------------------------------------- */ void modeBroche(int broche, int mode){ char bufferBroche[10]; //buffer de conversion sprintf(bufferBroche, "%d", broche); //conversion int en string char commande[50] = ""; //buffer commande if(mode == 1){ //broche en sortie //commande bash pour assigner le port //echo PIN > /sys/class/gpio/export strcpy(commande, "echo "); //composition commande par concaténation strcat(commande, bufferBroche);//composition commande strcat(commande, " > /sys/class/gpio/export"); //composition commande system(commande); //envoi commande système //commande bash pour assigner le port en sortie //echo out > /sys/class/gpio/gpioPIN/direction strcpy(commande, "echo out > /sys/class/gpio/gpio"); //composition commande par concaténation strcat(commande, bufferBroche);//composition commande strcat(commande, "/direction");//composition commande system(commande); //envoi commande système } else if(mode == 2){ //broche déactivée //commande bash pour désactiver le port //echo PIN > /sys/class/gpio/unexport strcpy(commande, "echo "); strcat(commande, bufferBroche); strcat(commande, " > /sys/class/gpio/unexport"); system(commande); } else { //broche en entrée *** en attente *** // //commande bash pour assigner le port // //echo PIN > /sys/class/gpio/export // strcpy(commande, "echo "); //composition commande par concaténation // strcat(commande, bufferBroche);//composition commande // strcat(commande, " > /sys/class/gpio/export"); // //composition commande // system(commande); //envoi commande système // //commande bash pour assigner le port en entrée // //echo in > /sys/class/gpio/gpioPIN/direction // strcpy(commande, "echo in > /sys/class/gpio/gpio"); // //composition commande par concaténation // strcat(commande, bufferBroche);//composition commande // strcat(commande, "/direction");//composition commande // system(commande); //envoi commande système } } /* ---------------------------------------------------------------------------- Fonction écriture état de sortie de la broche SYNTAXE : ecritureDigitale(BROCHE, ETAT) BROCHE : XX (Port GPIOXX) ETAT : HAUT = 1 = 3.3V ou BAS = 0 = 0V eq. digitalWrite() ---------------------------------------------------------------------------- */ void ecritureDigitale(int broche, int etat){ char bufferBroche[10]; //buffer de conversion sprintf(bufferBroche, "%d", broche); //conversion int en string char commande[50] = ""; //buffer commande if(etat == 1){ //état HAUT //commande bash pour état haut //echo 1 > /sys/class/gpio/gpioPIN/value strcpy(commande, "echo 1 > /sys/class/gpio/gpio"); //composition commande par concaténation strcat(commande, bufferBroche);//composition commande strcat(commande, "/value"); //composition commande system(commande); //envoi commande système } else { //état BAS //commande bash pour état bas //echo 0 > /sys/class/gpio/gpioPIN/value strcpy(commande, "echo 0 > /sys/class/gpio/gpio"); //composition commande par concaténation strcat(commande, bufferBroche);//composition commande strcat(commande, "/value"); //composition commande system(commande); //envoi commande système } } /* ---------------------------------------------------------------------------- Fonction attente blocante SYNTAXE : dormir(TEMPS) TEMPS : XX (en milli-seconde) eq. delay() ---------------------------------------------------------------------------- */ void dormir(unsigned int temps){ temps = temps * 1000; //temps en micro-seconde usleep(temps); //attente } /* ---------------------------------------------------------------------------- Fonction retourne le temps système SYNTAXE : TEMPS = mTemps() TEMPS : XX (en milli-seconde) eq. millis() ---------------------------------------------------------------------------- */ unsigned long int mTemps(void){ unsigned long int temps = 0; //variable enttière double uptime, idleTime; //variables décimales FILE* fp; //variable fichier fp = fopen("/proc/uptime", "r"); //ouverture fichier en lecture fscanf(fp, "%lf %lf\n", uptime, idleTime); //lecture données fclose(fp); //fermeture fichier temps = (unsigned long int)(uptime * 1000); //mise en forme sec en msec return temps; //retour temps } /* ------------------------------------------------------------------------- */
Le principe de ce programme est relativement simple puisqu’on appelle des commandes « bash » à partir d’un programme en C (system(commande)).
Les commentaires du programme sont auto-suffisants pour la compréhension.
Programme blink
Pour saisir ce programme blink50.c, il faut faire dans la console :
nano blink50.c
Cette commande ouvre un fichier texte vide appelé blink50.c (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
/* ----------------------------------------------------------------------------- Programme classique LED clignotante Led rouge sur GPIO23 via une résistance de 330 ohms os : RPi Linux 4.4.13+ (Jessie) logiciel : gcc (Raspbian 4.9.2-10) 4.9.2 cible : raspberry Pi date de création : 22/06/2016 date de mise à jour : 22/06/2016 version : 1.0 auteur : icarePetibles référence : Remarques : ----------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------- Bibliothèques ----------------------------------------------------------------------------- */ #include <stdio.h> //bibliothèque entrées/sorties #include "ipsGPIO.h" //bibliothèque ipsGPIO #define LED 23 //led sur GPIO23 int main(void){ //programme principal affiche("Led clignotante"); //IHM afficheLn(" by icarePetibles"); //IHM modeBroche(LED, SORTIE); //GPIO23 en sortie for(;;){ //boucle infinie ecritureDigitale(LED, HAUT); //allume led dormir(1000); //attente ecritureDigitale(LED, BAS); //éteint led dormir(1000); //attente } return 0; //code sortie }
La syntaxe utilisée est proche de celle de wiringPi ou Arduino mais en français.
La ligne 25 correspondent à la phase « Initialisation ».
L’allumage de la LED se fait ligne 27 suivi d’une attente d’une seconde ligne 28.
L’extinction de la LED se fait ligne 29 suivie de l’attente ligne 30.
Les lignes 23 et 24 transmettent des messages console signalant le démarrage du programme.
Exécution du programme
Pour exécuter ce programme, il faut d’abord le compiler. La compilation se fait par la commande ci-dessous (en mode console) pour les différents fichiers C en créant des fichier objet :
gcc -c ipsGPIO.c gcc -c blink50.c
Et pour terminer, il faut créer le fichier final via l’éditeur de lien :
gcc -o blink50 blink50.o ipsGPIO.o
Le résultat de la compilation est un fichier : blink50
Lancement du programme :
sudo ./blink50
Pour sortir de la boucle infinie, il suffit de faire un Ctrl+c au clavier.
Remarque : On peut supprimer les fichiers objets (.o) du répertoire courant par :
rm *.o
Commentaire bibliothèque
Cette bibliothèque n’a rien d’extraordinaire mais montre uniquement que l’on peut arriver à ses fins avec un peu d’imagination et peu de moyens.
Comme souvent les solutions ou les erreurs se trouvent localisées entre la chaise et le clavier.
Cette bibliothèque fera certainement l’objet de mise à jour lors d’une autre « Saga ».
Conclusion intermédiaire
La première partie de notre expérimentation se termine. On aurait pu faire la même chose avec d’autres langages de programmation.
Les programmes réalisés ne me conviennent pas, principalement pour les raisons suivantes :
- Lorsqu’on sort de la boucle infinie par une sortie sauvage du genre Ctrl+c, on abandonne la boucle en laissant la sortie GPIO dans un état incertain (ce n’est pas très propre)
- Le temps d’attente dans les boucles est du type bloquant, c’est-à-dire que la tâche attend la fin avant de faire autre chose. On peut admettre ce type de programmation pour une démonstration mais pas dans un programme réel.
- Si on avait réalisé d’autres traitements informatiques dans la boucle sans fin, ils auraient subit des retards d’exécution à cause des attentes bloquantes de la boucle.
On peut corriger cette situation par les programmes qui suivent.
Organigramme
Il comporte les différentes étapes qui permettront une transcription dans un langage donné.
Le premier pavé, qui nous intéresse, est « Initialisation » qui consiste à préparer la pin GPIO23 pour qu’elle puisse piloter la LED.
Après cette phase, on teste si un caractère a été saisi au clavier, si c’est le cas, on sort de la boucle sans fin en éteignant la LED et on désalloue la ressource GPIO.
Dans le cas contraire, on teste si la LED a été allumée ou éteinte pendant un temps égal ou supérieur à DUREE.
Si c’est le cas, on permute l’état de la LED.
Dans le cas contraire, on peut traiter une autre tâche, puis on boucle pour refaire les mêmes opérations.
Bash
Programme
Pour cette partie du programme qui traite des valeurs décimales, il y a lieu d’installer le paquet bc pour que bash puisse faire les traitements correspondants.
sudo apt-get update sudo apt-get install bc
Pour saisir ce programme, il faut faire dans la console :
nano blink93.sh
Cette commande ouvre un fichier texte vide appelé blink93.sh (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
#!/bin/bash #Programme classique LED clignotante #Led rouge sur GPIO23 via une résistance de 330 Ohms #Ajout Gestion Ctrl-C #Ajout attente non bloquante #Ajout vérification mode super utilisateur #logiciel : bash #cible : raspberry Pi #date de création : 18/06/2016 #date de mise à jour : 18/07/2016 #version : 1.0 #auteur : icarePetibles #référence : #Remarques : Pour fonctionner, il faut être sous super utilisateur # Il faut rendre le fichier exécutable avec # sudo chmod +x blink93.sh # Pour exécuter le fichier, il faut faire # sudo ./blink93.sh # LEDPIN=23 #GPIO23 OFF=0 #variable éteindre ON=1 #variable allumée DUREE=1000 #demi-période ETATLED=0 #led éteinte #vérification si accès root #if [ $EUID -ne 0 ] #si $EUID différent de 0 if [ $EUID != "0" ] #si $EUID différent de 0 then #alors echo "Il faut être root pour exécuter le script. Essaye sudo $0" exit #sortie fi #fin if #Procédure de netoyage, éteind led, désactive la sortie cleanup() { PIN=$1 #paramètre transmis # echo $PIN #affiche paramètre transmis #dans notre cas 23 echo $OFF > /sys/class/gpio/gpio$PIN/value #led éteinte echo $PIN > /sys/class/gpio/unexport #désactive port echo #esthétique echo Interruption #message IHM echo Led éteinte et pin désactivée #message IHM echo Fin script #message de fin exit #sortie } #lecture temps function mTemps() { ligne=<code>cat /proc/uptime</code> #lit uptime et idletime #valeurs décimales mTemps=$(echo "$ligne" | cut -f 1 -d ' ') #extrait uptime mTemps=$(echo "$mTemps*1000" |bc) #multiplie par 1000 pour #avoir des msec mTemps=${mTemps%%.*} #float to int return $mTemps #valeur mTemps } #programme principal echo Led clignotante #message de début echo ctrl-c pour sortir de la boucle #IHM #Setup pin et direction - Cature Control-C SIGHUP SIGKILL echo $LEDPIN > /sys/class/gpio/export #assigne pin 23 echo out > /sys/class/gpio/gpio$LEDPIN/direction #pin 23 en sortie #trap "cleanup $LEDPIN" 1 2 15 #capture SIGNAL trap "cleanup $LEDPIN" SIGHUP SIGINT SIGTERM #capture SIGNAL et lance la #la procédure cleanup avec #le paramètre 23 mTemps #lecture référence temps valeurPrecedente=$mTemps #sauve temps msec while true #boucle infinie do #faire mTemps #lecture référence temps valeurActuelle=$mTemps #sauve temps msec let "diff=$valeurActuelle - $valeurPrecedente" #calcule durée état if [ $diff -ge $DUREE ] #si temps écoulé >= DUREE then #alors valeurPrecedente=$valeurActuelle #init valeur précédente if [ $ETATLED -eq $ON ] #si led allumée then #alors echo $OFF > /sys/class/gpio/gpio$LEDPIN/value #éteint led # echo Led éteinte #affichage console ETATLED=$OFF #led éteinte else #sinon echo $ON > /sys/class/gpio/gpio$LEDPIN/value #allume led # echo Led allumée #affichage console ETATLED=$ON #led allumée fi fi # #Autres traitements # done #fin do #Fin du script
Les différentes variables sont définies aux lignes 20 à 24, si l’on souhaite modifier la fréquence du clignotement, il suffit de changer la valeur de DUREE (en milli-seconde).
En ligne 27, on teste si on est en mode « sudo » avec le message ad hoc (pas nécessaire dans notre cas).
La fonction cleanup(), ligne 34, permet une sortie « propre » de la boucle sans fin en éteignant la LED et en désactivant le port.
La fonction mTemps(), ligne 48, permet de mesurer le temps écoulé depuis le démarrage du Raspberry PI. Elle permet de mesurer la durée d’allumage/d’extinction de la LED.
Les lignes 62 et 63 correspondent à la phase « Initialisation ».
La ligne 65 capture le signal Ctrl+c et lance la fonction cleanup avec le paramètre correspondant à la LED.
L’allumage (ligne 85) ou l’extinction (ligne 80) de la LED est réalisé lorsque la différence entre valeurPrecedente et valeurActuelle est supérieure ou égale à DUREE.
Exécution du programme
Pour exécuter ce programme bash, il faut le rendre exécutable avec la commande :
sudo chmod +x blink93.sh
Et pour l’exécuter :
sudo ./blink93.sh
Pour sortir de la boucle infinie, il suffit de faire un Ctrl+c au clavier.
Python
Rpi.GPIO
Programme
Pour saisir ce programme, il faut faire dans la console :
nano blink04.py
Cette commande ouvre un fichier texte vide appelé blink04.py (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
#!/usr/bin/python3 # -*- coding:utf-8 -*- """ Programme classique LED clignotante Led rouge sur GPIO23 via une résistance de 330 Ohms Ajout d'une possibilité de sortie de la boucle sans fin Ajout temporisation non bloquante logiciel : python 3.4.2 cible : raspberry Pi date de création : 08/06/2016 date de mise à jour : 19/07/2016 version : 1.0 auteur : icarePetibles référence : """ #------------------------------------------------------------------------------- # Bibliothèques #------------------------------------------------------------------------------- import RPi.GPIO as GPIO #bibliothèque RPi.GPIO import time #bibliothèque time #------------------------------------------------------------------------------- if __name__ == '__main__': """ Programme par défaut """ #------------------------------------------------------------------------------- # Constantes #------------------------------------------------------------------------------- DUREE = 0.5 #durée demi période = 0.5 sec LED = 23 #sortie LED sur GPIO23 #------------------------------------------------------------------------------- GPIO.setwarnings(False) #désactive le mode warning GPIO.setmode(GPIO.BCM) #utilisation des numéros de ports du #processeur GPIO.setup(LED, GPIO.OUT) #mise en sortie du port GPIO 23 (broche #16 du connecteur) print("\nDébut du programme LED clignotante") print("Arrêt du clignotement par ctrl+c") #messages IHM GPIO.output(LED, GPIO.HIGH) #initialisation sortie 23 allume led etatLed = True #led allumée previousTime = time.time() #valeur time précédente try: while True : #boucle infinie currentTime = time.time() #sauve time actuel if abs(currentTime - previousTime) >= DUREE: #si temps écoulé >= à DUREE previousTime = currentTime #nouveau time précédent if etatLed: #si led allumée GPIO.output(LED, GPIO.LOW) #éteind led etatLed = False #led éteinte else: #si led éteinte GPIO.output(LED, GPIO.HIGH) #allume led etatLed = True #led allumée #capture du ctrl+c et sortie boucle except KeyboardInterrupt: GPIO.output(LED, GPIO.LOW) #Eteint la LED GPIO.cleanup() #remet toutes pins en entrée print("\nFin du programme\n") #IHM #-------------------------------------------------------------------------------
La phase « Initialisation » est faite aux lignes 32 à 36.
L’allumage (ligne 55) ou l’extinction (ligne 51) de la LED est réalisé lorsque la différence entre previousTime et currentTime est supérieure ou égale à DUREE.
La ligne 59 capture le signal Ctrl+c qui éteint la LED et libère les ressources GPIO.
Exécution du programme
Pour exécuter ce programme, il faut lancer la commande suivante dans la console Linux :
python3 blink04.py
Pour sortir de la boucle infinie, il suffit de faire un Ctrl+c au clavier.
gpiozero
Programme
Je déroge un peu de l’organigramme du chapitre 7, sinon on a toujours la même structure du programme. Il existe dans la bibliothèque gpiozero une fonction blink().
Pour saisir ce programme, il faut faire dans la console :
nano blink25.py
Cette commande ouvre un fichier texte vide appelé blink25.py (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
#!/usr/bin/python3 # -*- coding:utf-8 -*- """ Programme classique LED clignotante Led rouge sur GPIO23 via une résistance de 330 Ohms logiciel : python 3.4.2 cible : raspberry Pi date de création : 09/06/2016 date de mise à jour : 19/07/2016 version : 1.0 auteur : icarePetibles référence : https://gpiozero.readthedoc.io/en/v1.2.0/ """ #------------------------------------------------------------------------------- # Bibliothèques #------------------------------------------------------------------------------- from gpiozero import LED #bibliothèque gpiozero #------------------------------------------------------------------------------- if __name__ == '__main__': """ Programme par défaut """ DUREE = 0.5 #durée demi-période print("\nDébut du programme LED clignotante") print("Arrêter le clignotement - ctrl+c") #messages IHM led = LED(23) #instance LED sur GPIO23 led.blink(DUREE, DUREE) #clignote avec valeur par défaut try: while True : #boucle infinie pass #circuler, il n'y a rien à voir except KeyboardInterrupt: #capture ctrl+c print("\nFin du programme\n") #IHM #------------------------------------------------------------------------------- # Documentation #------------------------------------------------------------------------------- # led.blink(0.01, 1, 10, True) #voir Documentation (1) #pause() (attente signal) est remplacé par la boucle infinie while True #(1) #led.blink(on_time=1, off_time=1, n=None, background=True) #on_time = nombre de secondes (float) led allumée #off_time = nombre de secondes (float) led éteinte #n = nombre de clignotement - None = en continu #background = True (défaut) - démarre une tâche (thread) de clignotement # d'arrière plan et retour #background = Flase -retour que si le clignotement et fini (att. avec la valeur # par défaut de n, on n'aura jamais de retour #-------------------------------------------------------------------------------
La structure de ce programme est très simple. La phase « Initialisation » se résume à la ligne 27.
Pour le clignotement de la LED, tout est ligne 28. Le reste n’est que de l’habillage et l’attente de capture du Ctrl+c.
L’utilisation de led.blink() fait clignoter la LED avec les paramètres par défaut, c’est à dire en continu avec une demi-période de 1 seconde.
Syntaxe : Led.blink(on_time=1, off_time=1, n=None, background=True) on_time = durée d'allumage led (en sec) off_time = durée d'extinction led (en sec) n = nombre de clignotement (n=None clignotement continu) background = principe d'exécution de la tâche True (par défaut) = démarre la tâche et retourne False = retour après la fin du clignotement (Attention : avec n=None et background=False, on n'aura plus la main).
Exécution du programme
Pour exécuter ce programme, il faut lancer la commande suivante dans la console Linux :
python3 blink25.py
Pour sortir de la boucle infinie, il suffit de faire un Ctrl+c au clavier.
wiringpi
Programme
Pour l’installation de la bibliothèque voir le paragraphe 4.3.1.
Pour saisir ce programme, il faut faire dans la console :
nano blink62.py
Cette commande ouvre un fichier texte vide appelé blink62.py (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
#!/usr/bin/python3 # -*- coding:utf-8 -*- """ Programme classique LED clignotante Led rouge sur GPIO23 via une résistance de 330 Ohms Ajout sortie boucle infinie et attente non blocante logiciel : python 3.4.2 cible : raspberry Pi date de création : 21/06/2016 date de mise à jour : 19/07/2016 version : 1.0 auteur : icarePetibles référence : www.wiringpi.com Remarques : à exécuter avec les privilèges root """ #------------------------------------------------------------------------------- # Bibliothèques #------------------------------------------------------------------------------- import wiringpi #bibliothèque wiringpi #------------------------------------------------------------------------------- if __name__ == '__main__': """ Programme par défaut """ print("\nDébut du programme LED clignotante") print("Arrêter le clignotement - ctrl+c") #messages IHM LED = 4 #sortie LED sur GPIO23 = 4 mode wiringpi DUREE = 500 #durée demi période = 0.5 sec ON = 1 OFF = 0 wiringpi.wiringPiSetup() #mode wiringpi ou "pseudo Arduino" wiringpi.pinMode(LED, 1) #pi en sortie sortie wiringpi.digitalWrite(LED, OFF) #led éteinte etatLed = False #sauve temps précédent (en msec) previousTime = wiringpi.millis() try: while True: #boucle infinie currentTime = wiringpi.millis() #sauve temps actuel if (currentTime - previousTime) >= DUREE: #si temps écoulé >= à DUREE (en msec) previousTime = currentTime #sauve temps précédent (en msec) if etatLed: #si led allumée wiringpi.digitalWrite(LED, OFF) #éteind led etatLed = False #led éteinte else: #si led éteinte wiringpi.digitalWrite(LED, ON) #allume led etatLed = True #led allumée except KeyboardInterrupt: #capture ctrl+c wiringpi.digitalWrite(LED, OFF) #éteind led wiringpi.pinMode(LED, 0) #pin en entrée print("\nFin du programme\n") #IHM #-------------------------------------------------------------------------------
La structure de ce programme est identique à ceux que l’on a déjà vu jusqu’à présent.
Exécution du programme
Pour exécuter ce programme, il faut lancer la commande suivante dans la console Linux :
sudo python3 blink62.py
Pour sortir de la boucle infinie, il suffit de faire un Ctrl+c au clavier.
pigpio
Pour utiliser la bibliothèque pigpio, il faut l’installer au préalable. On trouvera la procédure l’installation sous le lien :
http://abyz.co.uk/rpi/pigpio/download.html
Programme
Ce programme, pour changer, utilise une autre méthode pour sortir de la boucle infinie. La saisie non bloquante d’un caractère clavier est incluse dans un module Python indépendant.
Pour saisir ce programme, il faut faire dans la console :
nano saisieCarac.py
Cette commande ouvre un fichier texte vide appelé saisieCarac.py (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
#!/usr/bin/python3 # -*- coding:utf-8 -*- """ Saisie caractère clavier non blocante logiciel : python 3.4.2 cible : raspberry Pi date de création : 08/06/2016 date de mise à jour : 16/06/2016 version : 1.0 auteur : icarePetibles référence : http://home.wlu.edu/~levys/software/kbhit.py """ #------------------------------------------------------------------------------- # Bibliothèques #------------------------------------------------------------------------------- import os #système d'exploitation import sys #informations système import termios #interface posix et contrôle I/O tty import atexit #nettoyage et enrégistrement fonctions from select import select #accès contrôles I/O plateforme #------------------------------------------------------------------------------- # Classe KBHit #------------------------------------------------------------------------------- class KBHit: #------------------------------------------------------------------------------- def __init__(self): """ Création d'un objet KBHit que l'on peut appeler pour faire différentes choses """ #Remarque : On ne traite pas le cas de windows #Sauvegade les paramètres du terminal self.fd = sys.stdin.fileno() #la méthode fileno() renvoie le #descripteur de fichier d'un objet de #type fichier self.new_term = termios.tcgetattr(self.fd) self.old_term = termios.tcgetattr(self.fd) #retourne une liste contenant les #attributs tty pour le descripteur de #fichier fd self.new_term[3] = (self.new_term[3] ~termios.ICANON ~termios.ECHO) #ICANON désactivé et ECHO désactivé termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.new_term) #fixe les attributs tty pour le #descripteur de fichier fd à partir des #attributs, qui est une liste comme #celle retournée par tcgetattr() #Réinitialisation terminal normal et sortie atexit.register(self.set_normal_term) #enrégistre la fonction à exécuter à la #fin #------------------------------------------------------------------------------- def set_normal_term(self): """ Reset vers le mode normal du terminal """ #Remarque : On ne traite pas le cas de windows termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.old_term) #fixe les attributs tty pour le #descripteur de fichier fd à partir des #attributs, qui est une liste comme #celle retournée par tcgetattr() #------------------------------------------------------------------------------- def getch(self): """ Renvoi le caractère du clavier après un appel KBHit(). """ s = '' #Remarque : On ne traite pas le cas de windows return sys.stdin.read(1) #lecture du caractère de stdin #------------------------------------------------------------------------------- def kbhit(self): """ Retourne True si un caractère a été frappé au clavier, sinon False """ #Remarque : On ne traite pas le cas de windows dr, dw, de = select([sys.stdin], [], [], 0) return dr != [] #True ou False #------------------------------------------------------------------------------- #Test #------------------------------------------------------------------------------- if __name__ == "__main__": kb = KBHit() #instance KBHit() print("Début du programme") print("Appuyer sur une touche, ou ESC pour sortir") while True: #boucle sans fin if kb.kbhit(): #si touche clavier c = kb.getch() #lecture touche if ord(c) == 27: #si ESC break #sortie de la boucle sans fin print(c) #affiche le caractère kb.set_normal_term() #terminal en mode normal print("Fin du programme") #message HIM #-------------------------------------------------------------------------------
Les lignes 82 à 95 permettent de tester le programme de saisie.
Pour saisir ce programme blink, il faut faire dans la console :
nano blink41.py
Cette commande ouvre un fichier texte vide appelé blink41.py (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ees commentaires sont représentés ci-dessous.
#!/usr/bin/python3 # -*- coding:utf-8 -*- """ Programme classique LED clignotante Led rouge sur GPIO23 via une résistance de 330 Ohms Ajout sortie boucle infinie Ajout test pigpiod existe Ajout temporisation non bloquante logiciel : python 3.4.2 cible : raspberry Pi date de création : 09/06/2016 date de mise à jour : 19/06/2016 version : 1.0 auteur : icarePetibles référence : abyz.co.uk/rpi/pigpio/index.html Remarques : """ #------------------------------------------------------------------------------- # Bibliothèques #------------------------------------------------------------------------------- from saisieCarac import * #saisie caractère non blocante import time #bibliothèque time import pigpio #bibliothèque pigpio import os #bibliothèque os #------------------------------------------------------------------------------- if __name__ == '__main__': """ Programme par défaut """ #Test si pigpiod existe sinon lance sudo pigpiod if os.system('pidof pigpiod >/dev/null') == 256: os.system('sudo pigpiod >/dev/null') print("'sudo pigpiod' lancé par le programme") #------------------------------------------------------------------------------- kb = KBHit() #instance KBHit() print("\nDébut du programme LED clignotante") print("Arrêter le clignotement - appuyer sur 'q'") #messages IHM LED = 23 #sortie LED sur GPIO23 DUREE = 0.5 #durée demi période = 0.5 sec ON = 1 #esthétique OFF = 0 #esthétique pi = pigpio.pi() #connection à la tâche pigpiod pi.set_mode(LED, pigpio.OUTPUT) #configure pin en sortie pi.write(LED, ON) #sortie 23 allume led etatLed = True #led allumée previousTime = pi.get_current_tick() #valeur time précédente (en micro-sec) while True: #boucle infinie if kb.kbhit(): #test si touche appuiée c = kb.getch() #lecture de la touche if c.lower() == "q": #touche q ou Q break #sortie de boucle infinie currentTime = pi.get_current_tick() #sauve time actuel (en micro-sec) if pigpio.tickDiff(previousTime, currentTime)/1000000.0 >= DUREE: #si temps écoulé >= à DUREE (en sec) previousTime = currentTime #nouveau time précédent if etatLed: #si led allumée pi.write(LED, OFF) #éteind led etatLed = False #led éteinte else: #si led éteinte pi.write(LED, ON) #allume led etatLed = True #led allumée pi.set_mode(LED, pigpio.INPUT) #nettoyage kb.set_normal_term() #rétablie le terminal normal print("\nFin du programme\n") #message IHM pi.stop() #déconnexion #-------------------------------------------------------------------------------
Pour exécuter ce programme, il faut lancer au préalable une tâche de fond qui assure le contrôle des autres tâches. Si vous l’oubliez, les lignes 31 à 33 le feront pour vous.
Ligne 21, on importe les fonctions pour la saisie non bloquante d’un caractère au clavier.
Les lignes 50 à 53 permettent de sortir de la boucle infinie si l’on saisie ‘q’ ou ‘Q’ au clavier.
Le reste du programme nous est familier.
Exécution du programme
Pour exécuter ce programme, il faut lancer la commande suivante dans la console Linux :
python3 blink41.py
Pour sortir de la boucle infinie, il suffit de faire un q ou Q au clavier.
Commentaire bibliothèque
La documentation pour cette librairie peut être consultée sur le site :
http://abyz.co.uk/rpi/pigpio/python.html
On peut également avoir quelques informations supplémentaires par les commandes suivantes :
python3 >>> import pigpio >>> help(pigpio)
Rappel : pour sortir de l’interpréteur Python, il suffit de faire Ctrl+d
Graphique tkinter
Un peu de graphisme pour piloter notre LED.
Programme
Pour saisir ce programme, il faut faire dans la console :
nano blink70.py
Cette commande ouvre un fichier texte vide appelé blink70.py (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
#!/usr/bin/python3 # -*- coding:utf-8 -*- """ Programme led clignotante avec interface graphique os : RPi Linux 4.4.13+ logiciel : python3.4.2 cible : raspberry Pi date de création : 25/06/2016 date de mise à jour : 25/06/2016 version : 1.0 auteur : icarePetibles référence : Remarques : """ #------------------------------------------------------------------------------- # Bibliothèques #------------------------------------------------------------------------------- from tkinter import * #bibliothèque graphique tkinter import RPi.GPIO as GPIO #bibliothèque RPi.GPIO #------------------------------------------------------------------------------- #variables et constantes DUREE = 500 #1/2 période du clignotement led largeur = 26 #largeur canvas hauteur = 26 #hauteur canvas ledOn = '#ff0000' #led allumée couleur rouge ledOff = '#B1B1B1' #led éteinte couleur grise etatLed = False #led éteinte #------------------------------------------------------------------------------- #fonctions #------------------------------------------------------------------------------- def maj(): """Bascule état led en fonction de DUREE""" global etatLed #variable global - pas très orthodose #mais pour faire simple if(etatLed): #si led allumée etatLed=False #led éteinte GPIO.output(23, GPIO.LOW) #sortie 23 low - led éteinte des1.itemconfig(lumiere, fill=ledOff) #affiche la led éteinte else: #si led éteinte etatLed=True #led éteinte GPIO.output(23, GPIO.HIGH) #sortie 23 high - led allumée des1.itemconfig(lumiere, fill=ledOn) #affiche la led allumée des1.update_idletasks() #force le rafraîchissement graphique des1.after(DUREE, maj) #appel maj après écoulement DUREE #------------------------------------------------------------------------------- def quitter(): """Quitte l'application""" GPIO.output(23, GPIO.LOW) #sortie 23 low GPIO.setup(23, GPIO.IN) #GPIO23 en entrée quit() #sortie de mainloop destroy() #détruit l'objet ainsi que les enfants #------------------------------------------------------------------------------- def initialisation(): """Initialisation""" GPIO.setwarnings(False) #désactive le mode warning GPIO.setmode(GPIO.BCM) #numérotation ports processeur GPIO.setup(23, GPIO.OUT) #sortie sur GPIO23 GPIO.output(23, GPIO.LOW) #sortie 23 low #------------------------------------------------------------------------------- #programme pricipal #------------------------------------------------------------------------------- fen = Tk() #instance Tk fen.title('La saga Blink') #titre de la fenêtre fen.iconbitmap('@framboise.xbm') #icon de l'application largApplication = 300 #largeur de l'application hautApplication = 110 #hauteur de l'application largDisplay = fen.winfo_screenwidth() #largeur de l'écran en pixels hautDisplay = fen.winfo_screenheight() #hauteur de l'écran en pixels posX = int((largDisplay - largApplication)/2) #position X de l'appli pour être centrer posY = int((hautDisplay - hautApplication)/2) #position Y de l'appli pour être centrer fen.geometry('{}x{}+{}+{}'.format(largApplication, hautApplication, posX, posY)) #taille et position de la fenêtre fen.resizable(False, False) #ne permet pas le re-dimensionnement fen.protocol('WM_DELETE_WINDOW', quitter) #sortie par la petite croix (X) #------------------------------------------------------------------------------- #création objets graphiques #------------------------------------------------------------------------------- tex1=Label(fen, text='La saga Blink - Led clignotante', font="Tahoma 12 bold", fg="blue") #label message tex1.pack(padx=5, pady=5) #activation graphique des1=Canvas(fen, width=largeur, height=hauteur, bd=0) #canvas pour le dessin de la led center=int(largeur/2) r=int((largeur-2)/2) lumiere=des1.create_oval(center-r+1, center-r+1,center+r, center+r, fill=ledOff, outline="") #dessine led avec couleur éteinte des1.pack() #activation graphique bou1=Button(fen, text='Quitter', font="Tahoma 10", command=quitter) #button pour quitter l'application bou1.pack(padx=5, pady=5) #activation graphique tex2=Label(fen, text='icarePetibles ', font="Tahoma 7") #label auteur ;) tex2.pack(side=RIGHT) #activation graphique #------------------------------------------------------------------------------- initialisation() #paramètres de départ maj() #lance le 'Blink' fen.mainloop() #boucle infinie graphique fen.destroy() #destruction de la fenêtre #-------------------------------------------------------------------------------
Normalement pour ce type de programme, la logique voudrait que l’on crée une classe pour l’application. Mais pour que le programme soit plus lisible, ce n’est pas le cas.
Notre programme comporte trois fonctions (initialisation, quitter et maj).
initialisation() : déclare et initialise le port GPIO via la bibliothèque RPi.GPIO (on aurait pu faire la même chose avec les autres bibliothèques).
quitter() : éteint la LED, libère la ressource port GPIO, sort de la boucle infinie et détruit le graphique. Cette fonction est appelée par le bouton quitter ou la petite croix (à droite et en haut de la fenêtre graphique).
maj() : cette fonction est appelée toutes les DUREE pour permuter l’état de la LED et l’affichage graphique.
Dans les lignes 65 à 78, on construit le support de notre fenêtre application. A la ligne 79, on capture le clic sur la petite croix.
Dans les lignes 84 à 102, on implémente les labels, bouton, canvas et dessin (LED).
Ligne 104 : on lance l’initialisation.
Ligne 105 : on déclenche le clignotement de la LED.
Ligne 106 : on active la boucle infinie graphique.
Ligne 107 : on détruit l’application graphique.
Exécution du programme
Pour exécuter ce programme, il faut lancer la commande suivante dans la console Linux dans l’environnement graphique :
python3 blink70.py
Pour sortir de la boucle infinie, il suffit de cliquer sur le bouton Quitter ou sur la petite croix.
Langage C
wiringPi
Pour ce programme, on utilise la même méthode pour sortir de la boucle infinie que pour pigpio. La saisie non bloquante d’un caractère clavier est incluse dans un fichier .h. Les experts du C vont voir tout rouge car on ne met pas de code dans un fichier .h, mais cela fonctionne et l’on fera mieux dans le prochain source. 🙂
Programme
Pour saisir ce programme, il faut faire dans la console :
nano saisieCarac.h
Cette commande ouvre un fichier texte vide appelé saisieCarac.h (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
/* ----------------------------------------------------------------------------- Programme saisie non bloquante caractère au clavier os : RPi Linux 4.4.13+ logiciel : gcc (Raspbian 4.9.2-10) 4.9.2 cible : raspberry Pi date de création : 22/06/2016 date de mise à jour : 22/06/2016 version : 1.0 auteur : icarePetibles référence : Remarques : ----------------------------------------------------------------------------- */ #ifndef saisieCarac_h #define saisieCarac_h /* ----------------------------------------------------------------------------- Bibliothèques ----------------------------------------------------------------------------- */ #include <stdio.h> //bibliothèque standard #include <termios.h> //bibliothèque entrées/sorties terminal #include <unistd.h> //bibliothèque constantes symboliques #include <fcntl.h> //bibliothèque descripteur de fichier /* -------------------------------------------------------------------------- */ int kbhit(void){ //fonction indiquant si frappe clavier struct termios oldt, newt; int ch; int oldf; tcgetattr(STDIN_FILENO, oldt); //sauve paramètres terminal newt = oldt; newt.c_lflag = ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, newt); //nouveaux paramètres terminal oldf = fcntl(STDIN_FILENO, F_GETFL, 0); fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); ch = getchar(); //lecture caractère tcsetattr(STDIN_FILENO, TCSANOW, oldt); //restaure paramètres terminal fcntl(STDIN_FILENO, F_SETFL, oldf); if(ch != EOF){ ungetc(ch, stdin); //replace le caractère dans le flux stdin //affiche le caractère dans la console return 1; //valeur de retour caractère saisie } return 0; //valeur de retour pas de caractère } /* -------------------------------------------------------------------------- */ #endif
Pour saisir le programme blink, il faut faire dans la console :
nano blink81.c
Cette commande ouvre un fichier texte vide appelé blink81.c (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
/* ----------------------------------------------------------------------------- Programme classique LED clignotante Led rouge sur GPIO23 (4) via une résistance de 330 ohms Ajout sortie boucle infinie et attente non blocante os : RPi Linux 4.4.13+ logiciel : gcc (Raspbian 4.9.2-10) 4.9.2 cible : raspberry Pi date de création : 22/06/2016 date de mise à jour : 22/06/2016 version : 1.0 auteur : icarePetibles référence : www.wiringpi.com Remarques : ----------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------- Bibliothèques ----------------------------------------------------------------------------- */ #include <stdio.h> //bibliothèque entrées/sorties #include <wiringPi.h> //bibliothèque wiringPi #include "saisieCarac.h" //fonction saisie caractère non bloquant #include <ctype.h> //bibliothèque pour tolower() //------------------------------------------------------------------------------ #define LED 4 //numéro led = GPIO23 #define DUREE 1000 int main(void){ //programme principal int c; //stocke touche clavier unsigned int valeurActuelle = 0; unsigned int valeurPrecedente = 0; int etatLed = FALSE; printf("Led clignotante\n"); //IHM printf("'q' pour arrêter le clignotement\n"); wiringPiSetup(); //numérotation wiringPi ou "pseudo Arduino" pinMode(LED, OUTPUT); //pin en sortie digitalWrite(LED, LOW); //led éteinte valeurPrecedente = millis(); for(;;){ //boucle infinie if(kbhit()) //si touche saisie c = getchar(); //lecture touche if(tolower(c) == 'q') //test si 'q' ou 'Q' break; //sortie de la boucle valeurActuelle = millis(); if(valeurActuelle - valeurPrecedente >= DUREE){ valeurPrecedente = valeurActuelle; if(etatLed){ digitalWrite(LED, LOW); etatLed = FALSE; } else { digitalWrite(LED, HIGH); etatLed = TRUE; } } } digitalWrite(LED, LOW); //éteint led pinMode(LED, INPUT); //pi en entrée printf("\nFin du programme\n"); //IHM return(0); //code sortie } //------------------------------------------------------------------------------
Rien de neuf par rapport à ce que l’on a vu dans les programmes précédents.
Exécution du programme
Pour exécuter se programme, il faut d’abord le compiler. La compilation se fait par la commande ci-dessous (en mode console) :
gcc -Wall -o blink81 blink81.c -lwiringPi
Le résultat de la compilation est un fichier : blink81
Lancement du programme :
sudo ./blink81
Pour sortir de la boucle infinie, il suffit de faire un ‘q’ ou ‘Q’ au clavier.
Perso
Programme
Ce programme se compose d’un fichier blink52.c et de deux bibliothèques externes (saisieCarac.h et ipsGPIO.h). La bibliothèque ipsGPIO.h est la même que celle du paragraphe 5.2.
saisieCarac.h et saisieCarac.c
Pour saisir le programme saisieCarac.h, il faut faire dans la console :
nano saisieCarac.h
Cette commande ouvre un fichier texte vide appelé saisieCarac.h (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
/* ----------------------------------------------------------------------------- Programme saisie non bloquante caractère au clavier Fichier entête de saisieCarac.c os : RPi Linux 4.4.13+ (Jessie) logiciel : gcc (Raspbian 4.9.2-10) 4.9.2 cible : raspberry Pi date de création : 26/06/2016 date de mise à jour : 28/06/2016 version : 1.0 auteur : icarePetibles référence : Remarques : ----------------------------------------------------------------------------- */ #ifndef SAISIE_CARAC_h #define SAISIE_CARAC_h /* -------------------------------------------------------------------------- */ //prototypes fonctions int kbhit(void); /* -------------------------------------------------------------------------- */ #endif
Pour saisir le programme saisieCarac.c, il faut faire dans la console :
nano saisieCarac.c
Cette commande ouvre un fichier texte vide appelé saisieCarac.c (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
/* ----------------------------------------------------------------------------- Programme saisie non bloquante caractère au clavier os : RPi Linux 4.4.13+ logiciel : gcc (Raspbian 4.9.2-10) 4.9.2 cible : raspberry Pi date de création : 22/06/2016 date de mise à jour : 22/06/2016 version : 1.0 auteur : icarePetibles référence : Remarques : ------ /* ----------------------------------------------------------------------------- Bibliothèques ----------------------------------------------------------------------------- */ #include <stdio.h> //bibliothèque standard #include <termios.h> //bibliothèque entrées/sorties terminal #include <unistd.h> //bibliothèque constantes symboliques #include <fcntl.h> //bibliothèque descripteur de fichier #include "saisieCarac.h" // /* -------------------------------------------------------------------------- */ int kbhit(void){ //fonction indiquant si frappe clavier struct termios oldt, newt; int ch; int oldf; tcgetattr(STDIN_FILENO, oldt); //sauve paramètres terminal newt = oldt; newt.c_lflag = ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, newt); //nouveaux paramètres terminal oldf = fcntl(STDIN_FILENO, F_GETFL, 0); fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); ch = getchar(); //lecture caractère tcsetattr(STDIN_FILENO, TCSANOW, oldt); //restaure paramètres terminal fcntl(STDIN_FILENO, F_SETFL, oldf); if(ch != EOF){ ungetc(ch, stdin); //replace le caractère dans le flux stdin //affiche le caractère dans la console return 1; //valeur de retour caractère saisie } return 0; //valeur de retour pas de caractère } /* -------------------------------------------------------------------------- */
ipsGPIO.h et ipsGPIO.c
voir paragraphe 5.2.1.1
blink52.c
Pour saisir le programme blink52.c, il faut faire dans la console :
nano blink52.c
Cette commande ouvre un fichier texte vide appelé blink52.c (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
/* ----------------------------------------------------------------------------- Programme classique LED clignotante Led rouge sur GPIO23 via une résistance de 330 ohms Ajout sortie boucle infinie Ajout attente non blocante os : RPi Linux 4.4.13+ (Jessie) logiciel : gcc (Raspbian 4.9.2-10) 4.9.2 cible : raspberry Pi date de création : 26/06/2016 date de mise à jour : 28/06/2016 version : 1.0 auteur : icarePetibles référence : Remarques : ----------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------- Bibliothèques ----------------------------------------------------------------------------- */ #include <stdio.h> //bibliothèque entrées/sorties #include <ctype.h> //manipulation caractères #include "ipsGPIO.h" //bibliothèque ipsGPIO #include "saisieCarac.h" //saisie caractère non blocant #define DUREE 500 //1/2 période clignotant #define LED 23 //led sur GPIO23 int main(void){ //programme principal int c; //caractère clavier unsigned long int valeurActuelle = 0; //sauve temps actuel unsigned long int valeurPrecedente = 0; //sauve temsp précédent int etatLed = FAUX; //led éteinte affiche("Led clignotante"); //IHM afficheLn(" by icarePetibles"); //IHM afficheLn("'q' ou 'Q' pour sortir");//IHM modeBroche(LED, SORTIE); //GPIO23 en sortie ecritureDigitale(LED, BAS); //éteind led valeurPrecedente = mTemps(); //temps for(;;){ //boucle infinie if(kbhit()) //si touche saisie c = getchar(); //lecture touche if(tolower(c) == 'q') //test si 'q' ou 'Q' break; //sortie boucle valeurActuelle = mTemps(); //temps if(valeurActuelle - valeurPrecedente >= DUREE){ //si temps écoulé supérieure DUREE valeurPrecedente = valeurActuelle; //temps if(etatLed){ //si led allumée ecritureDigitale(LED, BAS); //éteind la led etatLed = FAUX; //led éteinte }else{ //si led éteinte ecritureDigitale(LED, HAUT); //éteind la led etatLed = VRAI; //led éteinte } //fin (etat led) } //fin test DUREE } //fin boucle infinie ecritureDigitale(LED, BAS); //éteind led modeBroche(LED, DESACTIVE); //désactive pin LED afficheLn("\nFin du programme"); //IHM return 0; //code sortie } //fin programme
Exécution du programme
Pour exécuter se programme, il faut d’abord le compiler. La compilation se fait par la commande ci-dessous (en mode console) pour les différents fichiers C en créant des fichier objet :
gcc -c ipsGPIO.c gcc -c saisieCarac.c gcc -c blink52.c
Et pour terminer, il faut créer le fichier final via l’éditeur de lien :
gcc -o blink52 blink52.o ipsGPIO.o saisieCarac.o
Le résultat de la compilation est un fichier : blink52
Lancement du programme :
sudo ./blink52
Pour sortir de la boucle infinie, il suffit de faire q ou Q au clavier.
Remarque : On peut supprimer les fichiers objets (.o) du répertoire courant par :
rm *.o
Node.js
Un langage qui fait beaucoup parler et qui devient de plus en plus populaire (à surveiller). C’est quoi node.js ? C’est simplement du Javascript mais côté serveur contrairement à la version classique qui s’exécute côté client. Pour en savoir plus, il suffit de consulter les tutoriels sur le net ou des ouvrages spécialisés.
Ce langage est séduisant et l’on peut créer un serveur web en 3 à 4 lignes.
Pour ma part, je suis relativement « étanche » à ce langage et, mes vieux neurones ont du mal à s’adapter, aux fonctions avec des fonctions en paramètres qui s’exécutent de manière non bloquantes.
Pour notre application, nous n’utiliserons pas le concept serveur web mais comme un langage traditionnel.
Programme
Le programme utilise un module complémentaire « onoff« . La procédure d’installation ainsi que la documentation sont disponibles sous le lien :
https://www.npmjs.com/package/onoff
Pour les plus curieux, on trouvera sous https://www.npmjs.com/, la liste impressionnante des modules disponibles.
Pour saisir le programme, il faut faire dans la console :
nano blink02.js
Cette commande ouvre un fichier texte vide appelé blink02.js (pour la sauvegarde faire Ctrl+o et pour sortir Ctrl+x).
Le contenu du programme et de ses commentaires sont représentés ci-dessous.
/* ----------------------------------------------------------------------------- Programme classique LED clignotante Led rouge sur GPIO23 via une résistance de 330 ohms os : RPi Linux 4.4.13+ (Jessie) logiciel : node v0.12.6 cible : raspberry Pi date de création : 26/06/2016 date de mise à jour : 20/07/2016 version : 1.0 auteur : icarePetibles référence : https://www.npmjs.com/package/onoff Remarques : ----------------------------------------------------------------------------- */ var Gpio = require('onoff').Gpio, //module onoff led = new Gpio(23, 'out'); //led sur GPIO23 et en sortie DUREE = 500 //demi-période clignotement (msec) console.log('Début programme led clignotante'); console.log("'Sortie de la boucle infinie par ctrl+c'"); //IHM var iv = setInterval(function(){ //appel toutes les x milli-sec led.writeSync(led.readSync() === 0 ? 1 : 0) }, DUREE); //durée de répétition function exit(){ //sortie de la boucle infinie clearInterval(iv); //arrêt clignotement led.writeSync(0); //éteint led led.unexport(); //unexport GPIO et libère la resssource console.log('\nFin programme'); //IHM process.exit(); //arrêt node } process.on('SIGINT', exit); //capture du ^C et exécute exit()
Exécution programme
Pour exécuter ce programme, il faut lancer la commande suivante dans la console Linux :
node blink02.js
Pour sortir de la boucle infinie, il suffit de faire un Ctrl+c au clavier.
Conclusion
La saga pourrait continuer pendant des semaines et des semaines ou des pages et des pages. Finalement on va se trouver dans une situation de bis repetita.
On aurait pu utiliser d’autres langages (console ou graphique) pour commander notre port GPIO, comme Java, Scratch, Node-RED, C++, Pascal, Fortran, PHP, Javascript, etc…
Peut être à bientôt pour une prochaine saga (pushButton, I2C, SPI, 1-Wire, interruption, etc…)
La saga continue : Complément à la première partie de la saga Blink
Sources
Vous pouvez télécharger l’ensemble des sources ici :
http://psl.ibidouille.net/Images_forum/raspberryPi/sagaBlink.zip
Ping : RaspberryPi | Pearltrees
Le NE555, c’était quand même bien !… 😉
Bonjour,
Encore plus simple.
2 transistors, 4 résistances, 2 condensateurs et une led = bascule bistable.
🙂
Re,
Je suis trompé ce n’est pas bistable mais astable (multivibrateur).
🙁
plus simple ? tu rappelles comment on calcule les valeurs en fonction de la fréquence du clignotement ?
c’est plus simple pour celui qui sait, mais c’est pas « universellement » plus simple. par exemple moi je préfère de loin les petits microcontrôleurs à $1, c’est 4 lignes de code, et pas besoin de calculatrice 🙂
perso je trouve plus facile de faire clignoter une LED avec un ATTiny45 (moins de $1). Mais vraiment !
Pas moi…
Sans doute une question de génération.
En tout cas, cet article fort bien fait aura eu le mérite de susciter des réactions.
Ah que oui…. mais pour apprendre à programmer… pas terrible 😉
cordialement
François
Bonjour,
Je pense qu’il est dépassé. On trouve, du côté du soleil levant, des petites cartes à microcontrôleur qui seront bientôt moins cher que le NE555.
On a changé d’époque et ce n’est pas fini. 😉
🙂
Pour moi, très intéressant !
merci 🙂
Merci,
Cela fait plaisir
Bonjour,
2 remarques/observations complémentaires:
– Il me semble que wiringpi est installé d’office avec jessie.
– On peut utiliser le GPIO sans être SU. Il faut ajouter la ligne suivante à son fichier .profile:
WIRINGPI_GPIOMEM=1
Par principe, je n’aime pas travailler en étant SU (surtout en développement).
Ces 2 remarques mineures étant faites, je tiens à souligner la démarche de l’auteur. Étant assez actif sur le forum, je constate régulièrement que des débutants, qui viennent pour la plupart du monde Windows (ce n’est pas une insulte), veulent se lancer d’emblée dans des projets lourds, avec des cartes d’interface (écran LCD, I2C, 1 wire..).
Comme les fondamentaux ne sont pas maîtrisés, ils se découragent assez vite ou il faut les guider pas à pas.
L’auteur nous montre qu’il est possible de rentrer dans les arcanes du Raspberry avec une simple LED (et une résistance).
Je pense que sa démarche logique consistera à explorer ensuite les bus (I2C, SPI, série, 1 wire) avant de se lancer dans des projets complexes. AMHA, en procédant de la sorte, il a de fortes chances de mener à terme ses projets car il aura compris le fonctionnement de la bête et ne sera pas tributaire de bouts de code glanés à droite et à gauche, péniblement assemblés.
Sylvain
Bonjour,
Merci pour les infos, dans mon cas wiringpi n’est pas présent avec Jessie.
Je partage tout à fait tes remarques, oh combien de débutants veulent faire un « drone » en n’ayant pas l’ombre d’une expérience.
Il y aura une suite mais toujours dans la même démarche (multi-langages), le suivant sera la « saga push button ».
@+
Bonjour Sylvain
un grand merci pour le forum 🙂 merci aussi pour les remarques qui viennent en complément de l’article
Patrice, l’auteur de cet article devrait bientôt récidiver avec la lecture d’un inter etc.
Incroyable non ? A quoi ça peut servir d’allumer une LED avec un inter en passant par un Raspberry Pi… Ce serait tellement simple de relier directement la LED à l’inter 😀 et pourtant je suis tout à fait en phase avec lui !
à bientôt
François
oui, ces articles sont une excellente idée ! ils resteront je pense une bonne base de référence Francophone (et encore, pas certain que cette collection de méthodes existe ailleurs)
Merci 😉
Bonsoir François,
Merci de me dire merci ;-))
AMHA le succès de ce site est du :
-) à toi, maître des lieux, pour tes articles et la tonalité que tu donnes.
-) au travail, souvent ignoré, des modos et admins.
Cordialement.
Sylvain
🙂
Bonjour
J’avais fait les exercices avec python (raspberrypi.org) mais j’étais resté sur ma faim au niveau de la compréhension. Sur apple 2 avec des peek et des poke on avait les adresses mémoires du controlleur de manettes.
Le fichier bash, avec la commande echo répond à mon attente:
echo « 23 » > /sys/class/gpio/export #assigne pin
echo « out » > /sys/class/gpio/gpio23/direction #en sortie
echo « 1 » > /sys/class/gpio/gpio23/value #allume led
echo « 0 » > /sys/class/gpio/gpio23/value #éteint led
Bien sur que l’intérêt de cet article est pédagogique.
Dans une réalisation concrète on utilisera par exemple les bibliothèques python.
🙂
Je reste encore un peu sur ma faim pour comprendre le fonctionnement des broches.
Que ce soit les echo en bash, les bibliothèques python, celles en C on fait appel à des routines en langage machine.
Je ne demande pas un programme en langage machine pour programmer des led mais simplement de savoir ce qui se passe au niveau machine pour activer une broche du GPIO en input ou output, etc.
Si c’est comme appleII cela se faisait par une écriture ou une lecture en mémoire, et elles étaientt même accessible du basic avec des peek et des poke car les adresses mémoires étaient documentées
Bonjour
Venant de cette époque j’ai utilisée les Z80 PIO et autres 8255 à toutes les sauces… Mais avec les Soc on est passé à une échelle supérieure vu le nombre de ports et les registres à prendre en compte. Bon c’est faisable mais justement les bibliothèques permettent d’accéder aux E/S bien plus facilement en restant dans les couches supérieures, sans descendre au niveau du bit de sortie 🙂
Vous en saurez plus à partir de la page 89 de ce document : https://www.framboise314.fr/docs/BCM2835Datasheet.pdf
Cordialement
François
Merci bien François, je vais pouvoir satisfaire ma curiosité. Tout à fait d’accord qu’il faille passer ensuite par les bibliothèques.
cordialement
Antoin
Bonjour messieurs.
Voila un bel article très bien écrit et illustré comme on aimerait en voir plus souvent. Toutefois, en termes de programmation, les méthodes utilisées sont l’exemple type de ce qu’il ne faut pas faire, surtout sur un PI aux ressources particulièrement limitées. A l’exception de l’exemple nodejs (qui lui est fondamentalement asynchrone), tous les autres exemples occupent en permanence le thread principal à grand coup de comparaisons incessantes aussi gourmandes qu’inutiles et c’est justement ce qui est à l’origine de l’échec de nombreux projets de débutant. Pour voir ou je veux en venir, essayez donc de mettre une variable qui s’incrémente de 1 à chaque comparaison faites entre 2 changements d’état de la led. Vous allez vous rendre compte que des milliers (voir même millions pour les exemples en c) d’instructions sont exécutées et occupent constamment l’uc pour finalement ne rien faire. Dommage de ne pas profiter de cette belle aptitude rédactionnelle que vous possédez pour faire la démonstration d’un bon exemple qui laisserait l’uc complètement au repos entre 2 changements d’état de la led et qui ne s’inquièterait de la valeur d’un input key que dans le cas d’une interruption clavier.
Bonjour,
L’auteur est conscient de ce problème et le mentionne expressément dans son article qui vise les débutants. On ne peux pas les confronter de suite aux threads et mutex !
Le Raspberry est fait de compromis, pas toujours heureux ;-(
L’absence de gestionnaire d’interruptions dans l’espace noyau en est un exemple. Cela implique de gérer un ISR dans l’espace utilisateur. Heureusement la bibliothèque wiringpi le permet mais c’est assez peu documenté et pas trivial.
Sylvain
Je comprends bien que c’est à titre didactique que Patrice a écrit ce beau topic et c’est justement pour cela, je pense, qu’il n’est pas très judicieux d’orienter les débutants dans ce sens (il suffit de lire les forums pour s’apercevoir qu’ils font déjà tous ce genre d’erreur). Ici, absolument pas besoin de mutex pour faire quelque chose de cohérant et d’explicit pour un débutant puisque l’on n’est pas censé avoir plusieurs threads qui accèderaient au même gpio simultanément. Un simple thread externe (1 ligne de code …) qui appel une void qui gererait le blink (en utilisant des sleep pour la tempo pour ne rien consommer pendant les attentes) et attendre tranquillement sans rien faire l’appuis d’une touche dans le thread principale pour savoir si l’on doit quitter. Au final un programme bien plus simple qui ferait exactement le même boulot mais sans rien consommer et qui laisserait de la ressource pour le gps de la détection d’obstacle de la tondeuse ;). Je n’ai pas de pi sous la main, mais un truc du genre ferait très largement l’affaire :
int main()
{
pthread_t bled;
//init io
cout << "Initialisation GPIO …" << endl;
cout << "Press Enter to Quit." << endl;
pthread_create(&bled, NULL, &blinkLed,NULL);
cin.ignore();
pthread_cancel(tled) ;
pthread_join(tled,NULL);
cout << "Liberation GPIO …" << endl;
return 0;
}
Vous avez raison pour cette usage particulier où on se contente de changer l’état de sortie d’un GPIO, il n’y a pas besoin de mutex.
Dans le prochain article, lecture de l’état d’un bouton poussoir sur port GPIO, qui correspond à un besoin fondamental (cf. question récurrente des débutants), il sera certainement encore possible de s’en passer. Il est en effet peu probable, avec une action humaine, de provoquer 2 appuis successifs plus rapides que le temps de réaction du programme (c’est d’ailleurs mis à profit dans le filtrage logiciel des rebonds).
Quand il faudra faire de l’acquisition de données via I2C (ou SPI), il en sera tout autrement.
Avec une thread écrivain et une thread lecteur qui partagent la même ressource, il faudra mieux éviter de lire pendant une opération d’écriture (et vive versa).
Avec le bus I2C, c’est encore plus flagrant vu le nombre d’esclaves qu’il peut y avoir. On peut certes faire du polling mais c’est un gaspillage éhonté de ressources (sur ce point aussi je vous rejoins). Les PCF8574 que l’on retrouve sur beaucoup de cartes d’interface ont bien une broche INT et ce n’est pas pour faire joli.
Mais tout cela n’est pas trivial et dépasse, AMHA, le cadre de l’initiation d’un débutant. J’ai eu l’occasion, sur le forum, de discuter avec un modérateur qui est loin d’être un newby et il y a renoncé.
Personnellement, j’y travaille car mes projets sont trop lourds pour se contenter du polling ou de la boucle infinie. Ils sont aussi trop lourds pour être développés/compilés sur le Raspberry (surtout que je n’ai qu’un B+). Je n’ai pas envie d’attendre des heures le résultat d’une compil ou de flinguer rapidement la carte SSD par trop d’écritures.
J’y vais donc aussi « pas à pas ». Pour le moment, j’ai un environnement de cross compilation fonctionnel mais qui ne me satisfait pas à 100 %.
C’est peut-être le fait de partager cette approche ‘pas à pas » avec l’auteur qui me fait comprendre et admettre sa démarche en n’oubliant pas la cible visée.
Tout le monde n’a pas le temps ou la fibre rédactionnelle mais je pense que vos contributions seraient très appréciées sur le forum. Au plaisir de vous y retrouver bientôt.
Sylvain
salut Sylvain
je ne peux qu’aller dans ton sens ! Pour ma part je ne suis pas un dev je suis plutôt un hardeux. Mais le fait de se lancer à écrire un article comme celui-là en sachant qu’on va s’exposer aux critiques est déjà un sacré pas à franchir que beaucoup n’ont pas fait 🙂
Après, les critiques si elles sont constructives et amènent des éléments au débat, permettent à tout le monde d’avancer. L’auteur en profite pour ses prochains articles et les lecteurs s’aperçoivent que derrière la porte qui vient d’être ouverte il y en a encore beaucoup à explorer….
Et je pense aussi que c’est ce qui est intéressant dans ce monde de l’informatique. On sait qu’on ne saura jamais tout, qu’à chaque fois qu’on apprend on s’apercevra qu’il y a encore bien plus à apprendre…
Il faut avoir cette envie de toujours aller plus loin pour progresser et si on ne l’a pas il faut faire autre chose 🙂 enfin… c’est juste mon avis
cordialement
François
Soyons clair, il ne s’agit pas ici de remettre en cause l’excellent travail de rédaction de Patrice que je salue une fois de plus. Ma remarque se veut avant tout constructive. Elle n’a pas vocation à dire qu’une méthode est mieux ou moins bien qu’une autre, mais bien de mettre en garde, concernant celles utilisées ici. Soyons pragmatique, quel est l’intérêt d’utiliser un langage très rapide (je parle ici du C) si c’est pour augmenter la consommation de ressources proportionnellement à la vitesse d’exécution des instructions ? C’est exactement à ce paradoxe que nous somme confronté ici. Plus l’exécution des instructions conditionnelles sera rapide et plus on en fera, ce qui forcement augmentera la consommation de ressources. Ne voyez-vous pas une énorme faille face au fait qu’une seule instruction sur plusieurs milliers aura réel un effet sur le déroulement du programme et que ce rapport ne pourrait qu’augmenter si on passait sur un system plus rapide ?
Une petite suggestion pour Patrice : Si vous tenez absolument à utiliser ces boucles infernales, mettez au moins un usleep de quelques ms dans la partie systématique de vos boucles. Cela aura pour effet de réduire considérablement le nombre d’instructions inutiles. Bien sûr cela se transformera en latence sur l’input key et la précision de blinking sera un peu moins bonne, mais le piège que vous avez creusé est bien trop profond pour que vous puissiez vous en sortir sans payer un tribut 😉
Bonjour,
Merci à tous les deux pour votre retour et précisions.
Il est vrai que certains programmes sont exigeants en terme de ressources mais rien n’est parfait dans le monde réel. 😉
Le but de l’article est avant tout initiatique et il ne s’agit pas de décourager les débutants par des notions complexes et compliquées. A un moment donné, il faut faire des choix. Si le débutant commence par faire des minis cahier des charges, des organigrammes et de documenter sa programmation, je pense que j’ai atteint 80% de mon but.
Maintenant comme tout est perfectible et que j’ai prévu un petit complément à la saga blink.
Je vais voir pour ajouter quelques notions sur une programmation plus économe en terme de ressources tout en restant dans un cadre initiatique et facilement accessible.
Cela peu paraître utopique, mais je préfère un programmeur qui programme (même si cela n’est pas l’optimum) qu’un programmeur qui abandonne car c’est incompréhensible pour lui. Il pourra s’améliorer lorsqu’il rencontrera des problèmes et il sera plus résistant face à la difficulté.
Mais c’est juste mon avis.
@+
Re,
Le débat est intéressant car il permet d’orienter les articles en fonction des préoccupations des utilisateurs et de fournir de la matière première pour d’autres articles.
Je me doutais qu’il y aurait des réactions, c’est normal, mais pas sur ce point là. 😉
Pour revenir au sujet, AMHA, il y a deux approches possibles :
1) un environnement type carte Arduino ou cartes consœurs. Dans ce cas précis, si la tâche occupe 100% des ressources ce n’est pas un problème car elle tourne pour cela.
2) un environnement « nano-ordinateur » et, dans ce cas, la gestion des ressources est d’actualité.
Dans les prochains articles, je préciserais le contexte de mise en œuvre.
Je reste à votre écoute pour d’autres suggestions, remarques ou propositions.
@+
J’adore faire clignoter des DEL (ben oui LED c’est pas francais 🙂 ) et plus je ferais un truc complexe pour le faire plus ca me fera kiffer … (c’est français ça ?) car ou est l’intérêt si c’est pas pour te faire quelques noueds au cerveau
N’en peche le NE555 même si il est vieu et moche ben il etait bien utile avant …
Mais c’est de la tuerie cet article !
Bien-sur que pour faire clignoter une led on peut faire plus simple avec d’autres outils. Mais là, l’intérêt que je vois à l’article, c’est d’apprendre à exploiter les GPIO du raspberry, avec un prétexte de changement d’état régulier.
On pourrait très bien s’inspirer de ces exemples pour faire autre chose.
Merci pour cet article que j’ajoute dans ma liste des trucs à relire quand j’aurais besoin de jouer avec mes GPIO 😉
Comme mentionné au-dessus, c’est de la tuerie cet article 🙂 J’ai tout mon kit LED/résistances/breadboard étalé sur le bureau (ce soir c’est sur Arduino, avec le HS Hackable).
Très content de voir ça sur le Pi ! J’avais commencé avec les articles de PiMag, mais une version très complète en Français avec du C, du Python et… du bash (!) est très appréciable. Je sais ce que je fais demain. Merci !
Ceux qui ont lu les commentaires ont certainement remarqué mon objection concernant les méthodes utilisées par l’auteur de ce premier volet ‘Blink Saga’. J’avais déjà la conviction de ce que j’avançais, mais le doute subsistait malgré tout (par expérience, je sais tant que l’on n’a pas essayé, on n’est jamais sûr de rien …). N’avais-je pas exagéré les défaillances des méthodes utilisées ? Celles que j’avais en tête étaient t’elles réellement fiable ? N’avais-je pas tout simplement apporté une critique futile au risque de décourager un auteur au combien soigneux dans ces présentations ? Il fallait que j’en ai le cœur net. J’ai donc téléchargé les codes sources ‘Blink Saga’ et j’en ai choisi un qui était concerné par ma critique. Je me suis ensuite mis dans la peau d’un débutant et j’ai réalisé les opérations de compilation proposées puis j’ai essayé le programme. Ce que je craignais n’est rien comparé au résultat. Je m’attendais à un niveau de performance médiocre alors que dans la réalité c’est carrément alarmant au point que l’on ne peut pas orienter de jeunes développeurs dans cette direction. Bien que je n’ai pas la prétention de faire un article aussi bien rédigé que celui, je me propose d’en écrire un qui mettrait en évidence les erreurs commises ainsi que leurs conséquences et surtout comment les éviter pour la suite de cette très intéressante ‘Saga’ qui je n’en doute pas doit intéresser beaucoup de débutants francophones. Il appartiendra ensuite à la rédaction en chef de le publier ou pas. Par contre, je ne trouve nulle part le mode opératoire pour écrire un article. Quel format utiliser pour faciliter la publication et à qui l’adresser ?
Bonsoir,
Chic, on va avoir un article d’un pro du développement 😉
Tous les programmes fonctionnent et ont fait l’objet d’un test sur le B, zéro et le 3.
Maintenant s’il faut rentrer dans la programmation système pour débuter avec le GPIO, pourquoi pas.
Concernant les ressources, tant que l’on est dans l’organigramme de la figure 4, on est <8%;
Pour l'organigramme de la figure 5, on a 100% (mais ce n'est pas un secret) sauf pour tkinter <20% et node <10%.
@+
Bonjour
je vous contacte en direct sur l adresse associée à ce messagel adresse n est pas bonne (le .fr ne passe pas)
vous pouvez
aussime contacter sur contact@framboise314.frà bientôt
Cordialement
François
Bin mince alors … Bud … je te preferais largement en acteur de film spagetti … tu as mal digérè un truc ?
arrête de te prendre la tête hein … c’est un belle article qui a le mérite d’exister et surtout il est clair
Quand tu auras fait le 1/4 du boulot que Patrice a fait reviens nous voir et surtout mets toi dans ta caboche d’intello présomptueux et que le débutant que je suis (bon peut etre pas si débutant que ca) à juste envie de te dire … » hey mec prends du recule on est là pour faire mumuse avec nos joujoux tout en apprennent et les prise de melon c’est pas ici ….va te détendre »
PS: Désolé Francois et Patrice pour ce petit message (qui n’apporte rien sauf peut etre me détendre ) mais je déteste les Gens comme lui qui n’apporte rien … ca me met hors de moi … Beau travail de vous 2 en tout cas …
😉
Merci pour le soutient 🙂
Et quel soutient …
Tu vois, j’avais apprécié la rédaction de ton tuto, je l’avais dit et même répété et pour justement t’en remercier, je me proposais de t’aider à avancer (toi et surtout tous ceux qui vont reproduire tes erreurs). Finalement je constate que ton égo t’importe bien plus que ton besoin d’apprendre et que tu te fouts pas mal des résultats pour les autres. Je me suis couché hiers soir à 2h00 du mat (en devant me lever ce matin à 5h30) pour corriger tes sources et commencer la rédaction d’un article qui évidement te remettais en cause puisque ce sont TES erreurs qui me servaient d’exemple concret à éviter. Mais pour toi toute critique est mauvaise dans le sens où elle te remet en cause. Hé bien soit, je ne t’aiderai pas. A n’en pas douter, d’autres bien moins intentionné que moi finiront bien par te mettre le nez dans … tes erreurs. Vu que tu ne penses pas avoir besoin de conseils pour programmer, prends quand même celui-ci qui se veut plutôt ‘moral’ : Avant de proposer quelque tuto que ce soit, pose toi juste la question de savoir si ce que tu vas écrire est à la hauteur de l’espace qui va te publier et acceptes à l’avance les critiques qui pourraient arriver (à moins que tu ne te penses infaillible). Jusqu’à présent, je pensais être ici sur un site référence du Raspberry Pi Francophone, mais désormais, toi et d’autres m’ont vraiment mis le doute. Pour être carrément honnête, je me demande même pourquoi je perds mon temps à polémiquer avec vous.
Bonjour,
Je pense que la contribution de Bud Spencer est constructive car elle aborde un aspect important lorsqu’on fait du partage de temps.
Par contre, faire de la lévitation magnétique, en écoutant une radio internet, tout en utilisant libreOffice pour rédiger un article et, en prime, consulter des références sur le net.
Il va se passer quelques choses, la lévitation magnétique va pas fonctionner si elle accapare pas les ressources.
Les deux approches sont louables, et il y a de la place pour tout le monde.
Nous on veut juste s’amuser, apprendre de nos mutuelles différences et se coucher moins bête le soir.
D’après Patrice, il y aura une suite à la saga blink sinon ce ne serait pas une saga.
@+
ce n’est pas forcement le fond qui me gène au contraire toute expérience est toujours bien venu … mais la forme peut etre mieux exprimée genre:
» J’ai pris les sources et je les ai regardé, on devrait pouvoir amélioré certaines choses pour l’optimisation des ressources comme …. »
Et non:
« Ce que je craignais n’est rien comparé au résultat. Je m’attendais à un niveau de performance médiocre alors que dans la réalité c’est carrément alarmant au point que l’on ne peut pas orienter de jeunes développeurs dans cette direction. »
euh sérieux on envisage d’allumer des LED pas d’integrer un RPI dans la futur mission sur MARS
Et pourtant je suis le 1er a râler auprès de développeur qui ne savent pas optimiser les ressources et les cycles faut dire j’ai été à bonne école j’ai fait de l’assembleur sur des truc tellement faible en ressource que l’optimisation etait de rigueur et on rigolait pas avec ça …
Ah si j’avais eu un RPI à l’époque (dit le vieux)
pareil j ai démarré au Z80 et 6800 avec les Exorciser Motorola et on comptait les bits disponibles 🙂 aujourd’hui on entend « ouais mais y a que 4 Go de mémoire » 😀
effectivement ça ne nous rajeunit pas
Re,
Dans les 7 nains, il y avait un grincheux, je crois.
🙂
« Et pourtant je suis le 1er à râler auprès de développeur qui ne savent … »
Rassure-nous, tu plaisantes, tu te fouts de nous ou tu tentes de te la jouer la 🙂 🙂 :)
Tu sais de quoi je parle au moins ? Tu as au moins lus ces codes ? Tu les as essayés ? Je ne parle pas de quelques octets perdus de ci de là, mais d’un process qui consomme à lui seul et sans gui, plus que la visu d’un vidéo en streaming sur le net juste pour faire clignoter une led toutes les secondes, et je n’aborde même pas le coté optimisation. Crois-moi, si tu as envie de râler ou d’écrire au moins une chose de constructible sur ce coup, je te prie de croire qu’il y a des quoi alimenter ta grogne et il y en a grand besoin.
😀
Pour moi dans un sens ou dans l’autre tous les retours sont positifs car ils montrent la diversité des activités et des préoccupations des utilisateurs de la framboise (et des autres cartes aussi !)
bon amusement
François 🙂
Serait-ce des insultes 🙂
Tu te prétends débutant et c’est très bien de l’admettre et si je peux te donner un conseil, attend toi le rester encore très très longtemps, parce qu’avec une telle objectivité, tu n’es pas près d’avancer.
Toi tu n’apportes rien, je suis d’accord, en revanche, de mon côté j’ai lu, j’ai analysé et pour confirmer les erreurs critiques que je soupçonnais j’ai testé tous ces exemples puis je les ais corrigés ‘au mieux’ pour ne pas trop les déformer avec pour seul but d’aider patrice à ne pas refaire les mêmes erreurs et pouvoir proposer aux débutants soucieux d’apprendre (l’inverse de toi) des exemples non pas exemplaires mais au minimum acceptable. Lui n’a pas besoin de me dire que c’est un débutant, je le vois bien en lisant ses sources et je les juge avec toute l’indulgence que l’on doit avoir envers quelqu’un de son niveau qui malgré tout essais d’apporter sa pierre à l’édifice. Si je voulais mettre le doigt sur toutes les anomalies que j’arrive à lever dans cet article juste avec mon humble niveau, ce n’est plus un article que je devrais écrire, mais carrément un bouquin entier. Commence par apprendre que la seule chose que l’on tirer d’une erreur, c’est justement d’apprendre. Au lieu d’insulter, lis, analyses, expérimentes, comprends et quand tu penseras avoir le niveau ou au moins l’intelligence pour te joindre à un débat qui se veut avant tout technique, reviens me voir et là on pourra peut-être discuter.
Re,
@Bud Spencer
En attendant ton topo, tu peux essayer le programme en C ci-dessous :
1: #include //stdio.h //stdlib.h //pthread.h //unistd.h //wiringPi.h
2: #include
3: #include
4: #include
5: #include
6:
7: #define LED 4
8:
9: volatile char theCar = ‘\0’;
10:
11: void* blink(){
12: wiringPiSetup();
13: pinMode(LED, OUTPUT);
14: while(theCar != ‘q’){
15: digitalWrite(LED, HIGH);
16: delay(500);
17: digitalWrite(LED, LOW);
18: delay(500);
19: }
20: return NULL;
21: }
22:
23: void* sortie(){
24: while(theCar != ‘q’){
25: printf(« q pour sortir ! »);
26: theCar = getchar();
27: }
28: return NULL;
29: }
30:
31: int main(void){
32: pthread_t filsA, filsB;
33:
34: if(pthread_create(&filsA, NULL, blink, NULL)){
35: perror(« pthread_create »);
36: exit(EXIT_FAILURE);
37: }
38:
39: if(pthread_create(&filsB, NULL, sortie, NULL)){
40: perror(« pthread_create »);
41: exit(EXIT_FAILURE);
42: }
43:
44: if(pthread_join(filsA, NULL))
45: perror(« pthread_join »);
46:
47: if(pthread_join(filsB, NULL))
48: perror(« pthread_join »);
49:
50: digitalWrite(LED, LOW);
51: pinMode(LED, INPUT);
52:
53: printf(« Fin blink\n »);
54: }
Pour l’instant cela fonctionne pour C, C++ et python mais je n’ai pas trouver la solution pour le bash.
Tu vois que tes remarques n’étaient pas vaines.
Rq1: je sais j’ai utilisé une variable locale pour éviter de passer une structure en paramètre.
Rq2: je n’y connaît rien en programmation 😉
@+
[edit]
Pour compiler :
gcc nomFichier.c -lpthread -lwiringPi -o nomFichier
Pour exécuter :
sudo ./nomFichier
Je vote pour de I2C pour la prochaine fois …
Bonjour Francois
Article intéressant suivi d’une non moins intéressante passe d’armes pour une poignée de dollars.
Il faut juste espérer que ça ne découragera pas des gars comme Patrice Seibel de publier car en publiant on s’expose nécessairement à des avis qui ne font pas toujours plaisir.
Pendant les années ou je travaillais à l’assistance informatique d’une grande administration, j’étais aussi moniteur sur Multiplan (ça fait longtemps) 😉 puis sur Excel et quelques SGBD comme Dbase IV et Foxpro. J’ai été souvent confronté à des stagiaires qui essayaient de me déstabiliser et parfois en savait plus que moi mais ça m’a permis d’avancer et d’apprendre qu’on ne sait jamais et surtout de rester modeste.
Bonne fin de juillet
Mais non il ne va pas se décourager … Non parce que sinon je vais venir lui botter le train arrière car je le veux mon article sur l’I2C … d’ailleurs je comprends pas pourquoi c’est pas déjà en ligne il fait quoi ? et qu’on me dise pas c’est les vacances, c’est du boulot, ou encore tu sais il a aussi un travail …. ce se serait
😉
Bonjour à tous,
Tu l’auras ton article sur l’I2C en version « saga ».
Pour l’instant, je termine la « saga Push Button » et le complément à la « saga Blink ».
Par contre, je cherche des volontaires pour une pétition pour augmenter la durée légale de la journée. L’idéal serait de passer de 24 à 48. 🙂
@ bientôt
Patrice
pour le 24 -> 48 je signe si ca concerne que le samedi et le dimanche 😉
Bonjour Patrice,
Je constate avec plaisir que je ne m’étais pas trompé en analysant ta démarche . Dès mon premier post je soulignais qu’il serait cohérent, après le GPIO de base (LED, BP), d’aborder les bus série.
Je trouve sain et légitime qu’un article provoque des réactions car c’est reconnaître le travail de l’auteur. Je regrette juste la tournure de cet échange où l’on a vu apparaîtrent, cas très rare sur ce site, des attaques personnelles.
Il me reste à souligner, une fois encore, la cohérence et la pédagogie de ta démarche. Je ne pense pas me tromper mais je n’ai pas vu beaucoup d’articles d’initiation présentant le C comme langage de programmation permettant d’arriver assez facilement à un résultat. Par facilité ou par paresse intellectuelle, on trouve les sempiternels langages interprétés.
Les remarques techniques d’optimisation étaient certes justifiées mais je crains que l’appel aux threads n’ait brouillé le message pour un débutant qui risque d’avoir du mal à déchiffrer ce programme.
Quant à la pétition pour la durée de la journée, normalement celle-ci fait 24 h + la nuit 😉
Merci et félicitations pour ton travail
Cordialement
Sylvain
Bonjour,
Merci 🙂
Concernant les threads cela peut être déroutant pour les débutants et n’avait pas sa place dans mon approche. Maintenant que c’est fait, je ferai quelque chose de « very lite » sur le sujet dans mon complément.
Effectivement les critiques et remarques constructives font progresser les sujets.
Vu le nombre d’heures de vol de l’auteur, les attaques personnelles, dénigrements ou autres sarcasmes ne m’atteignent pas.
@ bientôt
Patrice
Bonjour à tous
Merci pour ce site…et pour ce super tuto ! Quel travail ! Il a bien pour objet l’utilisation des GPIO et est parfaitement didactique pour moi débutant en Raspberry…Etonnant cette polémique sur le multitache qui est hors sujet selon moi, même si sur le fond c’est intéressant. La critique est aisée mais l’art est difficile…
Comme je suis flemmard je fais mes tests avec mon multimetre….et la librairie gpiozero me plait bien !
Bonne journée et encore bravo à ceux qui donnent leur temps pour partager leurs connaisssances !
Yann
merci Yann
on voit bien le besoin qui existe
à propos de ce genre de tutoriel
bon amusement avec la framboise
cordialement
François
Bonjour,
Je suis un vieux à la retraite (70 ans) qui s’est intéressé à la framboise pour épater ses petits enfants …
J’ai donc passé l’examen de la led qui clignote, comme tout le monde, mais je n’ai pas eu le courage de faire aussi bien que l’auteur de cet article que je félicite pour son travail pédagogique, même si certains le trouvent perfectible.
Je suis allé plus loin dans cette saga, mais de manière perso et je n’ai pas la force de produire un article aussi bien structuré. Voici mon expérience, programmée à ma manière, forcément contestable, mais qui pourrait donner des idées à l’évolution de la saga blink.
La seconde étape de maîtrise du GPIO consiste à détecter une température au moyen d’un DS18B20 (moins de 3 euros pour une précision de 0.5 degré sans calibrage !!).
J’ai donc voulu faire clignoter ma led lorsque la température dépassait un certain seuil critique et l’arrêter en dessous d’un autre seuil. On peut faire l’inverse pour du froid.
J’ai construit un petit programme qui teste la température en faisant un petit démon (un thread) qui n’occupe les ressources que lorsqu’il devient actif, qui lance éventuellement l’allumage du blink de la led, ou bien l’extinction du blink de la led, et puis meurt. J’ai tenté aussi d’activer ce programme par CRON.
Je dirige mon PI depuis le net et j’ai voulu construire en PHP le service web qui me dit quel est l’état de la led, sans donner au serveur web les droits de SU.
Et voila, je suis parti sur une immense chose ! Je ne suis pas certain que mes programmes « bidouillesques » soient diffusables mais je soumets l’idée à faire développer par des puristes de la programmation pour mettre en place un canevas (un framework) qui aiderait les débutants à travailler proprement du premier coup … sans avoir à passer par les deux cent étapes possibles pour développer en DIY !
Encore toutes mes félicitations pour cet article.
L.D.
Bonjour Lucien
je ne suis pas un developpeur non plus mais un vieux hardeux qui a commencé avec des tubes 🙂
lorsque j’écris un programme je reste modeste et je sais qu’un dev. professionnel aurait sans doute fait mieux mais quoi ? on fait comme on sait et ça permet à d’autres de commencer, à d’autres d’améliorer ou de critiquer (pour moi une critique technique est toujours à prendre avec modestie et humilité)
alors si vous souhaitez publier ce que vous avez fait ce sera avec plaisir.
Pas facile d’exposer son travail à la vue de tous j’en sais quelque chose mais c’est aussi un moyen de mettre à plat ce qu’on a bien compris (Ce qui se conçoit bien s’énonce clairement – Et les mots pour le dire arrivent aisément – Nicolas Boileau) et souvent de s’apercevoir de ses lacunes et d’identifier ce qu’on a moins bien pigé 😉 )
alors les pages de framboise314 vous sont ouvertes comme à tous ceux qui ont envie de décrire un montage, une programme, une réalisation !
bonne fin de journée
cordialement
François
ps pour moi la retraite… c’est DANS UNE SEMAINE 😀
Allez Lucien, fais passer ton code
Juste comme ca l’idée je la trouve super mais aviez vous une idée d’application pratique en faisant ca ? ou c’etait juste pour le FUN
Ce qui m’étonne toujours c’est les idées qui sortent de la tête des gens … parce que moi ca sort pas …
Quand je vois les différents inventeurs ou les personnes qui créent des concepts à partir d’une feuille blanche ca me … enfin ca … Bon je suis béa d’admiration en faite … il doit me manquer un truc!?!
PS: désolé pour le tutoiement du début c’était pour le FUN
Bonjour Fred
les applications pratiques elles sont dans la tête des utilisateurs.
Il FAUT savoir allumer et éteindre une LED. C’est TOUJOURS la première chose qu’on fait quand on prend en main une carte et ça depuis des lustres (et je sais de quoi je parle, je suis très… lustré). Mais pourquoi ? bin… si on remplace le LED par un relais on peut commander… une cafetière, un volet roulant, un portail, une porte de garage…. en industriel faire tourner un moteur , faire sortir ou rentrer un vérin, chauffer une cuve, la vidanger ….
Lidée de Lucien d’allumer une LED au dessus d’une certaine température ? Super ! ça permet par exemple de déclencher une ventilation dans une serre quand il fait trop chaud… Et l’éteindre quand c’est trop chaud ? binnn si j’ai un aquarium et que je ne veux pas faire bouillir mes poissons, j’arrête le chauffage quand la température programmée est atteinte…
La LED c’est le premier pas vers les utilisations d’actionneurs externes. Savoir allumer et éteindre une LED c’est pouvoir agir sur le monde extérieur !
voili voilou
@+
François
Bonjour,
« … si on remplace le LED par un relais on peut commander… une cafetière, un volet roulant, un portail, une porte de garage…. en industriel faire tourner un moteur , faire sortir ou rentrer un vérin, chauffer une cuve, la vidanger ….
La LED c’est le premier pas vers les utilisations d’actionneurs externes. »
Et la saga push button fera le pendant « capture des inter-actions extérieur »
@+
Effectivement … Vendredi je devais pas être en phase avec mon cerveau (mon quoi?) la semaine fut longue … Bref, ça me parait si évident aujourd’hui En plus j’y avait pensé quand j’ai monté mon RPI avec commande via radio de prises et de volets roulants au départ pour faire de la simulation de présence et surtout parce que j’ai une baie vitrée qui prend le soleil en plein l’après midi, pour réguler un peu la température …
Bon ca veut donc dire que j’ai besoin de vacances 🙂
😀
Ping : Technologie | Pearltrees
Ping : Raspberry Pi | Pearltrees
Ping : Un Raspberry pour faire clignoter une LED ! - Steve Fuchs
Ping : Penser ‘Thread’ pour simplifier vos programmes | Framboise 314, le Raspberry Pi à la sauce française….
Ping : Plongez dans le Go | Framboise 314, le Raspberry Pi à la sauce française….
Bonjour,
tout d’abord merci beaucoup pour ce tuto très complet.
J’ai une question concernant la photo :
https://www.framboise314.fr/wp-content/uploads/2016/07/LED_GPIO.jpg
J’aimerais acheter le même type de connexion broches/resistances pour me fabriqué un câble vidéo pour mon Atari ST :p
j’ai cherché cobbler mais je trouve que des accessoires avec PCB alors que sur la photo on dirait un fil avec de la gaine thermo.
Auriez-vous un lien ?
D’avance merci
Bonjour,
Merci.
L’accessoire de la photo est une réalisation personnelle. Il ne faut pas grand chose et très facile à faire.
Une led + une résistance + un lien femelle/femelle du commerce + un bout de gaine thermorétractable.
Les liens femelle/femelle se trouvent facilement, pour qq cents, par paquet de 10, 50 ou 100 du côté du soleil levant. Le reste n’est que quelques soudures et la gaine pour des questions d’isolement.
Peut être en cherchant sur les sites chinois, tu trouveras des cordons fil vers connecteur femelle.
@+
Bonjour à tous
Un grand merci pour cet article, grâce à vous j’ai pu faire clignoter ma première LED avec un Pi Zéro W.
Je suis débutant dans le domaine de la framboise.
Je me suis fixé comme objectif de l’intégrer dans mon installation électrique.
Je m’explique :
Actuellement, en fourniture EDF, j’ai un tarif Tempo basé sur un principe de 3 tranches horaires, Bleu, Blanc, Rouge avec des heures pleines et creuses
Je suis chauffé par un plancher chauffant à eau chaude alimenté par une pompe à chaleur principalement sauf les jours rouges ou j’ai une ancienne chaudière qui prend la relève .
Le tout est orchestré par un automate Zélio de Schneider que j’ai mis en place à l’installation de la pompe.
Cet automate reçoit les informations des tranches horaires par l’intermédiaire d’un boitier indicateur Tempo d’EDF, que j’ai customisé afin qu’il me sorte des signaux correspondants aux tranches qui m’intéressent.
Ce boitier étant mis à jour par l’intermédiaire des signaux à 175 Hz qu’Enedis envoie sur les lignes d’alimentation.
Ce système étant sur la fin de vie, je souhaite mettre à contribution le GPIO de la Framboise pour le remplacer dans la gestion de mon chauffage.
J’ai une question à vous soumettre, pensez-vous que l’on puisse compter sur la mémoire du GPIO, je m’explique, si une application met une sortie à un état donné, ext-ce que cet état est conservé sans soucis même application terminée ou faut-il la rafraîchir de temps à autre ?
Merci de m’avoir lu jusque là et bravo encore pour ce site très bien fait !!
Bonjour Gilles
ma foi si vous avez fait clignoter une LED c’est déjà un super début 🙂
pour répondre à la question, oui, si une appli allume une LED celle ci reste allumée tant qu’on ne change pas l’état du GPIO
(ou qu’on ne coupe pas l’alimentation 🙂 )
je ne sais pas si ça peut vous servir mais il y a un cours ici https://www.framboise314.fr/geii/#Utiliser_un_GPIO_pour_commander_la_LED
pour piloter la LED avec la ligne de commande
je l’ai animé à l’IUT à la rentrée passée. si ça peut vous servir pour tester et vérifier que la LED reste allumée…pas de souci
cordialement
François
Super le lien vers le cours, je vais pouvoir m’améliorer encore.
Merci beaucoup pour la réponse et à bientôt ! 🙂
cordialement
Gilles
Bonjour à tous!
Ben voilà après + de 48H00 de fonctionnement avec une Led allumée, malgré pas mal de manipulation, la LED est toujours allumée. Cà a l’air stable.
Même après un update upgrade de la framboise qui était très long cette fois !!
Jusqu’au reboot demandé, bien sûr….
Je suis confiant pour la suite.
Une question François S.V.P:
J’entamerais bien un fil de discussion sur le forum, mais bon je trouve que le sujet Téléinformation EDF est déjà bien discuté, je ne voudrais pas encombrer le fofo.
Qu’en pensez vous ?
Merci
Gilles
Bieeennn !
Pour le forum pas de souci essayez d ouvrir un sujet avec un titre pas encore traité
Je suis peu sur le forum en fait (pas assez de temps) il y a une super equipe qui gere et modére ?
Bonjour,
Je vais débuter en Raspberry Pi … j’ai commandé un Zero WH ainsi qu’un guide en français …
et j’apprends avant de recevoir tout ce qu’il faut pour passer à la pratique ..
Aussi, j’ai lu cet article avec attention, et j’aurai aimé savoir si je peux mettre 2, 3, voir 10 leds à la suite … ( en série en fait ) ?
C’est peut être bête comme question, cela a peut être déjà été abordé mais je n’ai pas trouvé de réponse … D’après moi, une LED est une lampe donc ce serait possible, comme pour toute autre type de lampe … mais j’aimerai confirmation pour éviter de tout faire griller dès mon premier essai !
Merci !
PS: Mon ambition est de réaliser un(e) Tally pour OBS … 😉
Bonjour Olivier
il n’y a pas de question bête 🙂
bin… une LED ce n’est pas DU TOUT une ampoule c’est une diode. La différence ? le courant ne passe que dans un seul sens
j’ai fait un article là dessus si vous voulez y jeter un coup d’oeil… https://www.framboise314.fr/scratch-raspberry-pi-composants/led/
Une LED fonctionne TOUJOURS avec une résistance de protection, sinon elle crame (regardez ici pour le calcul de la résistance https://www.framboise314.fr/scratch-raspberry-pi-composants/resistance/)
parfois certains tentent le diable en reliant directement une LED à une pile. Ca marche mais c’est la résistance interne de la pile qui intervient
Une led rouge a à ses bornes 1,6v si vous en mettez 2 en série pour que ça s’allume il faudra 3,2 volts
avec 10 LED en série il faut 16 volts pour que ça s’allume etc…
après les LED d’autres couleurs ont des tensions différentes vous les trouverez sans problème
regardez dejà tout ça et revenez vers moi si vous avez des questions.
ps je ne sais pas du tout ce que c’est que « un(e) Tally pour OBS »
Ouah, j’avais pas vu ces articles qui m’apprennent encore des choses …
Oui, j’ai bien retenu : toujours utiliser une LED avec une résistance, pour éviter tout désagrément !
Une LED rouge ( ce que je vais utiliser ) a besoin de 1.6v donc avec l’alimentation d’un Raspberry Pi de 5V, je peux en mettre 3 ( 3 * 1.6 = 4.8 V ) avec 3 résistances ?
Pour info, un(e) tally c’est une lumière rouge qui indique que la caméra est celle qui est diffusée, enregistrée… comme par exemple, cela: https://live.ptzoptics.com/wp-content/uploads/2019/02/ZCam-with-Tally-Light.webp .
Bonjour
non si elles sont en série une seule résistance suffit
calcul de R : 5 – 4.8 = 0.2v
on prend par exemple un courant de 10mA
R = U/I R = 0.2/0.010 = 20 ohms
merci pour Tally je regarde le lien 🙂