Résolu sur le forum : Borne Wallbox Pulsar Plus 7,4 kW sur abonnement 6 kVA : quel délestage avant accord copro (urgent)Ma panne diagnostiquée — réponse sous 48 h29 €

Comment utiliser les interruptions sur Arduino : guide pratique

Arduinomis à jour le 25 février 2026

Les interruptions Arduino transforment un simple croquis en véritable système réactif. Un capteur déclenche un événement, le microcontrôleur interrompt son travail en cours, exécute une routine dédiée, puis reprend comme si de rien n’était. Bien configuré, ce mécanisme offre une gestion précise des signaux, des capteurs rapides et des tâches temps réel.

En pratique, tout ne se résume pas à un simple attachInterrupt(). Gestion de variables partagées, limites de delay() et millis(), priorités matérielles, contraintes avec Serial ou I2C : chaque détail influe sur la fiabilité du projet. La suite du guide entre dans le concret, avec des exemples, des schémas d’architecture logicielle et des bonnes pratiques applicables sur vos propres montages.

Élément clé Résumé
Rôle des interruptions ⚡ Permettent de réagir instantanément à un événement sans bloquer le programme principal.
Types d’interruptions Interruptions matérielles sur des broches dédiées et interruptions internes liées au système.
Fonction d’attache attachInterrupt() permet de déclencher une fonction lors d’un changement d’état du signal.
Bonnes pratiques 🛠️ Maintenir les routines très courtes, éviter les délais et protéger les variables partagées.

Comprendre le rôle des interruptions sur Arduino et microcontrôleur

Une interruption est un mécanisme matériel qui suspend l’exécution du programme principal pour exécuter immédiatement une fonction spéciale appelée ISR (Interrupt Service Routine). Une fois cette fonction terminée, le microcontrôleur reprend l’exécution là où il s’était arrêté.

Sur Arduino, ce principe s’appuie sur l’architecture du microcontrôleur (AVR pour l’UNO R3, ARM pour l’UNO R4 ou certains Teensy). Chaque événement matériel, comme un changement d’état sur une broche ou un débordement de timer, déclenche un vecteur d’interruption spécifique mappé dans la table interne du microcontrôleur.

Ce fonctionnement apporte une réponse rapide à des signaux extérieurs, sans boucler en permanence dans le code utilisateur. Au lieu de surveiller un bouton dans loop() avec digitalRead(), le programme attend tranquillement pendant que le matériel se charge de signaler le changement d’état dès qu’il survient.

« Une bonne utilisation des interruptions remplace avantageusement les boucles de polling bloquantes et améliore la réactivité globale d’un système embarqué. »

Interruptions matérielles vs interruptions logicielles sur Arduino

Sur Arduino, on distingue plusieurs familles d’interruptions. Certaines sont liées directement au matériel, d’autres à des événements gérés par les bibliothèques et les timers internes. Bien les différencier aide à structurer proprement le code.

Interruptions externes (changement sur une broche)

Les interruptions externes réagissent à un changement de niveau logique sur une broche dédiée. Sur Arduino Uno R3, elles se trouvent par défaut sur les broches 2 et 3 (INT0 et INT1). Elles se configurent avec la fonction attachInterrupt().

Plusieurs modes de déclenchement existent :

  • RISING : front montant (0 → 1 logique)
  • FALLING : front descendant (1 → 0 logique)
  • CHANGE : tout changement d’état
  • LOW : niveau bas maintenu

Chaque mode influence la fréquence potentielle de déclenchement et la sensibilité au bruit. Le mode CHANGE réagit le plus souvent, alors qu’un front unique (RISING ou FALLING) réduit le risque de doublons.

Interruptions de broches (Pin Change Interrupt)

En plus des interruptions externes, les microcontrôleurs AVR proposent des Pin Change Interrupt qui surveillent un groupe de broches. Plusieurs broches partagent la même ligne d’interruption, ce qui oblige à tester dans l’ISR quelle broche a réellement changé d’état.

ArduinoArduino et domotique : automatiser sa maison pour pas cher

Ce mécanisme élargit le nombre de broches « interruptibles », au prix d’un traitement logicielle un peu plus complexe. Pour un clavier matriciel ou plusieurs capteurs logiques, cette approche offre une solution flexible.

Interruptions de timers

