Interfaces Homme-Machine
Ecrans, boutons, encodeurs, ergonomie et conception IHM
Objectifs pedagogiques
- Identifier les composants d'entree et de sortie d'une IHM
- Programmer des afficheurs LCD et OLED avec Arduino
- Gerer les entrees utilisateur (boutons, encodeurs, tactile)
- Appliquer les principes d'ergonomie pour une IHM efficace
Introduction : Le dialogue Homme-Machine
Exemple concret : Thermostat connecte
Un thermostat moderne combine un ecran OLED pour afficher la temperature, un encodeur rotatif pour regler la consigne, et des boutons tactiles pour les modes. L'IHM doit etre intuitive : l'utilisateur comprend en quelques secondes comment l'utiliser.
L'Interface Homme-Machine (IHM) est le point de contact entre l'utilisateur et le systeme technique. Elle comprend les dispositifs d'entree (boutons, capteurs, ecran tactile) et de sortie (ecrans, LEDs, buzzer). Une bonne IHM est ergonomique, intuitive et accessible.
Schema fonctionnel IHM
Entrees
Boutons, tactile, voix
Traitement
Microcontroleur
Sorties
Ecran, LED, son
1Dispositifs de Sortie : Afficheurs
Technologies d'affichage
| Type | Caracteristiques | Interface | Usage |
|---|---|---|---|
| LCD 16x2 | 2 lignes, 16 caracteres | Parallele/I2C | Menus simples, valeurs |
| LCD graphique | 128x64 pixels | SPI | Graphiques, courbes |
| OLED | 128x64, contraste eleve | I2C/SPI | Wearables, IoT |
| TFT couleur | 240x320, 65K couleurs | SPI | IHM riches, images |
| 7 segments | Chiffres uniquement | Multiplexe | Compteurs, horloges |
Programmation LCD 16x2 avec I2C
// LCD 16x2 avec module I2C (adresse 0x27)
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup() {
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0); // Colonne 0, Ligne 0
lcd.print("Temperature:");
}
void loop() {
float temp = lireTemperature();
lcd.setCursor(0, 1); // Ligne 2
lcd.print(temp, 1); // 1 decimale
lcd.print(" C "); // Espaces pour effacer
delay(500);
}
Programmation OLED SSD1306
// OLED 128x64 avec bibliotheque Adafruit
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
// Texte avec differentes tailles
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 20);
display.println("25.3 C");
// Dessiner un rectangle
display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
display.display(); // Envoyer au buffer
}
Optimisation memoire : Les bibliotheques graphiques consomment beaucoup de RAM. Sur Arduino UNO (2Ko), preferez des afficheurs simples. L'ESP32 (520Ko) gere facilement les TFT couleur.
2Dispositifs d'Entree : Boutons et Encodeurs
Gestion des boutons avec anti-rebond
Un bouton mecanique genere des rebonds (oscillations) lors de l'appui, detectes comme plusieurs appuis. L'anti-rebond (debounce) filtre ces parasites par logiciel ou materiel.
// Anti-rebond logiciel simple
const int PIN_BOUTON = 2;
const unsigned long DEBOUNCE_DELAY = 50; // ms
bool dernierEtat = HIGH;
bool etatStable = HIGH;
unsigned long dernierChangement = 0;
bool lireBoutonDebounce() {
bool lecture = digitalRead(PIN_BOUTON);
if(lecture != dernierEtat) {
dernierChangement = millis();
}
if((millis() - dernierChangement) > DEBOUNCE_DELAY) {
etatStable = lecture;
}
dernierEtat = lecture;
return etatStable;
}
Encodeur rotatif
Principe
- 2 signaux en quadrature (A et B)
- Decalage de 90° entre A et B
- Sens = ordre des fronts
- Crans = nombre d'impulsions
Detection du sens
Horaire : A↑ puis B↑
Anti-horaire : B↑ puis A↑
Sur front de A :
Si B=0 → horaire (+)
Si B=1 → anti-horaire (-)
// Lecture encodeur avec interruption
const int PIN_A = 2; // Interrupt
const int PIN_B = 3;
volatile int compteur = 0;
void lireEncodeur() {
if(digitalRead(PIN_B) == LOW) {
compteur++; // Horaire
} else {
compteur--; // Anti-horaire
}
}
void setup() {
pinMode(PIN_A, INPUT_PULLUP);
pinMode(PIN_B, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(PIN_A), lireEncodeur, FALLING);
}
Ecran tactile
Technologies tactiles
- Resistif : 2 couches conductrices, pression detectee (stylet compatible)
- Capacitif : Detecte le doigt par variation de capacite (multitouch)
- Infrarouge : Grille de faisceaux IR, usage industriel
3Ergonomie et Conception d'IHM
Principes d'ergonomie
L'ergonomie vise a adapter l'interface a l'utilisateur pour minimiser les erreurs, la fatigue et le temps d'apprentissage. Une bonne IHM respecte des regles de lisibilite, coherence et feedback.
Les 10 heuristiques de Nielsen
1. Visibilite du statut
L'utilisateur sait toujours ce qui se passe
2. Correspondance systeme/reel
Utiliser le vocabulaire de l'utilisateur
3. Controle utilisateur
Permettre annuler/refaire
4. Coherence
Memes actions = memes resultats
5. Prevention des erreurs
Design qui evite les erreurs
6. Reconnaissance vs rappel
Options visibles, pas a memoriser
Conception d'un menu hierarchique
// Structure de menu simple avec encodeur
enum MenuState { PRINCIPAL, REGLAGES, TEMPERATURE, LUMINOSITE };
MenuState menuActuel = PRINCIPAL;
const char* menuPrincipal[] = {
"> Mesures",
" Reglages",
" A propos"
};
int selection = 0;
void afficherMenu() {
lcd.clear();
for(int i = 0; i < 3; i++) {
lcd.setCursor(0, i);
if(i == selection) {
lcd.print("> ");
} else {
lcd.print(" ");
}
lcd.print(menuPrincipal[i] + 2); // Sans le prefixe
}
}
void naviguer(int delta) {
selection = constrain(selection + delta, 0, 2);
afficherMenu();
}
Feedback immediat : Chaque action doit avoir une reponse visible (LED, son, changement ecran) dans les 100 ms pour que l'utilisateur sente le systeme reactif.
4Indicateurs Visuels et Sonores
LEDs indicatrices
| Couleur | Signification standard | Exemple |
|---|---|---|
| Vert | OK, marche, pret | Alimentation OK |
| Orange | Attention, en cours | Traitement en cours |
| Rouge | Erreur, danger, arret | Defaut detecte |
| Bleu | Communication, Bluetooth | Connexion active |
LED RGB et signalisation
// LED RGB cathode commune sur PWM
const int PIN_R = 9, PIN_G = 10, PIN_B = 11;
void couleur(int r, int g, int b) {
analogWrite(PIN_R, r);
analogWrite(PIN_G, g);
analogWrite(PIN_B, b);
}
// Signalisations
void statutOK() { couleur(0, 255, 0); }
void statutAttention() { couleur(255, 165, 0); }
void statutErreur() { couleur(255, 0, 0); }
// Clignotement erreur critique
void alerteCritique() {
for(int i = 0; i < 5; i++) {
couleur(255, 0, 0);
delay(200);
couleur(0, 0, 0);
delay(200);
}
}
Signalisation sonore (buzzer)
// Buzzer passif avec tone()
const int PIN_BUZZER = 8;
// Notes musicales (Hz)
#define NOTE_C4 262
#define NOTE_E4 330
#define NOTE_G4 392
void bipConfirmation() {
tone(PIN_BUZZER, NOTE_E4, 100);
}
void bipErreur() {
tone(PIN_BUZZER, 200, 500); // Grave = erreur
}
void melodieSucces() {
tone(PIN_BUZZER, NOTE_C4, 150);
delay(150);
tone(PIN_BUZZER, NOTE_E4, 150);
delay(150);
tone(PIN_BUZZER, NOTE_G4, 300);
}
Bonnes pratiques sonores
- Son bref pour confirmation (50-150 ms)
- Son grave pour erreur, aigu pour succes
- Volume ajustable ou desactivable
- Eviter les sons repetitifs longs (fatigue)
Resume en 5 points cles
- 1Les afficheurs (LCD, OLED, TFT) permettent de communiquer des informations a l'utilisateur.
- 2L'anti-rebond est essentiel pour une lecture fiable des boutons mecaniques.
- 3L'encodeur rotatif permet un reglage precis grace a ses signaux en quadrature.
- 4L'ergonomie (Nielsen) guide la conception d'interfaces intuitives et efficaces.
- 5Le feedback (LED, son) confirme les actions et informe sur l'etat du systeme.
Mini-Quiz
Question 1 : Quel est le role de l'anti-rebond sur un bouton ?
a) Accelerer la detection
b) Filtrer les oscillations parasites
c) Amplifier le signal
Reponse : b) L'anti-rebond elimine les faux appuis dus aux rebonds mecaniques
Question 2 : Comment un encodeur rotatif detecte-t-il le sens de rotation ?
a) Par la vitesse de rotation
b) Par l'ordre des fronts des signaux A et B
c) Par la tension de sortie
Reponse : b) Les signaux en quadrature (90° de decalage) indiquent le sens
Question 3 : Quelle couleur LED indique generalement une erreur ?
a) Vert
b) Bleu
c) Rouge
Reponse : c) Rouge = erreur/danger, c'est un code universel
