Formations à l'informatique et à l'électronique

Auteur : SD
Créé le : 21-12-2025

Raspberry Pi - Le port série avec pigpio

Cet article fait suite à « Raspberry Pi – Premiers pas avec pigpio » et suppose que la bibliothèque pigpio ainsi que le démon pigpiod sont déjà installés et fonctionnels sur votre Raspberry Pi. Si ce n’est pas le cas, reportez‑vous d’abord à l’article précédent avant de continuer.

L’objectif ici est de montrer comment utiliser pigpio pour accéder au port série (UART) du Raspberry Pi, aussi bien du point de vue matériel que logiciel, avec des exemples en langage C.

Sommaire

Rappels sur pigpio et le port série

La bibliothèque pigpio permet d’accéder aux GPIO du Raspberry Pi via un démon système (pigpiod). Parmi les fonctionnalités proposées, pigpio permet également :

Dans cet article, nous nous concentrons uniquement sur le port série matériel, déjà présent sur le Raspberry Pi. Pigpio ne crée pas un nouvel UART : il s’appuie sur les périphériques série Linux existants (par exemple /dev/serial0).

Configuration du Raspberry Pi

Avant de pouvoir utiliser le port série, quelques réglages sont nécessaires dans Raspbian. En effet, Raspbian utilise le port série GPIO comme port console sur lequel on peut se loguer avec un terminal (comme Putty par exemple). Il faut donc désactiver ceci pour libérer le port série. Pour cela, exécuter "raspi-config" :

raspi-config

Raspi-config est une interface en mode texte. Pour se déplacer, utiliser les flèches ou la touche tabulation. Pour valider un choix, utiliser la barre d'espace ou la touche Entrée.

Sélectionner "Interface Options" :

raspi-config serial port activation pigpio

Sélectionner "I6 Serial Port" :

raspi-config select serial pigpio

Sélectionner "No" pour désactiver le shell sur le port série :

raspi-config select no login pigpio

Sélectionner "Yes" pour que le port série soit activé :

raspi-config enable serial port pigpio

Sélectionner "Ok" pour confirmer :

raspi-config enable serial port pigpio

Sélectionner "Finish" pour quitter raspi-config :

raspi-config finish enable serial port pigpio

Sélectionner "Yes" pour redémarrer le Raspberry Pi et prendre en compte les modifications :

raspi-config reboot enable serial port pigpio

Nom du périphérique série

Sur les Raspberry Pi récents, il est conseillé d’utiliser :

Pour vérifier les correspondances exactes :

ls -l /dev/serial*

Cela permet de savoir si l’UART matériel correspond à /dev/ttyAMA0 ou /dev/ttyS0, selon le modèle et la configuration.

Connexion du port série du Raspberry Pi avec un PC

Cette connexion nécessite un adaptateur USB-TTL.

Points de vigilance

Connexion Raspberry Pi <=> PC avec adaptateur USB TTL

Exemple de code en langage C transmission UART avec pigpio

Actions réalisées par ce programme sur le port série :

  1. Ouverture du port série (serial_open())
  2. Ecriture du message "Hello pigpiod" sur le port série (serial_write())
  3. Fermeture du port série (serial_close())
#include <stdio.h>
#include <pigpiod_if2.h>

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;
    }

    // Ouverture du port série
    int hSerial = serial_open(pi, "/dev/serial0", 9600, 0);
    if (hSerial < 0) {
        printf("Erreur : impossible d'ouvrir /dev/serial0\n");
        pigpio_stop(pi);
        return 1;
    }

    // Ecrirure sur le port série
    serial_write(pi, hSerial, "Hello pigpiod\n", 14);

    // Fermeture du port série
    serial_close(pi, hSerial);

    // Fermeture de la connexion
    pigpio_stop(pi);

    return 0;
}

Résultat coté PC

Pour observer le résultat coté PC, il faut utiliser un terminal (Putty, RealTerm, Yat,...).

Le port série doit être configuré de la même manière que sur le Raspberry Pi (9600 bauds).

Exemple dans YAT :

Exemple 2 : réception et transmission (echo)

Actions réalisées par ce programme sur le port série :

  1. Ouverture du port série (serial_open())
  2. Ecriture du message "Port série en attente de caractères..." sur le port série (serial_write())
  3. Répète tant qu'il ne reçoit pas le caratère '*'
    1. Test si un caractère a été reçu (serial_data_available())
    2. Si oui, fait un "echo" : le lit et le renvoie au PC (serial_read_byte() et serial_write_byte())
  4. Ecriture du message "* reçu => fin du programme" sur le port série (serial_write())
  5. Fermeture du port série (serial_close())
#include <stdio.h>
#include <pigpiod_if2.h>