Les timers matériels génèrent aussi des interruptions. Ils s’activent à intervalles réguliers (overflow, compare match) et servent à créer un horloge interne précis, à produire des signaux PWM avancés ou à lancer des tâches périodiques.

Sur Arduino Uno R3 cadencé à 16 MHz, chaque timer dispose de ses propres registres. Sur un Teensy 4.x à 600 MHz, la précision et la fréquence maximale augmentent nettement, ce qui rend les interruptions de timers adaptées à des signaux très rapides.

Interruptions logicielles et bibliothèques

Certaines bibliothèques utilisent des interruptions en coulisse. Par exemple, la gestion de millis() s’appuie sur un timer. Des librairies de communication (UART, SPI, parfois I2C) déclenchent des interruptions pour recevoir ou transmettre des données en tâche de fond.

Le développeur n’a pas forcément besoin d’intervenir directement sur ces vecteurs. En revanche, il doit tenir compte de leur existence pour évaluer la charge globale d’interruptions et éviter les conflits de priorité dans des architectures complexes.

Conseil pratique : pour un premier projet structuré autour des interruptions, un guide général comme /arduino-guide-complet-debuter/ fournit un socle solide sur le fonctionnement de base de la carte avant de passer à des mécaniques temps réel.

Fonctionnement d’une ISR : règles de base et contraintes techniques

La routine d’interruption (ISR) est une fonction spéciale exécutée par le microcontrôleur lorsque l’événement associé survient. Sa signature, sur Arduino, suit en général le modèle suivant :

void ISR_nom() { /* code court et déterministe */ }

Le temps d’installation et de retour d’une ISR crée une latence incompressible. Sur les données disponibles, on relève par exemple un temps d’installation d’environ 3 µs et un temps de retour au programme d’environ 2 µs sur certaines plateformes. Ce budget s’ajoute au temps d’exécution propre du code de l’ISR.

Ce que le compilateur sauvegarde pendant une interruption

Lorsqu’une interruption survient, le microcontrôleur sauvegarde certains registres, l’adresse de retour et parfois des états spécifiques. Cette sauvegarde garantit le retour au programme principal dans l’état attendu.

Plus une ISR manipule de variables locales, d’opérations arithmétiques ou de fonctions imbriquées, plus le compilateur réserve de registres. Le temps d’exécution s’allonge et la réactivité globale diminue. Une approche minimaliste à l’intérieur de l’ISR reste préférable pour préserver un comportement stable.

Instructions à éviter dans une ISR sur Arduino

Plusieurs fonctions Arduino restent indisponibles ou inadaptées dans une ISR, soit parce qu’elles utilisent elles-mêmes des interruptions, soit parce qu’elles bloquent le flot d’exécution.

Parmi les restrictions connues :

  • delay() inactif dans une ISR
  • millis() inactif dans une ISR
  • Serial indisponible dans une ISR (risque de blocage ou corruption)
  • Wire (I2C) indisponible dans une ISR
  • tone() indisponible dans une ISR

Les protocoles comme SPI, I2C et UART restent fortement déconseillés dans une ISR. Ils s’appuient sur des mécanismes internes qui supportent mal une réentrée forcée, et l’attente de transferts peut bloquer le système.

Astuce de conception : limiter l’ISR à la mise à jour de quelques variables globales, puis traiter les opérations lourdes (calculs, communication série, écriture sur bus) dans loop(). Cette séparation améliore la robustesse et simplifie le débogage.

Configurer une interruption externe avec attachInterrupt()

La fonction attachInterrupt() fournit une interface simple pour lier une ISR à une broche et à un type de déclenchement.

Syntaxe générale :

attachInterrupt(digitalPinToInterrupt(pin), ISR_nom, mode);

Où :

  • pin : numéro de broche Arduino
  • ISR_nom : nom de la fonction d’interruption
  • mode : RISING, FALLING, CHANGE ou LOW

Exemple : interruption sur un bouton poussoir

Objectif : incrémenter un compteur à chaque appui sur un bouton relié à la broche 2 de l’Arduino Uno. Le comptage se fait dans l’ISR, l’affichage dans loop().

Principe général :

  • Une variable globale volatile pour le compteur
  • Une ISR très courte qui incrémente ce compteur
  • Dans loop(), une copie locale du compteur pour l’affichage

