Aller au contenu

33 - Périphériques et IHM

Les exercices se font dans Thonny, dans le fichier 33_peripheriques_et_ihm.py.

Cours associé : 24 - Périphériques et IHM .

Exercice 0 : QCM – vérification des connaissances

Pour chaque question, une seule réponse est correcte.

1. Qu’est-ce qu’un capteur ?

  • A. Un composant qui transforme une commande du programme en mouvement
  • B. Un composant qui mesure une grandeur physique et la transmet au programme sous forme de nombre
  • C. Un programme qui décide de l’action à effectuer
  • D. Un câble qui relie un périphérique à l’ordinateur

Correction publiée après la séance.

2. Lequel de ces composants est un actionneur ?

  • A. Un détecteur de mouvement
  • B. Une sonde de température
  • C. Un moteur
  • D. Une touche de clavier

Correction publiée après la séance.

3. Dans quel ordre se déroule la chaîne d’un système qui réagit à son environnement ?

  • A. Action, mesure, décision
  • B. Décision, mesure, action
  • C. Mesure, action, décision
  • D. Mesure, décision, action

Correction publiée après la séance.

4. Un écran tactile est :

  • A. seulement un périphérique d’entrée
  • B. seulement un périphérique de sortie
  • C. à la fois un périphérique d’entrée et un périphérique de sortie
  • D. ni l’un ni l’autre, car il fait partie du processeur

Correction publiée après la séance.

5. Dans un programme tkinter, on écrit bouton = tk.Button(fenetre, text="OK", command=valider). Que se passe-t-il ?

  • A. La fonction valider est appelée une seule fois, à la création du bouton
  • B. La fonction valider est appelée à chaque clic sur le bouton
  • C. Le programme s’arrête quand on clique sur le bouton
  • D. Le bouton affiche le texte renvoyé par valider

Correction publiée après la séance.

Exercice 1 : entrée ou sortie, capteur ou actionneur

Recopier et compléter le tableau. Pour chaque appareil, indiquer s’il s’agit d’un périphérique d’entrée, de sortie ou des deux, puis, quand c’est le cas, s’il s’agit d’un capteur ou d’un actionneur.

AppareilEntrée, sortie ou les deux ?Capteur ou actionneur ?
Clavier
Haut-parleur
Détecteur de mouvement
Moteur d’un store électrique
Micro
Écran tactile
Sonde de température
Électrovanne d’arrosage
Lampe d’un lampadaire

Correction publiée après la séance.

Exercice 2 : analyser des systèmes

Pour chacun des trois systèmes suivants, indiquer le capteur, la grandeur mesurée, la décision prise par le programme et l’actionneur.

  1. Un portail automatique s’arrête de se fermer si une voiture se trouve entre ses deux piliers.
  2. Un système d’arrosage ouvre l’eau quand la terre du jardin est trop sèche.
  3. Un détecteur de fumée déclenche une sirène quand il y a de la fumée dans la pièce.
Indice

Se demander d’abord ce que le système doit savoir pour réagir : c’est la grandeur mesurée, donc le capteur. Se demander ensuite ce qu’il fait : c’est l’actionneur. La décision est la condition qui relie les deux, de la forme « si … alors … ».

Correction publiée après la séance.

Exercice 3 : la décision d’un éclairage automatique

L’éclairage d’un couloir dispose d’un capteur de luminosité, qui renvoie un entier entre 0 (nuit noire) et 1000 (plein soleil), et d’un détecteur de mouvement, qui renvoie True si quelqu’un passe.

Écrire une fonction eclairer(luminosite, presence) qui renvoie True s’il faut allumer les lampes, c’est-à-dire si la luminosité est strictement inférieure à 300 et si quelqu’un est présent, et False sinon.

La fonction doit passer les tests suivants :

assert eclairer(100, True) == True      # sombre et quelqu'un passe
assert eclairer(100, False) == False    # sombre mais personne
assert eclairer(800, True) == False     # assez clair
assert eclairer(300, True) == False     # exactement le seuil : pas d'éclairage
print("Tous les tests passent")
Indice

Il faut que les deux conditions soient vraies en même temps : on les relie avec and. Une comparaison donne déjà un booléen, on peut donc renvoyer directement luminosite < 300 and presence.

Correction publiée après la séance.

Exercice 4 : le robot face à un obstacle

Un robot possède un capteur de distance, qui renvoie la distance à l’obstacle placé devant lui, en centimètres. Sa décision est écrite dans la fonction suivante :

def commande_robot(distance):
    """Renvoie l'ordre à donner aux moteurs selon la distance à l'obstacle, en cm."""
    if distance > 30:
        return "avancer"
    elif distance > 10:
        return "tourner"
    else:
        return "reculer"

Sans exécuter le programme, dire ce que renvoient les appels suivants :

  1. commande_robot(50)
  2. commande_robot(30)
  3. commande_robot(15)
  4. commande_robot(10)
  5. commande_robot(4)

Vérifier ensuite les réponses dans Thonny.

Correction publiée après la séance.

Exercice 5 : simuler un arrosage automatique

