Pages: [1] 2   Go Down
Author Topic: Lire une roue codeuse  (Read 2752 times)
0 Members and 1 Guest are viewing this topic.
Geneva
Offline Offline
Faraday Member
**
Karma: 30
Posts: 3228
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonsoir,

j'ai un moteur sur lequel est montée une roue codeuse et un fourche optique.
Le disque comporte 504 positions.

J'ai essayé de lire cet encodeur lors de la rotation de mon moteur, probablement vers les 100-200 t/min.

Dans les codes que j'ai essayés, j'incrémente de 1 une variable à chaque "top".

En lisant le signal directement sur une pin digital, j'ai environ 50 à 100 fois moins d'incrément que de "top" (même en tournant mon moteur à la main)

Pour un tour, je me retrouve avec une valeur de 74, 3-4 tours me donnent environ 200.

Code:

int codepin = 4;
int encoderpos = 0;

volatile int state = 0;

void setup()
{
  Serial.begin (19200);
}


void loop()
{
       digitalWrite(codepin,!state);
       if (digitalRead(codepin)==state)
{
       encoderpos++;
       state = !state;
}
 
  Serial.println (encoderpos,DEC);
}



Avec la fonction attachInterrupt(), j'ai des valeurs qui semblent correctes lorsque je tourne le moteur à la main, mais rotation rapide (c'est relatif environ 100-200 t/min), les valeurs retournées par le moniteur série sont espacées de plusieurs incréments (environ une centaines) et ces espaces sont variables.

Code:
int encoderpos = 0;

void setup()
{
  Serial.begin (19200);
  attachInterrupt(0,interrupt,RISING);
}

void loop()
{
  Serial.println (encoderpos,DEC);
}

void interrupt()
{
       encoderpos++;
}

Est-ce l'Arduino arrive a lire chaque top de mon disque ?

Les valeurs lisibles sur le moniteur série sont elles "décalées" par une latence de la liaison ?

J'aimerais pouvoir lire la position physique et temporelle de mon disque, est-ce possible avec l'Arduino ou faudrait-il passer par un autre CI pour cela ?

Merci pour vos réponses.
« Last Edit: March 11, 2009, 02:24:39 pm by jfs » Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Sophia-Antipolis (06)
Offline Offline
God Member
*****
Karma: 4
Posts: 618
Rejoignez le club !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quel est le diamètre de ta roue ? C'est nécessaire pour savoir combien de µs sépare chacun des fronts montants.
Logged

Geneva
Offline Offline
Faraday Member
**
Karma: 30
Posts: 3228
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


Le disque fait 37 mm de diamètre.

A 60 t/min il devrait y avoir un top toutes les 2 ms ?
« Last Edit: March 11, 2009, 02:48:31 pm by jfs » Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Sophia-Antipolis (06)
Offline Offline
God Member
*****
Karma: 4
Posts: 618
Rejoignez le club !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

J'ai trouvé le problème : tu utilises un "int" pour stocker la valeur, donc un entier entre 0 et 256. Comme tu es à 2-3 tours par seconde, à 504 ticks d'encodeurs, tu dépasses la capacité du int 6 fois par seconde smiley

Il faut que tu utilises un "long", tout simplement.


Logged

Geneva
Offline Offline
Faraday Member
**
Karma: 30
Posts: 3228
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

J'avais déjà essayé avec un "long", mais dans le doute j'ai refait un essai :

- les valeurs retournées ne sont pas cohérentes et sont parfois affichées avec des lettres ou des signes.

Dans les references (extended) il est indiqué que les variables doivent être déclarées "volatile".

Seul le "int" fonctionne et m'affiche des valeurs entre approximativement  -32'800 et 32'800.

J'ai essayer en changeant le Baudrate, ça devient effectivement plus précis, à 57600 j'ai une perte d'affichage de 18 top et cela de façon régulière, j'ai l'impression que tous mes tops sont lus, mais que le temps nécessaire à la liaison série me fait "sauter" l'affichage de 18 tops (qui sont tout de même comptabilisés).
Par contre à 57600 et plus, la liaison est peu fiable et lorsqu'elle se "perd" j'ai un panic-Kernel et je dois rebooter mon ordi  smiley-sad