Cette structure limite les accès concurrents à la variable partagée et respecte la contrainte sur les sections critiques.

Gestion des rebonds (debounce) avec interruptions

Un bouton mécanique génère souvent des rebonds électriques. Une interruption sur front CHANGE ou RISING déclencherait plusieurs appels d’ISR pour un seul appui.

Une stratégie consiste à combiner l’interruption avec une limitation temporelle via un timer ou une variable de temps en microsecondes enregistrée lors du dernier déclenchement. Le filtrage peut aussi se faire via un circuit RC ou un trigger de Schmitt.

Point de vigilance : pour un système de commande critique (arrêt d’urgence, fin de course de sécurité), un filtrage matériel du rebond reste préférable à un simple debounce logiciel, afin de réduire le risque de comportement erratique.

Interruptions et temps réel : limites de réactivité selon la carte

Le temps de réaction d’un système dépend de la fréquence d’horloge et de l’architecture du microcontrôleur. Les cartes suivantes illustrent bien les ordres de grandeur :

Carte Fréquence horloge Conséquence pratique sur les interruptions
Arduino Uno R3 16 MHz Réactivité suffisante pour capteurs lents à moyens, limitations sur des fréquences d’interruptions très élevées.
Arduino Uno R4 48 MHz Temps d’exécution réduit, plus de marge pour gérer des interruptions rapprochées.
Teensy 4.0 600 MHz Gestion d’interruptions haute fréquence, utile pour des signaux audio, moteurs rapides ou protocoles personnalisés.
Teensy 4.1 600 MHz Performances similaires au 4.0, avec plus d’entrées/sorties et de ressources mémoire pour des architectures complexes.

Même avec une horloge rapide, la fréquence maximale d’interruptions reste limitée par le temps d’installation, de retour et de traitement interne de chaque ISR. Une succession d’interruptions trop denses finit par monopoliser le processeur.

« Un système noyé sous les interruptions perd en prévisibilité. La qualité d’un design embarqué tient souvent davantage à la hiérarchisation des événements qu’à la simple puissance brute du microcontrôleur. »

Gestion des priorités d’interruptions et masquage temporaire

Sur certaines architectures, les interruptions disposent de priorités matérielles. Sur Arduino Uno, on recense par exemple 25 niveaux de priorité répartis suivant l’ordre défini par la table de vecteurs AVR. Les événements système critiques (reset, erreurs) se situent en haut de la liste, les autres plus bas.

L’utilisateur ne manipule pas directement ces niveaux sur une carte Arduino classique, mais doit en tenir compte lorsqu’il empile plusieurs fonctionnalités reposant sur des interruptions : timer, UART, broches externes, etc.

Désactiver et réactiver les interruptions

Lorsqu’un code doit manipuler une variable partagée entre le contexte principal et une ISR, une section critique protège cette variable. Sur Arduino, la bibliothèque AVR propose généralement les fonctions suivantes :

  • noInterrupts() : désactive globalement les interruptions
  • interrupts() : réactive globalement les interruptions

Le principe consiste à entourer l’accès à la variable partagée avec ce bloc, puis à rétablir la situation initiale au plus vite pour éviter de masquer trop longtemps les autres interruptions légitimes.

Variables volatiles et interdiction d’accès concurrent

Les variables partagées entre ISR et programme principal doivent être déclarées volatile. Ce mot-clé ordonne au compilateur de ne pas optimiser ces accès, afin de tenir compte des modifications asynchrones provoquées par les interruptions.

ArduinoPiloter un relais 230 V avec Arduino en sécurité : 5 erreurs à éviter

En complément, certains types de variables (entiers sur plusieurs octets) nécessitent une protection contre les accès non atomiques. Une lecture partielle pendant que l’ISR met à jour la valeur génère une incohérence. Dans ce cas, une brève désactivation des interruptions avant la lecture ou l’écriture sécurise l’opération.

Bon réflexe : considérer chaque variable modifiée dans une ISR comme une ressource partagée. Vérifier son type, sa taille et le contexte d’accès. Une simple structure de données mal protégée peut compromettre tout le comportement temps réel du système.

Interruptions et consommation de courant : impact sur l’alimentation

