Carte Romeo

De Wiki Arobose
(Langage C)
(Commande des moteurs)
Ligne 180 : Ligne 180 :
 
     // stop();
 
     // stop();
 
   }
 
   }
 +
  return 0;
 +
}
 +
</syntaxhighlight>
 +
 +
== Communication XBee ==
 +
Les modules Xbee de digi sont des modules de communication sans fils respectant la norme 802.15.4. Ces modules sont très simples à utiliser car ils convertissent les signaux Xbee en commande série.
 +
 +
La carte ROMEO est conçue pour recevoir un module Xbee lui permettant de communiquer à distance via sa liaison série. Le module est branché sur les pins 0 (RXD1) et 1 (TXD1) du microcontroleur utilisant l'USART 1.
 +
 +
=== Commande à distance ===
 +
Nous allons utiliser ce module pour piloter le robot à distance à partir du PC en envoyant un caractère de commande à la carte ROMEO. Pour cela, il faut également un module et un adaptateur XBee USB pour le PC.
 +
 +
Dans un premier temps, nous allons configurer la liaison série. Le message envoyé contient 8 bits de données et 1 bit de stop sans contrôle de parité. La vitesse de transmission est de 9600 bauds.
 +
 +
<syntaxhighlight lang="c">
 +
/* setup USART1
 +
* speed : 9600 Baud
 +
* 8-bits, no parity, 1-stop-bit */
 +
void
 +
USART_1_setup(void)
 +
{
 +
  PORTD &= ~(1 << PORT2); /* initialize pin PD2 (RX) as input pin */
 +
  PORTD |= (1 << PORT3); /* initialize pin PD3 (TX) as output pin */
 +
 +
  UBRR1 = 103; /* 9600 Baud at 16MHz */
 +
 +
  UCSR1A = 0;
 +
 +
  /* 8-bits, no parity, 1-stop-bit */
 +
  UCSR1C = (1 << UCSZ11) | (1 << UCSZ10);
 +
}
 +
</syntaxhighlight>
 +
 +
Il existe 2 solutions pour recevoir une donnée via la liaison série :
 +
La première solution est très simple mais elle est bloquante. En effet, si aucune donnée n'est reçue (perte de communication), le programme va rester bloqué dans le « while » ce qui peut être gênant pour le système.
 +
 +
<syntaxhighlight lang="c">
 +
 +
void
 +
USART_1_receiver_enable(void)
 +
{
 +
  UCSR1B |= (1 << RXEN1);
 +
}
 +
 +
unsigned char
 +
USART_1_receive(void)
 +
{
 +
  // wait for data to be received
 +
  while (!(UCSR1A & (1 << RXC1)))
 +
    ;
 +
  // get and return received data from buffer
 +
  return UDR1 ;
 +
}
 +
</syntaxhighlight>
 +
 +
La seconde solution utilise les interruptions. La fonction ISR est exécutée seulement quand une donnée est reçue (flag levé). Le reste du temps, le programme est exécuté normalement sans attendre la réception d'une donnée.
 +
 +
<syntaxhighlight lang="c">
 +
volatile char receive_char;
 +
 +
void
 +
USART_1_receiver_interrupt_enable(void)
 +
{
 +
  UCSR1B |= (1 << RXEN1);
 +
  /* enable interrupt on the RXC1 flag */
 +
  UCSR1B |= (1 << RXCIE1);
 +
  SREG |= (1 << SREG_I);
 +
}
 +
 +
// receiver interrupt
 +
ISR( USART1_RX_vect)
 +
{
 +
  unsigned char dustbin = 0;
 +
 
 +
  receive_char = UDR1;
 +
}
 +
</syntaxhighlight>
 +
 +
La fonction principale va tester le caractère reçu : 'a' pour avancer, 'b' pour reculer, 'r' pour tourner a droite, 'l' pour tourner à gauche et n'importe quel autre caractère pour s’arrêter.
 +
 +
<syntaxhighlight lang="c">
 +
void
 +
pin_setup(void)
 +
{
 +
  /* Motor controller */
 +
  DDRD = (1 << PORTD4); /* PD4 as output pin */
 +
  DDRE = (1 << PORTE6); /* PE6 as output pin */
 +
}
 +
 +
void
 +
setup(void)
 +
{
 +
  pin_setup();
 +
 +
  pwm_3_setup();
 +
  pwm_4_setup();
 +
 +
  pwm_3A_enable();
 +
  pwm_4D_enable();
 +
 +
  USART_1_setup();
 +
  //USART_1_receiver_enable();
 +
  USART_1_receiver_interrupt_enable();
 +
}
 +
 +
int
 +
main(void)
 +
{
 +
  //char c;
 +
  setup();
 +
 +
  while (1)
 +
    {
 +
      //c = USART_1_receive();
 +
 +
      switch (/*c*/receive_char)
 +
        {
 +
      case 'a':
 +
        advance(100);
 +
        break;
 +
      case 'b':
 +
        back_off(100);
 +
        break;
 +
      case 'r':
 +
        turn_right(100);
 +
        break;
 +
      case 'l':
 +
        turn_left(100);
 +
        break;
 +
      default:
 +
        stop();
 +
        break;
 +
        }
 +
    }
 
   return 0;
 
   return 0;
 
}
 
}

Version du 28 juin 2013 à 12:51

Outils personnels
Catégories