lundi 14 mars 2016

Odométrie : programme Arduino Micro

Pour compter et décompter le nombre de tours, on utilise un Arduino micro.

Le programme se présente sous quelques ligne en language C qui permettent de remonter les compteurs vers un port série virtuel.

int MOTG_INT = 2; // interrupt sur digital 0 = INT 2
int MOTG_PHA = 0; //  input digital 0
int MOTG_PHB = 1; //  input digital 1
int MOTG_VALA ;
int MOTG_VALA_old ;
int MOTG_VALB ;
volatile int MOTG_COUNT;
int MOTG_COUNT_OLD;

int MOTD_INT = 1; // interrupt sur digital 3 = INT 1
int MOTD_PHA = 3; //  input digital 3
int MOTD_PHB = 2; //  input digital 2
int MOTD_VALA ;
int MOTD_VALA_old ;
int MOTD_VALB ;
volatile int MOTD_COUNT;
int MOTD_COUNT_OLD;

String inputString = "";      // La chaine de commande reçue
char inChar;                  //  1 caractère reçu
boolean commande_ok = false;  //
boolean _odo_run = false;


void setup() {
  attachInterrupt(MOTG_INT, interrupt_MotG_phA, RISING );
  pinMode(MOTG_PHA, INPUT);
  pinMode(MOTG_PHB, INPUT);

  attachInterrupt(MOTD_INT, interrupt_MotD_phA, RISING );
  pinMode(MOTD_PHA, INPUT);
  pinMode(MOTD_PHB, INPUT); 
}

void interrupt_MotG_phA()
{
  if (!_odo_run) return;
 
  MOTG_VALA = digitalRead(MOTG_PHA);
  MOTG_VALB = digitalRead(MOTG_PHB);

  if ( MOTG_VALA != MOTG_VALA_old)
  {
    //  modification du signal sur l'entrée MOTG_PHA
  if (MOTG_VALA==1)
    {
      // signal sur l'entrée MOTG_PHA = 1
      if (MOTG_VALB==0)
        {
          MOTG_COUNT++;
        }
      else
        {
          MOTG_COUNT--;
        }
    }
    else
    {
      // signal sur l'entrée MOTG_PHA = 0
      if (MOTG_VALB==0)
        {
          MOTG_COUNT--;
        }
      else
        {
          MOTG_COUNT++;
        }     
    
    }
    MOTG_VALA_old = MOTG_VALA;
  }
  delay(1);
}

void interrupt_MotD_phA()
{
   if (!_odo_run) return;
 
  MOTD_VALA = digitalRead(MOTD_PHA);
  MOTD_VALB = digitalRead(MOTD_PHB);

  if ( MOTD_VALA != MOTD_VALA_old)
  {
    //  modification du signal sur l'entrée MOTD_PHA
  if (MOTD_VALA==1)
    {
      // signal sur l'entrée MOTD_PHA = 1
      if (MOTD_VALB==0)
        {
          MOTD_COUNT++;
        }
      else
        {
          MOTD_COUNT--;
        }
    }
    else
    {
      // signal sur l'entrée MOTD_PHA = 0
      if (MOTD_VALB==0)
        {
          MOTD_COUNT--;
        }
      else
        {
          MOTD_COUNT++;
        }     
    
    }
    MOTD_VALA_old = MOTD_VALA;
  }
  delay(1);
}

void loop()
{
  if (Serial.available() > 0)
  {
 // lecture du caractère reçu
    inChar = (char)Serial.read();
   
    if (inChar == 13)
    {
      //  Retour chariot = commande complète

          if (inputString == "ODO_start")
          {
            //  La commande est reconnue
                commande_ok = true ;
            //  accusé reception
                Serial.print(inputString);
                Serial.println(" OK");

                _odo_run = true;

          }     

          if (inputString == "ODO_reset")
          {
            //  La commande est reconnue
                commande_ok = true ;
            //  accusé reception
                Serial.print(inputString);
                Serial.println(" OK");

                MOTG_COUNT = 0;
                MOTG_COUNT_OLD = 0;
                MOTD_COUNT = 0;
                MOTD_COUNT_OLD = 0;
          }     

          if (inputString == "ODO_stop")
          {
            //  La commande est reconnue
                commande_ok = true ;
                    
            //  accusé reception
               Serial.print(inputString);
               Serial.println(" OK");

               _odo_run = false;
           }     




      //  Si la commande n'est pas reconnue
          if (commande_ok != true)
          {
              Serial.print(inputString);
              Serial.println(" KO");
          }

      //  prêt à recevoir une nouvelle commande
          commande_ok = false;
     
      //  Vidange de la chaine de commande
          inputString = "" ;
    }
    else
    {
      // ajoute le caractère
        inputString += inChar;   
    }
  }

 
  if((MOTG_COUNT_OLD!=MOTG_COUNT) || (MOTD_COUNT_OLD!=MOTD_COUNT))
  {
    Serial.print(MOTG_COUNT, DEC);
    Serial.print(" ");
    Serial.print(MOTD_COUNT, DEC);
    Serial.println();
    if(MOTG_COUNT_OLD!=MOTG_COUNT) MOTG_COUNT_OLD=MOTG_COUNT;
    if(MOTD_COUNT_OLD!=MOTD_COUNT) MOTD_COUNT_OLD=MOTD_COUNT;
  }
  delay(20);
}
La remontée des compteurs sur le Port COM4 (9600bauds, 8 bits, 1 stop)




dimanche 6 mars 2016

Odométrie : mesures

Les capteurs sont assemblés sur les axes, alimentés en 5 volts.


Pour déterminer le sens de rotation, les capteurs sont montés en quadrature. Voici les signaux générés lorsque le moteur est en rotation, ils sont clairement décalés dans le temps.

Rotation en sens horaire :


Rotation en sens anti horaire :


samedi 27 février 2016

Odométrie : modification du moteur

Odométrie
Pour estimer la position de Pablo nous allons mesurer individuellement le déplacement des deux roues et reconstituer ainsi le mouvement global du robot. Nous calculerons sa position en intégrant les déplacements à partir d'une position initiale connue.
Nous allons compter le nombre de tours de chacun des deux moteurs, deux capteurs montés en quadrature sont nécessaires pour déterminer le sens de rotation. Les capteurs utilisés sont disponibles à cette adresse.



Le moteur à modifier est du type Dynamic WMT 90103


Après avoir libéré le carter on aperçoit le frein électrique qu'il faut enlever.


L'axe du moteur est visible.

Reste à équiper l'axe avec une tige filetée


Sur l'axe fileté on fixe la roue en epoxy






Puis on fixe les codeurs optiques avec des tiges acier qui permettent d'ajuster les circuits par rapport à la roue codeuse.


Pour finir on câble l'alimentation 5 Volts et les signaux des codeurs