Si un doigt est maintenu entre la diode émettrice de lumière infrarouge et le photo transistor, l'impulsion peut être détectée à la sortie du signal.

Le fonctionnement d'un photo-transistor s'explique comme suit : il fonctionne généralement comme un transistor normal - ainsi, plus le courant qui le traverse est élevé, plus la tension de commande qui lui est appliquée est élevée. Dans un phototransistor, cependant, la lumière incidente représente la tension de commande - plus la lumière incidente est forte, plus le courant qui passe est élevé.

Si vous connectez une résistance en série devant le transistor, le comportement suivant se produit lorsque vous mesurez la tension aux bornes du transistor : si le transistor est très éclairé ou s'il fait jour, vous pouvez mesurer une faible tension proche de 0V - si le transistor est dans l'obscurité, il laisse passer un courant relativement faible et vous mesurez une tension proche de +V.

Le dispositif de mesure avec diode infrarouge et phototransistor intégré dans ce module de détection nous permet maintenant de mesurer l'impulsion en plaçant un doigt entre la diode et le transistor. Explication : la peau de la main peut être éclairée de la même manière qu'avec une torche. Si vous touchez une veine sanguine en faisant passer la lumière à travers elle, vous pouvez voir le sang pomper très faiblement. Ce pompage est reconnaissable parce que le sang a une densité différente à différents endroits de la veine et que l'on peut donc voir des différences de luminosité dans le flux sanguin. Le module de détection permet d'enregistrer précisément ces différences de luminosité et de reconnaître ainsi l'impulsion. Cela devient clair en regardant l'image d'oscilloscope suivante.

KY-039

L'axe des ordonnées montre le changement de tension au niveau du phototransistor, et donc les changements de luminosité causés par le sang qui coule. Les pics marqués ci-dessus montrent donc les battements du cœur. Si nous calculons maintenant les battements enregistrés par temps enregistré, nous arrivons à un pouls d'environ 71 battements/minute (bpm).

Comme vous pouvez le voir sur l'image supérieure de l'oscilloscope, le signal enregistré est relativement faible et le transistor est très sensible pour capter le signal faible. Pour obtenir un résultat optimal, nous vous recommandons de préparer le module pour la mesure comme indiqué dans les images suivantes :

Pour augmenter la sensibilité du capteur, nous recommandons de fixer le capteur au bout du petit doigt à l'aide d'un sparadrap / d'un ruban adhésif / d'un ruban isolant.

Le rythme cardiaque est particulièrement bien enregistré lorsque le capteur est placé au-dessus d'un gros vaisseau sanguin. Pour améliorer le signal, nous recommandons également de changer la position du capteur sur le bout du doigt si nécessaire.

Affectation des broches

Affectation des câbles

Couleur du câble Signification du câble
Noir Signal
Bleu +V
Gris GND

Exemple de code Arduino

Affectation des broches Arduino

Arduino Capteur
Pin A0 Signal
5V +V
Masse GND
////////////////////////////////////////////////////////////////////////
/// Copyright (c)2015 Dan Truong
/// Permission is granted to use this software under the MIT
/// licence, with my name and copyright kept in source code
/// http://http://opensource.org/licenses/MIT
///
/// KY039 Arduino Heartrate Monitor V1.0 (April 02, 2015)
////////////////////////////////////////////////////////////////////////
///
/// Commentaires en français de GO TRONIC
///
////////////////////////////////////////////////////////////////////////
/// @param[in] IRSensorPin broche analogique à laquelle est raccordé le capteur
/// @param[in] delay (msec) Le délai entre les appels de la fonction de balayage.
/// Les meilleurs résultats sont obtenus si vous appelez la fonction 5 fois/pulsation
/// Pas plus lent que 150 ms pour environ 70 pulsations/min.
/// Un délai de 60 ms ou plus rapide pour aller lusqu'à 200 pulsations/min.
///
///
/// @Résumé
/// Sortie Vraie si une pulsation est détectée
/// Ce code détecte seulement les impulsions, il ne donne
/// pas la forme d'onde des impulsions cardiaques.
///
///
////////////////////////////////////////////////////////////////////////
  
