[Numérique] problème acquisition haute fréquence codeur incrémental
Répondre à la discussion
Affichage des résultats 1 à 23 sur 23

problème acquisition haute fréquence codeur incrémental



  1. #1
    Tom9595

    problème acquisition haute fréquence codeur incrémental


    ------

    Bonjour tout le monde,

    Pour faire bref, je dois mesurer la vitesse de rotation d’un moteur brushless pour pouvoir établir un modèle.
    Pour cela j’utilise un codeur incremental rotatif de 600 pas par tour
    ( https://www.amazon.fr/Kuuleyn-incrém...A2IIY1FG6751PP ).

    Je peux acquérir la vitesse de rotation pour une fréquence maximale de 50 tours par secondes environ.
    Ensuite, lorsque j’augmente la vitesse de rotation du moteur, je perçois une vitesse qui devient nulle, et je ne sais pas d’où vient le problème.
    Je ne sais pas si le problème vient de mon code, d’Arduino, du codeur lui même ou bien d’autre par.
    Je vous fourni mon code ci-dessous.
    J’espère que quelqu’un pourra m’éclairer.

    Code:
    volatile unsigned int counter = 0;  //This variable will increase on the rotation of encoder
     
    unsigned long lastTime = 0;         // will store last time value was sendt
    const long interval = 100;         // interval at which to send result in milli second.  1000 ms = 1 second
     
     
    void setup() {
      Serial.begin (19200);
     
      pinMode(2, INPUT);           // set pin to input
      digitalWrite(2, HIGH);       // turn on pullup resistors
     
      //Setting up interrupt
      //A rising pulse from encodenren activated ai0(). AttachInterrupt 0 is DigitalPin nr 2 on moust Arduino.
      attachInterrupt(0, ai0, RISING);
     
    }
     
    void loop() {
     
      // Chedk if it's time to sendt data
      if(timeIntervall()) {
       sendData();
        resetSampling();
       
      }
    }
     
    void ai0() {
      // ai0 is activated if DigitalPin nr 2 is going from LOW to HIGH
     
      counter++;
    }
     
    void sendData() {
      Serial.print("Pulse pr second = ");      // Sending cout / time
      float speedOut=counter*10/600;            //tour par seconde =counter/(intervalle*nombre de pas du capteur)
      Serial.println(speedOut);
     
    }
     
    void resetSampling() {
      counter = 0;
     
    }
     
    boolean timeIntervall() {
      unsigned long currentTime = millis();
     
      // Chedk if it's time to make an interupt
      if (currentTime - lastTime >= interval) {
        lastTime = lastTime + interval;
     
        return true;
      } else if (currentTime < lastTime) {
        // After 50 day millis() will start 0 again
        lastTime = 0;
     
      } else {
        return false;
      }
     
    }

    PS : je maîtrise très peu le c++ et je manque de temps et connaissance pour trouver l’erreur ( vive les TIPE en CPGE …).

    -----
    Dernière modification par gienas ; 04/04/2023 à 21h42. Motif: Ajouté les balises code, obligatoires pour les programmes

  2. #2
    jiherve

    Re : problème acquisition haute fréquence codeur incrémental

    bonsoir
    600 pas par tour à 50 Tours par seconde cela fait 30kHz je doute que ton programme suive!
    JR
    l'électronique c'est pas du vaudou!

  3. #3
    Tom9595

    Re : problème acquisition haute fréquence codeur incrémental

    Bonjour JR,

    La fréquence d’exécution de mon arduino uno est de 8 MHz d’après ce que j’ai vu sur internet. Donc le programme devrait tenir non ? ( ou alors la fréquence mentionnée de 8MHz n’est pas la même que celle du programme).

  4. #4
    jiherve

    Re : problème acquisition haute fréquence codeur incrémental

    re
    la fréquence indiquée est celle de l'horloge interne, la majorité des instructions machine durent un cycle de cette horloge, mais ton code haut niveau demande plusieurs dizaines voire centaines d'instructions machine par ligne ex:
    float speedOut=counter*10/600 çà c'est plusieurs centaines avec une periode de 125ns en supposant 200 cycles cela fait 20µS et tes pulses se succèdent à 33µS donc çà coince!
    il faut passer par l'usage des timer pour assurer le comptage : le timer 1 pourra compter les pulses pendant une durée définie par l'un des deux autre.
    essayes de trouver un code arduino pour fréquencemètre.
    JR
    l'électronique c'est pas du vaudou!

  5. A voir en vidéo sur Futura
  6. #5
    mag1

    Re : problème acquisition haute fréquence codeur incrémental

    Bonjour,
    Je vois pas bien l'utilité d'un codeur 600 pas/tour pour compter les tours, sinon pour se compliquer la vie.
    Un capteur Hall donnera une impulsion/tour, c'est suffisant et plus simple.
    MM
    Si il y a des erreurs ci dessus, c'est que je n'ai pas eu le temps de les corriger...

  7. #6
    Murayama

    Re : problème acquisition haute fréquence codeur incrémental

    Bonjour!


    Pour faire bref, je dois mesurer la vitesse de rotation d’un moteur brushless pour
    pouvoir établir un modèle.

    Je vois pas bien l'utilité d'un codeur 600 pas/tour pour compter les tours, sinon
    pour se compliquer la vie.
    Un capteur Hall donnera une impulsion/tour, c'est suffisant et plus simple.

    Le monsieur ne dit pas qu'il veut compter les tours, mais mesurer la vitesse de
    rotation. Tout dépend de ce qui est demandé, mais pour moi qui fais en continu des
    prototypes d'encodeurs depuis 11 ans, on me demande souvent un encodeur qui mesure
    la vitesse en continu avec délai de mesure de 1µs max.
    Et par exemple un moteur industriel à 6000rpm, en 1µs, il ne tourne que de 0.036 degré.


    @Tom9595
    Résumons tout ce que vous ne devez pas faire:
    Répétez après moi, à peu près 100 fois chaque phrase:
    - Je ne dois pas faire de divisions dans un programme embarqué
    - Je ne dois pas utiliser de nombres à virgule flottante dans un programme embarqué.
    - Je ne dois pas utiliser de fonctions lentes et bloquantes dans ma boucle principale


    Et là, déjà on aura fait un progrès.
    Dans SendData, vous utilisez tout ce qui est interdit.
    La division, les nombres float, et SerialPrint.
    Donc même en admettant que le reste peut fonctionner (ce qui n'est pas le cas, c'est
    trop juste), vous auriez un arrêt de service temporaire en attendant que tout soit fini.
    Pour info: Vu comme les librairies d'Arduino sont faites, SerialPrint est probablement lent
    (s'il utilise une DMA, disons que je n'ai rien dit). Bref, vous allez envoyer 25 caractères
    environ, donc 250 bits. (1 caractère = 8 bits + start et parfois parité).
    Arrondissons 19.2 à 20kbits. 20k/0.25 = 80 buffers par seconde. Et dans ce cas là,
    vous n'avez pas le temps de faire autre chose.


    vive les TIPE en CPGE …

    Je n'ai pas le dictionnaire, j'ai dû regarder Wiki. Dans mon temps, on ne faisait
    que des maths en prépa.


    Mais j'aime bien changer les maths.


    Au moins cette fois ci, vous aurez appris qu'Arduino a ses limites.


    Ah oui, si vous voulez faire cela avec Arduino, c'est possible, mais il faut changer d'approche.
    Il existe un chip magnétique absolu à basse résolution (1024 pas par tour) qui peut fonctionner
    jusqu'à 4kHz. La bestiole s'appelle TW11.
    Pour 50 tours par seconde, vous pouvez l'utiliser à 200 Hz, lire la valeur et maintenir la
    valeur précédente. Vous pouvez avoir directement la vitesse si vous lisez à une cadence
    précise. Il y a un peu à réfléchir (si la valeur qui suit 1000 est 100, ce n'est pas parce que
    le moteur a reculé de 900, mais parce qu'il a passé le point 0 puisqu'à 50 tours par seconde
    il ne peut pas faire plus d'1/4 de tour à 200 Hz). Bref, c'est du détail.
    Et à 200 Hz, même Arduino peut le faire.


    Petite astuce: avec un chip comme ça, vous savez que 1 lsb = 1 tour / 1024.
    Vous calculez d'abord, non pas combien il faut de pas pour faire un certain angle puis
    faire ensuite la règle de 3, mais vous calculez combien de temps il vous faudra, par
    exemple à N tours par minute pour avancer d'exactement N pas. Donc si vous programmez
    votre intervalle de lecture à (N/1024) seconde, ben vous lisez directement la vitesse dans
    le chip. Ex: si vous avancez de 243 pas (valeur du registre de l'encodeur), cela signifie
    que vous tournez exactement à 243 tours/min. (ou 243 t.min^-1 comme diraient les HEC
    pour faire croire qu'ils s'y connaissent en maths/physique). Donc aucun calcul à faire, la valeur
    brute est la valeur réelle. J'ai la flemme de me relire, mais le principe est là.


    Pascal


    je maîtrise très peu le c++ et je manque de temps et connaissance pour trouver l’erreur

    Cette informaticienne compile le C. (Pas taper, aïe, non, pas les oreilles!).

  8. #7
    f6exb

    Re : problème acquisition haute fréquence codeur incrémental

    Citation Envoyé par Murayama Voir le message
    Bonjour!
    Cette informaticienne compile le C. (Pas taper, aïe, non, pas les oreilles!).
    J'irais bien faire un tour dans ton service informatique moi !
    Seuls les faucons volent. Les vrais restent au sol.

  9. #8
    Murayama

    Re : problème acquisition haute fréquence codeur incrémental

    Re!

    J'irais bien faire un tour dans ton service informatique moi !


    Surtout si elles aiment qu'on leur change les maths (voir plus haut, désolé pour la répétition).

    Pascal

  10. #9
    antek

    Re : problème acquisition haute fréquence codeur incrémental

    Citation Envoyé par Murayama Voir le message
    - Je ne dois pas faire de divisions dans un programme embarqué
    Sauf par 2, 4, 8 . . . et ne pas la confier à une informaticienne
    L'électronique c'est comme le violon. Soit on joue juste, soit on joue tzigane . . .

  11. #10
    jiherve

    Re : problème acquisition haute fréquence codeur incrémental

    bonjour,
    avec le µc des Arduino même un décalage n'est pas gratuit car il n'y a pas de barrel shifter.
    sur ces petites bécanes il n'y a que l'assembleur pour être efficace, mais l'assembleur c'est abscons et fastidieux!
    JR
    l'électronique c'est pas du vaudou!

  12. #11
    bobflux

    Re : problème acquisition haute fréquence codeur incrémental

    Murayama je pense que tu t'es fait enduire d'erreur par le framework arduino :

    Ceci est une interruption :

    Code:
    void ai0() {
      // ai0 is activated if DigitalPin nr 2 is going from LOW to HIGH
     
      counter++;
    }
    Mais c'est pas une interruption en direct, elle est activée par attachInterrupt() qui rajoute un niveau d'indirection (accès au pointeur de fonction dans l'interruption).

    Bref plus de 30k interruptions/s avec un mcu 8 bits à 8MHz ça va pas le faire, sans parler des autres interruptions concurrentes qui vont interférer.

    La solution est d'utiliser un timer en mode compteur pour compter les impulsions sur la broche, là c'est un compteur matériel donc il peut aller beaucoup plus vite.

  13. #12
    bobflux

    Re : problème acquisition haute fréquence codeur incrémental

    Bon après il y a le léger problème dans la description de l'encodeur :

    > la sortie pour le type de sortie à collecteur ouvert NPN Vitesse mécanique maximale: 5000 R / min Fréquence de réponse: 0-20 KHz Longueur du câble: 1,5 mètre

    (probablement une traduction du chinglish)

    C'est du collecteur ouvert, probablement un photo-transistor, donc difficile d'espérer plus de 20-30 kHz.

  14. #13
    Murayama

    Re : problème acquisition haute fréquence codeur incrémental

    Bonjour!

    Sauf par 2, 4, 8
    Oui, mais uniquement si le diviseur est une constante.
    Exemple:
    val = 155;
    div = 4;

    val /=div; // ça ne fonctionnera pas mieux qu'une division parce que div est une variable.

    En plus, même si c'est une constante, je ne suis pas certain que ça fonctionne bien avec un float.

    Ah oui, j'en profite pour donner un coup de pied dans la fourmilière, et j'ajoute aux phrases
    à répéter:
    Ne jamais remplacer une division par un shift, quel que soit le cas.
    Pourquoi?
    - Tout compilateur récent va le faire automatiquement (si c'est une constante). C'était
    utile peut-être dans les années 70, 80 mais plus maintenant.
    - Source potentielle de problèmes pour un mec non-averti (qui n'en vaut donc qu'un) qui
    reprend le programme.
    Exemple: Si vous partez du principe qu'un coefficient est une puissance de 2, et que plus tard
    vous vous dites qu'il faut un coefficient 20% plus grand, le shift ne fonctionnera plus.

    Bref: si vous voulez faire une division, faites une division. Si vous voulez shifter, utilisez shift.

    Murayama je pense que tu t'es fait enduire d'erreur par le framework arduino :
    Si fait, si fait, j'ai bien compris que c'était une interruption. Mais interruption ou pas,
    dans ce cas là qui est un peu critique (1), ça ne marchera jamais. Un appel d'interruption
    est avantageux parce qu'on peut penser à autre chose en attendant que ça vienne, comme
    disait la jeune mariée, mais ça prend plus de temps que l'appel d'une fonction.

    (1) Comme beaucoup de cas le sont.

    Pascal

  15. #14
    Tom9595

    Re : problème acquisition haute fréquence codeur incrémental

    Bonjour tout le monde excusez moi de ne pas vous avoir répondu pendant plus d'un mois alors que vous vouliez m'aidez ( il y avait les écrit à passer...).

    J'ai raccourci mon code pour ensuite avoir uniquement le compteur de "ticks" dans le moniteur série. Ensuite je récupère les données avec un copier coller brute du moniteur série que j'enregistre en fichier texte. Je peux alors utiliser python ( je ne sais pas vraiment coder en C ) pour effectuer une dérivation numérique et obtenir la vitesse en fonction du temps.
    Cependant j'ai toujours le même problème mais pour un vitesse de rotation un peu plus élevé donc j'ai une petite amélioration.

    Je pense acheter un codeur de 100 "ticks"/tour : je dois pouvoir mesurer une vitesse 6 fois plus grande en théorie.

    Pascal a dit que serialPrint était lent, mais je ne sais pas quelle autre fonction utiliser pour remonter aux données.
    Avez vous des améliorations à proposer pour ce code pour la vitesse d'exécution ? Ou alors avez vous une autre méthode ?

    Code:
    ============================== ============================== =====

    int pinA = 2; // Le port D2 est associé à l'interruption 0
    volatile int pos = 0; // Position (en nombre de pas) du codeur

    void setup() {
    Serial.begin(2000000);
    Serial.println("Codeur incremental");
    pinMode(2, INPUT);
    digitalWrite(2, HIGH);
    attachInterrupt(0, ai0, RISING);

    }

    void loop() {
    }

    void ai0() {
    pos++;
    Serial.println(pos);
    }


    ============================== ============================== =====

  16. #15
    Murayama

    Re : problème acquisition haute fréquence codeur incrémental

    Bonjour!


    Pour reprendre le sujet de départ:


    je dois mesurer la vitesse de rotation d’un moteur brushless pour pouvoir établir un modèle

    Je pense acheter un codeur de 100 "ticks"/tour

    Pourquoi 100?


    Il serait bon de connaître les spécifications du système. Vous voulez mesurer la vitesse
    du BLDC, mais:
    - Quelle est la plage de vitesses?
    - Quelle doit être la résolution?
    - La précision?
    - Le délai maxi (je ne sais pas si délai est le bon mot en français. Latence, peut-être).


    Parce que jusqu'à maintenant, on nage dans le vague. Et même si une vague n'empêche pas
    de nager, c'est tout de même imprécis.


    Pendant que vous y êtes, et juste pour info, il existe des chips qui permettent de
    générer les signaux UVW du moteur BLDC. Là, on arrive dans le haut de gamme, mais ça
    vaut la peine de s'y intéresser. L'avantage est que vous pouvez optimiser la commutation
    à 0.1 degré près (pour les plus modestes). Vous pouvez connaître simultanément ou presque,
    la position, la vitesse, etc...


    Pascal

  17. #16
    Tom9595

    Re : problème acquisition haute fréquence codeur incrémental

    Excusez moi pour le manque d'information ( la blague sur la vague m'a fait bien fait rire ).

    Latence : je n'ai pas besoin d'avoir le résultat en directe, je souhaite juste obtenir un modèle de mon moteur pour ensuite asservir un système.
    Résolution : je n'ai pas de résolution particulière à avoir ( juste de l'ordre du dixième de tour par seconde je dirais )
    Plage : mon moteur doit théoriquement pouvoir tourner jusqu'à 11 tr/min, soit 183 tr/s.

    Le but de mon projet ( dans le cadre du TIPE ) est avant tout d'obtenir une modélisation de mon système global pour prévoir son comportement, et de comparer les prévisions théoriques avec le comportement réel du système, et d'expliquer les éventuels écarts.
    Voila pourquoi je cherche à caractériser le comportement de mon moteur, qui est un élément ( central ) de mon système.

    Je ne sais pas ce qu'est un chips ( je ne connais que celles qui sont salées ), j'utilise un ESC ( electronic speed controller ) pour commander mon moteur triphasé.

    Par ailleurs je pense acheter un codeur de 100 ticks/tr car c'est le seul que j'ai trouvé pour pas cher sur internet ( 20 euros ), qui a la même géométrie que celui que j'avais récupéré ( sinon je dois refaire un nouveau support pour encastrer l'arbre moteur au codeur) et que je peux me procurer rapidement ( merci Amazon...).

    Merci beaucoup pour la réponse.

  18. #17
    Pascal071

    Re : problème acquisition haute fréquence codeur incrémental

    bonjour
    un article sur le comptage, bien documenté:
    https://www.f-legrand.fr/scidoc/docm...cillateur.html

    cordialement

  19. #18
    bobflux

    Re : problème acquisition haute fréquence codeur incrémental

    Citation Envoyé par Tom9595 Voir le message
    Plage : mon moteur doit théoriquement pouvoir tourner jusqu'à 11000 tr/min, soit 183 tr/s.
    Avec 100 ticks par tour ça fait 18.3 kHz.

    Si il a la même sortie collecteur ouvert à phototransistor que l'autre, limitée à 20kHz, c'est bon.

  20. #19
    Tom9595

    Re : problème acquisition haute fréquence codeur incrémental

    merci beaucoup,

    cependant je ne comprend rien au programme: je connais deja mal le language C++, mais alors la j'y comprend vraiment rien.

    qu'est-ce que cela veut dire par exemple : TCCR2B |= (1 << CS12) | (1 << CS11) | (1 << CS10).

    Je pense sincerement ne pas avoir actuellement le niveau pour comprendre ce code ( je ne sais même pas ce qu'est une interruption par exemple...)

    De plus je n'arrive pas à faire marcher le code, et vu que que je le comprend pas je peux pas résoudre le problème.
    J'ai bien alimenté mon codeur, et j'ai branché la branche de mesure sur la broche 5 comme convenue mais la fréquence affiché est nulle. Est-ce que je dois adapté mon programme par rapport à mon codeur ?

    Je passe vraiment pour le débutant de service qui doit être pris par la main dans tout ce qu'il fait mdr, mais bon j'ai pas le temps d'apprendre le language C++ en 2 jours... J'ai juste besoin de mesurer un triste vitesse de rotation... Si vous avez des pistes pour savoir pourquoi rien n'est affiché je suis preneur.

  21. #20
    bobflux

    Re : problème acquisition haute fréquence codeur incrémental

    Citation Envoyé par Tom9595 Voir le message
    qu'est-ce que cela veut dire par exemple : TCCR2B |= (1 << CS12) | (1 << CS11) | (1 << CS10).
    Bon là c'est pas du C++, c'est mettre une valeur dans un registre hardware pour dire au périphérique de faire ce que tu veux qu'il fasse. Il vaut mieux avoir la doc à portée de main, par exemple le reference manual du micro, ou alors un tuto

  22. #21
    bobflux

    Re : problème acquisition haute fréquence codeur incrémental


  23. #22
    Tom9595

    Re : problème acquisition haute fréquence codeur incrémental

    Merci pour l'aide, je vais m'accrocher pour déchiffrer ces documents ( pas facile quand on par de zero dans le domaine, mais la vie est faite d'aventure ahah ).

  24. #23
    Pascal071

    Re : problème acquisition haute fréquence codeur incrémental

    bonsoir
    tu fais comme tout le monde, tu profites de ceux qui ont travaillé pour faire ce code:
    https://www.f-legrand.fr/scidoc/srcd...uencemetre.ino
    ensuite, tu adaptes si besoin

    cordialement

Discussions similaires

  1. [Exercices] Fréquence maximale d'un codeur incrémental
    Par mibo39 dans le forum Électronique
    Réponses: 9
    Dernier message: 14/10/2022, 10h35
  2. calcul de la frequence d'un codeur incrémental
    Par lucas_63 dans le forum Électronique
    Réponses: 5
    Dernier message: 13/05/2014, 16h57
  3. problème: surtension codeur incrémental
    Par matfmy dans le forum Électronique
    Réponses: 3
    Dernier message: 06/01/2014, 10h34
  4. Problème précision codeur incrémental???
    Par invitee0ba7c35 dans le forum Électronique
    Réponses: 10
    Dernier message: 26/04/2008, 22h22
  5. Codeur Incremental
    Par invitef341dab1 dans le forum Électronique
    Réponses: 4
    Dernier message: 26/02/2006, 13h55
Découvrez nos comparatifs produits sur l'informatique et les technologies.