24 - Périphériques et IHM

Razik Ikhlef

Mise en situation

Un thermostat allume le chauffage quand la pièce est trop froide. Un lampadaire s’éclaire à la tombée de la nuit. Un aspirateur robot change de direction avant de toucher un mur. Dans ces trois objets, un petit ordinateur mesure quelque chose dans le monde réel, décide quoi faire, puis agit sur le monde réel.

Mise en situation (suite)

Dans le modèle de Von Neumann, vu au chapitre 09 - Architecture , ces échanges avec l’extérieur sont le rôle des entrées-sorties. Ce chapitre présente les composants qui les réalisent, les capteurs et les actionneurs, puis montre comment écrire un programme qui les relie, et comment programmer une interface homme-machine (IHM). La fiche d’exercices correspondante est 33 - Périphériques et IHM .

Les périphériques d’entrée et de sortie

Définition. Un périphérique est un appareil relié à l’unité centrale, qui permet à l’ordinateur d’échanger des informations avec l’extérieur :

  • un périphérique d’entrée fait entrer une information dans l’ordinateur : clavier, souris, micro, caméra ;
  • un périphérique de sortie fait sortir une information de l’ordinateur : écran, imprimante, haut-parleur.

Certains périphériques font les deux. Un écran tactile affiche une image (sortie) et repère la position du doigt (entrée).

Les périphériques d’entrée et de sortie (suite)

Un programme ne pilote pas directement le matériel : c’est le système d’exploitation, vu au chapitre 23 - Systèmes d’exploitation , qui gère les entrées-sorties grâce à ses pilotes. Quand un programme Python appelle input(), il demande au système le texte tapé au clavier ; quand il appelle print(), il lui demande d’afficher un texte à l’écran.

Les capteurs

Définition. Un capteur mesure une grandeur physique (température, lumière, distance, pression…) et la transforme en un signal électrique, que le système lit sous la forme d’un nombre.

Les capteurs (suite)

Un capteur est donc un périphérique d’entrée. Quelques exemples :

Grandeur mesurée Capteur Exemple d’utilisation
Température Thermomètre électronique (sonde) Thermostat, station météo
Lumière Capteur de luminosité (photorésistance) Éclairage public, réglage de l’écran d’un téléphone
Distance Capteur à ultrasons ou à infrarouge Robot, aide au stationnement d’une voiture

Les capteurs (suite)

Grandeur mesurée Capteur Exemple d’utilisation
Présence, mouvement Détecteur de mouvement infrarouge Éclairage d’un couloir, alarme
Contact, appui Bouton, interrupteur, touche de clavier Clavier, sonnette, butée d’un robot
Position du doigt Surface tactile Écran de téléphone, borne de distributeur

Le clavier et l’écran tactile sont eux aussi des capteurs : chaque touche est un petit interrupteur, et la surface tactile mesure l’endroit où le doigt la touche.

Les capteurs (suite)

Pour le programme, une mesure n’est qu’un nombre : 21 pour 21 °C, 350 pour une luminosité de 350 sur une échelle propre au capteur, 1 ou 0 pour un bouton appuyé ou non. C’est au programmeur de savoir ce que ce nombre représente et dans quelle unité.

Les actionneurs

Définition. Un actionneur reçoit une commande du programme, sous forme de signal électrique, et la transforme en une action physique : mouvement, lumière, son, chaleur.

Les actionneurs (suite)

Un actionneur est donc un périphérique de sortie. Quelques exemples :

Actionneur Action produite Exemple d’utilisation
Moteur Mouvement de rotation Roues d’un robot, ventilateur, store électrique
Lampe, diode électroluminescente (DEL) Lumière Éclairage, voyant d’un appareil
Haut-parleur, buzzer Son Alarme, signal sonore d’un four
Résistance chauffante Chaleur Radiateur électrique, bouilloire
Électrovanne Ouverture ou fermeture d’un passage d’eau Arrosage automatique, lave-linge