Donc il faut une solution qui me permette de faire une liaison avec un baudrate plus bas.
« Last Edit: March 11, 2009, 04:49:10 pm by jfs » Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Sophia-Antipolis (06)
Offline Offline
God Member
*****
Karma: 4
Posts: 618
Rejoignez le club !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Oui tu as raison, le "int" est suffisant, car Arduino utilise 2 octets (32767 exactement) contrairement au "int" d'AVR-GCC, j'ai confondu smiley

J'ai enfin compris. Tu voudrais recevoir toutes les valeurs sur la liaison série ! en tout cas avec le code que tu as écrit, je confirme que l'Arduino compte bien, c'est juste que la liaison série n'a pas le temps de t'envoyer la valeur qu'il y a déjà une interruption. Dans ce cas là, il faut faire une interpolation du côté du receveur, par exemple estimer la vitesse à partir des 2 dernières réceptions, en déduire quand les 18 tops manquant vont arriver, et s'il y a eu un changement entre 2 réceptions, rectifier le coup suivant.
Logged

Geneva
Offline Offline
Faraday Member
**
Karma: 30
Posts: 3228
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


Cela corrobore ce que je pensais.

Je vais essayer d'avancer avec ça (pour l'interpolation je sens que je vais encore faire quelques nuits blanches  ;D ).

Merci pour tes réponses.  smiley-wink
« Last Edit: March 11, 2009, 05:31:11 pm by jfs » Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Sophia-Antipolis (06)
Offline Offline
God Member
*****
Karma: 4
Posts: 618
Rejoignez le club !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, je ferai des mesures de ton code à l'analyseur logique pour mesurer combien de temps entre deux envois sur la liaison série.
Logged

Geneva
Offline Offline
Faraday Member
**
Karma: 30
Posts: 3228
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Merci, c'est très sympa de ta part.

De mon coté j'ai continué ma prospection, voici le code que j'ai actuellement :

Code:
volatile int encoderpos = 0;
int index = 0;
int senspin= 7;
unsigned long oldTime = 0;
volatile int rpmcount = 0;
unsigned int rpm = 0;

void setup()
{
  Serial.begin (38400);
  
}


void loop()
{

//if (rpmcount>=20)

 rpm = 120/(millis() - oldTime)*rpmcount;
 oldTime = millis();
 rpmcount=0;
 
 if (digitalRead(senspin) == 1){
   detachInterrupt(0);
   attachInterrupt(0,interrupt1,CHANGE);
  if (encoderpos >= 25200){encoderpos=0;index++;}
  
 }
 else if (digitalRead(senspin) == 0){
   detachInterrupt(1);
   attachInterrupt(0,interrupt0,CHANGE);
   if (encoderpos<=-25200){encoderpos=0;index--;}
  
 }
  
  
  Serial.print ("   time ");
  Serial.print (millis(),DEC);
  Serial.print ("   rpm ");
  Serial.print(rpm,DEC);
  Serial.print ("   pos ");
  Serial.print (encoderpos,DEC);
  Serial.print ("   index ");
  Serial.println (index,DEC);
  
}


void interrupt1()
{
       encoderpos++;
       rpmcount++;    
}


void interrupt0()
{
       encoderpos--;
       rpmcount++;
}

Mon moteur est branché sur un autre Arduino avec un motor shield et une manette Nunchuck cette carte me renvoi 1 ou 0 pour indiquer le sens de rotation, je récupère cette info sur la pin D7.

Ensuite je ne vais pas expliquer la fonction attachinterrupt() ...  smiley-wink
que je détache et attache suivant le sens de rotation, ainsi j'incrémente ou décremente mes tics.

La fonction millis() me sert a déterminer le temps depuis le début du process ainsi qaue pour le calcul des rpm moteur (attachinterrupt() également).

