IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Raspberry Pi Discussion :

Acquisition de donnée physiologique avec Raspbery Pi 2


Sujet :

Raspberry Pi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2014
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2014
    Messages : 16
    Par défaut Acquisition de donnée physiologique avec Raspbery Pi 2
    Bonjour,
    Je suis en train de réaliser un boitier permettant d’acquérir des données physiologiques telles que l'activité cardiaque et respiratoire. Pour cela j'ai mis en oeuvre un convertisseur analogique-numérique (un MCP3208) et une Raspberry Pi 2 qui communique via un bus SPI. Je doit donc acquérir 3 données analogiques simultanément à une fréquence de 1000Hz. J'ai pour cela mis en oeuvre ce code globalement fonctionnel cependant je me suis rendu compte que la fréquence plafonnait aux environ de 80Hz ce qui est très loin de mes exigences... Auriez-vous donc des conseils à me donner afin d'optimiser ce code afin d'augmenter de façon significative ma fréquence d’échantillonnage ?

    Merci d'avance

    Tom

    Code :

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
     
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    #include <stdlib.h>
    #include <time.h>
     
    #include <wiringPi.h>
    #include <wiringPiSPI.h>
     
    #define CS_MCP3208  8
     
    #define SPI_CHANNEL 0
    #define SPI_SPEED   100000000
     
     
    int read_mcp3208_adc(unsigned char adcChannel)
    {
        unsigned char buff[3];
        int adcValue = 0;
     
        buff[0] = 0x06 | ((adcChannel & 0x07) >> 7);
        buff[1] = ((adcChannel & 0x07) << 6);
        buff[2] = 0x00;
     
        digitalWrite(CS_MCP3208, 0);
     
        wiringPiSPIDataRW(SPI_CHANNEL, buff, 3);
     
        buff[1] = 0x0F & buff[1];
        adcValue = ( buff[1] << 8) | buff[2];
     
        digitalWrite(CS_MCP3208, 1);
     
        return adcValue;
    }
     
     
    int main (void)
    {
        int adc1Channel = 0;
        int adc1Value   = 0;
        int adc2Channel = 1;
        int adc2Value   = 0;
        int adc3Channel = 2;
        int adc3Value   = 0;
     
        if(wiringPiSetup() == -1)
        {
            fprintf (stdout, "Unable to start wiringPi: %s\n", strerror(errno));
            return 1 ;
        }
     
        if(wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1)
        {
            fprintf (stdout, "wiringPiSPISetup Failed: %s\n", strerror(errno));
            return 1 ;
        }
     
        FILE *fp;
        fp = fopen("mesureEDP.csv", "a");
        if(fp == NULL){
            printf("cannot open the file");
            return -1;
            }
        fprintf(fp, "Ecg	Resp1	Resp2\n"); 
        pinMode(CS_MCP3208, OUTPUT);
     
        while(1)
        {
            adc1Value = read_mcp3208_adc(adc1Channel);
           	adc2Value = read_mcp3208_adc(adc2Channel);
            adc3Value = read_mcp3208_adc(adc3Channel);
            printf("ECG = %d\t", adc1Value);
           	printf("Resp1 = %d\t", adc2Value);
            printf("Resp2 = %d\n", adc3Value);
            fprintf(fp, "%d\t", adc1Value);
           	fprintf(fp, "%d\t", adc2Value);
            fprintf(fp, "%d\n", adc3Value);
            system("clear");
            usleep(1000);
        }
        fclose(fp);
        return 0;
    }

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 497
    Billets dans le blog
    1
    Par défaut
    1000 Hz pour une fréquence cardiaque et un rythme respiratoire ?? Ca ne te parait pas un peu délirant ?

    Pour moi, il y a déjà un problème dans ton programme : à chaque tour de boucle, tu fais tes actions (qui prennent donc un certain temps) puis que tu endors ton programme pendant 1000 µs, soit 1 ms. Ainsi, chaque itération dure plus d'une milliseconde, c'est obligatoire. Or, tu souhaites échantillonner à 1000 Hz, c'est-à-dire réaliser un échantillon toutes les millisecondes....

  3. #3
    Membre averti
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2014
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2014
    Messages : 16
    Par défaut
    Bah je travail avec un cardiologue chercheur qui à besoin d'une fréquence élevé pour ces recherches...

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 497
    Billets dans le blog
    1
    Par défaut
    OK, on n'est donc pas dans la simple acquisition de la fréquence cardiaque mais de tous les mouvements du coeur.

    J'ai modifié mon précédent message entre temps... Je t'invite à le relire. Je réfléchis un peu d'ici là.

  5. #5
    Membre averti
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2014
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2014
    Messages : 16
    Par défaut
    Tout d'abord merci pour ta réponse rapide !
    Oui en ce qui concerne la fonction sleep je me suis bien rendu compte qu'elle n'était pas idéale, cependant j'ai cherché à utiliser la technique d'interruption mais je n'ai pas trouvé comment la mettre en œuvre dans un programme C sur Raspberry (si vous avez des idées là dessus je suis preneur)
    Sinon avant de s'attarder plus sur le sujet pensez-vous que la Raspberry est suffisamment puissante pour ce type de projet ?

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 497
    Billets dans le blog
    1
    Par défaut
    Je pense que le Raspberry pourra tout à fait supporter une telle charge. En tout cas, je l'espère ! Je ne connais pas trop les performances de cette plateforme mais ça ne me parait pas fou fou comme tâche. Tu peux regarder quelques articles de C. Blaess, il fait joujou avec les GPIO et atteint de bonnes fréquences :
    http://www.blaess.fr/christophe/2014...-de-frequence/
    http://www.blaess.fr/christophe/2012...-raspberry-pi/

    En revanche, il faudra construire intelligemment ton programme pour y arriver. La solution simple que je vois comme ça est la suivante :
    - Créer un timer qui se déclenche une interruption toutes les millisecondes (ce qui donne une fréquence de 1000 Hz). Tu trouveras des tuto sur le net pour faire ça. Je crois que C. Blaess en utilise un dans le 2e lien.
    - L'action périodique du timer est de faire les lectures qui vont bien et de pousser les résultats dans une file d'attente (queue).
    - En fond, un thread vient dépiler les éléments de la queue : mettre en forme les données, les filtrer, les enregistrer dans un fichier.

    Il est possible que tout fonctionne dans l'action du timer, à tester. Mais il faut alors bannir les affichages en console (cout, printf, puts ou trucs dans le genre), c'est lent comme la mort. Il faut aussi se méfier des écritures vers les fichiers, ça peut prendre du temps.

    L'intérêt de passer par une file est de découpler les traitements.
    - D'un côté, tu as un producteur : il lit les données et les pousse dans la file. Tu pourras éventuellement optimiser la manière de lire (je vois par exemple que tu sembles et allumer ton convertisseur à chaque fois, est-ce nécessaire ?)
    - De l'autre, tu as un consommateur : il récupère les données et les traite. Tu peux ainsi tester plusieurs stratégies de récupération. Notamment, tu pourras facilement adopter une nouvelle stratégie pour bufferiser plusieurs données et les écrire en une seule fois et ainsi limiter les accès aux fichiers.

    Le producteur étant cadencé par le timer, il préemptera le consommateur pour respecter la contrainte temps réel d'un acquisition toutes les millisecondes.

Discussions similaires

  1. Réponses: 10
    Dernier message: 04/08/2015, 20h59
  2. Acquisition de données avec un ActiveX External Interface
    Par Mjama dans le forum Interfaces Graphiques
    Réponses: 0
    Dernier message: 14/09/2010, 23h43
  3. Acquisition de données Agilent PSA E4440 avec Labview
    Par savoma2000 dans le forum LabVIEW
    Réponses: 1
    Dernier message: 04/08/2008, 16h55
  4. Probleme avec l'acquisition des données dans un port dans le serveur
    Par soufian2290 dans le forum Serveurs (Apache, IIS,...)
    Réponses: 12
    Dernier message: 04/11/2007, 12h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo