Guides Arduino

Pulse Sensor Arduino : Construire une Station Santé DIY Complète

Du Pulse Sensor analogique à la station santé multi-capteurs : code de détection de pic avec période réfractaire, alertes BPM, journalisation SD-card et dashboard web ESP32 — tout ce qu'il faut savoir pour bâtir un wearable maison sérieux.

5 avril 202616 min de lectureÉquipe Didactico

Imaginez la scène : amphi de l’INSAT, défense de projet de fin d’études. Deux étudiants présentent successivement leur prototype. Le premier sort fièrement un boîtier élégant à 280 DT contenant un MAX30102, un ESP32, un écran tactile, un module SD et toute la quincaillerie. Le second pose sur la table un Arduino UNO et un petit disque rouge avec un câble à trois fils — un Pulse Sensor à 8 DT. Il branche, pose son doigt, et instantanément, la LED clignote à son rythme cardiaque et le moniteur série affiche 72 BPM. Le jury, intrigué, passe finalement plus de temps sur le second projet — parce que son code de détection de pic est plus propre, plus pédagogique, plus instructif que toutes les couches d’abstraction du premier.

Le Pulse Sensor est un capteur fascinant par sa simplicité radicale. Aucun protocole I2C compliqué, aucune librairie obscure de 3000 lignes, aucun registre à configurer. Trois fils : +5V, GND, signal analogique. Vous le branchez sur A0, vous lisez avec analogRead(), et vous voyez votre cœur battre dans un graphique. C’est l’introduction parfaite à la photopléthysmographie analogique, et la base d’innombrables projets de station santé DIY.

⚠️ Information importante

Le Pulse Sensor est un capteur pédagogique et de prototypage, non certifié dispositif médical. Les mesures ne doivent pas servir au diagnostic, au suivi de patients ou à toute décision thérapeutique. Pour un usage clinique, utilisez un appareil homologué selon la norme ISO 80601-2-61.

Pulse Sensor vs MAX30102 : pas le même usage

Avant d’aller plus loin, clarifions ce qui distingue ces deux capteurs souvent mis en concurrence chez Didactico Sfax :

Critère Pulse Sensor MAX30100 / MAX30102
Interface Analogique (A0) I2C numérique (0x57)
LEDs 1 LED verte 525 nm ou IR 2 LEDs : Rouge 660 nm + IR 880 nm
Mesure BPM Oui Oui
Mesure SpO2 Non (impossible avec 1 LED) Oui
Complexité code Très simple (~50 lignes) Moyenne (librairie requise)
Précision BPM ±2-3 BPM en conditions stables ±1-2 BPM
Forme physique Disque souple avec attache velcro Module rigide
Prix Tunisie 8-15 DT 15-25 DT
Cas d’usage idéal Apprentissage, fitness DIY, wearable simple Oxymètre médical éducatif, projet PFE biomédical

En résumé : si votre objectif est de mesurer uniquement le rythme cardiaque et d’apprendre l’algorithmique de détection de pic à partir d’un signal analogique brut, le Pulse Sensor est imbattable. Si vous voulez en plus la SpO2 et un signal plus stable, le MAX30102 est préférable.

Principe : une LED IR et une photodiode

Le Pulse Sensor World (le modèle de référence conçu par Joel Murphy) utilise une LED verte à 525 nm pointée vers la peau et une photodiode APDS-9008 placée juste à côté. La lumière verte pénètre dans le derme sur quelques millimètres et est partiellement absorbée par l’hémoglobine du sang capillaire. Ce qui n’est pas absorbé est rétro-diffusé par les tissus environnants et capté par la photodiode. À chaque battement, le volume de sang augmente sous le capteur, plus de lumière est absorbée, moins est renvoyée à la photodiode — le signal baisse. Entre deux battements, le signal remonte.

Pourquoi la lumière verte plutôt que rouge ou IR ? Parce que l’hémoglobine absorbe très fortement à 525 nm (pic d’absorption secondaire). Le signal AC est donc beaucoup plus contrasté qu’en lumière rouge, et le rapport signal-sur-bruit excellent même avec une électronique simple. C’est aussi pour cette raison que les Apple Watch et les capteurs cardiaques de Garmin, Fitbit, Polar, utilisent quasi tous des LEDs vertes (regardez le dessous de votre montre dans le noir, vous verrez les LEDs vertes pulser).

