🛠 Multitâche non bloquant : heartbeat + bouton avec debounce

Arduino UNO R3 · intermediaire · Schéma : IMG-uno-r3-intermediaire-3-multitache-millis-debounce.svg — UNO R3 avec bouton sur pin 2 vers GND et LED sur pin 13, horloge dessinée symbolisant millis().

Objectives

Move away from sequential delay: execute two independent tasks in loop using millis — a 500 ms LED blink and a button with 30 ms software debouncing. This is the skill that separates beginners from intermediates on bare-metal microcontrollers (no OS on the UNO, just a bootloader).

Hardware

Complete code

// Deux tâches sans delay : heartbeat 500 ms + toggle par bouton (debounce 30 ms).
const uint8_t LED = 13;
const uint8_t BTN = 2;

bool ledOn = false;
bool dernierEtatBtn = HIGH;
uint32_t dernierBlink = 0, dernierChangementBtn = 0;

void setup {
  pinMode(LED, OUTPUT);
  pinMode(BTN, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop {
  uint32_t maintenant = millis;

  // Tâche 1 : heartbeat non bloquant.
  if (maintenant - dernierBlink >= 500) {
    dernierBlink = maintenant;
    digitalWrite(LED, !digitalRead(LED));
  }

  // Tâche 2 : bouton avec anti-rebond de 30 ms, front d'appui.
  bool btn = digitalRead(BTN);
  if (btn != dernierEtatBtn && maintenant - dernierChangementBtn >= 30) {
    dernierChangementBtn = maintenant;
    dernierEtatBtn = btn;
    if (btn == LOW) {              // appuyé (actif-bas)
      ledOn = !ledOn;
      Serial.print(F("toggle -> ")); Serial.println(ledOn);
    }
  }
  digitalWrite(LED, ledOn ? HIGH : LOW);
}

Expected verification

The LED pulses continuously; each press (a single one, even if the button clicks) toggles the state displayed in the Serial Monitor. Test the difference: without the 30 ms window, a single press triggers 3 to 10 visible toggles in the Monitor — mechanical bouncing is real.

Common errors

Other tutorials for this board

Code examples for this board

← Back to the board 🛠 All tutorials