en utilisant des "int" je suis limité  à 32768, comme ce n'est pas un multiple de 504, je m'arrête à 25200 (50 rotations) et j'incrémente ou décrémente un index qui m'indique chaque "lot" de 50 rotations.
Avec un "unsigned" je pourrais m'arrêter à 50400 (100 rotations), mais aprés je n'arrive pas à décrémenter en négatif.

Je suppose que lors du passage 25200 à 0 je pers quelques tic ...  :-?, mais pour l'instant je ne sais pas faire mieux  :smiley
« Last Edit: March 12, 2009, 02:59:34 pm by jfs » Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Sophia-Antipolis (06)
Offline Offline
God Member
*****
Karma: 4
Posts: 618
Rejoignez le club !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Il y a une erreur dans "detachInterrupt(1)" : 1 à la place de 0.

Le detachInterrupt n'est pas nécessaire quand tu fais un attachInterrupt derrière. Et pourquoi ne pas faire le test du sens dans l'interruption, puisque c'est la liaison série qui est lente, il ne faut pas surcharger la boucle avec des changements d'interruptions.
Logged

Geneva
Offline Offline
Faraday Member
**
Karma: 30
Posts: 3228
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

En fait j'ai fait des test en mettant le traitement du sens dans attachInterrupt(), ça me donne un affichage complètement chaotique et au bout d'un moment la liaison série plante.


Je ferai un essai sans les "detachInterrupt()".
Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Geneva
Offline Offline
Faraday Member
**
Karma: 30
Posts: 3228
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Effectivement les "detachInterrupt()" ne sont pas nécessaire.

Merci Luj06.   smiley-wink
Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Sophia-Antipolis (06)
Offline Offline
God Member
*****
Karma: 4
Posts: 618
Rejoignez le club !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

De rien, car je ne sais pas si ça a pu améliorer le temps de traitement.

Pour comparaison, voici mon code:

Code:
#include <Servo.h>

Servo servL;
Servo servR;

int consigneLeft = 0;
long counterLeft = 0;

int consigneRight = 0;
long counterRight = 0;


void setup() {
  // init serial communication
  Serial.begin(38400);
  //  
  servL.attach(10);
  servR.attach(9);
  //
  pinMode(3,INPUT);  
  attachInterrupt(1, interruptRight, CHANGE);
  //
  consigneLeft = 1;
  consigneRight = 1;
}

void loop() {
  //
  if (consigneLeft > 0)
  {
    servL.write(0);
    if (counterRight > 600) {
      consigneLeft = -1;  
    }
  }
  //
  if (consigneLeft < 0)
  {
    servL.write(255);
    if (counterRight < 400) {
      consigneLeft = 1;  
    }
  }  
  //
  if (consigneRight > 0)
  {
    servR.write(255);
    if (counterRight > 600) {
      consigneRight = -1;  
    }
  }
  //
  if (consigneRight < 0)
  {
    servR.write(0);
    if (counterRight < 400) {
      consigneRight = 1;  
    }
  }  

  //
  int val = (int) counterRight;
  //  
  Serial.print( 0xff, BYTE);
  Serial.print( (val >> 8) & 0xff, BYTE);
  Serial.print( val & 0xff, BYTE);

}

void interruptRight()
{
  if (consigneRight > 0)
  {
    counterRight++;
  }
  else {
    counterRight--;    
  }
}

Archive dispo en fin d'article : tu verras que de l'autre côté de la liaison série, on visualise une ligne très régulière.
Logged

Geneva
Offline Offline
Faraday Member
**
Karma: 30
Posts: 3228
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Merci pour le lien vers cet article (que j'avais déjà consulté  smiley-wink ), tu me conseillerai d'utiliser un AOP ?

Par contre les roues utilisées dans cet article ont moins de tic que la mienne, je pense que ça a une énorme influence dans les résultats que j'obtiens (trop de précisions nuit à la vitesse de traitement).
« Last Edit: March 14, 2009, 07:00:22 pm by jfs » Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Sophia-Antipolis (06)
Offline Offline
God Member
*****
Karma: 4
Posts: 618
Rejoignez le club !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Pas forcément, ça dépend le signal que sort ta fourche optique : tu as sa référence ?
Logged

Pages: [1] 2   Go Up
Jump to: