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

Arduino Discussion :

Calcul de vitesse de rotation avec capteur optique et arduino uno


Sujet :

Arduino

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 29
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2017
    Messages : 26
    Par défaut Calcul de vitesse de rotation avec capteur optique et arduino uno
    Bonjour,

    Je voudrais calculer la vitesse de rotation d'un disque fixé sur un arbre moteur avec un capteur optique. J'ai codé cela sur Arduino mais cela ne fonctionne pas. Je me suis aperçue que le problème vient de la fonction qui compte le nombre de tours du disque mais je ne vois pas comment le régler.
    Voici mon code

    Code : 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
     
    //capteur port OUT relié au pin2 de l'arduino
    const int pinCapteur=2;//on utilise le pin 2 (avec arduino uno pin 2 ou 3 pour les interruptions)
    // pour le pin2 l'interruption se fait sur le pin0
     
    // Initialisation des variables
    unsigned int Mesure; //variable qui compte le nombre de mesures
    float trmin; // variable qui affichera la vitesse du disque en tour/min
    unsigned long temps; //sert à déterminer le temps que met le disque pour réaliser exactement un tour
    volatile int tour; //compte le nombre de tours du disque
    const int n=100;  //nombre de tours du disque avant de faire le calcul de vitesse
    float dT;
     
    void setup() {
      Serial.begin(9600);   //connection au port série 
      pinMode(pinCapteur, INPUT); //connection du capteur au pin2 de l'arduino
     
      //Initialisation des variables
      tour=0;
      trmin=0;
      Mesure=0;
      temps=millis(); 
     
      //on appelle la fonction NouveauTourInterrupt dès qu'il y a un changement d'état abscence(HIGH) vers présence(LOW) du trou du disque, c'est à dire dès que le disque fait exactement un tour
      //attachInterrupt(interruption,fonction,mode)
      attachInterrupt(0,nouveauTourInterrupt,FALLING);
    }
     
    void loop() {
     
     
      // si il y a eu n tours du disque
      if (tour >= n){
        //on arrête l'interruption pendant le calcul
        //detachInterrupt(0);
        // trmin= (n* 60000)/ (temps écoulé pour faire n tours du disque en minute 1min=60 000ms
        //entre temps2 et temps1 il y a eu exactement 1 tour
        dT=millis()-temps;
        trmin= ((unsigned long)60000*n)/(dT); 
        Mesure++;
     
        Serial.print("Mesure:");
        Serial.print(Mesure);
        Serial.print("vitesse en tour/min: ");
        Serial.println(trmin);
        //Serial.print("nb de tours: ");
        //Serial.println(tour);
        //Serial.print("temps entre deux mesures en ms: ");
        //Serial.println(dT);
         //Réinitialisation du temps et du nombre de tours
        temps=millis();
        tour=0;
     
        //on recommence les interruptions
        attachInterrupt(0,nouveauTourInterrupt,FALLING);
      }
     
    }
    //Dès qu'il y a 1 nouveau tour on appelle  la fonction
    void nouveauTourInterrupt() {
      tour++;
      //Serial.println(tour);
    }
    Je compte sur vous!

  2. #2
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    bonjour,

    enlève le attachInterrupt dans ta fonction loop.
    https://www.arduino.cc/en/Reference/AttachInterrupt

  3. #3
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 29
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2017
    Messages : 26
    Par défaut
    J'ai déjà essayé en enlevant attach et detach mais ça n'arrange pas le problème

  4. #4
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    J'ai relu ton code et je crois que tu n'as pas complètement saisi le fonctionnement des interruptions. Il est clair que dans ton cas c'est plus intéressant de les utiliser.

    Mais :
    - dans le setup, tu vas initialiser tes variables et créer ton interruption.
    - dans le loop(), tu ne fais (presque) rien
    - dans la fonction appelée pour chaque interruption tu fais ton calcul !

    Par contre, les variables utilisées dans la fonction d'interruption doivent être déclarées en volatile.

    Voilà comment je vois un peu les choses :
    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
     
    const int pinCapteur = 2;  // voie d'entrée du capteur
    volatile unsigned long t2, t1, dt;  // gestion du temps
    volatile bool flag;   // flag pour avertir qu'une nouvelle donnée est disponible.
     
    setup()
    {
        Serial.begin(9600);   //connection au port série 
        pinMode(pinCapteur, INPUT);
     
        // création de l'interruption
        attachInterrupt( digitalPinToInterrupt(pinCapteur), nouveauTourInterrupt, FALLING );
     
        t2 = millis();
        t1 = t2;
        flag = false;
     
    }
     
    loop()
    {
        // rien à faire ici, sauf affichage avec Serial.println()
        // ne pas appeler serial.println() dans une fonction d'interruption
        if (flag)  // nouvelle donnée disponible
        {
            serial.println(dt);
            flag = false;
        }
    }
     
    void nouveauTourInterrupt()
    {
        t2 = millis();  
        dt = t2-t1;  // temps écoulé entre 2 appels à millis
        // calculs sur dt
     
        t1 = t2:   
        flag = true; //pour informer dans le loop qu'une nouvelle donnée est disponible pour l'affichage.
    }

  5. #5
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 29
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2017
    Messages : 26
    Par défaut
    Pour plus de précision lors du calcul je voudrais faire mon calcul non pas à chaque passage du trou devant le capteur mais tous les n passages. J'ai essayé d'adapter les recommandations à mon code. Quand je le vérifie il y a le message d'erreur " exit status 1 'nouveauTourInterrupt was not delared in this scope "

    Code : 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
    //capteur port OUT relié au pin2 de l'arduino
    const int pinCapteur=2;//on utilise le pin 2 (avec arduino uno pin 2 ou 3 pour les interruptions)
    // pour le pin2 l'interruption se fait sur le pin0
     
    // Initialisation des variables
    volatile unsigned int Mesure; //variable qui compte le nombre de mesures
    volatile float trmin; // variable qui affichera la vitesse du disque en tour/min
    volatile unsigned long temps; //sert à déterminer le temps que met le disque pour réaliser exactement un tour
    volatile int tour; //compte le nombre de tours du disque
    volatile const int n=100;  //nombre de tours du disque avant de faire le calcul de vitesse
    volatile unsigned long dT;
     
    void setup() {
      Serial.begin(9600);   //connection au port série 
      pinMode(pinCapteur, INPUT); //connection du capteur au pin2 de l'arduino
     
      //Initialisation des variables
      tour=0;
      trmin=0;
      Mesure=0;
      temps=millis(); 
     
      //on appelle la fonction NouveauTourInterrupt dès qu'il y a un changement d'état abscence(HIGH) vers présence(LOW) du trou du disque, c'est à dire dès que le disque fait exactement un tour
      //attachInterrupt(interruption,fonction,mode)
      attachInterrupt(0,nouveauTourInterrupt,FALLING);
    }
     
    void loop() {
      }  
    }
     
    //Dès qu'il y a 1 nouveau tour on appelle  la fonction
    void nouveauTourInterrupt() {
      tour++;
       // si il y a eu n tours du disque
      if (tour >= n){
        // trmin= (n* 60000)/ (temps écoulé pour faire n tours du disque en minute 1min=60 000ms
        //entre temps2 et temps1 il y a eu exactement 1 tour
        dT=millis()-temps;
        trmin= ((unsigned long)60000*n)/(dT); 
        Mesure++;
     
        Serial.print("Mesure:");
        Serial.print(Mesure);
        Serial.print("vitesse en tour/min: ");
        Serial.println(trmin);
        //Serial.print("nb de tours: ");
        //Serial.println(tour);
        //Serial.print("temps entre deux mesures en ms: ");
        //Serial.println(dT);
        //Réinitialisation du temps et du nombre de tours
        temps=millis();
        tour=0;
      //Serial.println(tour);
    }

  6. #6
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    Il y a une accolade en trop

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 12
    Dernier message: 27/03/2017, 01h05
  2. Capteur de vitesse de rotation d'un banc d'essai
    Par TinyFactory dans le forum LabVIEW
    Réponses: 1
    Dernier message: 17/03/2017, 09h30
  3. Réponses: 1
    Dernier message: 28/06/2011, 15h51
  4. Comment faire des calculs de Rotation avec Ogre
    Par Rumpel dans le forum Ogre
    Réponses: 0
    Dernier message: 22/07/2009, 18h15
  5. Calculer un inverse de matrice avec boost?
    Par Clad3 dans le forum Bibliothèques
    Réponses: 6
    Dernier message: 02/06/2005, 18h38

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