L’inconvénient du vert : il ne pénètre pas suffisamment pour faire de l’oxymétrie. Pour mesurer le SpO2, il faut absolument deux longueurs d’onde (rouge + IR), donc le Pulse Sensor en est intrinsèquement incapable. Une seule LED, une seule mesure : le rythme cardiaque.

Câblage et précautions

Trois fils : c’est tout.

  • Fil rouge (ou marqué “+”) → 5V Arduino (ou 3,3 V — fonctionne aussi)
  • Fil noir (ou marqué “-“) → GND Arduino
  • Fil violet/jaune (ou marqué “S”) → A0 Arduino

Précautions de pose :

  1. La face avec la LED et la photodiode doit être plaquée contre la peau. La face arrière reste libre.
  2. L’endroit le plus fiable : bout du doigt (index ou majeur), avec attache velcro. Lobe d’oreille fonctionne aussi.
  3. Ne pas exercer une pression excessive — vous écraseriez les capillaires.
  4. Éviter la lumière ambiante directe sur la face avant du capteur (idéalement, sous attache velcro opaque).
  5. Le capteur est fragile : ne pas plier le PCB, ne pas mouiller (sauf si vous l’enrobez de résine époxy pour un projet wearable).
💡 Découplage du bruit secteur

Le signal analogique du Pulse Sensor est très sensible aux parasites 50 Hz du secteur. Ajoutez un condensateur céramique 100 nF entre la broche S et GND, au plus près de l’Arduino. Cela atténue les harmoniques 50 Hz qui pourraient être interprétées comme des fausses pulsations.

Détection de pic : seuil et période réfractaire

Voici le cœur algorithmique du Pulse Sensor : transformer un signal analogique bruité en une détection fiable de chaque battement. Le code de base, sans librairie, tient en moins de 80 lignes et démystifie complètement la photopléthysmographie.

/*
 * Pulse Sensor — Detection de battement par seuillage
 * Methode : seuil adaptatif + periode refractaire
 * Branchement : signal sur A0, alim 5V
 */

const uint8_t PIN_SIGNAL = A0;
const uint8_t PIN_LED_BAT = 13;  // LED interne qui clignote au rythme

// Parametres de detection
const int SEUIL_INIT = 550;        // Seuil initial (sera adapte)
const unsigned long REFRACTAIRE = 300; // ms — periode aveugle apres pic
const int FENETRE_MIN_MAX = 100;    // echantillons pour calcul seuil adaptatif

int seuil = SEUIL_INIT;
int signalMin = 1024, signalMax = 0;
int compteur = 0;
bool surSeuil = false;
unsigned long dernierPic = 0;
unsigned long intervalle = 0;
float bpm = 0;