int rawValue;
  
  
bool
heartbeatDetected(int IRSensorPin, int delay)
{
 static int maxValue = 0;
 static bool isPeak = false;
  
  
 bool result = false;
  
 rawValue = analogRead(IRSensorPin);
 // La tension au phototransistor est lue et stockée dans la variable rawValue
 rawValue *= (1000/delay);
  
 // Si la valeur de la dernière mesure dévie trop 
 // (par exemple parce que le doigt a été enlevé ou a bougé)
 // maxValue se réinitialise
 if (rawValue * 4L < maxValue) { maxValue = rawValue * 0.8;  }  
 // Detect new peak 
 if (rawValue > maxValue - (1000/delay)) {
 // Détection de l'impulsion. Si la nouvelle rawValue est plus grande
 // que la dernière valeur maximale, elle sera prise en compte en enregistrée
 if (rawValue > maxValue) {
 maxValue = rawValue;
 }
 // Attribution des pulsations
 if (isPeak == false) {
 result = true;
 }
 isPeak = true;
 } else if (rawValue < maxValue - (3000/delay)) {
 isPeak = false;
 // La valeur maximale est légèrement diminuée à chaque passage.
 // Cela peut prendre plusieurs secondes pour détecter de nouveau
 // le signal lorsque le doigt a bougé ou que le capteur est devant
 // une partie osseuse du doigt. On peut aussi vérifier le délai
 // depuis la dernière pulsation et s'il excède 1 seconde, on
 // rénitialise maxValue
 maxValue-=(1000/delay);
 }
 return result;
}
  
  
////////////////////////////////////////////////////////////////////////
// Arduino main code
////////////////////////////////////////////////////////////////////////
int ledPin=13;
int analogPin=0;
  
void setup()
{
 // La LED Arduino intégrée (Digital 13) est utilisée pour la sortie
 pinMode(ledPin,OUTPUT);
  
 // Initialisation de la sortie série
 Serial.begin(9600);
 Serial.println("Exemple de code de détection de pulsations.");
}
  
const int delayMsec = 60; // 100msec per sample
  
// Le programme principal a deux sorties:
// - Si un battement de coeur est détecté, le voyant clignote
// - L'impulsion est calculée et envoyée vers la sortie série.
  
void loop()
{
 static int beatMsec = 0;
 int heartRateBPM = 0;
 Serial.println(rawValue);
 if (heartbeatDetected(analogPin, delayMsec)) {
 heartRateBPM = 60000 / beatMsec;
 // Sortie LED par impulsion
 digitalWrite(ledPin,1);
  
 // Envoi des données série
 Serial.print(rawValue);
 Serial.print(", ");
 Serial.println(heartRateBPM);
  
 beatMsec = 0;
 } else {
 digitalWrite(ledPin,0);
 }
 delay(delayMsec);
 beatMsec += delayMsec;
 }

Téléchargement d'un exemple de programme

KY039-Arduino.zip

Exemple de code Raspberry Pi

Affectation des broches Raspberry Pi

Raspberry Pi Capteur
KY-053 A0 Signal
3,3V [Pin 1] +V
Masse [Pin 6] GND
Capteur KY-053
Signal A0
+V 3,3V [Pin 1]
GND Masse [Pin 6]
Raspberry Pi KY-053
GPIO 3 [Pin 5] SCL
Gpio 2 [Pin 3] SDA

Capteur analogique, il faut donc respecter les points suivants.

Contrairement à l'Arduino, le Raspberry Pi n'a pas d'entrées analogiques ou il n'y a pas d'ADC (convertisseur analogique numérique) intégré dans la puce du Raspberry Pi. Cela limite le Raspberry Pi, si vous voulez utiliser des capteurs, où les valeurs de sortie ne sont pas numériques [valeur de tension dépassée -> valeur numérique ON | valeur de tension sous-cotée -> valeur numérique OFF | exemple : bouton enfoncé [ON] bouton relâché [OFF]], mais il doit s'agir d'une valeur variable continue (exemple : potentiomètre -> autre position = autre valeur de tension).

Pour éviter ce problème, notre kit de capteur X40 a le KY-053, un module avec ADC précis de 16 bits, que vous pouvez utiliser sur le Raspberry pour l'étendre avec 4 entrées analogiques. Il est connecté au Raspberry Pi via I2C, prend en charge la mesure analogique et transmet la valeur numérique au Raspberry Pi.

Ainsi, nous recommandons de connecter le module KY-053 avec ledit ADC entre les capteurs analogiques de cet ensemble. Pour plus d'informations, veuillez consulter la page d'information sur le convertisseur analogique-numérique KY-053.

