Raspberry Pi 1
UTILISATION des GPIOs
UTILISATION des GPIOs
Date
07/11/2024
Cours Raspberry Pi Raspberry Pi
Ordinateur avec internet (poste de travail)
RPi 3 ou 4
installation de Raspi OS 64 Bits, MISE EN SERVICE RPI
Shell (bash) / python / Gcc et C
Electronique de base , plaque d'essais , résistors , led
Matériels:
RPi, carte SD 16Go minimum ,
Alimentation 2 A 5 V microUSB
Clavier azerty , souris
led rouge , led verte , resistors de limitation pour les leds.
relai reed
plaque d'essai , cables
Plaque d'essais , led et resistance (pour la led), leds, résistances interrupteurs et/ou câble.
Maîtrise et usage des GPIO :
en Shell (initiation)
en python (initiation)
en C/C++ (gcc,g++) au programme du BTS
Un RPI ou vous êtes ROOT (RPI Installation)
GPio Usages / I/O / Résistance de rappel / PWM / Interruption
pilotage est Entrées Sorties du RPI
Utilisation du serveur web / php pour piloter les GPIO à travers un site
On peut utiliser les GPIO avec Sysfs mais il va être plus facile d'utiliser les librairies et les outils de WiringPi.
Système de fichier appelé sysfs
/sys/class/gpio
#Selectionner GPIO 17
echo 17 > /sys/class/gpio/export
#direction du port out/in
echo out > /sys/class/gpio/gpio17/direction
#allumer la led
echo 1 > /sys/class/gpio/gpio17/value
#eteindre la led
echo 0 > /sys/class/gpio/gpio17/value
#!/bin/bash
GPIO=17
# Exporter le GPIO
echo $GPIO > /sys/class/gpio/export
# Configurer en sortie
echo out > /sys/class/gpio/gpio$GPIO/direction
while true; do
# Allumer
echo 1 > /sys/class/gpio/gpio$GPIO/value
sleep 1
# Éteindre
echo 0 > /sys/class/gpio/gpio$GPIO/value
sleep 1
done
GPIO , General Purpose Input Output
nous allons installer wiringPi de Gordon
https://github.com/WiringPi/WiringPi
ou sur linux3
/Data/Outils_Logiciels/Linux/RaspiOS/2022/wiringpi
WiringPI-master.zip
scp 2gxxxxx@linux3.local:/Data/Outils_Logiciels/Linux/RaspiOS/2022/wiringpi/WiringPi-master.zip .
votre login et non pas 1gxxxxx
il est préférable de travailler dans un répertoire Works de votre compte
unzip WiringPi-master.zip
cd WiringPi-master
raspi@rpiPROF:~/Works/WiringPi-master $ ls
build debian-template gpio People update wiringPi
COPYING.LESSER devLib INSTALL pins VERSION wiringPiD
debian examples newVersion README.md version.h
raspi@rpiA10:~/wiringpi/WiringPi-master $
sudo ./build
on peut tester man gpio pour valider le travail
Gpio : donner la définition de GPIO
Tester votre led sur le +3.3V (on ne sait jamais ,elle est peut être grillées ou a l'envers !
Calculer la résistance de limitation du courant en fonction de la couleur
https://www.digikey.fr/fr/resources/conversion-calculators/conversion-calculator-resistor-color-code
pour avoir la valeur de votre résistor.
Pour la led rouge par exemple le point de fonctionnement pour une bonne luminosité est de 1.93 V pour 20 mA
R=U/I
U=3.3-1.93
Donner R
remarque: Les résistances misent à disposition sont bien pour toutes les couleurs.
Brochage
albert@workboot:~ $ pinout
,--------------------------------.
| oooooooooooooooooooo J8 +====
| 1ooooooooooooooooooo | USB
| +====
| Pi Model 3B V1.2 |
| +----+ +====
| |D| |SoC | | USB
| |S| | | +====
| |I| +----+ |
| |C| +======
| |S| | Net
| pwr |HDMI| |I||A| +======
`-| |--------| |----|V|-------'
Revision : a02082
SoC : BCM2837
RAM : 1024Mb
Storage : MicroSD
USB ports : 4 (excluding power)
Ethernet ports : 1
Wi-fi : True
Bluetooth : True
Camera ports (CSI) : 1
Display ports (DSI): 1
J8:
3V3 (1) (2) 5V
GPIO2 (3) (4) 5V
GPIO3 (5) (6) GND
GPIO4 (7) (8) GPIO14
GND (9) (10) GPIO15
GPIO17 (11) (12) GPIO18
GPIO27 (13) (14) GND
GPIO22 (15) (16) GPIO23
3V3 (17) (18) GPIO24
GPIO10 (19) (20) GND
GPIO9 (21) (22) GPIO25
GPIO11 (23) (24) GPIO8
GND (25) (26) GPIO7
GPIO0 (27) (28) GPIO1
GPIO5 (29) (30) GND
GPIO6 (31) (32) GPIO12
GPIO13 (33) (34) GND
GPIO19 (35) (36) GPIO16
GPIO26 (37) (38) GPIO20
GND (39) (40) GPIO21
For further information, please refer to https://pinout.xyz/
gpio -g mode 17 out #pour mettre le gpio17 en sortie
gpio -g write 17 1 #allume la led
gpio -g write 17 0 #eteint la led
man gpio #toujours utile
gpio -g blink 17
pour arrêter , ctrl c , stop le 'blink' !
on peut surveiller ce qui se passe sur les gpio (s) et voir clignoter la led !
avec un autre terminal lancer la commande suivante :
watch -n 0.1 gpio readall
Exemple d'un programme blink de GPIO17 (animation)
La fonction GPIO utilise le driver GPIO, pour ceux qui veulent approfondir la connaissance.
Mr Blaes nous explique ici le fonctionnement de ce drivers
gestion des gpio avec SYSFS:
https://www.blaess.fr/christophe/2012/11/26/les-gpio-du-raspberry-pi/
La led qui clignote est le "bonjour le monde" en version pour l' électronicien .
On utilisera les leds avec un résistor de limitation de courant comprise entre 300 Ohms et 1kOhms. Cette valeur n'étant pas critique , mais il faut la mettre pour ne pas surcharger le GPIO.
Avec une led rouge dans un premier temps.
En vous rappelant de vos cours en Shell faire clignoter la led a 0,5Hz (periode 2 secondes)
Exemple de code , boucle sans fin :
le rendre exécutable et le tester
blink.sh :
#!/bin/bash
gpio -g mode 17 out #pour mettre le gpio17 en sortie
while (true)
do
gpio -g write 17 1 #allume la led
sleep 1
gpio -g write 17 0 #eteint la led
sleep 1
done
rappel !! ctrl C , pour interrompre le script.
Pour avancer nous allons :
Ajouter une led sur gpio27 .
Et faire un code en shell qui alterne les 2 leds à la fréquence 0,5Hz
Sur le GPIO27 on va placer le relais reed qui quand on a pas l'aimant voit un 1 (3.3V)
et une résistance de rappel au 3.3V est nécessaire
Attention le GPIO27 devient une entrée!
Ecrire un code en BASH SHELL qui allume la led quand l'aimant est à coté du relais REED et eteint si loin..
#!/bin/bash
gpio -g mode 17 out #pour mettre le gpio17 en sortie
gpio -g mode 27 in #pour mettre le gpio27 en entrée
while (true)
do
val=$(gpio -g read 27)
#ou val=`gpio -g read 27` #permet de récupérer l'etat de GPIO 27
if [ "$val" -eq 1 ] # test si val égale 0
then
gpio -g write 17 1 #allume la led
else
gpio -g write 17 0 #eteint la led
fi
done
C'est nouveau ok !! (et vu ou a voir en cours)
Attention en Python , Début et Fin { } en C .. est réalisé par l'indentation .
A l'aide de ces tutos
https://www.raspberrypi.org/documentation/usage/gpio/python/README.md
https://www.framboise314.fr/la-saga-blink-un-raspberry-pour-faire-clignoter-une-led/
https://raspberrypihq.com/making-a-led-blink-using-the-raspberry-pi-and-python/
Ecrire un code en python qui fait clignoter alternativement la led rouge et la verte. (blink.py)
La librairie gpiozero est installée avec Raspbian .
#!/usr/bin/python3
# -*- coding:utf-8 -*-
#-------------------------------------------------------------------------------
# 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(17, GPIO.OUT) #mise en sortie du port GPIO 17
print("Début du programme LED clignotante")
#message IHM
while True : #boucle infinie
GPIO.output(17, GPIO.HIGH) #sortie 23 high
time.sleep(1) #attente 1 seconde
GPIO.output(17, GPIO.LOW) #sortie 23 low
time.sleep(1) #attente 1 seconde
#------------------------------------------------------------------------
Écrire un code en C qui fait le Blink , utiliser wiringpi
Utilisation de la libraire wiring pi
Attention par exemple le GPIO17 devient le numéro 0 avec WiringPi
On retrouve ces numéros avec la commande vu en 5 , gpio readall
Le librairie wiringpi est déjà installée sous Raspbian
Ecrire un code en C qui fait clignoter alternativement la led rouge et la verte. (blink)
pi@nas:~ $ gpio readall
+-----+-----+---------+------+---+---Pi 3B--+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | IN | 1 | 3 || 4 | | | 5v | | |
| 3 | 9 | SCL.1 | IN | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 0 | IN | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | IN | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | IN | 0 | 11 || 12 | 0 | IN | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 0 | IN | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | IN | 0 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | IN | 0 | 21 || 22 | 0 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | IN | 0 | 23 || 24 | 1 | IN | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | IN | CE1 | 11 | 7 |
| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 |
| 5 | 21 | GPIO.21 | IN | 1 | 29 || 30 | | | 0v | | |
| 6 | 22 | GPIO.22 | IN | 1 | 31 || 32 | 0 | IN | GPIO.26 | 26 | 12 |
| 13 | 23 | GPIO.23 | IN | 0 | 33 || 34 | | | 0v | | |
| 19 | 24 | GPIO.24 | ALT5 | 0 | 35 || 36 | 0 | IN | GPIO.27 | 27 | 16 |
| 26 | 25 | GPIO.25 | IN | 0 | 37 || 38 | 0 | IN | GPIO.28 | 28 | 20 |
| | | 0v | | | 39 || 40 | 0 | IN | GPIO.29 | 29 | 21 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+---Pi 3B--+---+------+---------+-----+-----+
Nous donne l'état des GPIO
Attention , ne jamais dépasser 3,3 V sur une entrée.
ATTENTION , ne pas broyer la carte SD! c'est fragile ça ne se plie pas
Câbler un GPIO27 en entrée et GPIO17 en sortie avec une LED
Les valeurs des résistors sont assez peu critiques
1kO à 1Mo (pour la résistance de rappelle de l'interrupteur)
Il est facile de "simuler" ou remplacer un interrupteur par un fil (! Attention au court circuit ), mais nous avons aussi des boutons poussoirs .
Tester sous shell votre câblage , si vous pilotez bien la led et si vous lisez bien l'état de l'interrupteur.
Le relais REED et l'aimant remplace l'interrupteur que nous n'avons pas :)!
Schéma sous fritzing .
Si on appuie pas sur le BP (bouton poussoir) (ouvert) GPIO27 est 1
Si on appuie sur le BP GPIO27 est 0
Tester et valider votre câblage sous shell. puis passer au programme.
Fonction de chaque broche
gpio -g mode 27 in # pour mettre en entrée
gpio -g mode 27 down # pull down
mode <pin> <mode>
Set a pin into input, output or pwm mode. Can also use the lit‐
erals up, down or tri to set the internal pull-up, pull-down or
tristate (off) controls.
Des résistances internes au SOC sont disponible pour être Pull UP ou Pull Down
pullUpDnControl( pin , ordres );
pin est le numéro de broche.
ordres :
PUD_DOWN : mettre la pin en pull Down
PUD_UP : mettre la pin en pull Up
PUD_OFF : aucun rappel . (tri state)
Toutes les broches ne gèrent pas la PWM voir image ci-dessus.
Pulse Width Modulation. wikipedia
en shell :
Tester avec une led sur le GPIO18 la fonction PWM
avec man gpio regarder comment faire de la PWM sur RPi
Ecrire un code faisant varier la luminosité de led sur GPIO18 de rien au maximum.
gpio -g mode 18 pwm
for i in $(seq 0 1024);do gpio -g pwm 18 $i;done;
gpio -g pwm 18 0
gpio -g pwm 18 512
gpio -g pwm 18 1024
Expliquer chacune des lignes
en C:
https://github.com/WiringPi/WiringPi/blob/master/examples/pwm.c
/*
* pwm.c:
* This tests the hardware PWM channel.
*
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main (void)
{
int bright ;
printf ("Raspberry Pi wiringPi PWM test program\n") ;
if (wiringPiSetup () == -1)
exit (1) ;
pinMode (1, PWM_OUTPUT) ;
for (;;)
{
for (bright = 0 ; bright < 1024 ; ++bright)
{
pwmWrite (1, bright) ;
delay (1) ;
}
for (bright = 1023 ; bright >= 0 ; --bright)
{
pwmWrite (1, bright) ;
delay (1) ;
}
}
return 0 ;
}
Que fais ce programme , expliquer .
Donnez l'algorithme de ce dernier.
Déclenchement sur front montant, front descendant , et interruption
Donner un code utilisant cette fonction
en shell:
on va travailler sur le GPio17
en shell:
gpio -g mode 17 in
gpio -g wfi 17 rising
avec un bouton poussoir (ou un fil) GPio17 ayant une résistance de pull up , faire un front descendant et que se passe t'il ?
gpio -g wfi 17 falling
a quoi sert cette fonction ?
int wiringPiISR (int pin, int edgeType, void (*function)(void))
This function registers a function to received interrupts on the specified pin. The edgeType parameter is either INT_EDGE_FALLING, INT_EDGE_RISING, INT_EDGE_BOTH or INT_EDGE_SETUP. If it is INT_EDGE_SETUP then no initialisation of the pin will happen – it’s assumed that you have already setup the pin elsewhere (e.g. with the gpio program), but if you specify one of the other types, then the pin will be exported and initialised as specified. This is accomplished via a suitable call to the gpio utility program, so it need to be available.
En résumé plus simple :
INT_EDGE_RISING (0 à 1), INT_EDGE_FALLING (1 à 0) ou INT_EDGE_BOTH (les deux).
ou rien INT_EDGE_SETUP
/ * Copyright (c) 2013 Gordon Henderson.
// La patte générant les interruptions est associée à la patte 11 du connecteur du RaspBerry
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <wiringPi.h>
#define BUTTON_PIN 0 //PIN 0 = GPIO17
static volatile int globalCounter = 0 ; //on utilise un compteur d'évènements
// la procedure recevant les interruptions. Placer ici le code de traitement
void myInterrupt (void)
{
++globalCounter ;//Dans cet exemple on ne fait qu'incrémenter un compteur
}
// main
int main (void)
{
int myCounter = 0 ;
if (wiringPiSetup () < 0)
{ //la bibliothèque n'a pas pu s'initialiser
fprintf (stderr, "Unable to setup wiringPi: %s\n", strerror (errno)) ;
return 1 ;
}
if (wiringPiISR (BUTTON_PIN, INT_EDGE_FALLING, &myInterrupt) < 0)
{ //ici on associe la procedure à la patte qui déclenche l'évènement
fprintf (stderr, "Unable to setup ISR: %s\n", strerror (errno)) ;
return 1 ;
}
for (;;)
{
printf ("Waiting ... ") ;
fflush (stdout) ;//
//on attend que quelque chose se passe (que global counter changer ce qui signifie qu'un evènement est //arrivé
while (myCounter == globalCounter)
delay (100) ;
printf (" Done. counter: %5d\n", globalCounter) ;
myCounter = globalCounter ;
}
return EXIT_SUCCESS ;
}
Donner le pseudo code
attention a bien compiler avec la lib -lwiringPi
Résistance de rappelle interne.
en shell:
rappel de niveau haut:
gpio -g mode 17 up
rappel de niveau bas:
gpio -g mode 17 down
et de aucun (troisième état tri-state )
gpio -g mode 17 tri
Installer le serveur web apache et php sur votre rpi. Tester et valider
petit projet :
Ecrire un code qui va permettre d'allumer une led ou de l’éteindre
PHP est capable d’exécuter une script , python ou Shell ou un exécutable.
Installations sous raspbian
sudo apt update && sudo apt install apache2 && sudo install php
Tester et valider le serveur web en locale et le php en ligne.
Exemple d'application qui allume ou éteint la LED sur GPIO17
Eviter de lancer un processus bloquant (pas de boucle infinie)
En Php il existe la fonction system pour exécuter des commandes ou des scripts.
installer Rust:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
On dispose de cargo
dans Works/Rust
on va créer un projet RUST blink
cargo new blink
cd blink
on va ajouter une librairie (crate)
rppal
pour ce faire il faut ajouter ces lignes , dans Cargi.toml
albert@workboot:~/Works/Rust/blink $ cat Cargo.toml
[package]
name = "blink"
version = "0.1.0"
edition = "2021"
[dependencies]
rppal = "0.13" # Vérifie la dernière version sur crates.io"0.13"
[dependencies]
rppal = "0.13" # Vérifie la dernière version sur crates.io
le source rust: blink/src/mains.rs
use rppal::gpio::Gpio;
use std::thread::sleep;
use std::time::Duration;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialisation du GPIO
let gpio = Gpio::new()?;
let mut pin = gpio.get(17)?.into_output(); // Remplace 17 par ton numéro de pin
// // Boucle blink
loop {
pin.set_high(); // Allume
sleep(Duration::from_secs(1));
pin.set_low(); // Éteint
sleep(Duration::from_secs(1));
}
}
et dans le projet
cargo build
et on obtient un executable en RUST de notre blink
albert@workboot:~/Works/Rust/blink/target/debug $ ls
blink blink.d build deps examples incremental
albert@workboot:~/Works/Rust/blink/target/debug $
./blink
et on doit constater la broche 17 qui fait clignoter notre LED !