void setup() {
  pinMode(PIN_LED_BAT, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  int signalBrut = analogRead(PIN_SIGNAL);
  unsigned long maintenant = millis();
  
  // Suivi min/max pour seuillage adaptatif
  if (signalBrut < signalMin) signalMin = signalBrut;
  if (signalBrut > signalMax) signalMax = signalBrut;
  compteur++;
  
  if (compteur >= FENETRE_MIN_MAX) {
    // Seuil = 70% entre min et max
    seuil = signalMin + (signalMax - signalMin) * 7 / 10;
    signalMin = 1024;
    signalMax = 0;
    compteur = 0;
  }
  
  // Detection de franchissement vers le haut
  if (signalBrut > seuil && !surSeuil
      && (maintenant - dernierPic) > REFRACTAIRE) {
    surSeuil = true;
    
    intervalle = maintenant - dernierPic;
    dernierPic = maintenant;
    
    // Filtrage intervalles aberrants (BPM 30-220 plausibles)
    if (intervalle > 270 && intervalle < 2000) {
      bpm = 60000.0 / intervalle;
      digitalWrite(PIN_LED_BAT, HIGH);
      Serial.print(F("BPM: "));
      Serial.println(bpm, 1);
    }
  } else if (signalBrut < seuil && surSeuil) {
    surSeuil = false;
    digitalWrite(PIN_LED_BAT, LOW);
  }
  
  delay(2); // ~500 Hz d'echantillonnage
}

Pourquoi un seuil adaptatif ?

Si vous fixez un seuil à 550 en dur, ça marchera pour vous, à un instant T, avec cette pression du doigt et cette lumière ambiante. Mais demain, après-demain, ou pour un autre utilisateur, le signal sera centré sur 480, ou 620, et votre détection s’effondrera. Le seuil adaptatif recalibre toutes les 100 mesures (~200 ms) en se basant sur le min et le max observés, garantissant une détection robuste quelles que soient les conditions.

Pourquoi une période réfractaire ?

Un battement cardiaque dans le signal PPG comporte typiquement un pic principal (systole) suivi parfois d’un pic secondaire plus petit (dicrote, reflet de la fermeture de la valve aortique). Sans période réfractaire, votre algorithme compterait deux battements par cycle. 300 ms correspond à un BPM maximum de 200 — au-delà, vous êtes en tachycardie sévère qui nécessite une consultation médicale immédiate de toute façon.

Calcul BPM en temps réel

Le BPM instantané calculé à chaque battement (60000 / intervalle) est très variable d’un cycle à l’autre — c’est la variabilité de la fréquence cardiaque (HRV), normale et même souhaitable. Pour un affichage stable et lisible, lissez avec une moyenne mobile sur 8 ou 10 intervalles consécutifs :

const uint8_t TAILLE_MOYENNE = 10;
unsigned long historiqueIntervalles[TAILLE_MOYENNE];
uint8_t idxHistorique = 0;
bool historiqueRempli = false;

float bpmLisse() {
  if (!historiqueRempli && idxHistorique < TAILLE_MOYENNE)
    return 0; // Pas encore assez de donnees
  
  unsigned long somme = 0;
  uint8_t taille = historiqueRempli ? TAILLE_MOYENNE : idxHistorique;
  for (uint8_t i = 0; i < taille; i++)
    somme += historiqueIntervalles[i];
  
  return 60000.0 * taille / somme;
}

// A appeler a chaque pic detecte valide :
void enregistrerIntervalle(unsigned long inter) {
  historiqueIntervalles[idxHistorique] = inter;
  idxHistorique = (idxHistorique + 1) % TAILLE_MOYENNE;
  if (idxHistorique == 0) historiqueRempli = true;
}

Alertes tachycardie et bradycardie

Définitions cliniques de référence chez l’adulte au repos :

  • Bradycardie : BPM < 60. Normal chez les sportifs entraînés. Pathologique en dehors.
  • Fréquence normale au repos : 60-100 BPM
  • Tachycardie : BPM > 100 au repos. Pathologique si persistant sans effort ni stress.
  • Seuils d’alerte fonctionnelle dans la plupart des wearables : alerte basse à 50 BPM, alerte haute à 120 BPM, alerte rouge au-dessus de 150 ou en-dessous de 40 BPM.
const float SEUIL_BRADY = 50;
const float SEUIL_TACHY = 120;
const float SEUIL_URGENCE_BAS = 40;
const float SEUIL_URGENCE_HAUT = 150;

void surveiller(float bpm) {
  if (bpm == 0) return; // Pas encore stabilise
  
  if (bpm < SEUIL_URGENCE_BAS || bpm > SEUIL_URGENCE_HAUT) {
    declencher(NIVEAU_ROUGE);
  } else if (bpm < SEUIL_BRADY) {
    declencher(NIVEAU_BRADY);
  } else if (bpm > SEUIL_TACHY) {
    declencher(NIVEAU_TACHY);
  } else {
    rassurer();
  }
}

L’alerte peut être un buzzer piezo (PWM avec fréquence variable selon gravité), une LED RGB qui change de couleur (vert/jaune/rouge), un message SMS via module GSM SIM800L, une notification push via ESP32 + IFTTT.

💗
CAPTEURS BIOMÉDICAUX

Pulse Sensor + Capteurs Santé Didactico

Pulse Sensor, DHT22, AD8232 ECG, MAX30102 — tout le nécessaire pour construire une station santé DIY complète. Livraison 24-48h en Tunisie.

Voir les capteurs santé →

Projet : station santé multi-capteurs

L’objectif : un dispositif Arduino capable de mesurer simultanément le rythme cardiaque, la température corporelle, l’humidité ambiante, et de journaliser le tout horodaté sur une carte SD avec affichage OLED. Coût total chez Didactico : environ 65 DT.

Liste de matériel

  • Arduino Nano ou UNO
  • Pulse Sensor (canal A0)
  • DHT22 (température corporelle au front + humidité ambiante)
  • Module RTC DS3231 (horodatage précis I2C)
  • Module SD-card SPI
  • Écran OLED 0,96″ SSD1306 I2C
  • Bouton poussoir (démarrer/arrêter session)
  • Buzzer piezo (alertes)
  • Batterie 9V + interrupteur

Bus utilisés sur Arduino UNO

  • I2C (A4/A5) : OLED + RTC en parallèle
  • SPI (D10-D13) : carte SD
  • Analogique A0 : Pulse Sensor
  • Numérique D2 : DHT22, D3 : bouton, D4 : buzzer

Architecture logicielle

void loop() {
  // 1. Lecture Pulse Sensor — DOIT etre TRES rapide (~2 ms)
  lirePulseSensor();
  
  // 2. Calculs et detections (a chaque pic)
  if (nouveauPic) {
    bpm = bpmLisse();
    surveiller(bpm);
  }
  
  // 3. Lecture DHT22 — lente (250 ms), pas a chaque iteration
  static unsigned long tDHT = 0;
  if (millis() - tDHT > 2000) {
    tempCorporelle = dht.readTemperature();
    humidite = dht.readHumidity();
    tDHT = millis();
  }
  
  // 4. Mise a jour ecran — 5 Hz suffisent
  static unsigned long tOLED = 0;
  if (millis() - tOLED > 200) {
    afficher(bpm, tempCorporelle, humidite, etat);
    tOLED = millis();
  }
  
  // 5. Journalisation SD — chaque 5 secondes
  static unsigned long tSD = 0;
  if (millis() - tSD > 5000) {
    enregistrer(rtc.now(), bpm, tempCorporelle, humidite);
    tSD = millis();
  }
  
  // 6. Bouton — debounce
  gererBouton();
}

Le défi est d’ordonnancer ces tâches sans bloquer la lecture du Pulse Sensor — d’où l’usage systématique de millis() et l’absence de delay() long. La lecture du DHT22 prend 250 ms ; si elle est faite dans la loop() à chaque tour, vous perdez 80 % des battements cardiaques.

Format CSV pour journal SD

timestamp,bpm,temp_C,humidite_%,etat
2026-05-15 14:32:05,72.4,36.8,52,NORMAL
2026-05-15 14:32:10,73.1,36.8,52,NORMAL
2026-05-15 14:32:15,124.7,37.1,53,TACHY_LEGER
2026-05-15 14:32:20,118.2,37.1,53,NORMAL

Format CSV simple, ouvrable dans Excel ou tableur, analysable en Python avec pandas pour exploitation pédagogique (graphique BPM dans le temps, corrélation avec température, distribution statistique, etc.).

Version ESP32 avec dashboard web

Pour transformer la station en objet connecté moderne, remplacez l’Arduino UNO par un ESP32 DevKit (15 DT chez Didactico). L’ESP32 apporte : Wi-Fi natif, Bluetooth, deux cœurs, 520 KB de RAM, et surtout la possibilité d’héberger un mini serveur web qui affiche les mesures temps réel sur smartphone.

Architecture

  • Cœur 0 : lecture haute fréquence Pulse Sensor + détection de pic
  • Cœur 1 : serveur web + WebSocket vers navigateur

Le serveur web sert une page HTML/JS qui ouvre un WebSocket vers l’ESP32. Toutes les 100 ms, l’ESP32 envoie un JSON {"bpm": 72.4, "raw": 542} au client. Le JS dessine une courbe en temps réel avec Chart.js — exactement comme un oxymètre médical hospitalier, mais sur le smartphone des étudiants.

Squelette de code ESP32

#include <WiFi.h>
#include <WebServer.h>
#include <WebSocketsServer.h>

WebServer serveur(80);
WebSocketsServer ws(81);

const char* SSID = "DidacticoLab";
const char* PASS = "Sfax2026";

void tachePulseSensor(void* p) {
  for (;;) {
    lirePulseSensor();
    if (nouveauPic) {
      char msg[64];
      snprintf(msg, 64, "{"bpm":%.1f}", bpmLisse());
      ws.broadcastTXT(msg);
    }
    vTaskDelay(2 / portTICK_PERIOD_MS);
  }
}

void setup() {
  Serial.begin(115200);
  WiFi.begin(SSID, PASS);
  while (WiFi.status() != WL_CONNECTED) delay(500);
  Serial.println(WiFi.localIP());
  
  serveur.on("/", []() {
    serveur.send(200, "text/html", pageHTML);
  });
  serveur.begin();
  ws.begin();
  
  // Tache haute priorite sur coeur 0
  xTaskCreatePinnedToCore(tachePulseSensor, "pulse",
                          8192, NULL, 2, NULL, 0);
}

void loop() {
  serveur.handleClient();
  ws.loop();
}

Vers un wearable maison

Un wearable est un objet qu’on porte au poignet, à l’oreille ou au cou de manière continue. Pour le construire à partir du Pulse Sensor, il faut résoudre trois problèmes : alimentation, encombrement, ergonomie.

Alimentation : batterie LiPo + charge USB

Une LiPo 3,7 V 500 mAh est l’idéal. Avec un module TP4056 (charge USB-C avec protection) et un step-up MT3608 (vers 5 V pour le Pulse Sensor s’il en a besoin — vérifiez avec 3,3 V d’abord, ça marche souvent). Autonomie typique avec un ESP32 en deep-sleep entre mesures : 8 à 12 heures de mesure continue, plusieurs jours en usage intermittent.

Encombrement : ESP32-C3 ou Seeed XIAO

Le DevKit ESP32 classique est trop gros pour un poignet. Privilégiez l’ESP32-C3 Super Mini (18×11 mm) ou la série Seeed XIAO. Le PCB est de la taille d’une pièce de monnaie.

Ergonomie : bracelet 3D imprimé + résine

Boîtier en TPU souple imprimé en 3D, électronique enrobée de résine époxy transparente (étanchéité), bracelet à attache silicone. Le Pulse Sensor est placé au niveau du poignet côté radial (où on prend le pouls manuellement). C’est un peu moins fiable qu’au doigt mais c’est la zone de référence des wearables.

Comparaison avec les montres connectées

Une Apple Watch ou une Galaxy Watch coûte 800 à 3000 DT. Que vaut votre station santé DIY à 65 DT en comparaison ?

Critère Wearable commercial Station santé DIY Didactico
Précision BPM ±1 BPM (cliniquement validée) ±2-3 BPM en bonnes conditions
SpO2 Oui (4-5 LEDs) Non avec Pulse Sensor, oui avec MAX30102
ECG Oui sur modèles haut de gamme Oui avec AD8232 ajouté
Autonomie 18-48 h 8-12 h (extensible avec sleep mode)
Personnalisation logicielle Très limitée Totale (vous écrivez le firmware)
Possibilité d’apprentissage Boîte noire Vous comprenez chaque ligne
Prix 800-3000 DT 50-150 DT
Crédibilité PFE Aucune Excellente (vous l’avez fait)

Le DIY n’a pas pour ambition de remplacer un produit commercial validé cliniquement. Il a pour ambition de comprendre ce qui se passe dans la boîte noire que vous portez au poignet, et de pouvoir le reproduire avec 50 DT et 200 lignes de code. C’est cette compétence-là qui vous fera embaucher dans une startup biomédicale tunisienne ou un labo de R&D.

FAQ

Le Pulse Sensor ne donne aucun signal, que faire ?

Vérifications : (1) câblage rouge/noir/jaune correct, (2) tension d’alimentation 5 V stable, (3) la LED verte du capteur doit être allumée quand vous le branchez — sinon, capteur défectueux, (4) doigt bien plaqué et immobile sur la face active, (5) analogRead(A0) doit retourner des valeurs entre 100 et 900 typiquement — si la valeur est figée à 0 ou 1023, problème de câblage ou capteur HS.

Faut-il acheter la librairie PulseSensor Playground ?

Elle est gratuite et open-source sur GitHub. Pour les débutants, oui, elle simplifie le démarrage. Pour comprendre vraiment la photopléthysmographie et personnaliser l’algorithme, écrivez votre propre détecteur (comme dans cet article) — c’est 50 lignes et c’est instructif.

Quelle différence entre Pulse Sensor et un capteur à pince à doigt commercial ?

Le Pulse Sensor est conçu pour être pédagogique : open hardware, signal analogique brut, attache velcro. Un capteur à pince à doigt commercial (type SpO2 médical) intègre LED rouge + IR + photodiode + ADC + DSP + protocole numérique dans un boîtier ergonomique. Plus précis, mais boîte noire.

Puis-je mesurer le pouls au poignet directement ?

Oui, mais le signal est plus faible qu’au bout du doigt. Placez le capteur sur l’artère radiale (côté pouce du poignet, où vous prenez le pouls manuellement) avec une attache velcro pas trop serrée. Augmentez si possible le gain en amplifiant le signal analogique avec un AOP. Les wearables commerciaux utilisent une LED plus puissante pour compenser.

Le signal est bruité même immobile, normal ?

Plusieurs sources de bruit possibles : (1) parasites 50 Hz secteur — ajoutez condensateur 100 nF entre A0 et GND, (2) variations d’éclairement ambiant — calez le capteur sous une attache opaque, (3) tremblements involontaires du doigt — posez la main sur la table, (4) alimentation USB instable — testez sur batterie 9 V. Ajoutez aussi un filtre passe-bas logiciel (moyenne mobile sur 3-5 échantillons).

Le DHT22 mesure-t-il vraiment la température corporelle ?

Le DHT22 est conçu pour mesurer la température ambiante (-40 à 80 °C, précision ±0,5 °C), pas spécifiquement la peau humaine. Placé au front avec un bon contact, il donne une indication grossière de la température corporelle (±1 °C) mais ce n’est pas un thermomètre médical. Pour une mesure médicale, utilisez plutôt un MLX90614 (infrarouge sans contact, ±0,2 °C en zone du front).

Mon BPM affiche 0 après quelques secondes de mesure stable, pourquoi ?

Probablement un dépassement de la période de timeout : si aucun pic n’est détecté pendant plus de 3-4 secondes, beaucoup d’algorithmes remettent le BPM à 0. Vérifiez que le seuil adaptatif n’a pas dérivé trop haut (par exemple si le signal a perdu en amplitude à cause d’un déplacement du doigt). Réinitialisez le seuil quand vous détectez une période d’inactivité.

Conclusion

Le Pulse Sensor est, à mon sens, le capteur biomédical le plus pédagogique du marché. Trois fils, un signal analogique, et tout le reste — détection de pic, calcul BPM, alertes, journalisation, dashboard temps réel — est entre vos mains. C’est exactement le profil de composant qui sépare un étudiant ENIT, INSAT, ISBS ou ISET qui sait coller des briques de bibliothèques d’un ingénieur qui comprend vraiment ce qu’il fait.

Chez Didactico, vous trouverez le Pulse Sensor, le DHT22, le MLX90614, l’AD8232 ECG, les modules SD, les RTC DS3231, les écrans OLED, les ESP32 — et tout l’écosystème nécessaire pour bâtir votre station santé DIY ou votre wearable. Livraison sous 24 à 48 heures partout en Tunisie depuis Sfax. Les étudiants en filière biomédicale trouvent souvent au FabLab Sfax les conseils méthodologiques pour structurer leur projet de fin d’études autour de ces capteurs.

Bon prototypage — et écoutez votre cœur, au sens propre comme au figuré.

🛒 Matériel nécessaire pour ce guide

Tout le matériel de ce tutoriel est disponible chez Didactico — livraison 24-48h partout en Tunisie, paiement à la livraison.

Voir toute la catégorie « Capteurs – Prototypage » →

📘 Guides liés : MAX30100 Arduino : Capteur SpO2 et Rythme Cardiaque DIY · Kit ECG AD8232 : Moniteur Cardiaque DIY avec Arduino en Tunisie

🛒 Passez à la pratique
Retrouvez nos capteurs cardiaques en stock chez Didactico, livraison partout en Tunisie.
Voir la boutique →