Les actionneurs (suite)

L’écran est aussi un actionneur particulier : il transforme les données envoyées par le programme en lumière, point par point.

La chaîne mesure, décision, action

Un système qui réagit à son environnement fonctionne toujours en trois étapes :

  1. Mesure : le capteur mesure une grandeur physique et fournit un nombre au programme.
  2. Décision : le programme compare ce nombre à une valeur de référence et choisit une commande.
  3. Action : l’actionneur exécute la commande, ce qui modifie l’environnement.
MESURE DÉCISION ACTION Capteur Programme Actionneur Environnement : pièce, rue, sol, obstacle… mesure commande grandeur physique action

La chaîne mesure, décision, action (suite)

L’action modifie la grandeur mesurée : le chauffage réchauffe la pièce, donc la température lue au tour suivant change. C’est pourquoi la chaîne se répète sans fin, tant que l’appareil est sous tension.

La chaîne mesure, décision, action (suite)

Le programme qui réalise la décision s’exécute sur un petit ordinateur intégré à l’objet :

  • un système embarqué est un ordinateur intégré à un appareil, qu’il commande : thermostat, lave-linge, voiture, montre ;
  • un objet connecté est un système embarqué relié à un réseau, souvent Internet : il peut envoyer ses mesures ou recevoir des ordres à distance, comme un thermostat réglable depuis un téléphone ;
  • un robot est un système embarqué qui se déplace ou manipule des objets grâce à ses actionneurs.

Trois exemples courants

Le thermostat

  • Mesure : une sonde de température mesure la température de la pièce.
  • Décision : si la température est inférieure à la consigne (la température souhaitée, par exemple 19 °C), il faut chauffer ; sinon, il ne faut pas chauffer.
  • Action : le programme allume ou éteint la résistance chauffante du radiateur.

L’éclairage automatique

  • Mesure : un capteur de luminosité mesure la lumière du jour ; dans un couloir, un détecteur de mouvement indique en plus si quelqu’un passe.
  • Décision : si la luminosité est inférieure à un seuil (et, dans le couloir, si quelqu’un est présent), il faut éclairer.
  • Action : le programme allume ou éteint les lampes.

Le robot aspirateur

  • Mesure : un capteur à ultrasons ou à infrarouge mesure la distance à l’obstacle placé devant le robot ; des capteurs de contact signalent un choc.
  • Décision : si l’obstacle est loin, le robot avance ; s’il est proche, il tourne pour l’éviter.
  • Action : le programme commande les moteurs des deux roues : même vitesse pour avancer, vitesses différentes pour tourner.

Le robot aspirateur (suite)

Système Capteur Décision Actionneur
Thermostat Sonde de température température < consigne ? Résistance chauffante
Éclairage automatique Capteur de luminosité, détecteur de mouvement luminosité < seuil et présence ? Lampes
Robot aspirateur Capteur de distance, capteur de contact obstacle proche ? Moteurs des roues

Programmer la chaîne en Python

Sur une carte programmable ou dans un robot, une bibliothèque fournit des fonctions qui lisent les capteurs et commandent les actionneurs. Ici, on n’a pas de matériel : on simule le capteur et l’actionneur par deux fonctions, ce qui permet d’écrire et de tester la partie la plus importante, la décision.

Le capteur, l’actionneur et la décision

Le capteur simulé renvoie une température tirée au hasard ; l’actionneur simulé affiche l’état du chauffage au lieu d’allumer un vrai radiateur.

Le capteur, l’actionneur et la décision (suite)

import random


def lire_temperature():
    """Capteur simulé : renvoie la température de la pièce, en degrés Celsius."""
    return random.randint(15, 25)


def commander_chauffage(allumer):
    """Actionneur simulé : allume le chauffage si allumer vaut True, l'éteint sinon."""
    if allumer:
        print("chauffage allumé")
    else:
        print("chauffage éteint")


