Skyduino:~#
Articles
arduino, pic ccs, programmation, projet

DIY Cardio fréquencemètre standalone ou arduino

Les projets s’enchaine et en voila encore un nouveau !

Ce coup ci je vais vous faire une présentation rapide du projet.

Ce cardio est était mon projet de bac j’ai décidé de le remettre au gout du jour avec un version “breakout” pour mon arduino.

J’ai appelé cette breakout du doux nom de mini-cardio (que c’est original …)

Pour les impatients chronique voici la video !

Pour les autres le principe :

On capte le signal cardiaque au moyen de trois électrodes, ce signal est ensuite amplifié une premier fois dans un amplificateur d’instrumentions, puis une seconde fois par un passe bande, en sortie on obtient alors un signal cardiaque propre et nette (comme dans docteur house).

Le programme de la version complète de la carte pic avec le 16F876A (version original sous ccs-compiler)

/*
* CARTE CARDIO FREQUENCEMETRE
*
*/

// INCLUDE
#include "C:\PICC\Devices\16F876A.h" // Include du header pour le pic

// FUSES
#FUSES NOWDT                         // Désactivation Watch Dog
#FUSES XT                            // Oscillateur Crystal 4mhz
#FUSES PUT                           // Activation du Power-Up Timer
#FUSES NOPROTECT                     // Désactivation protection code
#FUSES NOBROWNOUT                    // Désactivation du reset sur base tension
#FUSES NOLVP                         // Désactivation programmation basse tension
#FUSES NOCPD                         // Désactivation protection EEPROM
#FUSES NOWRT                         // Désactivation protection zone mémoire
#FUSES DEBUG                         // Activation du debugage ICD2

// USE
#use delay(clock=4000000)            // Définition de la fréquence d'horloge
#use i2c(SLAVE, I2C1, address=0xFB)  // Définition du bus i2c

// INTERRUPT PRIORITY
#priority TIMER2,EXT,SSP             // Priorité des interruptions

// VARIABLE

volatile long temps;                 // Définition de la variables contenant le temps entre 2 interruptions
volatile long tick[5];               // Définition du tableau contenant les valeurs prise par temps sur 5 interruptions
volatile int frequence;              // Définition de la variables contenant la fréquence
volatile int index;                  // Définition de la variables contenant l'index courant du tableau tick
volatile long moyenne;               // Définition de la variables contenant la moyenne de temps sur 5 sample

/* ----------------------- DEBUG PURPOSE ONLY ----------------------- */
#define DEBUG_PURPOSE 1              // Enable debug function         */
#if defined(DEBUG_PURPOSE)           // Debug function
#define EXT_INT_DebugPin PIN_B5      // Pin pour debug des intteruptions externe sur INT0
#define TIMER2_INT_DebugPin PIN_B4   // Pin pour debug des intteruptions interne sur TIMER2
#endif
/*------------------------------------------------------------------- */

#INT_EXT                             // Interruption sur front descendant de INT0
void int_ext_isr()
{

	clear_interrupt(INT_EXT);        // Suppression du flag d'interruption

	tick[index] = temps;             // On sauvegarde dans le tableau a l'index courant la valeur

	temps = 0;                       // Réinitialisation du compteur de ms

	int i;
	for(i=0;i= 0)              // BPM > 0
		output_low(PIN_A0);          // DEL -> Level 1

	if (frequence >= 25)             // BPM >= 25
		output_low(PIN_A1);          // DEL -> Level 2

	if (frequence >= 50)             // BPM >= 50
		output_low(PIN_A2);          // DEL -> Level 3

	if (frequence >= 75)             // BPM >= 75
		output_low(PIN_A3);          // DEL -> Level 4

	if (frequence >= 125)            // BPM >= 125
		output_low(PIN_A4);          // DEL -> Level 5

	if (frequence >= 150)            // BPM >= 150
		output_low(PIN_A5);          // DEL -> Level 6

}

#INT_TIMER2                          // Interruption sur overflow TIMER2 (~1ms)
void TIMER2_isr()
{

	temps ++;                        // Incrémentation du compteur de ms

	/* ----------------------- DEBUG PURPOSE ONLY ----------------------- */
#if defined(DEBUG_PURPOSE)           // Debug function
	output_toggle(TIMER2_INT_DebugPin);  // Pulse pour debug à l'oscilloscope
#endif
	/* ------------------------------------------------------------------ */

}