Une carte Arduino ne fournit qu’un courant limité par broche et sur la sortie 3,3 V. Sur les données disponibles :

  • 40 mA maximum par broche
  • 50 mA maximum sur la sortie 3,3 V

Les interruptions influencent indirectement la consommation en réveillant régulièrement le microcontrôleur. Sur un montage basse consommation, un système en mode veille se réveille à chaque interruption externe, traite l’événement, puis retourne en sommeil.

Un débit d’interruptions trop élevé maintient la carte en activité et augmente la consommation globale. Pour un projet alimenté sur batterie, une conception fine des seuils de déclenchement et de la fréquence des événements limite cet impact.

Timers, millis() et interruptions : construire une architecture non bloquante

La fonction millis() repose déjà sur une interruption de timer interne. Elle offre un compteur de millisecondes depuis le démarrage du microcontrôleur. Ce mécanisme sert à concevoir des systèmes non bloquants sans delay().

En combinant millis() avec des interruptions externes, on obtient des architectures répartissant clairement les responsabilités :

  • Les interruptions gèrent les événements imprévisibles (capteur, bouton, fin de course).
  • millis() gère le déclenchement périodique de tâches (mise à jour d’afficheur, envoi de trame série).
  • La boucle loop() orchestre le tout sans blocage.

Pour aller plus loin sur la gestion du temps sans delay(), un guide spécifique comme /arduino-timer-millis/ offre des schémas de code réutilisables et une approche modulaire.

Utiliser des timers matériels pour un contrôle fin

Pour des besoins de précision supérieurs ou des fréquences élevées, la configuration directe des timers matériels remplace les solutions basées sur millis(). Un registre de comparaison (compare match) génère une interruption à intervalle fixe, calculé selon la fréquence d’horloge et le prescaler.

Sur un Uno R3 à 16 MHz, le choix du prescaler et de la valeur de comparaison détermine la fréquence finale. Sur un Teensy à 600 MHz, la résolution augmente et ouvre la voie à des signaux très rapides, par exemple pour du contrôle moteur précis ou des générateurs de signaux.

Exemples concrets de projets utilisant les interruptions

Plusieurs applications classiques s’appuient déjà sur les interruptions pour améliorer leur robustesse et leur réactivité. Les exemples suivants montrent comment intégrer cette mécanique dans des projets réalistes.

Générateur de signal carré avec timers et interruptions

Un générateur de signal carré basé sur un timer matériel et une ISR permet d’obtenir une fréquence stable sans monopoliser loop(). Le principe :

  • Configuration d’un timer en mode CTC (Clear Timer on Compare).
  • Définition de la valeur de comparaison pour la fréquence souhaitée.
  • Dans l’ISR du timer, inversion de l’état d’une broche de sortie.

Cette approche produit un signal indépendant du reste du programme. Le microcontrôleur gère d’autres tâches pendant que le timer assure la stabilité temporelle.

Système de fins de course pour robot

Sur un robot mobile ou un axe motorisé, les fins de course signalent l’atteinte d’une extrémité de course. Une interruption externe sur chaque capteur de fin de course permet de couper immédiatement la commande moteur, sans attendre le prochain tour de loop().

Architecture typique :

  • Une ISR par fin de course, qui met à jour un drapeau d’erreur.
  • Dans loop(), lecture régulière de ce drapeau pour adapter la stratégie (arrêt, retour arrière, alerte).
  • Protection matérielle supplémentaire via relais ou driver pour couper la puissance en dernier recours.

Contrôle moteur avec détection d’anomalies

Dans un système de contrôle moteur, des capteurs d’encodeur, de courant ou de température signalent des anomalies. Une interruption sur front rapide détecte une surintensité, une perte de repère ou un dépassement de température avant que le moteur ne subisse des dommages.

L’ISR se contente de :

  • Couper immédiatement les signaux d’activation vers le driver.
  • Enregistrer la cause de l’arrêt dans une variable globale.
  • Laisser loop() gérer l’affichage d’un message, l’enregistrement en mémoire ou l’envoi d’une trame de diagnostic.
Idée d’évolution : pour enrichir ces projets, un tour d’horizon de montages plus ambitieux sur /projet-arduino-avance/ apporte de nouvelles pistes : gestion de bus, enregistrement de données, contrôle distribué, etc.

Bonnes pratiques pour architecturer un projet Arduino avec interruptions

