Sur Raspberry Pi, la gestion des entrées/sorties (GPIO) est souvent le premier point de contact avec le monde matériel. Parmi les nombreuses solutions disponibles, pigpio et son démon pigpiod se distinguent par leur précision, leur stabilité et leur polyvalence.
Cet article propose une prise en main progressive de pigpiod, en commençant par des opérations simples de lecture et d’écriture sur les GPIO, avant d’aborder l’utilisation du port série et du bus I²C, afin de fournir une base solide pour des projets matériels fiables et évolutifs.
sudo apt-get update
sudo apt-get install pigpiod pigpio-tools libpigpio-dev
sudo systemctl enable pigpiod
sudo systemctl start pigpiod
systemctl status pigpiod#include <stdio.h>
#include <pigpiod_if2.h>
#define LED_GPIO 20 // GPIO20 (BCM)
int main(void)
{
int pi;
// Connexion au démon pigpiod
pi = pigpio_start(NULL, NULL);
if (pi < 0) {
printf("Erreur : impossible de se connecter à pigpiod\n");
return 1;
}
// Configuration GPIO "LED_GPIO" en sortie
set_mode(pi, LED_GPIO, PI_OUTPUT);
printf("Blink pigpiod sur GPIO %d\n", LED_GPIO);
for (int i = 0 ; i < 10 ; i++) {
gpio_write(pi, LED_GPIO, 1); // LED ON
time_sleep(0.5);
gpio_write(pi, LED_GPIO, 0); // LED OFF
time_sleep(0.5);
}
// Fermeture de la connexion
pigpio_stop(pi);
return 0;
}Important : La variable "pi" représente la connexion au démon. Elle doit être passée en paramètre à toutes les fonctions de l’API.
gcc blink.c -o blink -lpigpiod_if2 -lrt -pthread
./blink
Attention à bien mettre "lpigpiod_if2" et non pas "lpigpiod_if".
Exemple : lecture d’un bouton sur GPIO 26
#include <stdio.h>
#include <pigpiod_if2.h>
#define BUTTON_GPIO 26
#define LED_GPIO 20
int main(void)
{
// Connexion au démon pigpiod
int pi = pigpio_start(NULL, NULL);
if (pi < 0) return 1;
// Configuration GPIO "BUTTON_GPIO" en entrée
set_mode(pi, BUTTON_GPIO, PI_INPUT);
// Configuration GPIO "LED_GPIO" en sortie
set_mode(pi, LED_GPIO, PI_OUTPUT);
// Configure une résistance de pullup interne au Raspberry PI
// Inutile si vous avez une résistance de pullup externe
set_pull_up_down(pi, BUTTON_GPIO, PI_PUD_UP);
printf("Lecture état GPIO %d et recopie sur GPIO %d\n", BUTTON_GPIO, LED_G>
while (1) {
// Lecture bouton
int level = gpio_read(pi, BUTTON_GPIO);
// Recopie sur LED et affichage
gpio_write(pi, LED_GPIO, level);
printf("Bouton : %d\n", level);
time_sleep(0.2);
}
// Fermeture de la connexion
pigpio_stop(pi);
return 0;
}
gcc lecture_gpio.c -o lecture_gpio -lpigpiod_if2 -lrt -pthread
./lecture_gpioPigpio permet de générer des signaux PWM matériels très précis, idéal pour contrôler :
Dans cet exemple nous utiliserons une LED. Le câblage est identique aux précédents : la LED est connecté sur la GPIO 20.
#include <stdio.h>
#include <pigpiod_if2.h>
#define LED 20
int main(void)
{
// Connexion au démon pigpiod
int pi = pigpio_start(NULL, NULL);
if (pi < 0)
{
printf("Erreur : impossible de se connecter à pigpiod\n");
return 1;
}
// Réglage fréquence PWM
int freq = set_PWM_frequency(pi, LED, 500); // 500 Hz
printf("Fréquence PWM réelle : %d Hz\n", freq);
// Configuration GPIO "LED" en sortie
set_mode(pi, LED, PI_OUTPUT);
// Augmentation progressive de l'intensité dans la LED
for (int duty = 0 ; duty <= 255 ; duty++) {
set_PWM_dutycycle(pi, LED, duty); // Valeur 0-255
time_sleep(0.02);
}
// Ralentir et éteindre
for (int duty = 255; duty >= 0; duty--) {
set_PWM_dutycycle(pi, LED, duty);
time_sleep(0.02);
}
set_PWM_dutycycle(pi, LED, 0);
// Fermeture de la connexion
pigpio_stop(pi);
return 0;
}
Remarques :
Relevé du signal obtenu (à un instant t, le rapport cyclique étant variable au cours de l'exécution du programme) à l'oscilloscope :
Il est possible de détecter les changements d'états sur les GPIO configurées en entrées (détection de fronts) et de déclencher automatiquement l'appel d'une fonction (callback). Ceci est très utile pour éviter d'avoir à tester l'état des entrées en permanence dans la boucle principale du programme et permet ainsi de gagner tu temps CPU.
Dans cet exemple nous utiliserons une LED et un bouton poussoir. Le câblage est identique aux précédents : la LED est connecté sur la GPIO 20 et le bouton poussoir sur la GPIO 26.
#include <stdio.h>
#include <pigpiod_if2.h>
#define BUTTON 26
#define LED 20
// Code de la fonction de callback
// Cette fonction est appelée de manière asynchrone lorsque qu'un front
// est détecté sur la GPIO concernée
void button_callback(int pi, unsigned gpio, unsigned edge, uint32_t tick) {
// Allume la LED si front montant
if (edge == 1) {
gpio_write(pi, LED, 1);
} else { // Sinon extinction de la LED
gpio_write(pi, LED, 0);
}
// Affiche les paramètres reçus par la fonction (pour info, à supprimer dans un "vrai" programme
printf("Front détecté : button_callback : gpio = %d - edge = %d - tick = %d", gpio, edge, tick);
}
int main(void) {
// Connexion au démon pigpiod
int pi = pigpio_start(NULL, NULL);
if (pi < 0)
{
printf("Erreur : impossible de se connecter à pigpiod\n");
return 1;
}
// Configuration GPIO "BUTTON" en entrée et activation pull-up interne
set_mode(pi, BUTTON, PI_INPUT);
set_pull_up_down(pi, BUTTON, PI_PUD_UP);
// Configuration GPIO "LED" en sortie
set_mode(pi, LED, PI_OUTPUT);
// Chaque front sur l'entré BUTTON déclechera l'appel
// de la fonction "button_callback"
int callback_id = callback(pi, BUTTON, EITHER_EDGE, button_callback);
if(callback_id < 0)
{
printf("Erreur : impossible de créer la callback\n");
return 1;
}
while (1) {
time_sleep(1); // boucle principale libre
}
// Fermeture de la connexion
pigpio_stop(pi);
return 0;
}
La fonction de callback (button_callback dans notre cas) reçoit 4 paramètres :
La fonction callback_ex()
La version étendue callback_ex() permet de passer un paramètre userdata à la fonction callback, ce qui est pratique pour structurer du code plus complexe ou utiliser plusieurs boutons sans variables globales (voir documentation officielle de pigpio).
Exemple de gestion anti-rebond
La fonction de callback serait modifiée ainsi :
void button_callback(int pi, unsigned gpio, unsigned edge, uint32_t tick) {
static uint32_t lastTick = 0;
if(tick - lastTick > 20000) // anti-rebond de 20ms
{
lastTick = tick;
// Allume la LED si front montant
if (edge == 1) {
gpio_write(pi, LED, 1);
} else { // Sinon extinction de la LED
gpio_write(pi, LED, 0);
}
}
// Affiche les paramètres reçus par la fonction (pour info, à supprimer dans un "vrai" programme
printf("Front détecté : button_callback : gpio = %d - edge = %d - tick = %d", gpio, edge, tick);
}