/* /!\ PARTIE I2C EN PHASE DE TEST /!\ */
#INT_SSP                             // Interruption sur reception de donnée I2C
void ssp_interupt ()
{

   clear_interrupt (INT_SSP);        // Suppression du flag d'interruption

   BYTE donnein, etatbus;            // declaration des variables

   etatbus = i2c_isr_state();        // On recupére l'etat du bus i2c

   if(etatbus    {
      donnein = i2c_read();          // On recoit les données
   }
   if(etatbus == 0x80)               // Le maitre demande des données
   {
      i2c_write(frequence);          // On envoie les données
   }

}

void main()                          // Fonction principal
{

	// Configuration des sortie
	Set_tris_A (0x00);               // PORTA en sortie

	/* ----------------------- DEBUG PURPOSE ONLY ----------------------- */
#if defined(DEBUG_PURPOSE)           // Debug function
	Output_A (0x00);                 // D0~D5 ON
	delay_ms(1000);                  // Attente de 1s
	Output_A (0xFF);                 // D0~D5 OFF
#endif
	/* ------------------------------------------------------------------ */

	// Initialisation des variable
	frequence = 0;                   // Initialisation de la variables
	index =0;
	moyenne =0;
	int i;
	for(i=0;i		tick[i] = 0;                        // Initialisation de la variables

	// Désactivation du CAN
	setup_adc_ports (NO_ANALOGS);    // Désactivation des ports CAN
	setup_adc (ADC_OFF);             // Désactivation du CAN

	// Configuration du TIMER1 et du CCP1
	ext_int_edge( H_TO_L );          // Capture d'un front descendant sur INT0_EXT
	setup_timer_2(
		T2_DIV_BY_4, 249, 1);        // Timer 1ms

	// Configuration des interruptions
	clear_interrupt(INT_EXT);        // Suppression du flag d'interruption
	enable_interrupts (INT_EXT);     // Déclenchement de l'interruption EXT

	clear_interrupt(INT_SSP);        // Suppression du flag d'interruption
	enable_interrupts (INT_SSP);     // Déclenchement de l'interruption SSP

	clear_interrupt(INT_TIMER2);     // Suppression du flag d'interruption
	enable_interrupts (INT_TIMER2);  // Déclenchement de l'interruption TIMER2

	enable_interrupts (GLOBAL);      // Activation des interruptions

	while(1);                        // Blocage Permanent (laisse travaille les interuptions)
}

Le schéma de la version complète de la carte pic avec le 16F876A

Lien à la base du projet:
http://fabrice.sincere.pagesperso-orange.fr/cm_electronique/projet_pic/cardiogramme/cardiogramme.htm

http://fr.wikipedia.org/wiki/Électrocardiographie

Le schéma de la version breakout pour arduino:

et une petite capture d’oscilloscope pour les fans de docteur house:

photo :

Advertisements

Discussion

16 réflexions sur “DIY Cardio fréquencemètre standalone ou arduino

  1. Bonjour
    Ca devrait bien me plaire
    Je vais y regarder de plus prés dès que j’ai un peu de temps
    La version Arduino me plait bien
    Merci

    Publié par Patrice | 13 mars 2012, 19 h 21 min
  2. Pas mal, je vais faire un lien

    Publié par soum | 11 septembre 2012, 23 h 46 min
  3. Bonjour,

    Je suis tombé sur cet article en testant une idée de vouloir réaliser un petit cardio-fréquencemètre …

    Par contre je voudrais le rendre « stand alone », portable… histoire de pouvoir faire du sport avec par exemple… et récupérer les datas ensuite (donc les stocker en attendant de les décharger) …ou transmettre sans fil…

    Est-ce que vous croyez cela possible ? (possible de me contacter par mail direct)

    Cordialement,

    Paul

    Publié par sapym | 17 novembre 2013, 16 h 00 min
  4. Bonjour,
    Je vous remercie pour cette vidéo 🙂
    pour le TLC274 dans le bloc U5:A, es que vous pourriez m’expliqué son rôle, et mercii 🙂

    Publié par Skyrim | 6 octobre 2014, 17 h 57 min
    • C’est le générateur de référence à VCC/2, c’est lui qui injecte une tension suffisante pour avoir un retour de valeur sur l’étage différentiel.

      Publié par Skywodd | 6 octobre 2014, 19 h 52 min
      • Merci pour votre aide 🙂
        mais on ne peut pas juste relier directement l’électrode de la cheville à la référence de l’étage différentielle ?

        Publié par Skyrim | 7 octobre 2014, 12 h 48 min
      • >> mais on ne peut pas juste relier directement l’électrode de la cheville à la référence de l’étage différentielle ?

        Si tu fais ça tu ne capteras que du bruit mais pas de signal.
        Le signal à VCC/2 sert de référence et injecte un tout petit peu de courant dans le corps pour que l’étage différentiel capte quelque chose par la suite.

        Publié par Skywodd | 8 octobre 2014, 14 h 28 min
  5. Bonjour
    Pourriez- vous m’expliquer le rôle de l’amplificateur qui est relier avec la jambe droite du sujet, ainsi que le rôle de l’avant dernier bloc(out amplifier). Est ce que il y différence entre la jambe droite et la jambe gauche, et merci :).

    Publié par najet | 7 octobre 2014, 21 h 18 min
    • C’est pas moi qui ai écris l’article en lien en fin de page.
      Mais dans les fait c’est juste une référence à VCC/2 avec une compensation dynamique pour limiter le bruit.

      Publié par Skywodd | 8 octobre 2014, 14 h 32 min
      • Merci pour votre aide,
        SVP concernant le dernier étage (output Amplifier) juste avant le nœud A, quelle est son rôle exactement ? et merci 🙂

        Publié par najet | 8 octobre 2014, 23 h 31 min
      • C’est un ampli à gain variable pour régler le niveau d’amplitude du signal en sortie du filtre.

        Publié par Skywodd | 9 octobre 2014, 23 h 14 min
  6. Ce n’est pas qu’un cardio frequencemetre, on peut carrément avoir les 6 derivations du plan frontal de goldberger. C’est un un vrai ECG, en plus le signal est plutôt net compte tenu de la différence de potentiel < 1mV en général. Je suis vraiment subjugué par la simplicité du montage et la qualité du signal de sortie, c'est vraiment la classe. Bravo

    Publié par Hocquard | 13 décembre 2014, 17 h 40 min
    • Le résultat est effectivement assez propre (en tout cas, beaucoup plus que ce que j’avais espéré) mais cette version reste vraiment simpliste 😉
      Il y aurait facilement moyen d’améliorer le montage (asservissement de la tension de référence en fonction du bruit, protection anti ESD, filtrage actif, etc.).

      Publié par Skywodd | 15 décembre 2014, 15 h 06 min

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

Skyduino devient Carnet du Maker

Le site Carnet du Maker remplace désormais le blog Skyduino pour tout ce qui touche à l'Arduino, l'informatique et au DIY.