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

  1. #41
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 28
    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
    Points : 4
    Points
    4
    Par défaut
    Le code marche! Il suffisait de calculer la variable tour dans le loop et non dans attachinterrupt. Je ne sais pas pourquoi ça ne fonctionnait pas mais là ça va. Merci à tous

  2. #42
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 647
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 647
    Points : 11 136
    Points
    11 136
    Par défaut
    Je suis perplexe, on peut voir ton code ?

  3. #43
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    Septembre 2008
    Messages
    1 267
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 267
    Points : 4 829
    Points
    4 829
    Par défaut
    Bonsoir

    Moi je ne comprends pas la modification, car tour n'est jamais calculé:
    - Il est initialisé à 0 dans le setup()
    - Il est remit à 0 après chaque envoi de résultat sur le moniteur série dans le loop() pour le 1er programme, et dans l’interruption pour le 2ème programme.
    - Et il est incrémenté à chaque interruption, et cela doit être dans l'interruption.

    Donc comme Auteur, j'aimerais bien voir le code qui marche, merci d'avance

    Bonne soirée

    Delias

  4. #44
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 28
    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
    Points : 4
    Points
    4
    Par défaut
    J'ai une prof qui s'est aperçue que le comptage de la variable tour se faisait normalement lorsqu'il est compté dans le loop. J'ai donc modifié le programme pour qu'à chaque front descendant le calcul se fasse dans le loop. Ensuite, avec la fonction fournie par delias je me suis aperçue que la variable se comptait en doublon à chaque passage du trou. J'en ai déduit que cela devait être du à la grosseur du trou (6mm de diamètre). Voilà donc mon code qui m'a tout l'air de marcher
    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
    64
    65
    66
    67
    68
    69
    //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
    const int n=100;  //nombre de tours du disque avant de faire le calcul de vitesse
    unsigned long dT;
    volatile bool mesuredispo; //permet l'affichage lorsqu'une nouvelle mesure est disponible
    volatile bool ok; //permet de savoir si le disque a fait exactement un tour
     
    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();
      mesuredispo=false;
     
      //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 un tour du disque
      if (ok){
        ok=0;
        tour++; //à cause de la surface du trou à chaque passage du trou la valeur tour augmente de 2
      }
       //si il y a eu n tour du disque
      if (tour >= n){
        // trmin= (n* 60000)/ (2*temps écoulé pour faire n tours du disque en minute 1min=60 000ms 
        //on divise par 2 pour corriger l'écart
        //entre millis et temps il y a eu exactement 1 tour
        dT=millis()-temps;
        trmin= ((unsigned long)60000*n)/(2*dT); 
        Mesure++;
        mesuredispo=true;
      }
     
      if (mesuredispo){
        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;
        mesuredispo=false;
      }
    }
     
    //Dès qu'il y a 1 nouveau tour on appelle  la fonction
    void nouveauTourInterrupt() {
      ok=1;
      }

  5. #45
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    Septembre 2008
    Messages
    1 267
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 267
    Points : 4 829
    Points
    4 829
    Par défaut
    Bonjour

    Tu crées un anti-rebond, l’interruption est probablement appelée 2x avant que le code dans le if (ok) n'aie été appelé.
    Si tu avais mesuré le temps entre chaque interruption, tu aurais probablement des durées de 0 ou 1 ms, séparées par des durées plus longues correspondant à 1 tour (20ms à 3000tpm).

    Pour cela il faudrait avoir un code dans cette idée (écrit en direct et non testé), 20 et 60 gageraient à être des constantes:
    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
    ...
    volatile unsigned long temps[20];
    ...
     
    void loop() {
      if (tour>60) {
        for (int i = 1; i<20; i++){
          Serial.println(temps[i] - temps[i-1]);
        }
      tour = 0;
      }
    }
     
    void nouveauTourInterrupt() {
      tour++;
      if (tour<20) {
        temps[tour] = millis();
      }
    }
     
    }

  6. #46
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Hummm.... C'est pas normal tout ça, ça sent la solution qui masque un bug sans pour autant l'avoir résolu ! C'est le pire cas de figure en développement car si ce bug se réveille on ne sait pas où chercher (puisqu'on croit l'avoir résolu)

    Est ce qu'on peut voir la tête du signal, à l'oscilloscope, qui sort du capteur lorsque le disque tourne ?
    -Faire une copie d'écran lorsque le capteur est simplement alimenté et non connecté à l'entrée d'interruption du Arduino
    - Faire une copie d'écran lorsque tout est connecté (alimentation + signal au Arduino)

    Je me demande si le signal est "Franc" et si il n'y a une espèce de jitter ?
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

+ Répondre à la discussion
Cette discussion est résolue.
Page 3 sur 3 PremièrePremière 123

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