Une utilisation maîtrisée des interruptions repose autant sur la technique que sur l’organisation du code. Quelques principes structurants aident à maintenir un projet lisible et extensible.

Limiter la logique dans les ISR

Une ISR se concentre idéalement sur trois types d’actions :

  • Mise à jour de variables globales simples.
  • Enregistrement d’un horodatage avec micros() ou un compteur local.
  • Déclenchement d’un drapeau ou d’un état dans une machine à états.

Le traitement complexe, les conversions, la fusion de données capteurs ou la communication externe se déplacent dans loop() ou dans des fonctions dédiées appelées depuis le contexte principal.

Documenter les ISR et les dépendances

Chaque ISR devrait être accompagnée de commentaires indiquant :

  • La source de l’interruption (broche, timer, périphérique).
  • Les variables globales modifiées.
  • Les hypothèses temporelles (fréquence maximale attendue, durée approximative d’exécution).

Cette documentation facilite la maintenance et révèle rapidement les zones sensibles en cas d’évolution du projet.

Tester sous charge et en conditions réelles

La théorie ne remplace pas un essai en dynamique. Un système d’interruptions se teste :

  • Avec des stimuli plus fréquents que ceux prévus en usage normal.
  • Avec plusieurs sources d’interruptions actives simultanément.
  • En surveillant les dérives de timing et les éventuels blocages.

Même si certaines données, comme la latence précise ou la fréquence maximale d’interruptions, ne sont pas toujours disponibles, un banc de test orienté vers le pire cas réaliste aide à vérifier le comportement global du système.

Limite à garder en tête : un Arduino n’est pas un automate industriel certifié. Pour des systèmes critiques de sécurité, une validation matérielle et logicielle spécifique, ainsi que des composants adaptés, restent nécessaires au-delà d’un simple usage hobbyiste ou prototypage.

Panorama des limites techniques connues et zones d’ombre

Les interruptions offrent un levier puissant, mais certaines zones restent moins documentées ou dépendent fortement de la carte et du compilateur utilisés.

Parmi les données manquantes ou très dépendantes du contexte :

  • Latence précise des interruptions sur chaque combinaison carte / fréquence.
  • Fréquence maximale supportée en continu sans dégradation du système.
  • Comportement sous forte charge avec plusieurs vecteurs simultanés.
  • Études complètes de fiabilité temps réel en environnement industriel.

Dans la plupart des projets Arduino de loisir ou de prototypage, ces limites ne sont pas atteintes. Pour des applications plus exigeantes, un profilage ciblé, l’utilisation d’outils de mesure (oscilloscope, analyseur logique) et une connaissance approfondie du microcontrôleur deviennent nécessaires.

Donnez votre avis

Soyez le 1er à noter cet article


Partagez cet article maintenant !


Ça ne règle pas votre cas ?

Décrivez la panne sur le forum, avec une photo si vous pouvez : les membres qui ont eu la même répondent, et le sujet reste pour les suivants.

Avatar photoAvatar photoAvatar photoAvatar photoAvatar photoRejoindre les 54 membres — gratuit, 44 pannes résolues

Dans le même tiroir

Scène réaliste d’un bureau d’électronique avec un Arduino et un capteur DHT22 connectés sur une table en bois, entourés d’outils et d’un ordinateur affichant des mesures.
Arduino

Arduino DHT22 code : exemple complet

Le capteur DHT22 transforme une simple carte Arduino en véritable poste de mesure température / humidité. Avec quelques lignes de…

Portrait de Inès DameronInès Dameron · 14 Fév 2026
Scène réaliste d’un établi électronique avec un Arduino Uno, une LED clignotante et une main ajustant les fils dans un environnement de bricolage naturel et détaillé.
Arduino

Arduino LED blink : premier programme

Programmer un Arduino avec un simple clignotement de LED ouvre très vite la porte à l’électronique et aux systèmes embarqués.…

Portrait de Inès DameronInès Dameron · 13 Fév 2026
La lettre du club

Une lettre par mois, accrochée au panneau

Les sujets du forum résolus dans le mois, un guide, un chiffre qu’on peut vérifier chez soi. Rien d’autre, jamais plus souvent — et on se désabonne d’un clic.

Ce qu’il y a dedans

Votre adresse

Une lettre par mois. Désabonnement en un clic.