Le programme utilise les bibliothèques Python ADS1x15 et I2C correspondantes d'Adafruit pour piloter l'ADC ADS1115. Ceux-ci ont été publiés au lien suivant https://github.com/adafruit/Adafruit_CircuitPython_ADS1x15 sous la licence MIT. Les bibliothèques requises ne sont pas incluses dans le paquet de téléchargement ci-dessous.

Le programme utilise l'ADC ADS1115 pour mesurer la valeur de la tension actuelle au niveau de l'ADC, calcule la résistance actuelle de la CTN à partir de celle-ci, calcule la température en utilisant les valeurs déterminées à l'avance pour ce capteur et les transmet à la console.

Veuillez noter que vous devez activer I2C sur votre Raspberry Pi avant d'utiliser cet exemple.

import time
import board
import busio
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

i2c = busio.I2C(board.SCL, board.SDA)

ads = ADS.ADS1115(i2c)

chan0 = AnalogIn(ads, ADS.P0)
chan1 = AnalogIn(ads, ADS.P1)
chan2 = AnalogIn(ads, ADS.P2)
chan3 = AnalogIn(ads, ADS.P3)

if __name__ == '__main__':

   
    # initialization 
    GAIN = 2/3  
    curState = 0
    thresh = 525  # mid point in the waveform
    P = 512
    T = 512
    stateChanged = 0
    sampleCounter = 0
    lastBeatTime = 0
    firstBeat = True
    secondBeat = False
    Pulse = False
    IBI = 600
    rate = [0]*10
    amp = 100

    lastTime = int(time.time()*1000)

    # Main loop. use Ctrl-c to stop the code
    while True:
        # read from the ADC
        Signal = chan0.value   #TODO: Select the correct ADC channel. I have selected A0 here
        curTime = int(time.time()*1000)

        sampleCounter += curTime - lastTime;
        lastTime = curTime
        N = sampleCounter - lastBeatTime;
       

        ##  find the peak 
        if Signal < thresh and N > (IBI/5.0)*3.0 :
            if Signal < T :
              T = Signal;

        if Signal > thresh and  Signal > P:
            P = Signal;

         
          # signal surges up in value every time there is a pulse
        if N > 250 :
            if  (Signal > thresh) and  (Pulse == False) and  (N > (IBI/5.0)*3.0)  :       
              Pulse = True;
              IBI = sampleCounter - lastBeatTime;
              lastBeatTime = sampleCounter;

              if secondBeat :
                secondBeat = False;
                for i in range(0,10):
                  rate[i] = IBI;                      

              if firstBeat :
                firstBeat = False;                   
                secondBeat = True;
                continue                              


              # keep a running total of the last 10 IBI values
              runningTotal = 0;

              for i in range(0,9):
                rate[i] = rate[i+1];                   
                runningTotal += rate[i];              

              rate[9] = IBI;                          
              runningTotal += rate[9];                
              runningTotal /= 10;                     
              BPM = 60000/runningTotal;               
              print ('BPM: {}'.format(BPM))

        if Signal > thresh and Pulse == True :
            Pulse = False;                         
            amp = P - T;                           
            thresh = amp/2 + T;                    
            P = thresh;                            
            T = thresh;

        if N > 2500 :
            thresh = 512;
            P = 512;
            T = 512;
            lastBeatTime = sampleCounter;
            firstBeat = True;
            secondBeat = False;
            print ("no beats found")

        time.sleep(0.005)

Exemple de téléchargement de programme

KY039-RPi.zip

Pour commencer avec la commande :

sudo python3 KY039.py

Exemple de code Micro:Bit

Affectation des broches Micro:Bit :

Micro:Bit Sensor
3V +V
Masse GND
Pin 2 Signal

Ceci est un exemple MakeCode pour Micro:Bit qui fait essentiellement la même chose que les exemples des deux autres variantes. Cependant, cet exemple est fondamentalement plus lent que les deux autres variantes. Dans cet exemple, il convient de noter que la case intitulée "numéro de série de la sortie" doit être supprimée après avoir défini la requête "if" située en dessous, car elle n'existe que dans ce seul but et ne doit donc être utilisée que la première fois que le capteur est utilisé. Par conséquent, il peut être retiré du code en toute sécurité après la première utilisation.