def decider(temperature, consigne):
    """Renvoie True s'il faut chauffer, c'est-à-dire si la pièce est plus froide que la consigne."""
    return temperature < consigne

Le capteur, l’actionneur et la décision (suite)

La fonction decider ne dépend d’aucun matériel : elle reçoit des nombres et renvoie un booléen. On peut donc la tester avec des valeurs choisies, sans attendre qu’il fasse froid :

assert decider(17, 19) == True     # trop froid : on chauffe
assert decider(21, 19) == False    # assez chaud : on ne chauffe pas
assert decider(19, 19) == False    # exactement la consigne : on ne chauffe pas
print("Tous les tests passent")

La boucle de régulation

Le programme principal répète la chaîne mesure, décision, action. Ici, on se limite à cinq mesures :

consigne = 19
for i in range(5):
    temperature = lire_temperature()            # mesure
    chauffer = decider(temperature, consigne)   # décision
    print(f"Mesure {i + 1} : {temperature} °C,", end=" ")
    commander_chauffage(chauffer)               # action

La boucle de régulation (suite)

Un affichage possible (les températures sont tirées au hasard) :

Mesure 1 : 17 °C, chauffage allumé
Mesure 2 : 22 °C, chauffage éteint
Mesure 3 : 19 °C, chauffage éteint
Mesure 4 : 15 °C, chauffage allumé
Mesure 5 : 24 °C, chauffage éteint

Dans un vrai thermostat, la boucle ne s’arrête jamais : on écrit while True, et le programme attend un moment, par exemple une minute, entre deux mesures.

La boucle de régulation (suite)

# NE PAS EXÉCUTER : boucle sans fin, comme dans un vrai thermostat
consigne = 19
while True:
    temperature = lire_temperature()
    commander_chauffage(decider(temperature, consigne))

Remarque. Dans ce programme, chaque fonction a un seul rôle : lire_temperature pour la mesure, decider pour la décision, commander_chauffage pour l’action. Pour faire tourner le même programme sur un vrai thermostat, il suffit de réécrire les deux fonctions qui touchent au matériel ; la décision ne change pas.

L’interface homme-machine

Définition. L’interface homme-machine (IHM) est l’ensemble des moyens par lesquels un utilisateur et une machine échangent des informations : les périphériques (boutons, écran, écran tactile…) et le programme qui affiche des informations et réagit aux actions de l’utilisateur.

Le panneau d’un four (un afficheur et quelques boutons), l’écran tactile d’un distributeur de billets, la fenêtre d’une application ou une page web, étudiée au chapitre 13 - IHM Web , sont des IHM.

Le cahier des charges

Avant de programmer une IHM, on écrit son cahier des charges : la liste de ce que l’interface doit afficher, des actions que l’utilisateur peut faire et de ce que le programme doit faire en réponse. Voici celui d’un thermostat :

  1. L’utilisateur règle la consigne entre 15 °C et 25 °C, avec un curseur. La consigne vaut 19 °C au démarrage.
  2. Un bouton « Mesurer » lit le capteur de température.
  3. L’interface affiche la dernière température mesurée.
  4. L’interface affiche l’état du chauffage : « Chauffage allumé » en rouge si la température est inférieure à la consigne, « Chauffage éteint » en bleu sinon.

La programmation événementielle

Un programme avec une interface graphique ne s’exécute pas de haut en bas puis s’arrête. Il crée la fenêtre et ses composants, associe une fonction à chaque action possible de l’utilisateur, puis attend : c’est la boucle d’événements. Un clic sur un bouton est un événement ; le programme répond en appelant la fonction associée à ce bouton. Ce style de programmation s’appelle la programmation événementielle.

Une IHM avec tkinter

Le module tkinter, fourni avec Python, permet de créer des fenêtres. La page 16 - GUI en donne d’autres exemples. Les composants (en anglais widgets) utilisés ici :

Une IHM avec tkinter (suite)