On a relevé six mesures successives du capteur d’humidité d’un jardin, en pourcentage :

mesures = [45, 38, 29, 25, 33, 41]

L’électrovanne doit être ouverte quand l’humidité est strictement inférieure à 30 %, et fermée sinon.

  1. Écrire une fonction arroser(humidite) qui renvoie True s’il faut ouvrir l’eau, False sinon.
  2. Écrire un programme qui parcourt la liste mesures et affiche, pour chaque mesure, une ligne de la forme Humidité : 29 %, eau ouverte ou Humidité : 45 %, eau fermée.
  3. Compléter le programme pour qu’il affiche, à la fin, le nombre de mesures pour lesquelles l’eau a été ouverte.
Indice

Chaque mesure joue le rôle d’une lecture du capteur : une boucle for humidite in mesures répète la chaîne mesure, décision, action. Pour compter, utiliser un compteur qui vaut 0 avant la boucle et augmente de 1 chaque fois que l’eau est ouverte.

Code à copier puis compléter
def arroser(humidite):
    """Renvoie True s'il faut ouvrir l'eau, c'est-à-dire si le sol est trop sec."""
    return ...

mesures = [45, 38, 29, 25, 33, 41]
nb_ouvertures = 0
for humidite in mesures:
    if ...:
        print(f"Humidité : {humidite} %, eau ouverte")
        nb_ouvertures = ...
    else:
        print(...)
print(f"L'eau a été ouverte {nb_ouvertures} fois")

Correction publiée après la séance.

Exercice 6 : une IHM en mode texte

Une IHM n’est pas forcément graphique : dans la console, input() est une entrée et print() une sortie.

Cahier des charges. Le programme demande à l’utilisateur la consigne d’un thermostat, en degrés. Tant que la valeur saisie n’est pas comprise entre 15 et 25 (bornes incluses), il affiche Consigne impossible : choisir entre 15 et 25. puis redemande. Quand la valeur est correcte, il affiche Consigne réglée sur 20 °C. (avec la valeur saisie).

Le programme suivant lit la consigne mais ne la contrôle pas encore. Le compléter pour qu’il respecte le cahier des charges. Pour le tester dans la page, écrire une valeur par ligne dans le champ « Saisies », par exemple 30, 12 puis 20.

consigne = int(input("Consigne (°C) : "))
print(f"Consigne réglée sur {consigne} °C.")
Indice

On ne sait pas combien de fois l’utilisateur se trompera : c’est une boucle while. Faire une première saisie avant la boucle ; la boucle redemande tant que la consigne est trop petite ou trop grande. Ne pas oublier de convertir la saisie en entier avec int().

Correction publiée après la séance.

Exercice 7 : une lampe commandée par un bouton

Cet exercice et le suivant utilisent tkinter : ils se font dans Thonny, pas dans la page.

Cahier des charges.

  1. La fenêtre a pour titre « Lampe ».
  2. Un texte indique l’état de la lampe : Lampe éteinte sur fond gris au démarrage.
  3. Un bouton Allumer / Éteindre change l’état : Lampe allumée sur fond jaune si elle était éteinte, Lampe éteinte sur fond gris si elle était allumée.
Indice

La fonction appelée par le bouton doit savoir si la lampe est allumée : elle peut lire le texte affiché avec etat.cget("text"). La couleur de fond d’un Label se règle avec le paramètre bg, par exemple etat.configure(text="Lampe allumée", bg="yellow").

Code à copier puis compléter
import tkinter as tk

def basculer():
    """Allume la lampe si elle est éteinte, l'éteint sinon."""
    if etat.cget("text") == ...:
        etat.configure(text=..., bg=...)
    else:
        etat.configure(text=..., bg=...)

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

etat = tk.Label(fenetre, text="Lampe éteinte", bg="grey", width=20)
etat.pack()

bouton = tk.Button(fenetre, text="Allumer / Éteindre", command=...)
bouton.pack()

fenetre.mainloop()

Correction publiée après la séance.

Exercice 8 : le compteur de places d’un parking

À l’entrée d’un parking de 10 places, un capteur détecte chaque voiture qui entre ou qui sort. On simule ces deux capteurs par deux boutons.

Cahier des charges.

  1. Sous le texte Places libres :, un nombre affiche les places libres : 10 au démarrage.
  2. Un bouton Entrée d'une voiture enlève une place libre, mais seulement s’il en reste au moins une.
  3. Un bouton Sortie d'une voiture ajoute une place libre, mais seulement s’il y a moins de 10 places libres.
  4. Un second texte affiche COMPLET en rouge quand il ne reste aucune place, et Ouvert en vert sinon.
Indice

Afficher le nombre de places dans un Label à part, qui ne contient que ce nombre : int(places.cget("text")) donne alors le nombre de places libres. Chaque fonction lit ce nombre, le modifie si c’est permis, l’affiche à nouveau, puis met à jour le texte COMPLET ou Ouvert. Cette dernière mise à jour est la même pour les deux boutons : l’écrire dans une troisième fonction, appelée par les deux autres.

Correction publiée après la séance.