int main(void)
{
	// Connexion au démon pigpiod
	int pi = pigpio_start(NULL, NULL);
	char caractere = '\0';

	if (pi < 0) {
		printf("Erreur : impossible de se connecter à pigpiod\n");
		return 1;
	}

	// Ouverture du port série
	int hSerial = serial_open(pi, "/dev/serial0", 9600, 0);
	if (hSerial < 0) {
		pintf("Erreur : impossible d'ouvrir /dev/serial0\n");
        	pigpio_stop(pi);
		return 1;
	}

    serial_write(pi, hSerial, "\nPort série en attente de caractères...\n", 40);

    while(caractere != '*')
    {
        if(serial_data_available(pi, hSerial) > 0)
        {
            caractere = serial_read_byte(pi, hSerial);
            serial_write_byte(pi, hSerial, caractere);
        }
    }
    
    serial_write(pi, hSerial, "\n* reçu => fin du programme\n", 28);

    // Fermeture du port série
    serial_close(pi, hSerial);
    
    // Fermeture de la connexion
    pigpio_stop(pi);
    
    return 0;
}

Résultat coté PC

Exemple dans YAT (en violet ce qui est reçu par le PC, en bleu ce qui est envoyé par le PC) :

Thread de réception

L'exemple précédent de réception présente un inconvénient majeur : la lecture du port série se fait par scrutation (polling en Anglais, on peut aussi utiliser le terme "attente active"). Cette technique consiste à tester régulièrement dans la boucle principale du programme si des données ont été reçues. Ceci provoque une charge supplémentaire pour le CPU.

Il donc est préférable, si possible, d'utiliser les interruptions ou une fonction de callback.

Dans le cas de "pigpio", il n'y a pas de mécanisme de callback ou d'interruption. Une bonne solution est d'effectuer la réception série dans un thread dédié à la lecture, la boucle principale sera ainsi libre pour effectuer d'autres tâches.

Principe

Ce mécanisme est particulièrement utile pour les applications temps réel légères ou multitâches.

#include <stdio.h>
#include <pigpiod_if2.h>
#include <pthread.h>
#include <string.h>

#define LED 20           // GPIO20 pour LED
#define SERIAL_PORT "/dev/serial0"
#define BAUD_RATE 9600

// Structure contenant les informations de connexion
// sera transmise en paramètre au thread de réception série
typedef struct {
    int pi;
    int hSerial;
} uart_data_t;

void* uart_thread(void* arg);

int main(void) {
    int pi = pigpio_start(NULL, NULL);
    if (pi < 0) {
        printf("Erreur : impossible de se connecter à pigpiod\n");
        return 1;
    }

	// GPIO "LED" en sortie
    set_mode(pi, LED, PI_OUTPUT);

	// Ouverture du port série
    int hSerial = serial_open(pi, SERIAL_PORT, BAUD_RATE, 0);
    if (hSerial < 0) {
        printf("Erreur ouverture port série\n");
        pigpio_stop(pi);
        return 1;
    }

	// Préparation de la structure qui sera transmise au thread
    uart_data_t uart_data = { pi, hSerial };
    pthread_t thread_id;

    // Lancer le thread UART
    pthread_create(&thread_id, NULL, uart_thread, &uart_data);

    // Boucle principale libre pour d'autres tâches
    while (1) {
        time_sleep(1);
    }

	// Fermeture du port série
    serial_close(pi, hSerial);
    
	// Fermeture de la connexion
	pigpio_stop(pi);
    
	return 0;
}

// Thread dédié à la lecture UART
void* uart_thread(void* arg) {
	// "Lecture" du paramètre reçu (pointeur sur structure uart_data_t)
    uart_data_t* data = (uart_data_t*)arg;
    // Buffer de réception
	char buf[128];
    int count;

    while (1) {
		// Lecture des caractères reçus
        count = serial_read(data->pi, data->hSerial, buf, sizeof(buf) - 1);
        if (count > 0) {
            buf[count] = '\0';
			// Affichage des caractères reçus
            printf("Reçu : %s\n", buf);

            // Commande LED : Si un '1' est trouvé dans les caractères on allume la LED
            for (int i = 0; i < count; i++) {
                if (buf[i] == '1') {
                    gpio_write(data->pi, LED, 1);
                } 
				else {		// Sinon, Si un '0' est trouvé dans les caractères on éteint la LED 
					if (buf[i] == '0') {
						gpio_write(data->pi, LED, 0);
					}
                }
            }
        }
        time_sleep(0.01);  	// limiter l'utilisation CPU (le thread se met en sommeil 10ms)
							// A 9600 bauds 10 caractères peuvent potentiellement 
							// être reçus en 10ms
    }
    return NULL;
}

Référence

Site officiel Pigpio

Articles connexes


Vous avez apprécié cet article ? Partagez le !