Composant ou méthode Rôle
tk.Tk() crée la fenêtre principale
tk.Label(fenetre, text="…") affiche un texte (sortie)
tk.Button(fenetre, text="…", command=f) bouton : un clic appelle la fonction f (entrée)
tk.Scale(fenetre, from_=a, to=b, orient="horizontal") curseur pour choisir un entier entre a et b (entrée)

Une IHM avec tkinter (suite)

Composant ou méthode Rôle
composant.pack() place le composant dans la fenêtre, sous le précédent
curseur.get(), curseur.set(v) lit ou fixe la valeur du curseur
etiquette.configure(text="…", fg="red") change le texte ou la couleur d’un Label
etiquette.cget("text") renvoie le texte affiché par un Label
fenetre.mainloop() lance la boucle d’événements

Une IHM avec tkinter (suite)

Le programme ci-dessous répond au cahier des charges du thermostat. Il ne fonctionne pas dans le navigateur : l’exécuter dans Thonny.

Une IHM avec tkinter (suite)

import tkinter as tk
import random


def lire_temperature():
    """Capteur simulé : renvoie la température de la pièce, en degrés Celsius."""
    return random.randint(15, 25)


def mesurer():
    """Lit le capteur, compare à la consigne, puis affiche la mesure et l'état du chauffage."""
    temperature = lire_temperature()
    texte_mesure.configure(text=f"Température mesurée : {temperature} °C")
    if temperature < curseur.get():
        texte_chauffage.configure(text="Chauffage allumé", fg="red")
    else:
        texte_chauffage.configure(text="Chauffage éteint", fg="blue")


fenetre = tk.Tk()
fenetre.title("Thermostat")

# Point 1 du cahier des charges : curseur de 15 à 25, réglé sur 19 au démarrage
curseur = tk.Scale(fenetre, label="Consigne (°C)", from_=15, to=25, orient="horizontal", length=250)
curseur.set(19)
curseur.pack()

# Point 2 : le bouton appelle la fonction mesurer
bouton = tk.Button(fenetre, text="Mesurer", command=mesurer)
bouton.pack()

# Points 3 et 4 : deux textes, modifiés par la fonction mesurer
texte_mesure = tk.Label(fenetre, text="Température mesurée : aucune mesure")
texte_mesure.pack()
texte_chauffage = tk.Label(fenetre, text="Chauffage éteint", fg="blue")
texte_chauffage.pack()

fenetre.mainloop()

Une IHM avec tkinter (suite)

On retrouve la chaîne mesure, décision, action, déclenchée cette fois par l’utilisateur :

  • le clic sur « Mesurer » est un événement, qui appelle mesurer ;
  • mesurer lit le capteur (mesure), compare la température à la valeur du curseur (décision), puis modifie les deux textes (action sur l’interface).

Dans command=mesurer, on écrit le nom de la fonction sans parenthèses : on indique au bouton quelle fonction appeler plus tard, au moment du clic. Avec command=mesurer(), la fonction serait appelée une seule fois, à la création du bouton.

Que retenir ?

A minima…

  • Un périphérique d’entrée fait entrer une information dans l’ordinateur, un périphérique de sortie la fait sortir.
  • Un capteur mesure une grandeur physique et la transmet au programme sous forme de nombre ; un actionneur transforme une commande du programme en action physique.
  • Un système qui réagit à son environnement répète sans fin la chaîne mesure, décision, action.
  • Une IHM est l’ensemble des moyens par lesquels un utilisateur et une machine échangent des informations. On la conçoit à partir d’un cahier des charges.

Au mieux…

  • Identifier, dans un objet courant (thermostat, éclairage automatique, robot, objet connecté), les capteurs, les actionneurs et la décision prise par le programme.
  • Écrire en Python la décision sous forme d’une fonction qui reçoit les mesures et renvoie la commande, puis la tester avec assert.
  • Programmer avec tkinter une IHM qui répond à un cahier des charges : composants d’entrée (bouton, curseur), composants de sortie (textes), fonctions appelées lors des événements, boucle d’événements.