<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="https://www.arobose.com/wiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
		<id>https://www.arobose.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ldoffe</id>
		<title>Wiki Arobose - Contributions de l'utilisateur [fr]</title>
		<link rel="self" type="application/atom+xml" href="https://www.arobose.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ldoffe"/>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Sp%C3%A9cial:Contributions/Ldoffe"/>
		<updated>2026-04-05T18:26:39Z</updated>
		<subtitle>Contributions de l'utilisateur</subtitle>
		<generator>MediaWiki 1.19.7</generator>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=XBee_shield_Arduino</id>
		<title>XBee shield Arduino</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=XBee_shield_Arduino"/>
				<updated>2013-10-04T13:01:32Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : XBee shield Arduino exemple d'utilisation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;La [http://www.dfrobot.com/wiki/index.php/Xbee_Shield_For_Arduino_%28no_Xbee%29_%28SKU:DFR0015%29 shield Arduino Xbee] de DRFobot permet d'accueillir le [http://www.digi.com/fr/products/wireless/point-multipoint/xbee-series1-module module Xbee] de digi qui convertit les signaux Xbee en commande série. &lt;br /&gt;
&lt;br /&gt;
== Shield XBee ==&lt;br /&gt;
Cette shield est une solution simple pour communiquer sans fil (ondes radio) en utilisant la liaison série de la Arduino.&lt;br /&gt;
&lt;br /&gt;
Elle est équipée de 2 interrupteurs :&lt;br /&gt;
&lt;br /&gt;
- RUN/PROG : La programmation de la Arduino via le cable USB utilise la liaison série. Pour éviter d'avoir à enlever la shield pour programmer la Arduino, il faut positionner l'interrupteur sur PROG. La liaison série entre la Arduino et la shield sera coupée et la shield ne perturbera pas la programmation. Quand la programmation de la Arduino est terminée, l'interrupteur devra être positionné sur RUN pour utiliser la communication Xbee du programme de la Arduino.&lt;br /&gt;
&lt;br /&gt;
- XBEE/USB : En position XBEE, c'est la communication série via Xbee qui est activée. En position USB, c'est la communication série via USB qui est activée.&lt;br /&gt;
&lt;br /&gt;
== Exemple ==&lt;br /&gt;
&lt;br /&gt;
Nous utilisons une Arduino UNO (ATMEGA328P) avec la shield et un module Xbee S1. Nous envoyons des caractères au PC en utilisant un adaptateur Xbee/USB et un module Xbee S1. Ces caractères sont lus dans un terminal série.&lt;br /&gt;
&lt;br /&gt;
=== Langage C ===&lt;br /&gt;
&lt;br /&gt;
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.  La fonction usart_0_transmit() permet d'envoyer un octet (caractère). La fonction principale envoie les 14 caractères « Hello World ! » en boucle toutes les 2 secondes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* setup USART0&lt;br /&gt;
 * speed : 9600 Baud&lt;br /&gt;
 * 8-bits, no parity, 1-stop-bit */&lt;br /&gt;
void&lt;br /&gt;
usart_0_setup(void)&lt;br /&gt;
{&lt;br /&gt;
//#if F_CPU == 16000000UL&lt;br /&gt;
  UBRR0 = 103; /* 9600 Baud at 16MHz */&lt;br /&gt;
  // elsif F_CPU == 20000000UL&lt;br /&gt;
  // UBRR1 = 129 /*9600 Baud at 20 MHz */&lt;br /&gt;
  UCSR0A = 0;&lt;br /&gt;
  UCSR0B = 0;&lt;br /&gt;
&lt;br /&gt;
  /* 8-bits, no parity, 1-stop-bit */&lt;br /&gt;
  UCSR0C = (1 &amp;lt;&amp;lt; UCSZ01) | (1 &amp;lt;&amp;lt; UCSZ00);&lt;br /&gt;
&lt;br /&gt;
  DDRD |= (1 &amp;lt;&amp;lt; PD1); /* initialize pin PD1 (TX) as output pin */&lt;br /&gt;
  UCSR0B |= (1 &amp;lt;&amp;lt; TXEN0); /* enable transmitter */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// transmit a char&lt;br /&gt;
void&lt;br /&gt;
usart_0_transmit(uint8_t data)&lt;br /&gt;
{&lt;br /&gt;
  // wait for empty transmit buffer&lt;br /&gt;
  while (!(UCSR0A &amp;amp; (1 &amp;lt;&amp;lt; UDRE0)))&lt;br /&gt;
    ;&lt;br /&gt;
  // put data info buffer, sends the data&lt;br /&gt;
  UDR0 = data;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t c[14] =&lt;br /&gt;
    { &amp;quot;Hello world !\n&amp;quot; };&lt;br /&gt;
&lt;br /&gt;
  usart_0_setup();&lt;br /&gt;
&lt;br /&gt;
  while (1)&lt;br /&gt;
    {&lt;br /&gt;
      for (uint8_t i = 0; i &amp;lt; 14; i++)&lt;br /&gt;
        {&lt;br /&gt;
          usart_0_transmit(c[i]);&lt;br /&gt;
        }&lt;br /&gt;
      _delay_ms(2000);&lt;br /&gt;
    }&lt;br /&gt;
  return 1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=GPS_LEA-5H_shield_Arduino</id>
		<title>GPS LEA-5H shield Arduino</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=GPS_LEA-5H_shield_Arduino"/>
				<updated>2013-10-03T14:13:42Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : GPS LEA-5H shield Arduino exemple d'utilisation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;La shield GPS pour ARDUINO basée sur le module [http://www.u-blox.com/en/lea-5h.html LEA_5H] de U-BLOX permet une location fiable en extérieure. Couplé à une antenne GPS, le LEA-5H permet de recevoir les signaux satellites GPS et GALILEO.&lt;br /&gt;
&lt;br /&gt;
Cette [http://www.dfrobot.com/wiki/index.php?title=DFRduino_GPS_Shield-LEA-5H_%28SKU:TEL0044%29 shield], proposée par DFRobot , permet une utilisation simple du module en intégrant les composants nécessaire à son utilisation (régulation de tension, résistances de pull-up pour la liaison i2c, led de power et fonctionnement, connecteur USB et antenne...).&lt;br /&gt;
&lt;br /&gt;
== Communication ==&lt;br /&gt;
Le module LEA-5H intègre plusieurs mode de communication : USB, série, i2c.&lt;br /&gt;
&lt;br /&gt;
Il suit la norme [http://fr.wikipedia.org/wiki/NMEA_0183 NMEA 0183] et envoie plusieurs trames GPS : RMC, VTG, GGA, GSA, GSV, GLL.&lt;br /&gt;
GGA est la plus courante, elle donne la position (latitude, longitude et altitude) du récepteur. Le détail des trames est expliquées [http://www.u-blox.com/images/downloads/Product_Docs/u-blox5_Protocol_Specifications%28GPS.G5-X-07036%29.pdf ici].&lt;br /&gt;
&lt;br /&gt;
Toutes les trames sont envoyées à chaque demande sous forme de caractères ASCII. Le code de la trame est envoyée en tête en commençant par $ (par exemple, $GPGGA) puis chaque valeur séparée par une virgule (4825.2680,N,00110.3895,E). Si la valeur n'est pas disponible (perte de communication avec le satellite) elle n'est pas envoyée, seules les virgules permettent de connaître le paramètre ($GPGGA,,,,,,,,,).&lt;br /&gt;
.&lt;br /&gt;
&lt;br /&gt;
=== USB ===&lt;br /&gt;
La shield peut être branchée à un ordinateur (port USB). Les données GPS sont directement transmises et peuvent être lues grâce à un terminal série (9600 bauds, 8 bits, 1 bit stop, sans parité). Les trames RMC, VTG, GGA, GSA, GSV et GLL sont envoyées environ toutes les secondes.&lt;br /&gt;
&lt;br /&gt;
=== I2C ===&lt;br /&gt;
La liaison i2c se fait grâce à une ARDUINO.&lt;br /&gt;
&lt;br /&gt;
==== Exemple Langage ARDUINO ====&lt;br /&gt;
&lt;br /&gt;
Un exemple est expliqué [http://www.dfrobot.com/wiki/index.php?title=DFRduino_GPS_Shield-LEA-5H_%28SKU:TEL0044%29 ici].&lt;br /&gt;
&lt;br /&gt;
==== Exemple Langage C ====&lt;br /&gt;
&lt;br /&gt;
La liaison twi (i2c) et les fonctions sont expliquées [http://geonobotwiki.free.fr/doku.php?id=robotics:computing:communication_twi_entre_atmega ici]&lt;br /&gt;
&lt;br /&gt;
Pour notre exemple, nous utilisons une carte ARDUINO UNO configurée en maitre. Le module GPS est utilisé en esclave à l'adresse 0x42.&lt;br /&gt;
Les trames GPS sont stockées à l'adresse 0xFF. Nous utiliserons la trame GGA pour afficher la position ( latitude, longitude et l'altitude) du récepteur GPS.&lt;br /&gt;
&lt;br /&gt;
Nous avons créé une structure gps qui contient la latitude, longitude et l'altitude. Les données sont stockées sous forme de chaînes de caractères ASCII. Par exemple, pour une latitude de 48°45'2584, la chaine latitude contiendra le code ASCII de chaque valeur : 52 (pour 4), 56 (pour 8)...&lt;br /&gt;
&lt;br /&gt;
Comme tous les formats de trames sont envoyés, il faut retrouver la trame GGA et identifier les paramètres qui nous intéresse. Pour commencer, on demande une lecture de 200 octets. Une fois reçus, la fonction gps_gpgga() parcourt le buffer pour retrouver la séquence $GPGGA. Quand l'entête a été retrouvée, il suffit de compter les virgules pour connaître le paramètre.&lt;br /&gt;
La fonction gps_print() permet d'envoyer les paramètres sur le port série pour les afficher dans un terminal.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct&lt;br /&gt;
{&lt;br /&gt;
  uint8_t latitude[9];&lt;br /&gt;
  uint8_t dir_lat;&lt;br /&gt;
  uint8_t longitude[11];&lt;br /&gt;
  uint8_t dir_long;&lt;br /&gt;
  uint8_t altitude[5];&lt;br /&gt;
} gps;&lt;br /&gt;
&lt;br /&gt;
/* GPS GGA message */&lt;br /&gt;
gps&lt;br /&gt;
gps_gpgga(uint8_t *buffer)&lt;br /&gt;
{&lt;br /&gt;
  gps g;&lt;br /&gt;
  uint8_t gpgga[6] =&lt;br /&gt;
    { '$', 'G', 'P', 'G', 'G', 'A' };&lt;br /&gt;
&lt;br /&gt;
  uint8_t header = 0;&lt;br /&gt;
  uint8_t j = 0, count = 0;&lt;br /&gt;
&lt;br /&gt;
  for (uint8_t i = 0; i &amp;lt; 200; i++)&lt;br /&gt;
    {&lt;br /&gt;
      if (!header)&lt;br /&gt;
        {&lt;br /&gt;
          if (buffer[i] == gpgga[j])&lt;br /&gt;
            {&lt;br /&gt;
              j++;&lt;br /&gt;
              if (j == 6)&lt;br /&gt;
                {&lt;br /&gt;
                  header = 1;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
      else&lt;br /&gt;
        {&lt;br /&gt;
          if (buffer[i] == ',')&lt;br /&gt;
            {&lt;br /&gt;
              count++;&lt;br /&gt;
              j = 0;&lt;br /&gt;
            }&lt;br /&gt;
          else&lt;br /&gt;
            {&lt;br /&gt;
              switch (count)&lt;br /&gt;
                {&lt;br /&gt;
              case 1: // utc time&lt;br /&gt;
                break;&lt;br /&gt;
              case 2: // latitude&lt;br /&gt;
                g.latitude[j] = buffer[i];&lt;br /&gt;
                break;&lt;br /&gt;
              case 3: // direction latitude&lt;br /&gt;
                g.dir_lat = buffer[i];&lt;br /&gt;
                break;&lt;br /&gt;
              case 4: // longitude&lt;br /&gt;
                g.longitude[j] = buffer[i];&lt;br /&gt;
                break;&lt;br /&gt;
              case 5: // direction longitude&lt;br /&gt;
                g.dir_long = buffer[i];&lt;br /&gt;
                break;&lt;br /&gt;
              case 9: // altitude&lt;br /&gt;
                g.altitude[j] = buffer[i];&lt;br /&gt;
                break;&lt;br /&gt;
              case 10: //&lt;br /&gt;
              default:&lt;br /&gt;
                break;&lt;br /&gt;
                }&lt;br /&gt;
              j++;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
  return g;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
gps_print(gps g)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t lat[11] =&lt;br /&gt;
    { &amp;quot;latitude : &amp;quot; };&lt;br /&gt;
  uint8_t lon[12] =&lt;br /&gt;
    { &amp;quot;longitude : &amp;quot; };&lt;br /&gt;
  uint8_t alt[11] =&lt;br /&gt;
    { &amp;quot;altitude : &amp;quot; };&lt;br /&gt;
&lt;br /&gt;
  for (uint8_t i = 0; i &amp;lt; 11; i++)&lt;br /&gt;
    {&lt;br /&gt;
      usart_0_transmit(lat[i]);&lt;br /&gt;
    }&lt;br /&gt;
  for (uint8_t i = 0; i &amp;lt; 9; i++)&lt;br /&gt;
    {&lt;br /&gt;
      usart_0_transmit(g.latitude[i]);&lt;br /&gt;
    }&lt;br /&gt;
  usart_0_transmit(' ');&lt;br /&gt;
  usart_0_transmit(g.dir_lat);&lt;br /&gt;
  usart_0_transmit('\n');&lt;br /&gt;
&lt;br /&gt;
  for (uint8_t i = 0; i &amp;lt; 12; i++)&lt;br /&gt;
    {&lt;br /&gt;
      usart_0_transmit(lon[i]);&lt;br /&gt;
    }&lt;br /&gt;
  for (uint8_t i = 0; i &amp;lt; 11; i++)&lt;br /&gt;
    {&lt;br /&gt;
      usart_0_transmit(g.longitude[i]);&lt;br /&gt;
    }&lt;br /&gt;
  usart_0_transmit(' ');&lt;br /&gt;
  usart_0_transmit(g.dir_long);&lt;br /&gt;
  usart_0_transmit('\n');&lt;br /&gt;
&lt;br /&gt;
  for (uint8_t i = 0; i &amp;lt; 11; i++)&lt;br /&gt;
    {&lt;br /&gt;
      usart_0_transmit(alt[i]);&lt;br /&gt;
    }&lt;br /&gt;
  for (uint8_t i = 0; i &amp;lt; 5; i++)&lt;br /&gt;
    {&lt;br /&gt;
      usart_0_transmit(g.altitude[i]);&lt;br /&gt;
    }&lt;br /&gt;
  usart_0_transmit(' ');&lt;br /&gt;
  usart_0_transmit('m');&lt;br /&gt;
  usart_0_transmit('\n');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  twi_master_setup();&lt;br /&gt;
  usart_0_setup();&lt;br /&gt;
  usart_0_transmitter_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  gps g;&lt;br /&gt;
  setup();&lt;br /&gt;
  while (1)&lt;br /&gt;
    {&lt;br /&gt;
      uint8_t reg = 0xFF;&lt;br /&gt;
      uint8_t buffer[200];&lt;br /&gt;
      twi_read_bytes((0x42 &amp;lt;&amp;lt; 1), &amp;amp;reg, 200, buffer);&lt;br /&gt;
&lt;br /&gt;
      g = gps_gpgga(buffer);&lt;br /&gt;
&lt;br /&gt;
      gps_print(g);&lt;br /&gt;
      _delay_ms(2000);&lt;br /&gt;
    }&lt;br /&gt;
  return 1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Acc%C3%A9l%C3%A9rom%C3%A8tre-Gyroscope-Boussole_9_axes_MPU-9150</id>
		<title>Accéléromètre-Gyroscope-Boussole 9 axes MPU-9150</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Acc%C3%A9l%C3%A9rom%C3%A8tre-Gyroscope-Boussole_9_axes_MPU-9150"/>
				<updated>2013-09-27T13:27:39Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le [http://www.invensense.com/mems/gyro/mpu9150.html MPU-9150], proposé par InvenSense, est un module permettant de détecter l'orientation sur 9 degré de liberté. Il est composé du [http://www.invensense.com/mems/gyro/mpu6050.html MPU-6050] qui contient un gyroscope 3 axes et un accéléromètre 3 axes et du [http://www.akm.com/akm/en/file/datasheet/AK8975.pdf AK8975] qui est une boussole numérique 3 axes.&lt;br /&gt;
&lt;br /&gt;
== MPU-9150 ==&lt;br /&gt;
L'accéléromètre 3 axes mesure l'accélération linéaire suivant x, y et z. La mesure est en g.&lt;br /&gt;
&lt;br /&gt;
Le gyromètre 3 axes mesure la vitesse angulaire autour des 3 axes x, y et z. La mesure est en °/s.&lt;br /&gt;
&lt;br /&gt;
La boussole 3 axes mesure le champs magnétique sur x, y et z. La mesure est en µT.&lt;br /&gt;
&lt;br /&gt;
La communication avec le MPU-9150 se fait par liaison i2c. L'adresse du module par défaut est 0x68. Il est cependant possible de modifier l'adresse (0x69) grace au cavalier à souder sur AD0.&lt;br /&gt;
&lt;br /&gt;
Les nombreux registres accessibles permettent de configurer le MPU-9150 au besoin du système (précision du gyroscope et de l'accéléromètre...). Voir le document sur la [http://www.invensense.com/mems/gyro/documents/RM-MPU-9150A-00v4_2.pdf description des registres]. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tests ==&lt;br /&gt;
&lt;br /&gt;
Nous utilisons une carte ARDUINO UNO et le MPU-9150 monté sur la carte d'évaluation de [https://www.sparkfun.com/products/11486 Sparkfun]. Cette carte permet une utilisation facile du composant MPU-9150 en intégrant les condensateurs nécessaire à son utilisation et les résistances de pull up pour la liaison i2c.&lt;br /&gt;
&lt;br /&gt;
Le câblage est très simple :&lt;br /&gt;
&lt;br /&gt;
MPU91-50 / ARDUINO&lt;br /&gt;
&lt;br /&gt;
GND → GND&lt;br /&gt;
&lt;br /&gt;
VCC → +3.3V&lt;br /&gt;
&lt;br /&gt;
SDA → A4&lt;br /&gt;
&lt;br /&gt;
SCL → A5&lt;br /&gt;
&lt;br /&gt;
Nous allons décrire quelques fonctions permettant de récupérer les données en x, y et z de l'accéléromètre, du gyroscope et la température.&lt;br /&gt;
&lt;br /&gt;
=== Exemple langage ARDUINO ===&lt;br /&gt;
Un exemple est expliqué [http://playground.arduino.cc/Main/MPU-6050#sketch ici]&lt;br /&gt;
&lt;br /&gt;
=== Exemple langage C ===&lt;br /&gt;
&lt;br /&gt;
==== Liaison i2c ====&lt;br /&gt;
La liaison twi (i2c) et les fonctions sont expliquées [http://geonobotwiki.free.fr/doku.php?id=robotics:computing:communication_twi_entre_atmega ici]&lt;br /&gt;
&lt;br /&gt;
Le MPU-9150 est configuré en esclave à l'adresse 0x68. La UNO est configurée en maitre.&lt;br /&gt;
&lt;br /&gt;
==== Fonctions du MPU-9150 ====&lt;br /&gt;
&lt;br /&gt;
===== Initialisation =====&lt;br /&gt;
&lt;br /&gt;
Le capteur est par défaut en mode sleep. Pour le réveiller, il faut mettre à 0 le bit SLEEP du registre 107 – Power Management 1 (PWR_MGMT_1). Ce registre permet également d'activer le capteur de température (mettre le bit TEMP_DIS à 0).&lt;br /&gt;
&lt;br /&gt;
Le tableau reg[2] contient l'adresse du registre  PWR_MGMT_1 et la valeur à écrire dans le registre (ici 0 car nous voulons désactiver le mode sleep et activer le capteur de température).&lt;br /&gt;
Il faut configurer la liaison i2c en mode master. &lt;br /&gt;
La fonction twi_write_bytes permet d'envoyer des octets à un esclave. Ici on envoie 2 octets du tableau reg à l'adresse  MPU9150_DEFAULT_ADDRESS.&lt;br /&gt;
Le décalage de l'adresse vient de fait que dans le MPU-9150 stocke son adresse sur les 7 bits de poids fort.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define MPU9150_DEFAULT_ADDRESS 0x68&lt;br /&gt;
#define MPU9150_ACCEL_XOUT_H 0x3B&lt;br /&gt;
#define MPU9150_TEMP_OUT_H 0x41&lt;br /&gt;
#define MPU9150_GYRO_XOUT_H 0x43&lt;br /&gt;
#define MPU9150_PWR_MGMT_1 0x6B&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
mpu9150_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* clear the SLEEP bit to start the sensor */&lt;br /&gt;
  uint8_t reg[2] = {MPU9150_PWR_MGMT_1, 0};&lt;br /&gt;
&lt;br /&gt;
  twi_master_setup(); /* i2c to master mode */&lt;br /&gt;
  twi_write_bytes((MPU9150_DEFAULT_ADDRESS &amp;lt;&amp;lt; 1), 2, reg);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Lecture de la température =====&lt;br /&gt;
&lt;br /&gt;
La température est lue sur 2 octets à l'adresse MPU9150_TEMP_OUT_H (registres 65   (high) et 66 (low)). La valeur lue est une image de la température : Température en degré Celsius = valeur des registres / 340 + 35.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * @return temperature in degrees C = (TEMP_OUT signed / 340) + 35&lt;br /&gt;
 * */&lt;br /&gt;
int16_t&lt;br /&gt;
mpu9150_read_temperature(void)&lt;br /&gt;
{&lt;br /&gt;
  volatile uint8_t buffer[2] = { 0, 0 };&lt;br /&gt;
  uint8_t reg = MPU9150_TEMP_OUT_H;&lt;br /&gt;
&lt;br /&gt;
  twi_read_bytes(MPU9150_DEFAULT_ADDRESS &amp;lt;&amp;lt; 1, &amp;amp;reg, 2, buffer);&lt;br /&gt;
&lt;br /&gt;
  int16_t temperature;&lt;br /&gt;
  temperature = ((buffer[0] &amp;lt;&amp;lt; 8) + buffer[1]);&lt;br /&gt;
  temperature /= 340;&lt;br /&gt;
  temperature += 35;&lt;br /&gt;
  return temperature;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Lecture du gyroscope =====&lt;br /&gt;
On a définit une structure contenant les variables x, y et z pour stocker les valeurs sur les 3 axes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct&lt;br /&gt;
{&lt;br /&gt;
  int16_t x;&lt;br /&gt;
  int16_t y;&lt;br /&gt;
  int16_t z;&lt;br /&gt;
} x_y_z;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
x_y_z&lt;br /&gt;
mpu9150_read_gyroscope(void)&lt;br /&gt;
{&lt;br /&gt;
  volatile uint8_t buffer[6];&lt;br /&gt;
  uint8_t reg = MPU9150_GYRO_XOUT_H;&lt;br /&gt;
&lt;br /&gt;
  twi_read_bytes(MPU9150_DEFAULT_ADDRESS &amp;lt;&amp;lt; 1, &amp;amp;reg, 6, buffer);&lt;br /&gt;
&lt;br /&gt;
  x_y_z gyro;&lt;br /&gt;
  gyro.x = (buffer[0] &amp;lt;&amp;lt; 8) + buffer[1];&lt;br /&gt;
  gyro.y = (buffer[2] &amp;lt;&amp;lt; 8) + buffer[3];&lt;br /&gt;
  gyro.z = (buffer[4] &amp;lt;&amp;lt; 8) + buffer[5];&lt;br /&gt;
  return gyro;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Lecture de l'accéléromètre =====&lt;br /&gt;
C'est le même modèle que la lecture du gyroscope.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
x_y_z&lt;br /&gt;
mpu9150_read_accelerometer(void)&lt;br /&gt;
{&lt;br /&gt;
  volatile uint8_t buffer[6];&lt;br /&gt;
  uint8_t reg = MPU9150_ACCEL_XOUT_H;&lt;br /&gt;
&lt;br /&gt;
  twi_read_bytes(MPU9150_DEFAULT_ADDRESS &amp;lt;&amp;lt; 1, &amp;amp;reg, 6, buffer);&lt;br /&gt;
&lt;br /&gt;
  x_y_z accel;&lt;br /&gt;
  accel.x = (buffer[0] &amp;lt;&amp;lt; 8) + buffer[1];&lt;br /&gt;
  accel.y = (buffer[2] &amp;lt;&amp;lt; 8) + buffer[3];&lt;br /&gt;
  accel.z = (buffer[4] &amp;lt;&amp;lt; 8) + buffer[5];&lt;br /&gt;
  return accel;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Fonction de tests =====&lt;br /&gt;
La fonction principale demande les valeurs du capteur de température, du gyroscope et de l'accéléromètre et retourne les valeurs sur le port série.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  usart_0_setup();&lt;br /&gt;
  usart_0_transmitter_enable();&lt;br /&gt;
  mpu9150_setup();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
  _delay_ms(1000);&lt;br /&gt;
&lt;br /&gt;
  while (1)&lt;br /&gt;
    {&lt;br /&gt;
      _delay_ms(1000);&lt;br /&gt;
      int16_t t = mpu9150_read_temperature();&lt;br /&gt;
&lt;br /&gt;
      usart_0_transmit(t &amp;gt;&amp;gt; 8);&lt;br /&gt;
      usart_0_transmit(t);&lt;br /&gt;
&lt;br /&gt;
      _delay_ms(1000);&lt;br /&gt;
&lt;br /&gt;
      x_y_z gyro = mpu9150_read_gyroscope();&lt;br /&gt;
&lt;br /&gt;
      usart_0_transmit(gyro.x &amp;gt;&amp;gt; 8);&lt;br /&gt;
      usart_0_transmit(gyro.x);&lt;br /&gt;
      usart_0_transmit(gyro.y &amp;gt;&amp;gt; 8);&lt;br /&gt;
      usart_0_transmit(gyro.y);&lt;br /&gt;
      usart_0_transmit(gyro.z &amp;gt;&amp;gt; 8);&lt;br /&gt;
      usart_0_transmit(gyro.z);&lt;br /&gt;
&lt;br /&gt;
	_delay_ms(1000);&lt;br /&gt;
&lt;br /&gt;
      x_y_z acc = mpu9150_read_accelerometer();&lt;br /&gt;
&lt;br /&gt;
      usart_0_transmit(acc.x &amp;gt;&amp;gt; 8);&lt;br /&gt;
      usart_0_transmit(acc.x);&lt;br /&gt;
      usart_0_transmit(acc.y &amp;gt;&amp;gt; 8);&lt;br /&gt;
      usart_0_transmit(acc.y);&lt;br /&gt;
      usart_0_transmit(acc.z &amp;gt;&amp;gt; 8);&lt;br /&gt;
      usart_0_transmit(gyro.z);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Acc%C3%A9l%C3%A9rom%C3%A8tre-Gyroscope-Boussole_9_axes_MPU-9150</id>
		<title>Accéléromètre-Gyroscope-Boussole 9 axes MPU-9150</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Acc%C3%A9l%C3%A9rom%C3%A8tre-Gyroscope-Boussole_9_axes_MPU-9150"/>
				<updated>2013-09-27T13:26:32Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : Page créée avec « Le [http://www.invensense.com/mems/gyro/mpu9150.html MPU-9150], proposé par InvenSense, est un module permettant de détecter l'orientation sur 9 degré de liberté. Il e... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le [http://www.invensense.com/mems/gyro/mpu9150.html MPU-9150], proposé par InvenSense, est un module permettant de détecter l'orientation sur 9 degré de liberté. Il est composé du [http://www.invensense.com/mems/gyro/mpu6050.html MPU-6050] qui contient un gyroscope 3 axes et un accéléromètre 3 axes et du [http://www.akm.com/akm/en/file/datasheet/AK8975.pdf AK8975] qui est une boussole numérique 3 axes.&lt;br /&gt;
&lt;br /&gt;
== MPU-9150 ==&lt;br /&gt;
L'accéléromètre 3 axes mesure l'accélération linéaire suivant x, y et z. La mesure est en g.&lt;br /&gt;
&lt;br /&gt;
Le gyromètre 3 axes mesure la vitesse angulaire autour des 3 axes x, y et z. La mesure est en °/s.&lt;br /&gt;
&lt;br /&gt;
La boussole 3 axes mesure le champs magnétique sur x, y et z. La mesure est en µT.&lt;br /&gt;
&lt;br /&gt;
La communication avec le MPU-9150 se fait par liaison i2c. L'adresse du module par défaut est 0x68. Il est cependant possible de modifier l'adresse (0x69) grace au cavalier à souder sur AD0.&lt;br /&gt;
&lt;br /&gt;
Les nombreux registres accessibles permettent de configurer le MPU-9150 au besoin du système (précision du gyroscope et de l'accéléromètre...). Voir le document sur la [http://www.invensense.com/mems/gyro/documents/RM-MPU-9150A-00v4_2.pdf description des registres]. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tests ==&lt;br /&gt;
&lt;br /&gt;
Nous utilisons une carte ARDUINO UNO et le MPU-9150 monté sur la carte d'évaluation de [https://www.sparkfun.com/products/11486 Sparkfun]. Cette carte permet une utilisation facile du composant MPU-9150 en intégrant les condensateurs nécessaire à son utilisation et les résistances de pull up pour la liaison i2c.&lt;br /&gt;
&lt;br /&gt;
Le câblage est très simple :&lt;br /&gt;
&lt;br /&gt;
MPU91-50 / ARDUINO&lt;br /&gt;
&lt;br /&gt;
GND → GND&lt;br /&gt;
&lt;br /&gt;
VCC → +3.3V&lt;br /&gt;
&lt;br /&gt;
SDA → A4&lt;br /&gt;
&lt;br /&gt;
SCL → A5&lt;br /&gt;
&lt;br /&gt;
Nous allons décrire quelques fonctions permettant de récupérer les données en x, y et z de l'accéléromètre, du gyroscope et la température.&lt;br /&gt;
&lt;br /&gt;
=== Exemple langage ARDUINO ===&lt;br /&gt;
Un exemple est expliqué [http://playground.arduino.cc/Main/MPU-6050#sketch ici]&lt;br /&gt;
&lt;br /&gt;
=== Exemple langage C ===&lt;br /&gt;
&lt;br /&gt;
==== Liaison i2c ====&lt;br /&gt;
La liaison twi (i2c) et les fonctions sont expliquées [http://geonobotwiki.free.fr/doku.php?id=robotics:computing:communication_twi_entre_atmega ici]&lt;br /&gt;
&lt;br /&gt;
Le MPU-9150 est configuré en esclave à l'adresse 0x68. La UNO est configurée en maitre.&lt;br /&gt;
&lt;br /&gt;
==== Fonctions du MPU-9150 ====&lt;br /&gt;
&lt;br /&gt;
===== Initialisation =====&lt;br /&gt;
&lt;br /&gt;
Le capteur est par défaut en mode sleep. Pour le réveiller, il faut mettre à 0 le bit SLEEP du registre 107 – Power Management 1 (PWR_MGMT_1). Ce registre permet également d'activer le capteur de température (mettre le bit TEMP_DIS à 0).&lt;br /&gt;
&lt;br /&gt;
Le tableau reg[2] contient l'adresse du registre  PWR_MGMT_1 et la valeur à écrire dans le registre (ici 0 car nous voulons désactiver le mode sleep et activer le capteur de température).&lt;br /&gt;
Il faut configurer la liaison i2c en mode master. &lt;br /&gt;
La fonction twi_write_bytes permet d'envoyer des octets à un esclave. Ici on envoie 2 octets du tableau reg à l'adresse  MPU9150_DEFAULT_ADDRESS.&lt;br /&gt;
Le décalage de l'adresse vient de fait que dans le MPU-9150 stocke son adresse sur les 7 bits de poids fort.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define MPU9150_DEFAULT_ADDRESS 0x68&lt;br /&gt;
#define MPU9150_ACCEL_XOUT_H 0x3B&lt;br /&gt;
#define MPU9150_TEMP_OUT_H 0x41&lt;br /&gt;
#define MPU9150_GYRO_XOUT_H 0x43&lt;br /&gt;
#define MPU9150_PWR_MGMT_1 0x6B&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
mpu9150_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* clear the SLEEP bit to start the sensor */&lt;br /&gt;
  uint8_t reg[2] = {MPU9150_PWR_MGMT_1, 0};&lt;br /&gt;
&lt;br /&gt;
  twi_master_setup(); /* i2c to master mode */&lt;br /&gt;
  twi_write_bytes((MPU9150_DEFAULT_ADDRESS &amp;lt;&amp;lt; 1), 2, reg);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Lecture de la température =====&lt;br /&gt;
&lt;br /&gt;
La température est lue sur 2 octets à l'adresse MPU9150_TEMP_OUT_H (registres 65   (high) et 66 (low)). La valeur lue est une image de la température : Température en degré Celsius = valeur des registres / 340 + 35.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * @return temperature in degrees C = (TEMP_OUT signed / 340) + 35&lt;br /&gt;
 * */&lt;br /&gt;
int16_t&lt;br /&gt;
mpu9150_read_temperature(void)&lt;br /&gt;
{&lt;br /&gt;
  volatile uint8_t buffer[2] = { 0, 0 };&lt;br /&gt;
  uint8_t reg = MPU9150_TEMP_OUT_H;&lt;br /&gt;
&lt;br /&gt;
  twi_read_bytes(MPU9150_DEFAULT_ADDRESS &amp;lt;&amp;lt; 1, &amp;amp;reg, 2, buffer);&lt;br /&gt;
&lt;br /&gt;
  int16_t temperature;&lt;br /&gt;
  temperature = ((buffer[0] &amp;lt;&amp;lt; 8) + buffer[1]);&lt;br /&gt;
  temperature /= 340;&lt;br /&gt;
  temperature += 35;&lt;br /&gt;
  return temperature;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Lecture du gyroscope =====&lt;br /&gt;
On a définit une structure contenant les variables x, y et z pour stocker les valeurs sur les 3 axes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct&lt;br /&gt;
{&lt;br /&gt;
  int16_t x;&lt;br /&gt;
  int16_t y;&lt;br /&gt;
  int16_t z;&lt;br /&gt;
} x_y_z;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
x_y_z&lt;br /&gt;
mpu9150_read_gyroscope(void)&lt;br /&gt;
{&lt;br /&gt;
  volatile uint8_t buffer[6];&lt;br /&gt;
  uint8_t reg = MPU9150_GYRO_XOUT_H;&lt;br /&gt;
&lt;br /&gt;
  twi_read_bytes(MPU9150_DEFAULT_ADDRESS &amp;lt;&amp;lt; 1, &amp;amp;reg, 6, buffer);&lt;br /&gt;
&lt;br /&gt;
  x_y_z gyro;&lt;br /&gt;
  gyro.x = (buffer[0] &amp;lt;&amp;lt; 8) + buffer[1];&lt;br /&gt;
  gyro.y = (buffer[2] &amp;lt;&amp;lt; 8) + buffer[3];&lt;br /&gt;
  gyro.z = (buffer[4] &amp;lt;&amp;lt; 8) + buffer[5];&lt;br /&gt;
  return gyro;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Lecture de l'accéléromètre =====&lt;br /&gt;
C'est le même modèle que la lecture du gyroscope.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
x_y_z&lt;br /&gt;
mpu9150_read_accelerometer(void)&lt;br /&gt;
{&lt;br /&gt;
  volatile uint8_t buffer[6];&lt;br /&gt;
  uint8_t reg = MPU9150_ACCEL_XOUT_H;&lt;br /&gt;
&lt;br /&gt;
  twi_read_bytes(MPU9150_DEFAULT_ADDRESS &amp;lt;&amp;lt; 1, &amp;amp;reg, 6, buffer);&lt;br /&gt;
&lt;br /&gt;
  x_y_z accel;&lt;br /&gt;
  accel.x = (buffer[0] &amp;lt;&amp;lt; 8) + buffer[1];&lt;br /&gt;
  accel.y = (buffer[2] &amp;lt;&amp;lt; 8) + buffer[3];&lt;br /&gt;
  accel.z = (buffer[4] &amp;lt;&amp;lt; 8) + buffer[5];&lt;br /&gt;
  return accel;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Fonction de tests =====&lt;br /&gt;
La fonction principale demande les valeurs du capteur de température, du gyroscope et de l'accéléromètre et retourne les valeurs sur le port série.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  usart_0_setup();&lt;br /&gt;
  usart_0_transmitter_enable();&lt;br /&gt;
  mpu9150_setup();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
  _delay_ms(1000);&lt;br /&gt;
&lt;br /&gt;
  while (1)&lt;br /&gt;
    {&lt;br /&gt;
      _delay_ms(1000);&lt;br /&gt;
      int16_t t = mpu9150_read_temperature();&lt;br /&gt;
&lt;br /&gt;
      usart_0_transmit(t &amp;gt;&amp;gt; 8);&lt;br /&gt;
      usart_0_transmit(t);&lt;br /&gt;
&lt;br /&gt;
      _delay_ms(1000);&lt;br /&gt;
&lt;br /&gt;
      x_y_z gyro = mpu9150_read_gyroscope();&lt;br /&gt;
&lt;br /&gt;
      usart_0_transmit(gyro.x &amp;gt;&amp;gt; 8);&lt;br /&gt;
      usart_0_transmit(gyro.x);&lt;br /&gt;
      usart_0_transmit(gyro.y &amp;gt;&amp;gt; 8);&lt;br /&gt;
      usart_0_transmit(gyro.y);&lt;br /&gt;
      usart_0_transmit(gyro.z &amp;gt;&amp;gt; 8);&lt;br /&gt;
      usart_0_transmit(gyro.z);&lt;br /&gt;
&lt;br /&gt;
	_delay_ms(1000);&lt;br /&gt;
&lt;br /&gt;
      x_y_z acc = mpu9150_read_accelerometer();&lt;br /&gt;
&lt;br /&gt;
      usart_0_transmit(acc.x &amp;gt;&amp;gt; 8);&lt;br /&gt;
      usart_0_transmit(acc.x);&lt;br /&gt;
      usart_0_transmit(acc.y &amp;gt;&amp;gt; 8);&lt;br /&gt;
      usart_0_transmit(acc.y);&lt;br /&gt;
      usart_0_transmit(acc.z &amp;gt;&amp;gt; 8);&lt;br /&gt;
      usart_0_transmit(gyro.z);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Capteur_US_URM37</id>
		<title>Capteur US URM37</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Capteur_US_URM37"/>
				<updated>2013-09-02T13:46:33Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : utilisation du capteur URM37 avec une ARDUINO UNO&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le capteur URM37 est un capteur de distance utilisant les ultrasons. Il a une portée de 4 à 500 cm avec une résolution de 1 cm. Ce capteur est également équipé d'un capteur de température (de -10 à 70 °C). Le principal avantage de ce capteur est de pouvoir contrôler directement un servomoteur dans le but de monter le capteur sur une tourelle pour faire un scanner. La précision de rotation du servomoteur est de 6°.&lt;br /&gt;
&lt;br /&gt;
= Description des pins =&lt;br /&gt;
&lt;br /&gt;
1. +VCC - +5V&lt;br /&gt;
&lt;br /&gt;
2. GND - Masse&lt;br /&gt;
&lt;br /&gt;
3. RST - Reset&lt;br /&gt;
&lt;br /&gt;
4. PWM – sortie PWM&lt;br /&gt;
&lt;br /&gt;
5. MOTO pour le contrôle d'un servomoteur&lt;br /&gt;
&lt;br /&gt;
6. COMP/TRIG&lt;br /&gt;
COMP – En mode AUTO, la pin passe à 0 quand la distance détectée est plus petite que la distance seuil.&lt;br /&gt;
TRIG – En mode PWM, entrée trigger (pour déclencher une lecture)&lt;br /&gt;
&lt;br /&gt;
7. NC &lt;br /&gt;
&lt;br /&gt;
8. RXD - communication RS232, et TTL&lt;br /&gt;
&lt;br /&gt;
9. TXD – communication RS232 et TTL &lt;br /&gt;
&lt;br /&gt;
= Mode =&lt;br /&gt;
Ce capteur peut être utilisé selon 3 modes : communication série (TTL ou RS232), PWM ou TRIG AUTO. Le mode série est toujours activé et le capteur est toujours en attente d'une commande (configuration ou demande de lecture).&lt;br /&gt;
&lt;br /&gt;
== Mode série ==&lt;br /&gt;
Ce mode très simple à mettre an œuvre permet de configurer les modes TRIG AUTO et PWM. Il sert également à lire la distance et la température.&lt;br /&gt;
=== RS232 / TTL ===&lt;br /&gt;
La liaison série peut être configurée en sortie RS232 (+12V / -12V) pour être utilisée directement avec un PC ou en sortie TTL (0V / +5V) pour être utilisée avec un microcontroleur. Les cavaliers J1, J2 et J3 permettent de changer la configuration de la liaison. La configuration est expliquée [http://www.dfrobot.com/wiki/index.php/URM37_V3.2_Ultrasonic_Sensor_%28SKU:SEN0001%29 ici].&lt;br /&gt;
&lt;br /&gt;
Pour notre exemple, nous allons utiliser une ARDUINO UNO donc il faut donc configurer la liaison en sortie TTL.&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
Il faut brancher RX (pin 8) du capteur sur TX (pin 1) de la ARDUINO et TX (pin 9) du capteur sur RX (pin 0) de la ARDUINO. La sortie 5 MOTO du capteur doit être branchée sur l'entrée contrôle du servomoteur (fil orange).&lt;br /&gt;
=== Protocole série ===&lt;br /&gt;
La liaison série est configurée à 9600 baud avec 8 bits de données, 1 bit de stop et sans parité. Les trames envoyées ou reçues sont composées de 4 octets : commande + donnée1 + donnée2 + somme.&lt;br /&gt;
somme permet de contrôler que la trame envoyée ou reçue est correcte : on additionne sur 8 bits commande + donnée1 + donnée2.&lt;br /&gt;
Par exemple, la trame 0x44 + 0x02 + 0xAA donne une somme de 0xF0.&lt;br /&gt;
=== Commandes ===&lt;br /&gt;
==== Lecture de la température (16 bits) ====&lt;br /&gt;
Commande : 0x11＋NC＋NC＋Sum&lt;br /&gt;
Réponse : 0x11+High(temperature)+Low(temperature)+SUM&lt;br /&gt;
Remarques : La valeur de la température est sur 12 bits (4 bits faible de High et les 8 bits de Low). Les 4 premiers bits de High représente le signe. Si la température est positive, ils sont à 0. Si la température est négative ils sont à 1. La résolution est de 0,1.&lt;br /&gt;
Erreur : Si la lecture de la température est incorrecte, le capteur retourne 0x11+0xFF+0xFF+SUM &lt;br /&gt;
Exemple : 0x11 + 0x00 + 0xDC + 0x27 représente une température de 22°C (0xDC = 220)&lt;br /&gt;
		0x11 + 0xF0 + 0x32 + 0x33 représente une température de -5°C (0x32 = 50)&lt;br /&gt;
==== Lecture de la distance (16 bits) ====&lt;br /&gt;
Commande : 0x22＋Degree＋NC＋SUM&lt;br /&gt;
Réponse :  0x22＋High(distance)＋Low(distance)+SUM&lt;br /&gt;
Remarques : Degree est un pas (de 0 à 46) qui correspond au degré de rotation du servomoteur (de 0 à 270°).&lt;br /&gt;
Si la lecture de distance est incorrecte, le capteur retourne 0x22+0xFF+0xFF+SUM.&lt;br /&gt;
Exemple : 0x22 + 0x03 + 0x00 + 0x25 est une demande de lecture de distance en plaçant le servo à 18°.&lt;br /&gt;
==== Lecture en EEPROM ====&lt;br /&gt;
Commande : 0x33＋Add＋NC＋SUM&lt;br /&gt;
Réponse : 0x33＋Add＋NC＋SUM&lt;br /&gt;
==== Ecriture en EEPROM ====&lt;br /&gt;
Cette écriture permet de configurer les modes PWM ou TRIG AUTO.&lt;br /&gt;
Commande : 0x44＋Add＋Data＋SUM&lt;br /&gt;
Réponse :  0x44＋Add＋Data＋SUM&lt;br /&gt;
Remarques : Les adresses (de 0x00 à 0x02) permettent de configurer les modes :&lt;br /&gt;
0x00 : distance seuil (Low)&lt;br /&gt;
0x01 : distance seuil (High)&lt;br /&gt;
0x02 : mode 0xAA pour TRIG AUTO et 0xBB pour PWM&lt;br /&gt;
&lt;br /&gt;
Exemple : 0x44 + 0x02 + 0xBB + 0x01 configure le mode PWM.&lt;br /&gt;
=== Exemple Langage ARDUINO ===&lt;br /&gt;
Des exemples sont expliqués [http://www.dfrobot.com/wiki/index.php/URM37_V3.2_Ultrasonic_Sensor_%28SKU:SEN0001%29 ici].&lt;br /&gt;
=== Exemple Langage C ===&lt;br /&gt;
Dans un premier temps, il faut configurer la liaison série ( 9600 Baud, 8 bits de données, sans parité avec 1 bit de stop) et activer l’émission et la réception. Ensuite, il faut écrire les fonctions de base pour émettre et recevoir un octet.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
usart_0_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  DDRD &amp;amp;= ~(1 &amp;lt;&amp;lt; PD0); /* initialize pin PD0 (RX) as input pin */&lt;br /&gt;
  DDRD |= (1 &amp;lt;&amp;lt; PD1); /* initialize pin PD1 (TX) as output pin */&lt;br /&gt;
&lt;br /&gt;
  UBRR0 = 103; /* 9600 Baud at 16MHz */&lt;br /&gt;
  &lt;br /&gt;
  UCSR0A = 0;&lt;br /&gt;
  UCSR0B |= (1 &amp;lt;&amp;lt; RXEN0) | (1 &amp;lt;&amp;lt; TXEN0);&lt;br /&gt;
&lt;br /&gt;
  /* 8-bits, no parity, 1-stop-bit */&lt;br /&gt;
  UCSR0C = (1 &amp;lt;&amp;lt; UCSZ01) | (1 &amp;lt;&amp;lt; UCSZ00);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint8_t&lt;br /&gt;
usart_0_receive(void)&lt;br /&gt;
{&lt;br /&gt;
  // wait for data to be received&lt;br /&gt;
  while (!(UCSR0A &amp;amp; (1 &amp;lt;&amp;lt; RXC0)))&lt;br /&gt;
    ;&lt;br /&gt;
  // get and return received data from buffer&lt;br /&gt;
  //PORTB = 0xFF;&lt;br /&gt;
  return UDR0 ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// transmit a char&lt;br /&gt;
void&lt;br /&gt;
usart_0_transmit(uint8_t data)&lt;br /&gt;
{&lt;br /&gt;
  // wait for empty transmit buffer&lt;br /&gt;
  while (!(UCSR0A &amp;amp; (1 &amp;lt;&amp;lt; UDRE0)))&lt;br /&gt;
    ;&lt;br /&gt;
  // put data info buffer, sends the data&lt;br /&gt;
  UDR0 = data;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite, il faut écrire les fonctions du capteur pour pouvoir demander une lecture de distance et température.&lt;br /&gt;
&lt;br /&gt;
urm37_send_command calcule la somme de la trame et envoie les 4 octets&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
urm37_send_command(uint8_t command, uint8_t data1, uint8_t data2)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t sum = command + data1 + data2;&lt;br /&gt;
  usart_0_transmit(command);&lt;br /&gt;
  usart_0_transmit(data1);&lt;br /&gt;
  usart_0_transmit(data2);&lt;br /&gt;
  usart_0_transmit(sum);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
urm37_read_command receptionne la reponse du capteur et la stocke dans le tableau urm37_command&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
urm37_read_command(void)&lt;br /&gt;
{&lt;br /&gt;
  for (uint8_t i = 0; i &amp;lt; 4; i++)&lt;br /&gt;
    {&lt;br /&gt;
      urm37_command[i] = usart_0_receive();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
urm37_read_distance effectue une lecture en distance en précisant l'angle du servomoteur et retourne la distance. De même, urm37_read_temperature effectue une lecture de température et retourne la température du capteur.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint16_t&lt;br /&gt;
urm37_read_distance(uint16_t angle)&lt;br /&gt;
{&lt;br /&gt;
  uint16_t distance = 0;&lt;br /&gt;
&lt;br /&gt;
  angle /= 6;&lt;br /&gt;
  if (angle &amp;gt; 46)&lt;br /&gt;
    {&lt;br /&gt;
      angle = 46;&lt;br /&gt;
    }&lt;br /&gt;
  urm37_send_command(READ_DIST, angle, 0x00);&lt;br /&gt;
&lt;br /&gt;
  urm37_read_command();&lt;br /&gt;
&lt;br /&gt;
  distance = (urm37_command[1] &amp;lt;&amp;lt; 8) + urm37_command[2];&lt;br /&gt;
    &lt;br /&gt;
  return distance;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int16_t&lt;br /&gt;
urm37_read_temperature(void)&lt;br /&gt;
{&lt;br /&gt;
  int16_t temperature;&lt;br /&gt;
&lt;br /&gt;
  urm37_send_command(READ_TEMP, 0x00, 0x00);&lt;br /&gt;
  urm37_read_command();&lt;br /&gt;
&lt;br /&gt;
  if (urm37_command[1] &amp;gt;= 0xF0)&lt;br /&gt;
    {&lt;br /&gt;
      temperature = -(((urm37_command[1] - 0xF0) &amp;lt;&amp;lt; 8) + urm37_command[2])&lt;br /&gt;
          / 10;&lt;br /&gt;
    }&lt;br /&gt;
  else&lt;br /&gt;
    {&lt;br /&gt;
      temperature = ((urm37_command[1] &amp;lt;&amp;lt; 8) + urm37_command[2]) / 10;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
  return temperature;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La fonction principale permet de faire une lecture de distance et de température toutes les secondes et de renvoyer les réponses sur le port série.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  usart_0_setup();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  unsigned int distance, temperature;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  _delay_ms(1000); /* delay 1s */&lt;br /&gt;
&lt;br /&gt;
  while (1)&lt;br /&gt;
    {&lt;br /&gt;
      distance = urm37_read_distance(200);&lt;br /&gt;
      _delay_ms(1000); // delay 1s&lt;br /&gt;
&lt;br /&gt;
      usart_0_transmit(distance);&lt;br /&gt;
&lt;br /&gt;
      /* uniquement en mode serie */&lt;br /&gt;
      temperature = urm37_read_temperature();&lt;br /&gt;
      _delay_ms(1000); /* delay 1s*/&lt;br /&gt;
&lt;br /&gt;
      usart_0_transmit(temperature);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Carte_Romeo</id>
		<title>Carte Romeo</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Carte_Romeo"/>
				<updated>2013-07-29T12:29:10Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : /* Commande à distance */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;La carte ROMEO de DFROBOT est une carte tout-en-un conçue pour faire ses premiers pas vers la robotique. Cette carte très simple d'utilisation permet de commander 2 moteurs, d'interfacer des capteurs et de piloter le robot à distance via un module X-bee. Elle est basée sur un microcontroleur ATMEGA32u4 (V2.0 R3).&lt;br /&gt;
&lt;br /&gt;
Pour tester la carte ROMEO, nous avons utilisé la plateforme de développement Turtle 2WD de DFROBOT. Cette plateforme est équipée de 2 roues montées en direct sur 2 motoréducteurs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Commande des moteurs ==&lt;br /&gt;
&lt;br /&gt;
Le moteur à courant continu est l'élément principal qui permet au robot de se déplacer. Sa vitesse est proportionnelle à la tension d'alimentation. Plus la tension est élevée plus le moteur va tourner rapidement. Il faut donc créer une tension continue variable pour faire varier la vitesse du moteur. &lt;br /&gt;
&lt;br /&gt;
=== Signaux PWM ===&lt;br /&gt;
Les signaux PWM permettent de fournir une tension continue variable à partir de signaux numériques (0 et 5V). Le microcontroleur va générer un signal en forme de créneaux. En faisant varier le rapport cyclique, la tension moyenne va varier et le moteur va tourner plus ou moins vite.&lt;br /&gt;
&lt;br /&gt;
=== Electronique ===&lt;br /&gt;
La carte ROMEO est équipée d'un module de commande pour moteur à courant continu (L298). Ce pont H va fournir la puissance nécessaire au moteur pour tourner. Le microcontroleur va fournir un signal PWM et un signal de direction pour chaque moteur.&lt;br /&gt;
&lt;br /&gt;
=== Exemple de code ===&lt;br /&gt;
==== Langage Arduino ====&lt;br /&gt;
Le L298 utilise la pin 4 (M1 : direction) et 5 (E1 : PWM) pour le moteur 1 et la pin 6 (E2 : PWM) et 7 (M2 : direction) pour le moteur 2.&lt;br /&gt;
&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php/DFRduino_Romeo-All_in_one_Controller_V1.1%28SKU:DFR0004%29 ici]&lt;br /&gt;
&lt;br /&gt;
==== Langage C ====&lt;br /&gt;
===== Fonctions PWM =====&lt;br /&gt;
Pour générer un signal PWM, le microcontroleur a besoin d'un timer interne. Il utilise le timer 3A  pour E1 et le timer 4D pour E2.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, il faut initialiser les timers en mode PWM. Nous configurons le mode PWM avec des valeurs fréquemment utilisées pour la commande de moteurs.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* timer3 is used for phase-correct 8-bits PWM mode &lt;br /&gt;
and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_3_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* set timer3 prescale factor to 64 */&lt;br /&gt;
  TCCR3B = (1 &amp;lt;&amp;lt; CS31) | (1 &amp;lt;&amp;lt; CS30);&lt;br /&gt;
  /* put timer3 in phase correct PWM mode */&lt;br /&gt;
  TCCR3A = (1 &amp;lt;&amp;lt; WGM30);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* timer4 is used for phase and frequency correct 10-bits PWM mode &lt;br /&gt;
* and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_4_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  TC4H = 0;&lt;br /&gt;
  /* set timer4 prescale factor to 64 */&lt;br /&gt;
  TCCR4B = (1 &amp;lt;&amp;lt; CS42) | (1 &amp;lt;&amp;lt; CS41) | (1 &amp;lt;&amp;lt; CS40);&lt;br /&gt;
  /* put timer 4 in phase and frequency correct PWM mode */&lt;br /&gt;
  TCCR4D =(1 &amp;lt;&amp;lt; WGM40);&lt;br /&gt;
  /* not used */&lt;br /&gt;
  TCCR4E = 0;&lt;br /&gt;
  /* Set top to 0xFF */&lt;br /&gt;
  OCR4C = 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut activer les pins utilisées par le L298 (5:OC3A et 6:OC4D).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PC6(OC3A) pin as output pin */&lt;br /&gt;
  DDRC |= (1 &amp;lt;&amp;lt; PORTC6);&lt;br /&gt;
  /* enable OC3A pin as PWM pin */&lt;br /&gt;
  TCCR3A |= (1 &amp;lt;&amp;lt; COM3A1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PD7 pin as output pin */&lt;br /&gt;
  DDRD |= (1 &amp;lt;&amp;lt; PORTD7);&lt;br /&gt;
  /* enable OC4D pin as PWM pin */TCCR4C |= (1 &amp;lt;&amp;lt; PWM4D);&lt;br /&gt;
  TCCR4C |= (1 &amp;lt;&amp;lt; COM4D1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, il faut indiquer la valeur du PWM : cette valeur indique le temps haut du signal compris entre 0 et 255. Par exemple, pour avoir un signal carré (temps haut = temps bas), il faut avoir une valeur de 127. Ces valeurs sont écrites dans les registres OCRnx.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* write value a in PWM 3A */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_write(char a)&lt;br /&gt;
{&lt;br /&gt;
  OCR3A = a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* write value a in PWM 4D */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_write(char a)&lt;br /&gt;
{&lt;br /&gt;
  OCR4D = a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Fonctions moteur =====&lt;br /&gt;
Nous avons ensuite créer des fonctions qui permettent au robot d'avancer, reculer et tourner en précisant la vitesse (de 0 à 255).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* stop */&lt;br /&gt;
void&lt;br /&gt;
stop(void)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(0);&lt;br /&gt;
  pwm_3A_write(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* advance&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
advance(uint8_t m1_speed, uint8_t m2_speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_3A_write(m1_speed);&lt;br /&gt;
  pwm_4D_write(m2_speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* back off&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
back_off(uint8_t m1_speed, uint8_t m2_speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_3A_write(m1_speed);&lt;br /&gt;
  pwm_4D_write(m2_speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn left&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_left(uint8_t m1_speed, uint8_t m2_speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_3A_write(m1_speed);&lt;br /&gt;
  pwm_4D_write(m2_speed);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn right&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_right(uint8_t m1_speed, uint8_t m2_speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_3A_write(m1_speed);&lt;br /&gt;
  pwm_4D_write(m2_speed);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, la fonction principale main() et les fonctions setup() qui définissent l'état des pins (entrée ou sortie) et active les modules PWM.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
motor_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* Motor controller */&lt;br /&gt;
  DDRD = (1 &amp;lt;&amp;lt; PORTD4); /* E1 (PD4) as output pin */&lt;br /&gt;
  DDRE = (1 &amp;lt;&amp;lt; PORTE6); /* E2 (PE6) as output pin */&lt;br /&gt;
&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  motor_setup();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    turn_left(100);&lt;br /&gt;
    //advance(200);&lt;br /&gt;
    // stop();&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Communication XBee ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Commande à distance ===&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* setup USART1&lt;br /&gt;
 * speed : 9600 Baud&lt;br /&gt;
 * 8-bits, no parity, 1-stop-bit */&lt;br /&gt;
void&lt;br /&gt;
USART_1_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  DDRD &amp;amp;= ~(1 &amp;lt;&amp;lt; PD2); /* initialize pin PD2 (RX) as input pin */&lt;br /&gt;
  DDRD |= (1 &amp;lt;&amp;lt; PD3); /* initialize pin PD3 (TX) as output pin */&lt;br /&gt;
&lt;br /&gt;
  UBRR1 = 103; /* 9600 Baud at 16MHz */&lt;br /&gt;
&lt;br /&gt;
  UCSR1A = 0;&lt;br /&gt;
&lt;br /&gt;
  /* 8-bits, no parity, 1-stop-bit */&lt;br /&gt;
  UCSR1C = (1 &amp;lt;&amp;lt; UCSZ11) | (1 &amp;lt;&amp;lt; UCSZ10);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il existe 2 solutions pour recevoir une donnée via la liaison série :&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
USART_1_receiver_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXEN1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned char&lt;br /&gt;
USART_1_receive(void)&lt;br /&gt;
{&lt;br /&gt;
  // wait for data to be received&lt;br /&gt;
  while (!(UCSR1A &amp;amp; (1 &amp;lt;&amp;lt; RXC1)))&lt;br /&gt;
    ;&lt;br /&gt;
  // get and return received data from buffer&lt;br /&gt;
  return UDR1 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
volatile char receive_char;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
USART_1_receiver_interrupt_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXEN1);&lt;br /&gt;
  /* enable interrupt on the RXC1 flag */&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXCIE1);&lt;br /&gt;
  SREG |= (1 &amp;lt;&amp;lt; SREG_I);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// receiver interrupt&lt;br /&gt;
ISR( USART1_RX_vect)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char dustbin = 0;&lt;br /&gt;
  &lt;br /&gt;
  receive_char = UDR1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
pin_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* Motor controller */&lt;br /&gt;
  DDRD = (1 &amp;lt;&amp;lt; PORTD4); /* PD4 as output pin */&lt;br /&gt;
  DDRE = (1 &amp;lt;&amp;lt; PORTE6); /* PE6 as output pin */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
&lt;br /&gt;
  USART_1_setup();&lt;br /&gt;
  //USART_1_receiver_enable();&lt;br /&gt;
  USART_1_receiver_interrupt_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  //char c;&lt;br /&gt;
  setup();&lt;br /&gt;
&lt;br /&gt;
  while (1)&lt;br /&gt;
    {&lt;br /&gt;
      //c = USART_1_receive();&lt;br /&gt;
&lt;br /&gt;
      switch (/*c*/receive_char)&lt;br /&gt;
        {&lt;br /&gt;
      case 'a':&lt;br /&gt;
        advance(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'b':&lt;br /&gt;
        back_off(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'r':&lt;br /&gt;
        turn_right(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'l':&lt;br /&gt;
        turn_left(100);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        stop();&lt;br /&gt;
        break;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conversion analogique / numérique ==&lt;br /&gt;
&lt;br /&gt;
Les capteurs que nous utilisons retourne généralement une information (tension) sous forme analogique. Pour exploiter cette information, le microcontroleur doit la convertir en signal numérique.&lt;br /&gt;
&lt;br /&gt;
Le convertisseur analogique / numérique de l'ATMEGA32U4 est un convertisseur 10 bits soit une précision de 1024 points. En se basant sur une tension de référence (généralement la tension d'alimentation), il va, par approximation successive, définir la valeur numérique correspondante à la tension.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, nous allons configurer le convertisseur. Le microcontroleur a 6 entrées analogiques sur le port F qu'il faut configurer en entrée. La tension de référence pour effectuer la conversion est la tension d'alimentation Vcc = 5V.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* Voltage reference : Vcc&lt;br /&gt;
 * Right adjust result&lt;br /&gt;
 * and with clock prescaled to system clock divided by 1024 */&lt;br /&gt;
void&lt;br /&gt;
adc_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* initialize PORTF pins as input pin */&lt;br /&gt;
  DDRF = 0x00;&lt;br /&gt;
&lt;br /&gt;
  /* set ADC prescale factor to 1024 */&lt;br /&gt;
  ADCSRA |= (1 &amp;lt;&amp;lt; ADPS2) | (1 &amp;lt;&amp;lt; ADPS1) | (1 &amp;lt;&amp;lt; ADPS0);&lt;br /&gt;
&lt;br /&gt;
  /* Vcc is reference voltage */&lt;br /&gt;
  ADMUX |= (1 &amp;lt;&amp;lt; REFS0);&lt;br /&gt;
&lt;br /&gt;
  /* Set ADC to Free-Running Mode */&lt;br /&gt;
  ADCSRB = 0;&lt;br /&gt;
&lt;br /&gt;
  /* adc enable */&lt;br /&gt;
  ADCSRA |= (1 &amp;lt;&amp;lt; ADEN);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite, nous allons lire la valeur de chaque entrée en démarrant la conversion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
adc_start_conversion(uint8_t pin)&lt;br /&gt;
{&lt;br /&gt;
  //adc_enable(pin);&lt;br /&gt;
  ADMUX = (1 &amp;lt;&amp;lt; REFS0) | pin;&lt;br /&gt;
  DIDR0 = (1 &amp;lt;&amp;lt; pin);&lt;br /&gt;
  ADCSRA |= (1 &amp;lt;&amp;lt; ADSC); // adc start conversion&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint16_t&lt;br /&gt;
adc_read(uint8_t pin)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t low;&lt;br /&gt;
  adc_start_conversion(pin);&lt;br /&gt;
  while (ADCSRA &amp;amp; (1 &amp;lt;&amp;lt; ADSC))&lt;br /&gt;
    ;                    // wait for result&lt;br /&gt;
  low = ADCL;   // must read LSB first&lt;br /&gt;
  return (ADCH &amp;lt;&amp;lt; 8) | low;     // must read MSB only once!&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Carte_Romeo</id>
		<title>Carte Romeo</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Carte_Romeo"/>
				<updated>2013-07-19T13:04:06Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : /* Fonctions moteur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;La carte ROMEO de DFROBOT est une carte tout-en-un conçue pour faire ses premiers pas vers la robotique. Cette carte très simple d'utilisation permet de commander 2 moteurs, d'interfacer des capteurs et de piloter le robot à distance via un module X-bee. Elle est basée sur un microcontroleur ATMEGA32u4 (V2.0 R3).&lt;br /&gt;
&lt;br /&gt;
Pour tester la carte ROMEO, nous avons utilisé la plateforme de développement Turtle 2WD de DFROBOT. Cette plateforme est équipée de 2 roues montées en direct sur 2 motoréducteurs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Commande des moteurs ==&lt;br /&gt;
&lt;br /&gt;
Le moteur à courant continu est l'élément principal qui permet au robot de se déplacer. Sa vitesse est proportionnelle à la tension d'alimentation. Plus la tension est élevée plus le moteur va tourner rapidement. Il faut donc créer une tension continue variable pour faire varier la vitesse du moteur. &lt;br /&gt;
&lt;br /&gt;
=== Signaux PWM ===&lt;br /&gt;
Les signaux PWM permettent de fournir une tension continue variable à partir de signaux numériques (0 et 5V). Le microcontroleur va générer un signal en forme de créneaux. En faisant varier le rapport cyclique, la tension moyenne va varier et le moteur va tourner plus ou moins vite.&lt;br /&gt;
&lt;br /&gt;
=== Electronique ===&lt;br /&gt;
La carte ROMEO est équipée d'un module de commande pour moteur à courant continu (L298). Ce pont H va fournir la puissance nécessaire au moteur pour tourner. Le microcontroleur va fournir un signal PWM et un signal de direction pour chaque moteur.&lt;br /&gt;
&lt;br /&gt;
=== Exemple de code ===&lt;br /&gt;
==== Langage Arduino ====&lt;br /&gt;
Le L298 utilise la pin 4 (M1 : direction) et 5 (E1 : PWM) pour le moteur 1 et la pin 6 (E2 : PWM) et 7 (M2 : direction) pour le moteur 2.&lt;br /&gt;
&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php/DFRduino_Romeo-All_in_one_Controller_V1.1%28SKU:DFR0004%29 ici]&lt;br /&gt;
&lt;br /&gt;
==== Langage C ====&lt;br /&gt;
===== Fonctions PWM =====&lt;br /&gt;
Pour générer un signal PWM, le microcontroleur a besoin d'un timer interne. Il utilise le timer 3A  pour E1 et le timer 4D pour E2.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, il faut initialiser les timers en mode PWM. Nous configurons le mode PWM avec des valeurs fréquemment utilisées pour la commande de moteurs.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* timer3 is used for phase-correct 8-bits PWM mode &lt;br /&gt;
and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_3_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* set timer3 prescale factor to 64 */&lt;br /&gt;
  TCCR3B = (1 &amp;lt;&amp;lt; CS31) | (1 &amp;lt;&amp;lt; CS30);&lt;br /&gt;
  /* put timer3 in phase correct PWM mode */&lt;br /&gt;
  TCCR3A = (1 &amp;lt;&amp;lt; WGM30);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* timer4 is used for phase and frequency correct 10-bits PWM mode &lt;br /&gt;
* and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_4_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  TC4H = 0;&lt;br /&gt;
  /* set timer4 prescale factor to 64 */&lt;br /&gt;
  TCCR4B = (1 &amp;lt;&amp;lt; CS42) | (1 &amp;lt;&amp;lt; CS41) | (1 &amp;lt;&amp;lt; CS40);&lt;br /&gt;
  /* put timer 4 in phase and frequency correct PWM mode */&lt;br /&gt;
  TCCR4D =(1 &amp;lt;&amp;lt; WGM40);&lt;br /&gt;
  /* not used */&lt;br /&gt;
  TCCR4E = 0;&lt;br /&gt;
  /* Set top to 0xFF */&lt;br /&gt;
  OCR4C = 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut activer les pins utilisées par le L298 (5:OC3A et 6:OC4D).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PC6(OC3A) pin as output pin */&lt;br /&gt;
  DDRC |= (1 &amp;lt;&amp;lt; PORTC6);&lt;br /&gt;
  /* enable OC3A pin as PWM pin */&lt;br /&gt;
  TCCR3A |= (1 &amp;lt;&amp;lt; COM3A1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PD7 pin as output pin */&lt;br /&gt;
  DDRD |= (1 &amp;lt;&amp;lt; PORTD7);&lt;br /&gt;
  /* enable OC4D pin as PWM pin */TCCR4C |= (1 &amp;lt;&amp;lt; PWM4D);&lt;br /&gt;
  TCCR4C |= (1 &amp;lt;&amp;lt; COM4D1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, il faut indiquer la valeur du PWM : cette valeur indique le temps haut du signal compris entre 0 et 255. Par exemple, pour avoir un signal carré (temps haut = temps bas), il faut avoir une valeur de 127. Ces valeurs sont écrites dans les registres OCRnx.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* write value a in PWM 3A */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_write(char a)&lt;br /&gt;
{&lt;br /&gt;
  OCR3A = a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* write value a in PWM 4D */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_write(char a)&lt;br /&gt;
{&lt;br /&gt;
  OCR4D = a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Fonctions moteur =====&lt;br /&gt;
Nous avons ensuite créer des fonctions qui permettent au robot d'avancer, reculer et tourner en précisant la vitesse (de 0 à 255).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* stop */&lt;br /&gt;
void&lt;br /&gt;
stop(void)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(0);&lt;br /&gt;
  pwm_3A_write(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* advance&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
advance(uint8_t m1_speed, uint8_t m2_speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_3A_write(m1_speed);&lt;br /&gt;
  pwm_4D_write(m2_speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* back off&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
back_off(uint8_t m1_speed, uint8_t m2_speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_3A_write(m1_speed);&lt;br /&gt;
  pwm_4D_write(m2_speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn left&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_left(uint8_t m1_speed, uint8_t m2_speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_3A_write(m1_speed);&lt;br /&gt;
  pwm_4D_write(m2_speed);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn right&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_right(uint8_t m1_speed, uint8_t m2_speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_3A_write(m1_speed);&lt;br /&gt;
  pwm_4D_write(m2_speed);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, la fonction principale main() et les fonctions setup() qui définissent l'état des pins (entrée ou sortie) et active les modules PWM.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
motor_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* Motor controller */&lt;br /&gt;
  DDRD = (1 &amp;lt;&amp;lt; PORTD4); /* E1 (PD4) as output pin */&lt;br /&gt;
  DDRE = (1 &amp;lt;&amp;lt; PORTE6); /* E2 (PE6) as output pin */&lt;br /&gt;
&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  motor_setup();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    turn_left(100);&lt;br /&gt;
    //advance(200);&lt;br /&gt;
    // stop();&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Communication XBee ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Commande à distance ===&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* setup USART1&lt;br /&gt;
 * speed : 9600 Baud&lt;br /&gt;
 * 8-bits, no parity, 1-stop-bit */&lt;br /&gt;
void&lt;br /&gt;
USART_1_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT2); /* initialize pin PD2 (RX) as input pin */&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT3); /* initialize pin PD3 (TX) as output pin */&lt;br /&gt;
&lt;br /&gt;
  UBRR1 = 103; /* 9600 Baud at 16MHz */&lt;br /&gt;
&lt;br /&gt;
  UCSR1A = 0;&lt;br /&gt;
&lt;br /&gt;
  /* 8-bits, no parity, 1-stop-bit */&lt;br /&gt;
  UCSR1C = (1 &amp;lt;&amp;lt; UCSZ11) | (1 &amp;lt;&amp;lt; UCSZ10);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il existe 2 solutions pour recevoir une donnée via la liaison série :&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
USART_1_receiver_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXEN1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned char&lt;br /&gt;
USART_1_receive(void)&lt;br /&gt;
{&lt;br /&gt;
  // wait for data to be received&lt;br /&gt;
  while (!(UCSR1A &amp;amp; (1 &amp;lt;&amp;lt; RXC1)))&lt;br /&gt;
    ;&lt;br /&gt;
  // get and return received data from buffer&lt;br /&gt;
  return UDR1 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
volatile char receive_char;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
USART_1_receiver_interrupt_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXEN1);&lt;br /&gt;
  /* enable interrupt on the RXC1 flag */&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXCIE1);&lt;br /&gt;
  SREG |= (1 &amp;lt;&amp;lt; SREG_I);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// receiver interrupt&lt;br /&gt;
ISR( USART1_RX_vect)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char dustbin = 0;&lt;br /&gt;
  &lt;br /&gt;
  receive_char = UDR1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
pin_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* Motor controller */&lt;br /&gt;
  DDRD = (1 &amp;lt;&amp;lt; PORTD4); /* PD4 as output pin */&lt;br /&gt;
  DDRE = (1 &amp;lt;&amp;lt; PORTE6); /* PE6 as output pin */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
&lt;br /&gt;
  USART_1_setup();&lt;br /&gt;
  //USART_1_receiver_enable();&lt;br /&gt;
  USART_1_receiver_interrupt_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  //char c;&lt;br /&gt;
  setup();&lt;br /&gt;
&lt;br /&gt;
  while (1)&lt;br /&gt;
    {&lt;br /&gt;
      //c = USART_1_receive();&lt;br /&gt;
&lt;br /&gt;
      switch (/*c*/receive_char)&lt;br /&gt;
        {&lt;br /&gt;
      case 'a':&lt;br /&gt;
        advance(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'b':&lt;br /&gt;
        back_off(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'r':&lt;br /&gt;
        turn_right(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'l':&lt;br /&gt;
        turn_left(100);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        stop();&lt;br /&gt;
        break;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conversion analogique / numérique ==&lt;br /&gt;
&lt;br /&gt;
Les capteurs que nous utilisons retourne généralement une information (tension) sous forme analogique. Pour exploiter cette information, le microcontroleur doit la convertir en signal numérique.&lt;br /&gt;
&lt;br /&gt;
Le convertisseur analogique / numérique de l'ATMEGA32U4 est un convertisseur 10 bits soit une précision de 1024 points. En se basant sur une tension de référence (généralement la tension d'alimentation), il va, par approximation successive, définir la valeur numérique correspondante à la tension.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, nous allons configurer le convertisseur. Le microcontroleur a 6 entrées analogiques sur le port F qu'il faut configurer en entrée. La tension de référence pour effectuer la conversion est la tension d'alimentation Vcc = 5V.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* Voltage reference : Vcc&lt;br /&gt;
 * Right adjust result&lt;br /&gt;
 * and with clock prescaled to system clock divided by 1024 */&lt;br /&gt;
void&lt;br /&gt;
adc_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* initialize PORTF pins as input pin */&lt;br /&gt;
  DDRF = 0x00;&lt;br /&gt;
&lt;br /&gt;
  /* set ADC prescale factor to 1024 */&lt;br /&gt;
  ADCSRA |= (1 &amp;lt;&amp;lt; ADPS2) | (1 &amp;lt;&amp;lt; ADPS1) | (1 &amp;lt;&amp;lt; ADPS0);&lt;br /&gt;
&lt;br /&gt;
  /* Vcc is reference voltage */&lt;br /&gt;
  ADMUX |= (1 &amp;lt;&amp;lt; REFS0);&lt;br /&gt;
&lt;br /&gt;
  /* Set ADC to Free-Running Mode */&lt;br /&gt;
  ADCSRB = 0;&lt;br /&gt;
&lt;br /&gt;
  /* adc enable */&lt;br /&gt;
  ADCSRA |= (1 &amp;lt;&amp;lt; ADEN);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite, nous allons lire la valeur de chaque entrée en démarrant la conversion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
adc_start_conversion(uint8_t pin)&lt;br /&gt;
{&lt;br /&gt;
  //adc_enable(pin);&lt;br /&gt;
  ADMUX = (1 &amp;lt;&amp;lt; REFS0) | pin;&lt;br /&gt;
  DIDR0 = (1 &amp;lt;&amp;lt; pin);&lt;br /&gt;
  ADCSRA |= (1 &amp;lt;&amp;lt; ADSC); // adc start conversion&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint16_t&lt;br /&gt;
adc_read(uint8_t pin)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t low;&lt;br /&gt;
  adc_start_conversion(pin);&lt;br /&gt;
  while (ADCSRA &amp;amp; (1 &amp;lt;&amp;lt; ADSC))&lt;br /&gt;
    ;                    // wait for result&lt;br /&gt;
  low = ADCL;   // must read LSB first&lt;br /&gt;
  return (ADCH &amp;lt;&amp;lt; 8) | low;     // must read MSB only once!&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Carte_Romeo</id>
		<title>Carte Romeo</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Carte_Romeo"/>
				<updated>2013-07-19T13:00:59Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : /* Langage C */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;La carte ROMEO de DFROBOT est une carte tout-en-un conçue pour faire ses premiers pas vers la robotique. Cette carte très simple d'utilisation permet de commander 2 moteurs, d'interfacer des capteurs et de piloter le robot à distance via un module X-bee. Elle est basée sur un microcontroleur ATMEGA32u4 (V2.0 R3).&lt;br /&gt;
&lt;br /&gt;
Pour tester la carte ROMEO, nous avons utilisé la plateforme de développement Turtle 2WD de DFROBOT. Cette plateforme est équipée de 2 roues montées en direct sur 2 motoréducteurs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Commande des moteurs ==&lt;br /&gt;
&lt;br /&gt;
Le moteur à courant continu est l'élément principal qui permet au robot de se déplacer. Sa vitesse est proportionnelle à la tension d'alimentation. Plus la tension est élevée plus le moteur va tourner rapidement. Il faut donc créer une tension continue variable pour faire varier la vitesse du moteur. &lt;br /&gt;
&lt;br /&gt;
=== Signaux PWM ===&lt;br /&gt;
Les signaux PWM permettent de fournir une tension continue variable à partir de signaux numériques (0 et 5V). Le microcontroleur va générer un signal en forme de créneaux. En faisant varier le rapport cyclique, la tension moyenne va varier et le moteur va tourner plus ou moins vite.&lt;br /&gt;
&lt;br /&gt;
=== Electronique ===&lt;br /&gt;
La carte ROMEO est équipée d'un module de commande pour moteur à courant continu (L298). Ce pont H va fournir la puissance nécessaire au moteur pour tourner. Le microcontroleur va fournir un signal PWM et un signal de direction pour chaque moteur.&lt;br /&gt;
&lt;br /&gt;
=== Exemple de code ===&lt;br /&gt;
==== Langage Arduino ====&lt;br /&gt;
Le L298 utilise la pin 4 (M1 : direction) et 5 (E1 : PWM) pour le moteur 1 et la pin 6 (E2 : PWM) et 7 (M2 : direction) pour le moteur 2.&lt;br /&gt;
&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php/DFRduino_Romeo-All_in_one_Controller_V1.1%28SKU:DFR0004%29 ici]&lt;br /&gt;
&lt;br /&gt;
==== Langage C ====&lt;br /&gt;
===== Fonctions PWM =====&lt;br /&gt;
Pour générer un signal PWM, le microcontroleur a besoin d'un timer interne. Il utilise le timer 3A  pour E1 et le timer 4D pour E2.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, il faut initialiser les timers en mode PWM. Nous configurons le mode PWM avec des valeurs fréquemment utilisées pour la commande de moteurs.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* timer3 is used for phase-correct 8-bits PWM mode &lt;br /&gt;
and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_3_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* set timer3 prescale factor to 64 */&lt;br /&gt;
  TCCR3B = (1 &amp;lt;&amp;lt; CS31) | (1 &amp;lt;&amp;lt; CS30);&lt;br /&gt;
  /* put timer3 in phase correct PWM mode */&lt;br /&gt;
  TCCR3A = (1 &amp;lt;&amp;lt; WGM30);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* timer4 is used for phase and frequency correct 10-bits PWM mode &lt;br /&gt;
* and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_4_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  TC4H = 0;&lt;br /&gt;
  /* set timer4 prescale factor to 64 */&lt;br /&gt;
  TCCR4B = (1 &amp;lt;&amp;lt; CS42) | (1 &amp;lt;&amp;lt; CS41) | (1 &amp;lt;&amp;lt; CS40);&lt;br /&gt;
  /* put timer 4 in phase and frequency correct PWM mode */&lt;br /&gt;
  TCCR4D =(1 &amp;lt;&amp;lt; WGM40);&lt;br /&gt;
  /* not used */&lt;br /&gt;
  TCCR4E = 0;&lt;br /&gt;
  /* Set top to 0xFF */&lt;br /&gt;
  OCR4C = 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut activer les pins utilisées par le L298 (5:OC3A et 6:OC4D).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PC6(OC3A) pin as output pin */&lt;br /&gt;
  DDRC |= (1 &amp;lt;&amp;lt; PORTC6);&lt;br /&gt;
  /* enable OC3A pin as PWM pin */&lt;br /&gt;
  TCCR3A |= (1 &amp;lt;&amp;lt; COM3A1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PD7 pin as output pin */&lt;br /&gt;
  DDRD |= (1 &amp;lt;&amp;lt; PORTD7);&lt;br /&gt;
  /* enable OC4D pin as PWM pin */TCCR4C |= (1 &amp;lt;&amp;lt; PWM4D);&lt;br /&gt;
  TCCR4C |= (1 &amp;lt;&amp;lt; COM4D1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, il faut indiquer la valeur du PWM : cette valeur indique le temps haut du signal compris entre 0 et 255. Par exemple, pour avoir un signal carré (temps haut = temps bas), il faut avoir une valeur de 127. Ces valeurs sont écrites dans les registres OCRnx.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* write value a in PWM 3A */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_write(char a)&lt;br /&gt;
{&lt;br /&gt;
  OCR3A = a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* write value a in PWM 4D */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_write(char a)&lt;br /&gt;
{&lt;br /&gt;
  OCR4D = a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Fonctions moteur =====&lt;br /&gt;
Nous avons ensuite créer des fonctions qui permettent au robot d'avancer, reculer et tourner en précisant la vitesse (de 0 à 255).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
motor_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* Motor controller */&lt;br /&gt;
  DDRD = (1 &amp;lt;&amp;lt; PORTD4); /* E1 (PD4) as output pin */&lt;br /&gt;
  DDRE = (1 &amp;lt;&amp;lt; PORTE6); /* E2 (PE6) as output pin */&lt;br /&gt;
&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* stop */&lt;br /&gt;
void&lt;br /&gt;
stop(void)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(0);&lt;br /&gt;
  pwm_3A_write(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* advance&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
advance(uint8_t m1_speed, uint8_t m2_speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_3A_write(m1_speed);&lt;br /&gt;
  pwm_4D_write(m2_speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* back off&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
back_off(uint8_t m1_speed, uint8_t m2_speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_3A_write(m1_speed);&lt;br /&gt;
  pwm_4D_write(m2_speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn left&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_left(uint8_t m1_speed, uint8_t m2_speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_3A_write(m1_speed);&lt;br /&gt;
  pwm_4D_write(m2_speed);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn right&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_right(uint8_t m1_speed, uint8_t m2_speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_3A_write(m1_speed);&lt;br /&gt;
  pwm_4D_write(m2_speed);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, les fonctions main() et setup()&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
pin_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* Motor controller */&lt;br /&gt;
  DDRD = (1 &amp;lt;&amp;lt; PORTD4); /* PD4 as output pin */&lt;br /&gt;
  DDRE = (1 &amp;lt;&amp;lt; PORTE6); /* PE6 as output pin */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    turn_left(100);&lt;br /&gt;
    //advance(200);&lt;br /&gt;
    // stop();&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Communication XBee ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Commande à distance ===&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* setup USART1&lt;br /&gt;
 * speed : 9600 Baud&lt;br /&gt;
 * 8-bits, no parity, 1-stop-bit */&lt;br /&gt;
void&lt;br /&gt;
USART_1_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT2); /* initialize pin PD2 (RX) as input pin */&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT3); /* initialize pin PD3 (TX) as output pin */&lt;br /&gt;
&lt;br /&gt;
  UBRR1 = 103; /* 9600 Baud at 16MHz */&lt;br /&gt;
&lt;br /&gt;
  UCSR1A = 0;&lt;br /&gt;
&lt;br /&gt;
  /* 8-bits, no parity, 1-stop-bit */&lt;br /&gt;
  UCSR1C = (1 &amp;lt;&amp;lt; UCSZ11) | (1 &amp;lt;&amp;lt; UCSZ10);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il existe 2 solutions pour recevoir une donnée via la liaison série :&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
USART_1_receiver_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXEN1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned char&lt;br /&gt;
USART_1_receive(void)&lt;br /&gt;
{&lt;br /&gt;
  // wait for data to be received&lt;br /&gt;
  while (!(UCSR1A &amp;amp; (1 &amp;lt;&amp;lt; RXC1)))&lt;br /&gt;
    ;&lt;br /&gt;
  // get and return received data from buffer&lt;br /&gt;
  return UDR1 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
volatile char receive_char;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
USART_1_receiver_interrupt_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXEN1);&lt;br /&gt;
  /* enable interrupt on the RXC1 flag */&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXCIE1);&lt;br /&gt;
  SREG |= (1 &amp;lt;&amp;lt; SREG_I);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// receiver interrupt&lt;br /&gt;
ISR( USART1_RX_vect)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char dustbin = 0;&lt;br /&gt;
  &lt;br /&gt;
  receive_char = UDR1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
pin_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* Motor controller */&lt;br /&gt;
  DDRD = (1 &amp;lt;&amp;lt; PORTD4); /* PD4 as output pin */&lt;br /&gt;
  DDRE = (1 &amp;lt;&amp;lt; PORTE6); /* PE6 as output pin */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
&lt;br /&gt;
  USART_1_setup();&lt;br /&gt;
  //USART_1_receiver_enable();&lt;br /&gt;
  USART_1_receiver_interrupt_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  //char c;&lt;br /&gt;
  setup();&lt;br /&gt;
&lt;br /&gt;
  while (1)&lt;br /&gt;
    {&lt;br /&gt;
      //c = USART_1_receive();&lt;br /&gt;
&lt;br /&gt;
      switch (/*c*/receive_char)&lt;br /&gt;
        {&lt;br /&gt;
      case 'a':&lt;br /&gt;
        advance(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'b':&lt;br /&gt;
        back_off(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'r':&lt;br /&gt;
        turn_right(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'l':&lt;br /&gt;
        turn_left(100);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        stop();&lt;br /&gt;
        break;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conversion analogique / numérique ==&lt;br /&gt;
&lt;br /&gt;
Les capteurs que nous utilisons retourne généralement une information (tension) sous forme analogique. Pour exploiter cette information, le microcontroleur doit la convertir en signal numérique.&lt;br /&gt;
&lt;br /&gt;
Le convertisseur analogique / numérique de l'ATMEGA32U4 est un convertisseur 10 bits soit une précision de 1024 points. En se basant sur une tension de référence (généralement la tension d'alimentation), il va, par approximation successive, définir la valeur numérique correspondante à la tension.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, nous allons configurer le convertisseur. Le microcontroleur a 6 entrées analogiques sur le port F qu'il faut configurer en entrée. La tension de référence pour effectuer la conversion est la tension d'alimentation Vcc = 5V.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* Voltage reference : Vcc&lt;br /&gt;
 * Right adjust result&lt;br /&gt;
 * and with clock prescaled to system clock divided by 1024 */&lt;br /&gt;
void&lt;br /&gt;
adc_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* initialize PORTF pins as input pin */&lt;br /&gt;
  DDRF = 0x00;&lt;br /&gt;
&lt;br /&gt;
  /* set ADC prescale factor to 1024 */&lt;br /&gt;
  ADCSRA |= (1 &amp;lt;&amp;lt; ADPS2) | (1 &amp;lt;&amp;lt; ADPS1) | (1 &amp;lt;&amp;lt; ADPS0);&lt;br /&gt;
&lt;br /&gt;
  /* Vcc is reference voltage */&lt;br /&gt;
  ADMUX |= (1 &amp;lt;&amp;lt; REFS0);&lt;br /&gt;
&lt;br /&gt;
  /* Set ADC to Free-Running Mode */&lt;br /&gt;
  ADCSRB = 0;&lt;br /&gt;
&lt;br /&gt;
  /* adc enable */&lt;br /&gt;
  ADCSRA |= (1 &amp;lt;&amp;lt; ADEN);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite, nous allons lire la valeur de chaque entrée en démarrant la conversion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
adc_start_conversion(uint8_t pin)&lt;br /&gt;
{&lt;br /&gt;
  //adc_enable(pin);&lt;br /&gt;
  ADMUX = (1 &amp;lt;&amp;lt; REFS0) | pin;&lt;br /&gt;
  DIDR0 = (1 &amp;lt;&amp;lt; pin);&lt;br /&gt;
  ADCSRA |= (1 &amp;lt;&amp;lt; ADSC); // adc start conversion&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint16_t&lt;br /&gt;
adc_read(uint8_t pin)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t low;&lt;br /&gt;
  adc_start_conversion(pin);&lt;br /&gt;
  while (ADCSRA &amp;amp; (1 &amp;lt;&amp;lt; ADSC))&lt;br /&gt;
    ;                    // wait for result&lt;br /&gt;
  low = ADCL;   // must read LSB first&lt;br /&gt;
  return (ADCH &amp;lt;&amp;lt; 8) | low;     // must read MSB only once!&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Robot_suiveur_de_ligne</id>
		<title>Robot suiveur de ligne</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Robot_suiveur_de_ligne"/>
				<updated>2013-07-19T12:56:47Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : robot suiveur de ligne&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Un robot suiveur de ligne est un robot mobile qui va se déplacer en suivant une ligne (par exemple une ligne noire sur fond blanc). C'est un robot autonome très simple à concevoir.&lt;br /&gt;
&lt;br /&gt;
== Matériel ==&lt;br /&gt;
Pour réaliser ce robot, nous avons besoin d'un chassis, d'une carte de commande et de capteurs :&lt;br /&gt;
&lt;br /&gt;
* un chassis [http://www.dfrobot.com/wiki/index.php?title=2WD_Mobile_Platform_for_Arduino_%28SKU:ROB0005%29| Turtle 2WD] de DRFobot&lt;br /&gt;
* une [[Carte Romeo]] de DFRobot basée sur un ATMEGA32U4 et qui intègre un étage de puissance pour contrôler les 2 moteurs CC&lt;br /&gt;
* un [[Capteur niveau de gris DFR0022]] de DFRobot&lt;br /&gt;
&lt;br /&gt;
== Principe général ==&lt;br /&gt;
Le robot doit suivre la ligne noire grâce aux capteurs niveau de gris. Si le capteur détecte du noir, le robot va tout droit. Si le capteur détecte du blanc, le robot a dévié de la ligne et doit donc corriger sa trajectoire.&lt;br /&gt;
&lt;br /&gt;
== Tests ==&lt;br /&gt;
&lt;br /&gt;
=== Robot avec un seul capteur ===&lt;br /&gt;
Pour commencer, nous allons installer un seul capteur sur notre robot.&lt;br /&gt;
&lt;br /&gt;
==== Principe ====&lt;br /&gt;
Avec un seul capteur, il faut placer le robot à cheval sur la ligne (blanc à gauche et noir à droite). Si le capteur détecte du blanc, le robot doit corriger en allant à droite et inversement si le capteur détecte du noir, le robot doit corriger en allant sur la gauche. Si le capteur détecte une nuance entre les deux, le robot va tout droit.&lt;br /&gt;
&lt;br /&gt;
==== Programme ====&lt;br /&gt;
Les fonctions sur le convertisseur analogique / numérique et le déplacement du robot sont expliqués [[carte Romeo| ici]].&lt;br /&gt;
La valeur du blanc est 55 et celle du noir est 260. On estime que la nuance de gris pour aller tout droit se situe entre 130 et 170. En dessous de cette nuance (inférieur à 130), le robot se dirige vers le blanc et doit tourner vers la droite en ralentissant son moteur droit. Au dessus de cette nuance (supérieur à 170), le robot se dirige vers le noir et doit tourner vers la gauche en ralentissant son moteur gauche.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  adc_setup();&lt;br /&gt;
  motor_setup();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
&lt;br /&gt;
  while (1)&lt;br /&gt;
    {&lt;br /&gt;
      int niveau_gris = adc_read(0);&lt;br /&gt;
&lt;br /&gt;
      if ((niveau_gris &amp;gt;= 130) &amp;amp;&amp;amp; (niveau_gris &amp;lt;= 170))&lt;br /&gt;
        {&lt;br /&gt;
          // avance&lt;br /&gt;
          advance(100, 100);&lt;br /&gt;
        }&lt;br /&gt;
      else if (niveau_gris &amp;lt; 130)      // blanc&lt;br /&gt;
        {&lt;br /&gt;
          // corrige a droite&lt;br /&gt;
          advance(50, 100);&lt;br /&gt;
        }&lt;br /&gt;
      else      // noir (gris &amp;gt; 170)&lt;br /&gt;
        {&lt;br /&gt;
          // corrige a gauche&lt;br /&gt;
          advance(100, 50);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Conclusion ====&lt;br /&gt;
Cette solution fonctionne très bien mais si le robot perd le bord de la ligne, il va tourner en rond sans jamais la retrouver. Pour éviter ce problème, il faut placer plusieurs capteurs en ligne.&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutoriels]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Capteur_niveau_de_gris_DFR0022</id>
		<title>Capteur niveau de gris DFR0022</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Capteur_niveau_de_gris_DFR0022"/>
				<updated>2013-07-19T11:46:25Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : capteur niveau de gris DFR0022&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ce capteur niveau de gris de DFRobot retourne une tension analogique image de la couleur détectée. Il est composé d'une led et d'une photo-résistance.&lt;br /&gt;
&lt;br /&gt;
== Principe ==&lt;br /&gt;
&lt;br /&gt;
La lumière émise par la led va plus ou moins se réfléchir selon la couleur rencontrée. Le blanc va réfléchir totalement la lumière alors que le noir va l'absorber. La photo-résistance est un composant dont la résistance interne varie en fonction de la lumière captée. Plus la lumière est intense moins sa résistivité est élevée. La tension de sortie va donc varier en fonction de la nuance de gris.&lt;br /&gt;
&lt;br /&gt;
Nous avons mesurer 0.26V pour du blanc et 1.36V pour du noir.&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
&lt;br /&gt;
Ce capteur peut être utilisé pour faire un [[robot suiveur de ligne]].&lt;br /&gt;
&lt;br /&gt;
== Tests ==&lt;br /&gt;
&lt;br /&gt;
Nous avons testé ce capteur avec la [[Carte Romeo]] de DRFobot en utilisant le convertisseur analogique / numérique 10 bits (1024) avec une tension de référence Vcc (5V). Le principe et les fonctions du convertisseur sont expliqués [[Carte Romeo |ici]].&lt;br /&gt;
&lt;br /&gt;
Le capteur est branché sur A5(ADC0).&lt;br /&gt;
&lt;br /&gt;
'''Attention''' : le cable fournit avec le capteur ne correspond pas au brochage de la ROMEO. Il faut inverser la masse (noir) et alimentation (rouge) sur le connecteur noir allant sur la carte.&lt;br /&gt;
&lt;br /&gt;
=== Langage ARDUINO ===&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php?title=DFRobot_Grayscale_Sensor_%28SKU:DFR0022%29 |ici].&lt;br /&gt;
&lt;br /&gt;
=== Langage C ===&lt;br /&gt;
Le programme est très simple. Il faut configurer le convertisseur analogique / numérique puis lire l'entrée analogique. &amp;quot;niveau_gris&amp;quot; contient la valeur qui correspond au niveau de gris. Plus elle est élevée, plus la couleur est foncée.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  adc_setup();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
&lt;br /&gt;
  while (1)&lt;br /&gt;
    {&lt;br /&gt;
      int niveau_gris = adc_read(0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Acc%C3%A9l%C3%A9rom%C3%A8tre_MMA7361</id>
		<title>Accéléromètre MMA7361</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Acc%C3%A9l%C3%A9rom%C3%A8tre_MMA7361"/>
				<updated>2013-07-10T19:01:25Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : A protégé « Accéléromètre MMA7361 » (‎[edit=sysop] (infini) ‎[move=sysop] (infini))&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Un accéléromètre est un capteur qui permet de mesurer l'accélération linéaire d'un objet mobile. C'est un capteur utile pour un robot. Il va pouvoir par exemple détecter les chocs ou une pente. Couplé à un gyroscope (mesure de la vitesse angulaire), il devient un composant de la centrale inertielle qui permet de localiser le robot.&lt;br /&gt;
&lt;br /&gt;
== Accéléromètre 3 axes MMA7361 ==&lt;br /&gt;
&lt;br /&gt;
Ce module est basé sur l'accéléromètre 3 axes MMA7361 de Freescale. Il est possible de régler la précision entre 2 valeurs. En effet, un interrupteur permet de choisir une précision de 1,5g (800mV/g) ou de 6g (206mV/g). Ce capteur ratiométrique retourne une tension analogique proportionnelle à l'accélération et à la tension d'alimentation Vcc.&lt;br /&gt;
&lt;br /&gt;
La tension retournée est comprise entre 0 et 3,3V (alimentation du MMA7361). Elle est centrée sur 1,65V qui correspond à 0g théorique. Cette valeur peut légèrement changer selon le capteur. Il est donc préférable de mesurer cette valeur.&lt;br /&gt;
&lt;br /&gt;
== Tests ==&lt;br /&gt;
&lt;br /&gt;
Nous avons tester ce capteur avec la [[Carte Romeo]] en utilisant le convertisseur analogique / numérique 10 bits (1024) avec une tension de référence Vcc (5V). Le principe et les fonctions du convertisseur sont expliqués [[Carte Romeo |ici]] &lt;br /&gt;
&lt;br /&gt;
L'axe X est branché sur A5 (ADC0), Y sur A4 (ADC1) et Z sur A3 (ADC4). Nous choisissons une précision de 1,5g (800mV/g).&lt;br /&gt;
&lt;br /&gt;
'''Attention''' : le cable fournit avec le capteur ne correspond pas au brochage de la ROMEO. Il faut inverser la masse (noir) et alimentation (rouge) sur le connecteur noir allant sur la carte.&lt;br /&gt;
&lt;br /&gt;
=== Exemple de code ===&lt;br /&gt;
&lt;br /&gt;
==== Langage Arduino ====&lt;br /&gt;
&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php/Triple_Axis_Accelerometer_MMA7361_%28SKU:_DFR0143%29 |ici]&lt;br /&gt;
==== Langage C ====&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, nous allons lire la valeur sur l'entrée analogique. Puis nous allons définir l'accélération pour chaque axe en tenant compte de la précision et de la valeur du 0.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define VALUE_ZERO_G    1.7&lt;br /&gt;
#define SENSIBILITY     0.8&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  adc_setup();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  int adc_x, adc_y, adc_z;&lt;br /&gt;
  double acc_x, acc_y, acc_z;&lt;br /&gt;
&lt;br /&gt;
  setup();&lt;br /&gt;
&lt;br /&gt;
  while (1)&lt;br /&gt;
    {&lt;br /&gt;
      /* X-axe */&lt;br /&gt;
      adc_x = adc_read(0);&lt;br /&gt;
&lt;br /&gt;
      acc_x = (double) (adc_x * 5) / 1023;&lt;br /&gt;
      acc_x -= VALUE_ZERO_G;&lt;br /&gt;
      acc_x /= SENSIBILITY;&lt;br /&gt;
&lt;br /&gt;
      /* Y-axe */&lt;br /&gt;
      adc_y = adc_read(1);&lt;br /&gt;
&lt;br /&gt;
      acc_y = (double) (adc_y * 5) / 1023;&lt;br /&gt;
      acc_y -= VALUE_ZERO_G;&lt;br /&gt;
      acc_y /= SENSIBILITY;&lt;br /&gt;
&lt;br /&gt;
      /* Z-axe */&lt;br /&gt;
      adc_z = adc_read(4);&lt;br /&gt;
&lt;br /&gt;
      acc_z = (double) (adc_z * 5) / 1023;&lt;br /&gt;
      acc_z -= VALUE_ZERO_G;&lt;br /&gt;
      acc_z /= SENSIBILITY;&lt;br /&gt;
    }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Carte_Romeo</id>
		<title>Carte Romeo</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Carte_Romeo"/>
				<updated>2013-07-10T19:01:04Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : A protégé « Carte Romeo » (‎[edit=sysop] (infini) ‎[move=sysop] (infini))&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;La carte ROMEO de DFROBOT est une carte tout-en-un conçue pour faire ses premiers pas vers la robotique. Cette carte très simple d'utilisation permet de commander 2 moteurs, d'interfacer des capteurs et de piloter le robot à distance via un module X-bee. Elle est basée sur un microcontroleur ATMEGA32u4 (V2.0 R3).&lt;br /&gt;
&lt;br /&gt;
Pour tester la carte ROMEO, nous avons utilisé la plateforme de développement Turtle 2WD de DFROBOT. Cette plateforme est équipée de 2 roues montées en direct sur 2 motoréducteurs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Commande des moteurs ==&lt;br /&gt;
&lt;br /&gt;
Le moteur à courant continu est l'élément principal qui permet au robot de se déplacer. Sa vitesse est proportionnelle à la tension d'alimentation. Plus la tension est élevée plus le moteur va tourner rapidement. Il faut donc créer une tension continue variable pour faire varier la vitesse du moteur. &lt;br /&gt;
&lt;br /&gt;
=== Signaux PWM ===&lt;br /&gt;
Les signaux PWM permettent de fournir une tension continue variable à partir de signaux numériques (0 et 5V). Le microcontroleur va générer un signal en forme de créneaux. En faisant varier le rapport cyclique, la tension moyenne va varier et le moteur va tourner plus ou moins vite.&lt;br /&gt;
&lt;br /&gt;
=== Electronique ===&lt;br /&gt;
La carte ROMEO est équipée d'un module de commande pour moteur à courant continu (L298). Ce pont H va fournir la puissance nécessaire au moteur pour tourner. Le microcontroleur va fournir un signal PWM et un signal de direction pour chaque moteur.&lt;br /&gt;
&lt;br /&gt;
=== Exemple de code ===&lt;br /&gt;
==== Langage Arduino ====&lt;br /&gt;
Le L298 utilise la pin 4 (M1 : direction) et 5 (E1 : PWM) pour le moteur 1 et la pin 6 (E2 : PWM) et 7 (M2 : direction) pour le moteur 2.&lt;br /&gt;
&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php/DFRduino_Romeo-All_in_one_Controller_V1.1%28SKU:DFR0004%29 ici]&lt;br /&gt;
&lt;br /&gt;
==== Langage C ====&lt;br /&gt;
Pour générer un signal PWM, le microcontroleur a besoin d'un timer interne. Il utilise le timer 3A  pour E1 et le timer 4D pour E2.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, il faut initialiser les timers en mode PWM. Nous configurons le mode PWM avec des valeurs fréquemment utilisées pour la commande de moteurs.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* timer3 is used for phase-correct 8-bits PWM mode &lt;br /&gt;
and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_3_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* set timer3 prescale factor to 64 */&lt;br /&gt;
  TCCR3B = (1 &amp;lt;&amp;lt; CS31) | (1 &amp;lt;&amp;lt; CS30);&lt;br /&gt;
  /* put timer3 in phase correct PWM mode */&lt;br /&gt;
  TCCR3A = (1 &amp;lt;&amp;lt; WGM30);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* timer4 is used for phase and frequency correct 10-bits PWM mode &lt;br /&gt;
* and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_4_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  TC4H = 0;&lt;br /&gt;
  /* set timer4 prescale factor to 64 */&lt;br /&gt;
  TCCR4B = (1 &amp;lt;&amp;lt; CS42) | (1 &amp;lt;&amp;lt; CS41) | (1 &amp;lt;&amp;lt; CS40);&lt;br /&gt;
  /* put timer 4 in phase and frequency correct PWM mode */&lt;br /&gt;
  TCCR4D =(1 &amp;lt;&amp;lt; WGM40);&lt;br /&gt;
  /* not used */&lt;br /&gt;
  TCCR4E = 0;&lt;br /&gt;
  /* Set top to 0xFF */&lt;br /&gt;
  OCR4C = 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut activer les pins utilisées par le L298 (5:OC3A et 6:OC4D).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PC6(OC3A) pin as output pin */&lt;br /&gt;
  DDRC |= (1 &amp;lt;&amp;lt; PORTC6);&lt;br /&gt;
  /* enable OC3A pin as PWM pin */&lt;br /&gt;
  TCCR3A |= (1 &amp;lt;&amp;lt; COM3A1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PD7 pin as output pin */&lt;br /&gt;
  DDRD |= (1 &amp;lt;&amp;lt; PORTD7);&lt;br /&gt;
  /* enable OC4D pin as PWM pin */TCCR4C |= (1 &amp;lt;&amp;lt; PWM4D);&lt;br /&gt;
  TCCR4C |= (1 &amp;lt;&amp;lt; COM4D1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, il faut indiquer la valeur du PWM : cette valeur indique le temps haut du signal compris entre 0 et 255. Par exemple, pour avoir un signal carré (temps haut = temps bas), il faut avoir une valeur de 127. Ces valeurs sont écrites dans les registres OCRnx.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* write value a in PWM 3A */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_write(char a)&lt;br /&gt;
{&lt;br /&gt;
  OCR3A = a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* write value a in PWM 4D */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_write(char a)&lt;br /&gt;
{&lt;br /&gt;
  OCR4D = a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite créer des fonctions qui permettent au robot d'avancer, reculer et tourner en précisant la vitesse (de 0 à 255).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* stop */&lt;br /&gt;
void&lt;br /&gt;
stop(void)&lt;br /&gt;
{&lt;br /&gt;
  pwm_4D_write(0);&lt;br /&gt;
  pwm_3A_write(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* advance&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
advance(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* back off&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
back_off(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn left&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_left(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn right&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_right(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, les fonctions main() et setup()&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
pin_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* Motor controller */&lt;br /&gt;
  DDRD = (1 &amp;lt;&amp;lt; PORTD4); /* PD4 as output pin */&lt;br /&gt;
  DDRE = (1 &amp;lt;&amp;lt; PORTE6); /* PE6 as output pin */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    turn_left(100);&lt;br /&gt;
    //advance(200);&lt;br /&gt;
    // stop();&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Communication XBee ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Commande à distance ===&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* setup USART1&lt;br /&gt;
 * speed : 9600 Baud&lt;br /&gt;
 * 8-bits, no parity, 1-stop-bit */&lt;br /&gt;
void&lt;br /&gt;
USART_1_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT2); /* initialize pin PD2 (RX) as input pin */&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT3); /* initialize pin PD3 (TX) as output pin */&lt;br /&gt;
&lt;br /&gt;
  UBRR1 = 103; /* 9600 Baud at 16MHz */&lt;br /&gt;
&lt;br /&gt;
  UCSR1A = 0;&lt;br /&gt;
&lt;br /&gt;
  /* 8-bits, no parity, 1-stop-bit */&lt;br /&gt;
  UCSR1C = (1 &amp;lt;&amp;lt; UCSZ11) | (1 &amp;lt;&amp;lt; UCSZ10);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il existe 2 solutions pour recevoir une donnée via la liaison série :&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
USART_1_receiver_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXEN1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned char&lt;br /&gt;
USART_1_receive(void)&lt;br /&gt;
{&lt;br /&gt;
  // wait for data to be received&lt;br /&gt;
  while (!(UCSR1A &amp;amp; (1 &amp;lt;&amp;lt; RXC1)))&lt;br /&gt;
    ;&lt;br /&gt;
  // get and return received data from buffer&lt;br /&gt;
  return UDR1 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
volatile char receive_char;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
USART_1_receiver_interrupt_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXEN1);&lt;br /&gt;
  /* enable interrupt on the RXC1 flag */&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXCIE1);&lt;br /&gt;
  SREG |= (1 &amp;lt;&amp;lt; SREG_I);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// receiver interrupt&lt;br /&gt;
ISR( USART1_RX_vect)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char dustbin = 0;&lt;br /&gt;
  &lt;br /&gt;
  receive_char = UDR1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
pin_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* Motor controller */&lt;br /&gt;
  DDRD = (1 &amp;lt;&amp;lt; PORTD4); /* PD4 as output pin */&lt;br /&gt;
  DDRE = (1 &amp;lt;&amp;lt; PORTE6); /* PE6 as output pin */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
&lt;br /&gt;
  USART_1_setup();&lt;br /&gt;
  //USART_1_receiver_enable();&lt;br /&gt;
  USART_1_receiver_interrupt_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  //char c;&lt;br /&gt;
  setup();&lt;br /&gt;
&lt;br /&gt;
  while (1)&lt;br /&gt;
    {&lt;br /&gt;
      //c = USART_1_receive();&lt;br /&gt;
&lt;br /&gt;
      switch (/*c*/receive_char)&lt;br /&gt;
        {&lt;br /&gt;
      case 'a':&lt;br /&gt;
        advance(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'b':&lt;br /&gt;
        back_off(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'r':&lt;br /&gt;
        turn_right(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'l':&lt;br /&gt;
        turn_left(100);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        stop();&lt;br /&gt;
        break;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conversion analogique / numérique ==&lt;br /&gt;
&lt;br /&gt;
Les capteurs que nous utilisons retourne généralement une information (tension) sous forme analogique. Pour exploiter cette information, le microcontroleur doit la convertir en signal numérique.&lt;br /&gt;
&lt;br /&gt;
Le convertisseur analogique / numérique de l'ATMEGA32U4 est un convertisseur 10 bits soit une précision de 1024 points. En se basant sur une tension de référence (généralement la tension d'alimentation), il va, par approximation successive, définir la valeur numérique correspondante à la tension.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, nous allons configurer le convertisseur. Le microcontroleur a 6 entrées analogiques sur le port F qu'il faut configurer en entrée. La tension de référence pour effectuer la conversion est la tension d'alimentation Vcc = 5V.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* Voltage reference : Vcc&lt;br /&gt;
 * Right adjust result&lt;br /&gt;
 * and with clock prescaled to system clock divided by 1024 */&lt;br /&gt;
void&lt;br /&gt;
adc_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* initialize PORTF pins as input pin */&lt;br /&gt;
  DDRF = 0x00;&lt;br /&gt;
&lt;br /&gt;
  /* set ADC prescale factor to 1024 */&lt;br /&gt;
  ADCSRA |= (1 &amp;lt;&amp;lt; ADPS2) | (1 &amp;lt;&amp;lt; ADPS1) | (1 &amp;lt;&amp;lt; ADPS0);&lt;br /&gt;
&lt;br /&gt;
  /* Vcc is reference voltage */&lt;br /&gt;
  ADMUX |= (1 &amp;lt;&amp;lt; REFS0);&lt;br /&gt;
&lt;br /&gt;
  /* Set ADC to Free-Running Mode */&lt;br /&gt;
  ADCSRB = 0;&lt;br /&gt;
&lt;br /&gt;
  /* adc enable */&lt;br /&gt;
  ADCSRA |= (1 &amp;lt;&amp;lt; ADEN);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite, nous allons lire la valeur de chaque entrée en démarrant la conversion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
adc_start_conversion(uint8_t pin)&lt;br /&gt;
{&lt;br /&gt;
  //adc_enable(pin);&lt;br /&gt;
  ADMUX = (1 &amp;lt;&amp;lt; REFS0) | pin;&lt;br /&gt;
  DIDR0 = (1 &amp;lt;&amp;lt; pin);&lt;br /&gt;
  ADCSRA |= (1 &amp;lt;&amp;lt; ADSC); // adc start conversion&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint16_t&lt;br /&gt;
adc_read(uint8_t pin)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t low;&lt;br /&gt;
  adc_start_conversion(pin);&lt;br /&gt;
  while (ADCSRA &amp;amp; (1 &amp;lt;&amp;lt; ADSC))&lt;br /&gt;
    ;                    // wait for result&lt;br /&gt;
  low = ADCL;   // must read LSB first&lt;br /&gt;
  return (ADCH &amp;lt;&amp;lt; 8) | low;     // must read MSB only once!&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Acc%C3%A9l%C3%A9rom%C3%A8tre_MMA7361</id>
		<title>Accéléromètre MMA7361</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Acc%C3%A9l%C3%A9rom%C3%A8tre_MMA7361"/>
				<updated>2013-07-10T14:36:47Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : /* Langage C */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Un accéléromètre est un capteur qui permet de mesurer l'accélération linéaire d'un objet mobile. C'est un capteur utile pour un robot. Il va pouvoir par exemple détecter les chocs ou une pente. Couplé à un gyroscope (mesure de la vitesse angulaire), il devient un composant de la centrale inertielle qui permet de localiser le robot.&lt;br /&gt;
&lt;br /&gt;
== Accéléromètre 3 axes MMA7361 ==&lt;br /&gt;
&lt;br /&gt;
Ce module est basé sur l'accéléromètre 3 axes MMA7361 de Freescale. Il est possible de régler la précision entre 2 valeurs. En effet, un interrupteur permet de choisir une précision de 1,5g (800mV/g) ou de 6g (206mV/g). Ce capteur ratiométrique retourne une tension analogique proportionnelle à l'accélération et à la tension d'alimentation Vcc.&lt;br /&gt;
&lt;br /&gt;
La tension retournée est comprise entre 0 et 3,3V (alimentation du MMA7361). Elle est centrée sur 1,65V qui correspond à 0g théorique. Cette valeur peut légèrement changer selon le capteur. Il est donc préférable de mesurer cette valeur.&lt;br /&gt;
&lt;br /&gt;
== Tests ==&lt;br /&gt;
&lt;br /&gt;
Nous avons tester ce capteur avec la [[Carte Romeo]] en utilisant le convertisseur analogique / numérique 10 bits (1024) avec une tension de référence Vcc (5V). Le principe et les fonctions du convertisseur sont expliqués [[Carte Romeo |ici]] &lt;br /&gt;
&lt;br /&gt;
L'axe X est branché sur A5 (ADC0), Y sur A4 (ADC1) et Z sur A3 (ADC4). Nous choisissons une précision de 1,5g (800mV/g).&lt;br /&gt;
&lt;br /&gt;
'''Attention''' : le cable fournit avec le capteur ne correspond pas au brochage de la ROMEO. Il faut inverser la masse (noir) et alimentation (rouge) sur le connecteur noir allant sur la carte.&lt;br /&gt;
&lt;br /&gt;
=== Exemple de code ===&lt;br /&gt;
&lt;br /&gt;
==== Langage Arduino ====&lt;br /&gt;
&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php/Triple_Axis_Accelerometer_MMA7361_%28SKU:_DFR0143%29 |ici]&lt;br /&gt;
==== Langage C ====&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, nous allons lire la valeur sur l'entrée analogique. Puis nous allons définir l'accélération pour chaque axe en tenant compte de la précision et de la valeur du 0.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define VALUE_ZERO_G    1.7&lt;br /&gt;
#define SENSIBILITY     0.8&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  adc_setup();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  int adc_x, adc_y, adc_z;&lt;br /&gt;
  double acc_x, acc_y, acc_z;&lt;br /&gt;
&lt;br /&gt;
  setup();&lt;br /&gt;
&lt;br /&gt;
  while (1)&lt;br /&gt;
    {&lt;br /&gt;
      /* X-axe */&lt;br /&gt;
      adc_x = adc_read(0);&lt;br /&gt;
&lt;br /&gt;
      acc_x = (double) (adc_x * 5) / 1023;&lt;br /&gt;
      acc_x -= VALUE_ZERO_G;&lt;br /&gt;
      acc_x /= SENSIBILITY;&lt;br /&gt;
&lt;br /&gt;
      /* Y-axe */&lt;br /&gt;
      adc_y = adc_read(1);&lt;br /&gt;
&lt;br /&gt;
      acc_y = (double) (adc_y * 5) / 1023;&lt;br /&gt;
      acc_y -= VALUE_ZERO_G;&lt;br /&gt;
      acc_y /= SENSIBILITY;&lt;br /&gt;
&lt;br /&gt;
      /* Z-axe */&lt;br /&gt;
      adc_z = adc_read(4);&lt;br /&gt;
&lt;br /&gt;
      acc_z = (double) (adc_z * 5) / 1023;&lt;br /&gt;
      acc_z -= VALUE_ZERO_G;&lt;br /&gt;
      acc_z /= SENSIBILITY;&lt;br /&gt;
    }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Acc%C3%A9l%C3%A9rom%C3%A8tre_MMA7361</id>
		<title>Accéléromètre MMA7361</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Acc%C3%A9l%C3%A9rom%C3%A8tre_MMA7361"/>
				<updated>2013-07-10T14:35:20Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : Page créée avec « Un accéléromètre est un capteur qui permet de mesurer l'accélération linéaire d'un objet mobile. C'est un capteur utile pour un robot. Il va pouvoir par exemple dét... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Un accéléromètre est un capteur qui permet de mesurer l'accélération linéaire d'un objet mobile. C'est un capteur utile pour un robot. Il va pouvoir par exemple détecter les chocs ou une pente. Couplé à un gyroscope (mesure de la vitesse angulaire), il devient un composant de la centrale inertielle qui permet de localiser le robot.&lt;br /&gt;
&lt;br /&gt;
== Accéléromètre 3 axes MMA7361 ==&lt;br /&gt;
&lt;br /&gt;
Ce module est basé sur l'accéléromètre 3 axes MMA7361 de Freescale. Il est possible de régler la précision entre 2 valeurs. En effet, un interrupteur permet de choisir une précision de 1,5g (800mV/g) ou de 6g (206mV/g). Ce capteur ratiométrique retourne une tension analogique proportionnelle à l'accélération et à la tension d'alimentation Vcc.&lt;br /&gt;
&lt;br /&gt;
La tension retournée est comprise entre 0 et 3,3V (alimentation du MMA7361). Elle est centrée sur 1,65V qui correspond à 0g théorique. Cette valeur peut légèrement changer selon le capteur. Il est donc préférable de mesurer cette valeur.&lt;br /&gt;
&lt;br /&gt;
== Tests ==&lt;br /&gt;
&lt;br /&gt;
Nous avons tester ce capteur avec la [[Carte Romeo]] en utilisant le convertisseur analogique / numérique 10 bits (1024) avec une tension de référence Vcc (5V). Le principe et les fonctions du convertisseur sont expliqués [[Carte Romeo |ici]] &lt;br /&gt;
&lt;br /&gt;
L'axe X est branché sur A5 (ADC0), Y sur A4 (ADC1) et Z sur A3 (ADC4). Nous choisissons une précision de 1,5g (800mV/g).&lt;br /&gt;
&lt;br /&gt;
'''Attention''' : le cable fournit avec le capteur ne correspond pas au brochage de la ROMEO. Il faut inverser la masse (noir) et alimentation (rouge) sur le connecteur noir allant sur la carte.&lt;br /&gt;
&lt;br /&gt;
=== Exemple de code ===&lt;br /&gt;
&lt;br /&gt;
==== Langage Arduino ====&lt;br /&gt;
&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php/Triple_Axis_Accelerometer_MMA7361_%28SKU:_DFR0143%29 |ici]&lt;br /&gt;
==== Langage C ====&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, nous allons lire la valeur sur l'entrée analogique. Puis nous allons définir l'accélération pour chaque axe en tenant compte de la précision et de la valeur du 0.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  adc_setup();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  int adc_x, adc_y, adc_z;&lt;br /&gt;
  double acc_x, acc_y, acc_z;&lt;br /&gt;
&lt;br /&gt;
  setup();&lt;br /&gt;
&lt;br /&gt;
  while (1)&lt;br /&gt;
    {&lt;br /&gt;
      /* X-axe */&lt;br /&gt;
      adc_x = adc_read(0);&lt;br /&gt;
&lt;br /&gt;
      acc_x = (double) (adc_x * 5) / 1023;&lt;br /&gt;
      acc_x -= VALUE_ZERO_G;&lt;br /&gt;
      acc_x /= SENSIBILITY;&lt;br /&gt;
&lt;br /&gt;
      /* Y-axe */&lt;br /&gt;
      adc_y = adc_read(1);&lt;br /&gt;
&lt;br /&gt;
      acc_y = (double) (adc_y * 5) / 1023;&lt;br /&gt;
      acc_y -= VALUE_ZERO_G;&lt;br /&gt;
      acc_y /= SENSIBILITY;&lt;br /&gt;
&lt;br /&gt;
      /* Z-axe */&lt;br /&gt;
      adc_z = adc_read(4);&lt;br /&gt;
&lt;br /&gt;
      acc_z = (double) (adc_z * 5) / 1023;&lt;br /&gt;
      acc_z -= VALUE_ZERO_G;&lt;br /&gt;
      acc_z /= SENSIBILITY;&lt;br /&gt;
    }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Carte_Romeo</id>
		<title>Carte Romeo</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Carte_Romeo"/>
				<updated>2013-07-10T12:42:53Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : /* Communication XBee */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;La carte ROMEO de DFROBOT est une carte tout-en-un conçue pour faire ses premiers pas vers la robotique. Cette carte très simple d'utilisation permet de commander 2 moteurs, d'interfacer des capteurs et de piloter le robot à distance via un module X-bee. Elle est basée sur un microcontroleur ATMEGA32u4 (V2.0 R3).&lt;br /&gt;
&lt;br /&gt;
Pour tester la carte ROMEO, nous avons utilisé la plateforme de développement Turtle 2WD de DFROBOT. Cette plateforme est équipée de 2 roues montées en direct sur 2 motoréducteurs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Commande des moteurs ==&lt;br /&gt;
&lt;br /&gt;
Le moteur à courant continu est l'élément principal qui permet au robot de se déplacer. Sa vitesse est proportionnelle à la tension d'alimentation. Plus la tension est élevée plus le moteur va tourner rapidement. Il faut donc créer une tension continue variable pour faire varier la vitesse du moteur. &lt;br /&gt;
&lt;br /&gt;
=== Signaux PWM ===&lt;br /&gt;
Les signaux PWM permettent de fournir une tension continue variable à partir de signaux numériques (0 et 5V). Le microcontroleur va générer un signal en forme de créneaux. En faisant varier le rapport cyclique, la tension moyenne va varier et le moteur va tourner plus ou moins vite.&lt;br /&gt;
&lt;br /&gt;
=== Electronique ===&lt;br /&gt;
La carte ROMEO est équipée d'un module de commande pour moteur à courant continu (L298). Ce pont H va fournir la puissance nécessaire au moteur pour tourner. Le microcontroleur va fournir un signal PWM et un signal de direction pour chaque moteur.&lt;br /&gt;
&lt;br /&gt;
=== Exemple de code ===&lt;br /&gt;
==== Langage Arduino ====&lt;br /&gt;
Le L298 utilise la pin 4 (M1 : direction) et 5 (E1 : PWM) pour le moteur 1 et la pin 6 (E2 : PWM) et 7 (M2 : direction) pour le moteur 2.&lt;br /&gt;
&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php/DFRduino_Romeo-All_in_one_Controller_V1.1%28SKU:DFR0004%29 ici]&lt;br /&gt;
&lt;br /&gt;
==== Langage C ====&lt;br /&gt;
Pour générer un signal PWM, le microcontroleur a besoin d'un timer interne. Il utilise le timer 3A  pour E1 et le timer 4D pour E2.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, il faut initialiser les timers en mode PWM. Nous configurons le mode PWM avec des valeurs fréquemment utilisées pour la commande de moteurs.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* timer3 is used for phase-correct 8-bits PWM mode &lt;br /&gt;
and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_3_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* set timer3 prescale factor to 64 */&lt;br /&gt;
  TCCR3B = (1 &amp;lt;&amp;lt; CS31) | (1 &amp;lt;&amp;lt; CS30);&lt;br /&gt;
  /* put timer3 in phase correct PWM mode */&lt;br /&gt;
  TCCR3A = (1 &amp;lt;&amp;lt; WGM30);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* timer4 is used for phase and frequency correct 10-bits PWM mode &lt;br /&gt;
* and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_4_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  TC4H = 0;&lt;br /&gt;
  /* set timer4 prescale factor to 64 */&lt;br /&gt;
  TCCR4B = (1 &amp;lt;&amp;lt; CS42) | (1 &amp;lt;&amp;lt; CS41) | (1 &amp;lt;&amp;lt; CS40);&lt;br /&gt;
  /* put timer 4 in phase and frequency correct PWM mode */&lt;br /&gt;
  TCCR4D =(1 &amp;lt;&amp;lt; WGM40);&lt;br /&gt;
  /* not used */&lt;br /&gt;
  TCCR4E = 0;&lt;br /&gt;
  /* Set top to 0xFF */&lt;br /&gt;
  OCR4C = 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut activer les pins utilisées par le L298 (5:OC3A et 6:OC4D).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PC6(OC3A) pin as output pin */&lt;br /&gt;
  DDRC |= (1 &amp;lt;&amp;lt; PORTC6);&lt;br /&gt;
  /* enable OC3A pin as PWM pin */&lt;br /&gt;
  TCCR3A |= (1 &amp;lt;&amp;lt; COM3A1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PD7 pin as output pin */&lt;br /&gt;
  DDRD |= (1 &amp;lt;&amp;lt; PORTD7);&lt;br /&gt;
  /* enable OC4D pin as PWM pin */TCCR4C |= (1 &amp;lt;&amp;lt; PWM4D);&lt;br /&gt;
  TCCR4C |= (1 &amp;lt;&amp;lt; COM4D1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, il faut indiquer la valeur du PWM : cette valeur indique le temps haut du signal compris entre 0 et 255. Par exemple, pour avoir un signal carré (temps haut = temps bas), il faut avoir une valeur de 127. Ces valeurs sont écrites dans les registres OCRnx.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* write value a in PWM 3A */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_write(char a)&lt;br /&gt;
{&lt;br /&gt;
  OCR3A = a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* write value a in PWM 4D */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_write(char a)&lt;br /&gt;
{&lt;br /&gt;
  OCR4D = a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite créer des fonctions qui permettent au robot d'avancer, reculer et tourner en précisant la vitesse (de 0 à 255).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* stop */&lt;br /&gt;
void&lt;br /&gt;
stop(void)&lt;br /&gt;
{&lt;br /&gt;
  pwm_4D_write(0);&lt;br /&gt;
  pwm_3A_write(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* advance&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
advance(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* back off&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
back_off(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn left&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_left(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn right&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_right(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, les fonctions main() et setup()&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
pin_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* Motor controller */&lt;br /&gt;
  DDRD = (1 &amp;lt;&amp;lt; PORTD4); /* PD4 as output pin */&lt;br /&gt;
  DDRE = (1 &amp;lt;&amp;lt; PORTE6); /* PE6 as output pin */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    turn_left(100);&lt;br /&gt;
    //advance(200);&lt;br /&gt;
    // stop();&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Communication XBee ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Commande à distance ===&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* setup USART1&lt;br /&gt;
 * speed : 9600 Baud&lt;br /&gt;
 * 8-bits, no parity, 1-stop-bit */&lt;br /&gt;
void&lt;br /&gt;
USART_1_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT2); /* initialize pin PD2 (RX) as input pin */&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT3); /* initialize pin PD3 (TX) as output pin */&lt;br /&gt;
&lt;br /&gt;
  UBRR1 = 103; /* 9600 Baud at 16MHz */&lt;br /&gt;
&lt;br /&gt;
  UCSR1A = 0;&lt;br /&gt;
&lt;br /&gt;
  /* 8-bits, no parity, 1-stop-bit */&lt;br /&gt;
  UCSR1C = (1 &amp;lt;&amp;lt; UCSZ11) | (1 &amp;lt;&amp;lt; UCSZ10);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il existe 2 solutions pour recevoir une donnée via la liaison série :&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
USART_1_receiver_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXEN1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned char&lt;br /&gt;
USART_1_receive(void)&lt;br /&gt;
{&lt;br /&gt;
  // wait for data to be received&lt;br /&gt;
  while (!(UCSR1A &amp;amp; (1 &amp;lt;&amp;lt; RXC1)))&lt;br /&gt;
    ;&lt;br /&gt;
  // get and return received data from buffer&lt;br /&gt;
  return UDR1 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
volatile char receive_char;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
USART_1_receiver_interrupt_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXEN1);&lt;br /&gt;
  /* enable interrupt on the RXC1 flag */&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXCIE1);&lt;br /&gt;
  SREG |= (1 &amp;lt;&amp;lt; SREG_I);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// receiver interrupt&lt;br /&gt;
ISR( USART1_RX_vect)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char dustbin = 0;&lt;br /&gt;
  &lt;br /&gt;
  receive_char = UDR1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
pin_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* Motor controller */&lt;br /&gt;
  DDRD = (1 &amp;lt;&amp;lt; PORTD4); /* PD4 as output pin */&lt;br /&gt;
  DDRE = (1 &amp;lt;&amp;lt; PORTE6); /* PE6 as output pin */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
&lt;br /&gt;
  USART_1_setup();&lt;br /&gt;
  //USART_1_receiver_enable();&lt;br /&gt;
  USART_1_receiver_interrupt_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  //char c;&lt;br /&gt;
  setup();&lt;br /&gt;
&lt;br /&gt;
  while (1)&lt;br /&gt;
    {&lt;br /&gt;
      //c = USART_1_receive();&lt;br /&gt;
&lt;br /&gt;
      switch (/*c*/receive_char)&lt;br /&gt;
        {&lt;br /&gt;
      case 'a':&lt;br /&gt;
        advance(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'b':&lt;br /&gt;
        back_off(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'r':&lt;br /&gt;
        turn_right(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'l':&lt;br /&gt;
        turn_left(100);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        stop();&lt;br /&gt;
        break;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conversion analogique / numérique ==&lt;br /&gt;
&lt;br /&gt;
Les capteurs que nous utilisons retourne généralement une information (tension) sous forme analogique. Pour exploiter cette information, le microcontroleur doit la convertir en signal numérique.&lt;br /&gt;
&lt;br /&gt;
Le convertisseur analogique / numérique de l'ATMEGA32U4 est un convertisseur 10 bits soit une précision de 1024 points. En se basant sur une tension de référence (généralement la tension d'alimentation), il va, par approximation successive, définir la valeur numérique correspondante à la tension.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, nous allons configurer le convertisseur. Le microcontroleur a 6 entrées analogiques sur le port F qu'il faut configurer en entrée. La tension de référence pour effectuer la conversion est la tension d'alimentation Vcc = 5V.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* Voltage reference : Vcc&lt;br /&gt;
 * Right adjust result&lt;br /&gt;
 * and with clock prescaled to system clock divided by 1024 */&lt;br /&gt;
void&lt;br /&gt;
adc_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* initialize PORTF pins as input pin */&lt;br /&gt;
  DDRF = 0x00;&lt;br /&gt;
&lt;br /&gt;
  /* set ADC prescale factor to 1024 */&lt;br /&gt;
  ADCSRA |= (1 &amp;lt;&amp;lt; ADPS2) | (1 &amp;lt;&amp;lt; ADPS1) | (1 &amp;lt;&amp;lt; ADPS0);&lt;br /&gt;
&lt;br /&gt;
  /* Vcc is reference voltage */&lt;br /&gt;
  ADMUX |= (1 &amp;lt;&amp;lt; REFS0);&lt;br /&gt;
&lt;br /&gt;
  /* Set ADC to Free-Running Mode */&lt;br /&gt;
  ADCSRB = 0;&lt;br /&gt;
&lt;br /&gt;
  /* adc enable */&lt;br /&gt;
  ADCSRA |= (1 &amp;lt;&amp;lt; ADEN);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensuite, nous allons lire la valeur de chaque entrée en démarrant la conversion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
adc_start_conversion(uint8_t pin)&lt;br /&gt;
{&lt;br /&gt;
  //adc_enable(pin);&lt;br /&gt;
  ADMUX = (1 &amp;lt;&amp;lt; REFS0) | pin;&lt;br /&gt;
  DIDR0 = (1 &amp;lt;&amp;lt; pin);&lt;br /&gt;
  ADCSRA |= (1 &amp;lt;&amp;lt; ADSC); // adc start conversion&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint16_t&lt;br /&gt;
adc_read(uint8_t pin)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t low;&lt;br /&gt;
  adc_start_conversion(pin);&lt;br /&gt;
  while (ADCSRA &amp;amp; (1 &amp;lt;&amp;lt; ADSC))&lt;br /&gt;
    ;                    // wait for result&lt;br /&gt;
  low = ADCL;   // must read LSB first&lt;br /&gt;
  return (ADCH &amp;lt;&amp;lt; 8) | low;     // must read MSB only once!&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Carte_Romeo</id>
		<title>Carte Romeo</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Carte_Romeo"/>
				<updated>2013-06-28T11:51:52Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : /* Commande des moteurs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;La carte ROMEO de DFROBOT est une carte tout-en-un conçue pour faire ses premiers pas vers la robotique. Cette carte très simple d'utilisation permet de commander 2 moteurs, d'interfacer des capteurs et de piloter le robot à distance via un module X-bee. Elle est basée sur un microcontroleur ATMEGA32u4 (V2.0 R3).&lt;br /&gt;
&lt;br /&gt;
Pour tester la carte ROMEO, nous avons utilisé la plateforme de développement Turtle 2WD de DFROBOT. Cette plateforme est équipée de 2 roues montées en direct sur 2 motoréducteurs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Commande des moteurs ==&lt;br /&gt;
&lt;br /&gt;
Le moteur à courant continu est l'élément principal qui permet au robot de se déplacer. Sa vitesse est proportionnelle à la tension d'alimentation. Plus la tension est élevée plus le moteur va tourner rapidement. Il faut donc créer une tension continue variable pour faire varier la vitesse du moteur. &lt;br /&gt;
&lt;br /&gt;
=== Signaux PWM ===&lt;br /&gt;
Les signaux PWM permettent de fournir une tension continue variable à partir de signaux numériques (0 et 5V). Le microcontroleur va générer un signal en forme de créneaux. En faisant varier le rapport cyclique, la tension moyenne va varier et le moteur va tourner plus ou moins vite.&lt;br /&gt;
&lt;br /&gt;
=== Electronique ===&lt;br /&gt;
La carte ROMEO est équipée d'un module de commande pour moteur à courant continu (L298). Ce pont H va fournir la puissance nécessaire au moteur pour tourner. Le microcontroleur va fournir un signal PWM et un signal de direction pour chaque moteur.&lt;br /&gt;
&lt;br /&gt;
=== Exemple de code ===&lt;br /&gt;
==== Langage Arduino ====&lt;br /&gt;
Le L298 utilise la pin 4 (M1 : direction) et 5 (E1 : PWM) pour le moteur 1 et la pin 6 (E2 : PWM) et 7 (M2 : direction) pour le moteur 2.&lt;br /&gt;
&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php/DFRduino_Romeo-All_in_one_Controller_V1.1%28SKU:DFR0004%29 ici]&lt;br /&gt;
&lt;br /&gt;
==== Langage C ====&lt;br /&gt;
Pour générer un signal PWM, le microcontroleur a besoin d'un timer interne. Il utilise le timer 3A  pour E1 et le timer 4D pour E2.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, il faut initialiser les timers en mode PWM. Nous configurons le mode PWM avec des valeurs fréquemment utilisées pour la commande de moteurs.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* timer3 is used for phase-correct 8-bits PWM mode &lt;br /&gt;
and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_3_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* set timer3 prescale factor to 64 */&lt;br /&gt;
  TCCR3B = (1 &amp;lt;&amp;lt; CS31) | (1 &amp;lt;&amp;lt; CS30);&lt;br /&gt;
  /* put timer3 in phase correct PWM mode */&lt;br /&gt;
  TCCR3A = (1 &amp;lt;&amp;lt; WGM30);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* timer4 is used for phase and frequency correct 10-bits PWM mode &lt;br /&gt;
* and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_4_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  TC4H = 0;&lt;br /&gt;
  /* set timer4 prescale factor to 64 */&lt;br /&gt;
  TCCR4B = (1 &amp;lt;&amp;lt; CS42) | (1 &amp;lt;&amp;lt; CS41) | (1 &amp;lt;&amp;lt; CS40);&lt;br /&gt;
  /* put timer 4 in phase and frequency correct PWM mode */&lt;br /&gt;
  TCCR4D =(1 &amp;lt;&amp;lt; WGM40);&lt;br /&gt;
  /* not used */&lt;br /&gt;
  TCCR4E = 0;&lt;br /&gt;
  /* Set top to 0xFF */&lt;br /&gt;
  OCR4C = 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut activer les pins utilisées par le L298 (5:OC3A et 6:OC4D).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PC6(OC3A) pin as output pin */&lt;br /&gt;
  DDRC |= (1 &amp;lt;&amp;lt; PORTC6);&lt;br /&gt;
  /* enable OC3A pin as PWM pin */&lt;br /&gt;
  TCCR3A |= (1 &amp;lt;&amp;lt; COM3A1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PD7 pin as output pin */&lt;br /&gt;
  DDRD |= (1 &amp;lt;&amp;lt; PORTD7);&lt;br /&gt;
  /* enable OC4D pin as PWM pin */TCCR4C |= (1 &amp;lt;&amp;lt; PWM4D);&lt;br /&gt;
  TCCR4C |= (1 &amp;lt;&amp;lt; COM4D1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, il faut indiquer la valeur du PWM : cette valeur indique le temps haut du signal compris entre 0 et 255. Par exemple, pour avoir un signal carré (temps haut = temps bas), il faut avoir une valeur de 127. Ces valeurs sont écrites dans les registres OCRnx.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* write value a in PWM 3A */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_write(char a)&lt;br /&gt;
{&lt;br /&gt;
  OCR3A = a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* write value a in PWM 4D */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_write(char a)&lt;br /&gt;
{&lt;br /&gt;
  OCR4D = a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite créer des fonctions qui permettent au robot d'avancer, reculer et tourner en précisant la vitesse (de 0 à 255).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* stop */&lt;br /&gt;
void&lt;br /&gt;
stop(void)&lt;br /&gt;
{&lt;br /&gt;
  pwm_4D_write(0);&lt;br /&gt;
  pwm_3A_write(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* advance&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
advance(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* back off&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
back_off(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn left&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_left(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn right&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_right(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, les fonctions main() et setup()&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
pin_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* Motor controller */&lt;br /&gt;
  DDRD = (1 &amp;lt;&amp;lt; PORTD4); /* PD4 as output pin */&lt;br /&gt;
  DDRE = (1 &amp;lt;&amp;lt; PORTE6); /* PE6 as output pin */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    turn_left(100);&lt;br /&gt;
    //advance(200);&lt;br /&gt;
    // stop();&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Communication XBee ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=== Commande à distance ===&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* setup USART1&lt;br /&gt;
 * speed : 9600 Baud&lt;br /&gt;
 * 8-bits, no parity, 1-stop-bit */&lt;br /&gt;
void&lt;br /&gt;
USART_1_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT2); /* initialize pin PD2 (RX) as input pin */&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT3); /* initialize pin PD3 (TX) as output pin */&lt;br /&gt;
&lt;br /&gt;
  UBRR1 = 103; /* 9600 Baud at 16MHz */&lt;br /&gt;
&lt;br /&gt;
  UCSR1A = 0;&lt;br /&gt;
&lt;br /&gt;
  /* 8-bits, no parity, 1-stop-bit */&lt;br /&gt;
  UCSR1C = (1 &amp;lt;&amp;lt; UCSZ11) | (1 &amp;lt;&amp;lt; UCSZ10);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il existe 2 solutions pour recevoir une donnée via la liaison série :&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
USART_1_receiver_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXEN1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned char&lt;br /&gt;
USART_1_receive(void)&lt;br /&gt;
{&lt;br /&gt;
  // wait for data to be received&lt;br /&gt;
  while (!(UCSR1A &amp;amp; (1 &amp;lt;&amp;lt; RXC1)))&lt;br /&gt;
    ;&lt;br /&gt;
  // get and return received data from buffer&lt;br /&gt;
  return UDR1 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
volatile char receive_char;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
USART_1_receiver_interrupt_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXEN1);&lt;br /&gt;
  /* enable interrupt on the RXC1 flag */&lt;br /&gt;
  UCSR1B |= (1 &amp;lt;&amp;lt; RXCIE1);&lt;br /&gt;
  SREG |= (1 &amp;lt;&amp;lt; SREG_I);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// receiver interrupt&lt;br /&gt;
ISR( USART1_RX_vect)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char dustbin = 0;&lt;br /&gt;
  &lt;br /&gt;
  receive_char = UDR1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
pin_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* Motor controller */&lt;br /&gt;
  DDRD = (1 &amp;lt;&amp;lt; PORTD4); /* PD4 as output pin */&lt;br /&gt;
  DDRE = (1 &amp;lt;&amp;lt; PORTE6); /* PE6 as output pin */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
&lt;br /&gt;
  USART_1_setup();&lt;br /&gt;
  //USART_1_receiver_enable();&lt;br /&gt;
  USART_1_receiver_interrupt_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  //char c;&lt;br /&gt;
  setup();&lt;br /&gt;
&lt;br /&gt;
  while (1)&lt;br /&gt;
    {&lt;br /&gt;
      //c = USART_1_receive();&lt;br /&gt;
&lt;br /&gt;
      switch (/*c*/receive_char)&lt;br /&gt;
        {&lt;br /&gt;
      case 'a':&lt;br /&gt;
        advance(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'b':&lt;br /&gt;
        back_off(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'r':&lt;br /&gt;
        turn_right(100);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'l':&lt;br /&gt;
        turn_left(100);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        stop();&lt;br /&gt;
        break;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Carte_Romeo</id>
		<title>Carte Romeo</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Carte_Romeo"/>
				<updated>2013-06-28T09:44:36Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : /* Langage C */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;La carte ROMEO de DFROBOT est une carte tout-en-un conçue pour faire ses premiers pas vers la robotique. Cette carte très simple d'utilisation permet de commander 2 moteurs, d'interfacer des capteurs et de piloter le robot à distance via un module X-bee. Elle est basée sur un microcontroleur ATMEGA32u4 (V2.0 R3).&lt;br /&gt;
&lt;br /&gt;
Pour tester la carte ROMEO, nous avons utilisé la plateforme de développement Turtle 2WD de DFROBOT. Cette plateforme est équipée de 2 roues montées en direct sur 2 motoréducteurs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Commande des moteurs ==&lt;br /&gt;
&lt;br /&gt;
Le moteur à courant continu est l'élément principal qui permet au robot de se déplacer. Sa vitesse est proportionnelle à la tension d'alimentation. Plus la tension est élevée plus le moteur va tourner rapidement. Il faut donc créer une tension continue variable pour faire varier la vitesse du moteur. &lt;br /&gt;
&lt;br /&gt;
=== Signaux PWM ===&lt;br /&gt;
Les signaux PWM permettent de fournir une tension continue variable à partir de signaux numériques (0 et 5V). Le microcontroleur va générer un signal en forme de créneaux. En faisant varier le rapport cyclique, la tension moyenne va varier et le moteur va tourner plus ou moins vite.&lt;br /&gt;
&lt;br /&gt;
=== Electronique ===&lt;br /&gt;
La carte ROMEO est équipée d'un module de commande pour moteur à courant continu (L298). Ce pont H va fournir la puissance nécessaire au moteur pour tourner. Le microcontroleur va fournir un signal PWM et un signal de direction pour chaque moteur.&lt;br /&gt;
&lt;br /&gt;
=== Exemple de code ===&lt;br /&gt;
==== Langage Arduino ====&lt;br /&gt;
Le L298 utilise la pin 4 (M1 : direction) et 5 (E1 : PWM) pour le moteur 1 et la pin 6 (E2 : PWM) et 7 (M2 : direction) pour le moteur 2.&lt;br /&gt;
&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php/DFRduino_Romeo-All_in_one_Controller_V1.1%28SKU:DFR0004%29 ici]&lt;br /&gt;
&lt;br /&gt;
==== Langage C ====&lt;br /&gt;
Pour générer un signal PWM, le microcontroleur a besoin d'un timer interne. Il utilise le timer 3A  pour E1 et le timer 4D pour E2.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, il faut initialiser les timers en mode PWM. Nous configurons le mode PWM avec des valeurs fréquemment utilisées pour la commande de moteurs.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* timer3 is used for phase-correct 8-bits PWM mode &lt;br /&gt;
and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_3_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* set timer3 prescale factor to 64 */&lt;br /&gt;
  TCCR3B = (1 &amp;lt;&amp;lt; CS31) | (1 &amp;lt;&amp;lt; CS30);&lt;br /&gt;
  /* put timer3 in phase correct PWM mode */&lt;br /&gt;
  TCCR3A = (1 &amp;lt;&amp;lt; WGM30);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* timer4 is used for phase and frequency correct 10-bits PWM mode &lt;br /&gt;
* and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_4_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  TC4H = 0;&lt;br /&gt;
  /* set timer4 prescale factor to 64 */&lt;br /&gt;
  TCCR4B = (1 &amp;lt;&amp;lt; CS42) | (1 &amp;lt;&amp;lt; CS41) | (1 &amp;lt;&amp;lt; CS40);&lt;br /&gt;
  /* put timer 4 in phase and frequency correct PWM mode */&lt;br /&gt;
  TCCR4D =(1 &amp;lt;&amp;lt; WGM40);&lt;br /&gt;
  /* not used */&lt;br /&gt;
  TCCR4E = 0;&lt;br /&gt;
  /* Set top to 0xFF */&lt;br /&gt;
  OCR4C = 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut activer les pins utilisées par le L298 (5:OC3A et 6:OC4D).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PC6(OC3A) pin as output pin */&lt;br /&gt;
  DDRC |= (1 &amp;lt;&amp;lt; PORTC6);&lt;br /&gt;
  /* enable OC3A pin as PWM pin */&lt;br /&gt;
  TCCR3A |= (1 &amp;lt;&amp;lt; COM3A1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PD7 pin as output pin */&lt;br /&gt;
  DDRD |= (1 &amp;lt;&amp;lt; PORTD7);&lt;br /&gt;
  /* enable OC4D pin as PWM pin */TCCR4C |= (1 &amp;lt;&amp;lt; PWM4D);&lt;br /&gt;
  TCCR4C |= (1 &amp;lt;&amp;lt; COM4D1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, il faut indiquer la valeur du PWM : cette valeur indique le temps haut du signal compris entre 0 et 255. Par exemple, pour avoir un signal carré (temps haut = temps bas), il faut avoir une valeur de 127. Ces valeurs sont écrites dans les registres OCRnx.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* write value a in PWM 3A */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_write(char a)&lt;br /&gt;
{&lt;br /&gt;
  OCR3A = a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* write value a in PWM 4D */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_write(char a)&lt;br /&gt;
{&lt;br /&gt;
  OCR4D = a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite créer des fonctions qui permettent au robot d'avancer, reculer et tourner en précisant la vitesse (de 0 à 255).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* stop */&lt;br /&gt;
void&lt;br /&gt;
stop(void)&lt;br /&gt;
{&lt;br /&gt;
  pwm_4D_write(0);&lt;br /&gt;
  pwm_3A_write(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* advance&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
advance(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* back off&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
back_off(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn left&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_left(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn right&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_right(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, les fonctions main() et setup()&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
pin_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* Motor controller */&lt;br /&gt;
  DDRD = (1 &amp;lt;&amp;lt; PORTD4); /* PD4 as output pin */&lt;br /&gt;
  DDRE = (1 &amp;lt;&amp;lt; PORTE6); /* PE6 as output pin */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    turn_left(100);&lt;br /&gt;
    //advance(200);&lt;br /&gt;
    // stop();&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Accueil</id>
		<title>Accueil</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Accueil"/>
				<updated>2013-06-25T19:34:37Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bonjour et Bienvenue sur le Wiki d'Arobose.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez y trouver des tutoriels sur la Robotique et des explications sur les produits de la Boutique, des exemples, des librairies Arduino, bref plein de solutions, d'idée et de techniques pour créer, améliorer votre robot.&lt;br /&gt;
&lt;br /&gt;
Admin&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;categorytree mode=pages&amp;gt;Sommaire&amp;lt;/categorytree&amp;gt;'''&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Accueil</id>
		<title>Accueil</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Accueil"/>
				<updated>2013-06-25T19:27:59Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bonjour et Bienvenue sur le Wiki d'Arobose.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez y trouver des tutoriels sur la Robotique et des explications sur les produits de la Boutique, des exemples, des librairies Arduino, bref plein de solutions, d'idée et de techniques pour créer, améliorer votre robot.&lt;br /&gt;
&lt;br /&gt;
Admin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;categorytree mode=pages&amp;gt;Sommaire&amp;lt;/categorytree&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Carte_Romeo</id>
		<title>Carte Romeo</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Carte_Romeo"/>
				<updated>2013-06-25T19:21:36Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;La carte ROMEO de DFROBOT est une carte tout-en-un conçue pour faire ses premiers pas vers la robotique. Cette carte très simple d'utilisation permet de commander 2 moteurs, d'interfacer des capteurs et de piloter le robot à distance via un module X-bee. Elle est basée sur un microcontroleur ATMEGA32u4 (V2.0 R3).&lt;br /&gt;
&lt;br /&gt;
Pour tester la carte ROMEO, nous avons utilisé la plateforme de développement Turtle 2WD de DFROBOT. Cette plateforme est équipée de 2 roues montées en direct sur 2 motoréducteurs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Commande des moteurs ==&lt;br /&gt;
&lt;br /&gt;
Le moteur à courant continu est l'élément principal qui permet au robot de se déplacer. Sa vitesse est proportionnelle à la tension d'alimentation. Plus la tension est élevée plus le moteur va tourner rapidement. Il faut donc créer une tension continue variable pour faire varier la vitesse du moteur. &lt;br /&gt;
&lt;br /&gt;
=== Signaux PWM ===&lt;br /&gt;
Les signaux PWM permettent de fournir une tension continue variable à partir de signaux numériques (0 et 5V). Le microcontroleur va générer un signal en forme de créneaux. En faisant varier le rapport cyclique, la tension moyenne va varier et le moteur va tourner plus ou moins vite.&lt;br /&gt;
&lt;br /&gt;
=== Electronique ===&lt;br /&gt;
La carte ROMEO est équipée d'un module de commande pour moteur à courant continu (L298). Ce pont H va fournir la puissance nécessaire au moteur pour tourner. Le microcontroleur va fournir un signal PWM et un signal de direction pour chaque moteur.&lt;br /&gt;
&lt;br /&gt;
=== Exemple de code ===&lt;br /&gt;
==== Langage Arduino ====&lt;br /&gt;
Le L298 utilise la pin 4 (M1 : direction) et 5 (E1 : PWM) pour le moteur 1 et la pin 6 (E2 : PWM) et 7 (M2 : direction) pour le moteur 2.&lt;br /&gt;
&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php/DFRduino_Romeo-All_in_one_Controller_V1.1%28SKU:DFR0004%29 ici]&lt;br /&gt;
&lt;br /&gt;
==== Langage C ====&lt;br /&gt;
Pour générer un signal PWM, le microcontroleur a besoin d'un timer interne. Il utilise le timer 3A  pour E1 et le timer 4D pour E2.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, il faut initialiser les timers en mode PWM. Nous configurons le mode PWM avec des valeurs fréquemment utilisées pour la commande de moteurs.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* timer3 is used for phase-correct 8-bits PWM mode &lt;br /&gt;
and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_3_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* set timer3 prescale factor to 64 */&lt;br /&gt;
  TCCR3B = (1 &amp;lt;&amp;lt; CS31) | (1 &amp;lt;&amp;lt; CS30);&lt;br /&gt;
  /* put timer3 in phase correct PWM mode */&lt;br /&gt;
  TCCR3A = (1 &amp;lt;&amp;lt; WGM30);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* timer4 is used for phase and frequency correct 10-bits PWM mode &lt;br /&gt;
* and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_4_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  TC4H = 0;&lt;br /&gt;
  /* set timer4 prescale factor to 64 */&lt;br /&gt;
  TCCR4B = (1 &amp;lt;&amp;lt; CS42) | (1 &amp;lt;&amp;lt; CS41) | (1 &amp;lt;&amp;lt; CS40);&lt;br /&gt;
  /* put timer 4 in phase and frequency correct PWM mode */&lt;br /&gt;
  TCCR4D =(1 &amp;lt;&amp;lt; WGM40);&lt;br /&gt;
  /* not used */&lt;br /&gt;
  TCCR4E = 0;&lt;br /&gt;
  /* Set top to 0xFF */&lt;br /&gt;
  OCR4C = 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut activer les pins utilisées par le L298 (5:OC3A et 6:OC4D).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PC6(OC3A) pin as output pin */&lt;br /&gt;
  DDRC |= (1 &amp;lt;&amp;lt; PORTC6);&lt;br /&gt;
  /* enable OC3A pin as PWM pin */&lt;br /&gt;
  TCCR3A |= (1 &amp;lt;&amp;lt; COM3A1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PD7 pin as output pin */&lt;br /&gt;
  DDRD |= (1 &amp;lt;&amp;lt; PORTD7);&lt;br /&gt;
  /* enable OC4D pin as PWM pin */TCCR4C |= (1 &amp;lt;&amp;lt; PWM4D);&lt;br /&gt;
  TCCR4C |= (1 &amp;lt;&amp;lt; COM4D1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Nous avons ensuite créer des fonctions qui permettent au robot d'avancer, reculer et tourner en précisant la vitesse (de 0 à 255).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* stop */&lt;br /&gt;
void&lt;br /&gt;
stop(void)&lt;br /&gt;
{&lt;br /&gt;
  pwm_4D_write(0);&lt;br /&gt;
  pwm_3A_write(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* advance&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
advance(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* back off&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
back_off(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn left&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_left(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn right&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_right(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, les fonctions main() et setup()&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    turn_left(100);&lt;br /&gt;
    //advance(200);&lt;br /&gt;
    // stop();&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Accueil</id>
		<title>Accueil</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Accueil"/>
				<updated>2013-06-25T19:20:31Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bonjour et Bienvenue sur le Wiki d'Arobose.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez y trouver des tutoriels sur la Robotique et des explications sur les produits de la Boutique, des exemples, des librairies Arduino, bref plein de solutions, d'idée et de techniques pour créer, améliorer votre robot.&lt;br /&gt;
&lt;br /&gt;
Admin&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;categorytree mode=all&amp;gt;Sommaire&amp;lt;/categorytree&amp;gt;'''&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Cat%C3%A9gorie:Produits</id>
		<title>Catégorie:Produits</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Cat%C3%A9gorie:Produits"/>
				<updated>2013-06-25T19:13:26Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Présentation, Détails techniques, exemples d'utilisation de produits proposés sur notre site.&lt;br /&gt;
&lt;br /&gt;
[[Category:Sommaire]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Carte_Romeo</id>
		<title>Carte Romeo</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Carte_Romeo"/>
				<updated>2013-06-25T19:10:32Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;La carte ROMEO de DFROBOT est une carte tout-en-un conçue pour faire ses premiers pas vers la robotique. Cette carte très simple d'utilisation permet de commander 2 moteurs, d'interfacer des capteurs et de piloter le robot à distance via un module X-bee. Elle est basée sur un microcontroleur ATMEGA32u4 (V2.0 R3).&lt;br /&gt;
&lt;br /&gt;
Pour tester la carte ROMEO, nous avons utilisé la plateforme de développement Turtle 2WD de DFROBOT. Cette plateforme est équipée de 2 roues montées en direct sur 2 motoréducteurs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Commande des moteurs ==&lt;br /&gt;
&lt;br /&gt;
Le moteur à courant continu est l'élément principal qui permet au robot de se déplacer. Sa vitesse est proportionnelle à la tension d'alimentation. Plus la tension est élevée plus le moteur va tourner rapidement. Il faut donc créer une tension continue variable pour faire varier la vitesse du moteur. &lt;br /&gt;
&lt;br /&gt;
=== Signaux PWM ===&lt;br /&gt;
Les signaux PWM permettent de fournir une tension continue variable à partir de signaux numériques (0 et 5V). Le microcontroleur va générer un signal en forme de créneaux. En faisant varier le rapport cyclique, la tension moyenne va varier et le moteur va tourner plus ou moins vite.&lt;br /&gt;
&lt;br /&gt;
=== Electronique ===&lt;br /&gt;
La carte ROMEO est équipée d'un module de commande pour moteur à courant continu (L298). Ce pont H va fournir la puissance nécessaire au moteur pour tourner. Le microcontroleur va fournir un signal PWM et un signal de direction pour chaque moteur.&lt;br /&gt;
&lt;br /&gt;
=== Exemple de code ===&lt;br /&gt;
==== Langage Arduino ====&lt;br /&gt;
Le L298 utilise la pin 4 (M1 : direction) et 5 (E1 : PWM) pour le moteur 1 et la pin 6 (E2 : PWM) et 7 (M2 : direction) pour le moteur 2.&lt;br /&gt;
&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php/DFRduino_Romeo-All_in_one_Controller_V1.1%28SKU:DFR0004%29 ici]&lt;br /&gt;
&lt;br /&gt;
==== Langage C ====&lt;br /&gt;
Pour générer un signal PWM, le microcontroleur a besoin d'un timer interne. Il utilise le timer 3A  pour E1 et le timer 4D pour E2.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, il faut initialiser les timers en mode PWM. Nous configurons le mode PWM avec des valeurs fréquemment utilisées pour la commande de moteurs.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* timer3 is used for phase-correct 8-bits PWM mode &lt;br /&gt;
and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_3_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* set timer3 prescale factor to 64 */&lt;br /&gt;
  TCCR3B = (1 &amp;lt;&amp;lt; CS31) | (1 &amp;lt;&amp;lt; CS30);&lt;br /&gt;
  /* put timer3 in phase correct PWM mode */&lt;br /&gt;
  TCCR3A = (1 &amp;lt;&amp;lt; WGM30);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* timer4 is used for phase and frequency correct 10-bits PWM mode &lt;br /&gt;
* and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_4_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  TC4H = 0;&lt;br /&gt;
  /* set timer4 prescale factor to 64 */&lt;br /&gt;
  TCCR4B = (1 &amp;lt;&amp;lt; CS42) | (1 &amp;lt;&amp;lt; CS41) | (1 &amp;lt;&amp;lt; CS40);&lt;br /&gt;
  /* put timer 4 in phase and frequency correct PWM mode */&lt;br /&gt;
  TCCR4D =(1 &amp;lt;&amp;lt; WGM40);&lt;br /&gt;
  /* not used */&lt;br /&gt;
  TCCR4E = 0;&lt;br /&gt;
  /* Set top to 0xFF */&lt;br /&gt;
  OCR4C = 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut activer les pins utilisées par le L298 (5:OC3A et 6:OC4D).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PC6(OC3A) pin as output pin */&lt;br /&gt;
  DDRC |= (1 &amp;lt;&amp;lt; PORTC6);&lt;br /&gt;
  /* enable OC3A pin as PWM pin */&lt;br /&gt;
  TCCR3A |= (1 &amp;lt;&amp;lt; COM3A1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PD7 pin as output pin */&lt;br /&gt;
  DDRD |= (1 &amp;lt;&amp;lt; PORTD7);&lt;br /&gt;
  /* enable OC4D pin as PWM pin */TCCR4C |= (1 &amp;lt;&amp;lt; PWM4D);&lt;br /&gt;
  TCCR4C |= (1 &amp;lt;&amp;lt; COM4D1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Nous avons ensuite créer des fonctions qui permettent au robot d'avancer, reculer et tourner en précisant la vitesse (de 0 à 255).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* stop */&lt;br /&gt;
void&lt;br /&gt;
stop(void)&lt;br /&gt;
{&lt;br /&gt;
  pwm_4D_write(0);&lt;br /&gt;
  pwm_3A_write(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* advance&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
advance(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* back off&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
back_off(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn left&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_left(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn right&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_right(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, les fonctions main() et setup()&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    turn_left(100);&lt;br /&gt;
    //advance(200);&lt;br /&gt;
    // stop();&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;br /&gt;
[[Category:Sommaire:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Carte_Romeo</id>
		<title>Carte Romeo</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Carte_Romeo"/>
				<updated>2013-06-25T19:09:56Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;La carte ROMEO de DFROBOT est une carte tout-en-un conçue pour faire ses premiers pas vers la robotique. Cette carte très simple d'utilisation permet de commander 2 moteurs, d'interfacer des capteurs et de piloter le robot à distance via un module X-bee. Elle est basée sur un microcontroleur ATMEGA32u4 (V2.0 R3).&lt;br /&gt;
&lt;br /&gt;
Pour tester la carte ROMEO, nous avons utilisé la plateforme de développement Turtle 2WD de DFROBOT. Cette plateforme est équipée de 2 roues montées en direct sur 2 motoréducteurs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Commande des moteurs ==&lt;br /&gt;
&lt;br /&gt;
Le moteur à courant continu est l'élément principal qui permet au robot de se déplacer. Sa vitesse est proportionnelle à la tension d'alimentation. Plus la tension est élevée plus le moteur va tourner rapidement. Il faut donc créer une tension continue variable pour faire varier la vitesse du moteur. &lt;br /&gt;
&lt;br /&gt;
=== Signaux PWM ===&lt;br /&gt;
Les signaux PWM permettent de fournir une tension continue variable à partir de signaux numériques (0 et 5V). Le microcontroleur va générer un signal en forme de créneaux. En faisant varier le rapport cyclique, la tension moyenne va varier et le moteur va tourner plus ou moins vite.&lt;br /&gt;
&lt;br /&gt;
=== Electronique ===&lt;br /&gt;
La carte ROMEO est équipée d'un module de commande pour moteur à courant continu (L298). Ce pont H va fournir la puissance nécessaire au moteur pour tourner. Le microcontroleur va fournir un signal PWM et un signal de direction pour chaque moteur.&lt;br /&gt;
&lt;br /&gt;
=== Exemple de code ===&lt;br /&gt;
==== Langage Arduino ====&lt;br /&gt;
Le L298 utilise la pin 4 (M1 : direction) et 5 (E1 : PWM) pour le moteur 1 et la pin 6 (E2 : PWM) et 7 (M2 : direction) pour le moteur 2.&lt;br /&gt;
&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php/DFRduino_Romeo-All_in_one_Controller_V1.1%28SKU:DFR0004%29 ici]&lt;br /&gt;
&lt;br /&gt;
==== Langage C ====&lt;br /&gt;
Pour générer un signal PWM, le microcontroleur a besoin d'un timer interne. Il utilise le timer 3A  pour E1 et le timer 4D pour E2.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, il faut initialiser les timers en mode PWM. Nous configurons le mode PWM avec des valeurs fréquemment utilisées pour la commande de moteurs.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* timer3 is used for phase-correct 8-bits PWM mode &lt;br /&gt;
and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_3_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* set timer3 prescale factor to 64 */&lt;br /&gt;
  TCCR3B = (1 &amp;lt;&amp;lt; CS31) | (1 &amp;lt;&amp;lt; CS30);&lt;br /&gt;
  /* put timer3 in phase correct PWM mode */&lt;br /&gt;
  TCCR3A = (1 &amp;lt;&amp;lt; WGM30);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* timer4 is used for phase and frequency correct 10-bits PWM mode &lt;br /&gt;
* and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_4_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  TC4H = 0;&lt;br /&gt;
  /* set timer4 prescale factor to 64 */&lt;br /&gt;
  TCCR4B = (1 &amp;lt;&amp;lt; CS42) | (1 &amp;lt;&amp;lt; CS41) | (1 &amp;lt;&amp;lt; CS40);&lt;br /&gt;
  /* put timer 4 in phase and frequency correct PWM mode */&lt;br /&gt;
  TCCR4D =(1 &amp;lt;&amp;lt; WGM40);&lt;br /&gt;
  /* not used */&lt;br /&gt;
  TCCR4E = 0;&lt;br /&gt;
  /* Set top to 0xFF */&lt;br /&gt;
  OCR4C = 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut activer les pins utilisées par le L298 (5:OC3A et 6:OC4D).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PC6(OC3A) pin as output pin */&lt;br /&gt;
  DDRC |= (1 &amp;lt;&amp;lt; PORTC6);&lt;br /&gt;
  /* enable OC3A pin as PWM pin */&lt;br /&gt;
  TCCR3A |= (1 &amp;lt;&amp;lt; COM3A1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PD7 pin as output pin */&lt;br /&gt;
  DDRD |= (1 &amp;lt;&amp;lt; PORTD7);&lt;br /&gt;
  /* enable OC4D pin as PWM pin */TCCR4C |= (1 &amp;lt;&amp;lt; PWM4D);&lt;br /&gt;
  TCCR4C |= (1 &amp;lt;&amp;lt; COM4D1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Nous avons ensuite créer des fonctions qui permettent au robot d'avancer, reculer et tourner en précisant la vitesse (de 0 à 255).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* stop */&lt;br /&gt;
void&lt;br /&gt;
stop(void)&lt;br /&gt;
{&lt;br /&gt;
  pwm_4D_write(0);&lt;br /&gt;
  pwm_3A_write(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* advance&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
advance(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* back off&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
back_off(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn left&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_left(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn right&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_right(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, les fonctions main() et setup()&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    turn_left(100);&lt;br /&gt;
    //advance(200);&lt;br /&gt;
    // stop();&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;br /&gt;
[[Category:Sommaire]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Cat%C3%A9gorie:Produits</id>
		<title>Catégorie:Produits</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Cat%C3%A9gorie:Produits"/>
				<updated>2013-06-25T19:07:39Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Présentation, Détails techniques, exemples d'utilisation de produits proposés sur notre site.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Sommaire]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Carte_Romeo</id>
		<title>Carte Romeo</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Carte_Romeo"/>
				<updated>2013-06-25T19:07:18Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;La carte ROMEO de DFROBOT est une carte tout-en-un conçue pour faire ses premiers pas vers la robotique. Cette carte très simple d'utilisation permet de commander 2 moteurs, d'interfacer des capteurs et de piloter le robot à distance via un module X-bee. Elle est basée sur un microcontroleur ATMEGA32u4 (V2.0 R3).&lt;br /&gt;
&lt;br /&gt;
Pour tester la carte ROMEO, nous avons utilisé la plateforme de développement Turtle 2WD de DFROBOT. Cette plateforme est équipée de 2 roues montées en direct sur 2 motoréducteurs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Commande des moteurs ==&lt;br /&gt;
&lt;br /&gt;
Le moteur à courant continu est l'élément principal qui permet au robot de se déplacer. Sa vitesse est proportionnelle à la tension d'alimentation. Plus la tension est élevée plus le moteur va tourner rapidement. Il faut donc créer une tension continue variable pour faire varier la vitesse du moteur. &lt;br /&gt;
&lt;br /&gt;
=== Signaux PWM ===&lt;br /&gt;
Les signaux PWM permettent de fournir une tension continue variable à partir de signaux numériques (0 et 5V). Le microcontroleur va générer un signal en forme de créneaux. En faisant varier le rapport cyclique, la tension moyenne va varier et le moteur va tourner plus ou moins vite.&lt;br /&gt;
&lt;br /&gt;
=== Electronique ===&lt;br /&gt;
La carte ROMEO est équipée d'un module de commande pour moteur à courant continu (L298). Ce pont H va fournir la puissance nécessaire au moteur pour tourner. Le microcontroleur va fournir un signal PWM et un signal de direction pour chaque moteur.&lt;br /&gt;
&lt;br /&gt;
=== Exemple de code ===&lt;br /&gt;
==== Langage Arduino ====&lt;br /&gt;
Le L298 utilise la pin 4 (M1 : direction) et 5 (E1 : PWM) pour le moteur 1 et la pin 6 (E2 : PWM) et 7 (M2 : direction) pour le moteur 2.&lt;br /&gt;
&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php/DFRduino_Romeo-All_in_one_Controller_V1.1%28SKU:DFR0004%29 ici]&lt;br /&gt;
&lt;br /&gt;
==== Langage C ====&lt;br /&gt;
Pour générer un signal PWM, le microcontroleur a besoin d'un timer interne. Il utilise le timer 3A  pour E1 et le timer 4D pour E2.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, il faut initialiser les timers en mode PWM. Nous configurons le mode PWM avec des valeurs fréquemment utilisées pour la commande de moteurs.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* timer3 is used for phase-correct 8-bits PWM mode &lt;br /&gt;
and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_3_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* set timer3 prescale factor to 64 */&lt;br /&gt;
  TCCR3B = (1 &amp;lt;&amp;lt; CS31) | (1 &amp;lt;&amp;lt; CS30);&lt;br /&gt;
  /* put timer3 in phase correct PWM mode */&lt;br /&gt;
  TCCR3A = (1 &amp;lt;&amp;lt; WGM30);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* timer4 is used for phase and frequency correct 10-bits PWM mode &lt;br /&gt;
* and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_4_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  TC4H = 0;&lt;br /&gt;
  /* set timer4 prescale factor to 64 */&lt;br /&gt;
  TCCR4B = (1 &amp;lt;&amp;lt; CS42) | (1 &amp;lt;&amp;lt; CS41) | (1 &amp;lt;&amp;lt; CS40);&lt;br /&gt;
  /* put timer 4 in phase and frequency correct PWM mode */&lt;br /&gt;
  TCCR4D =(1 &amp;lt;&amp;lt; WGM40);&lt;br /&gt;
  /* not used */&lt;br /&gt;
  TCCR4E = 0;&lt;br /&gt;
  /* Set top to 0xFF */&lt;br /&gt;
  OCR4C = 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut activer les pins utilisées par le L298 (5:OC3A et 6:OC4D).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PC6(OC3A) pin as output pin */&lt;br /&gt;
  DDRC |= (1 &amp;lt;&amp;lt; PORTC6);&lt;br /&gt;
  /* enable OC3A pin as PWM pin */&lt;br /&gt;
  TCCR3A |= (1 &amp;lt;&amp;lt; COM3A1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PD7 pin as output pin */&lt;br /&gt;
  DDRD |= (1 &amp;lt;&amp;lt; PORTD7);&lt;br /&gt;
  /* enable OC4D pin as PWM pin */TCCR4C |= (1 &amp;lt;&amp;lt; PWM4D);&lt;br /&gt;
  TCCR4C |= (1 &amp;lt;&amp;lt; COM4D1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Nous avons ensuite créer des fonctions qui permettent au robot d'avancer, reculer et tourner en précisant la vitesse (de 0 à 255).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* stop */&lt;br /&gt;
void&lt;br /&gt;
stop(void)&lt;br /&gt;
{&lt;br /&gt;
  pwm_4D_write(0);&lt;br /&gt;
  pwm_3A_write(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* advance&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
advance(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* back off&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
back_off(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn left&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_left(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn right&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_right(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, les fonctions main() et setup()&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    turn_left(100);&lt;br /&gt;
    //advance(200);&lt;br /&gt;
    // stop();&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Carte_Romeo</id>
		<title>Carte Romeo</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Carte_Romeo"/>
				<updated>2013-06-25T19:05:49Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;La carte ROMEO de DFROBOT est une carte tout-en-un conçue pour faire ses premiers pas vers la robotique. Cette carte très simple d'utilisation permet de commander 2 moteurs, d'interfacer des capteurs et de piloter le robot à distance via un module X-bee. Elle est basée sur un microcontroleur ATMEGA32u4 (V2.0 R3).&lt;br /&gt;
&lt;br /&gt;
Pour tester la carte ROMEO, nous avons utilisé la plateforme de développement Turtle 2WD de DFROBOT. Cette plateforme est équipée de 2 roues montées en direct sur 2 motoréducteurs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Commande des moteurs ==&lt;br /&gt;
&lt;br /&gt;
Le moteur à courant continu est l'élément principal qui permet au robot de se déplacer. Sa vitesse est proportionnelle à la tension d'alimentation. Plus la tension est élevée plus le moteur va tourner rapidement. Il faut donc créer une tension continue variable pour faire varier la vitesse du moteur. &lt;br /&gt;
&lt;br /&gt;
=== Signaux PWM ===&lt;br /&gt;
Les signaux PWM permettent de fournir une tension continue variable à partir de signaux numériques (0 et 5V). Le microcontroleur va générer un signal en forme de créneaux. En faisant varier le rapport cyclique, la tension moyenne va varier et le moteur va tourner plus ou moins vite.&lt;br /&gt;
&lt;br /&gt;
=== Electronique ===&lt;br /&gt;
La carte ROMEO est équipée d'un module de commande pour moteur à courant continu (L298). Ce pont H va fournir la puissance nécessaire au moteur pour tourner. Le microcontroleur va fournir un signal PWM et un signal de direction pour chaque moteur.&lt;br /&gt;
&lt;br /&gt;
=== Exemple de code ===&lt;br /&gt;
==== Langage Arduino ====&lt;br /&gt;
Le L298 utilise la pin 4 (M1 : direction) et 5 (E1 : PWM) pour le moteur 1 et la pin 6 (E2 : PWM) et 7 (M2 : direction) pour le moteur 2.&lt;br /&gt;
&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php/DFRduino_Romeo-All_in_one_Controller_V1.1%28SKU:DFR0004%29 ici]&lt;br /&gt;
&lt;br /&gt;
==== Langage C ====&lt;br /&gt;
Pour générer un signal PWM, le microcontroleur a besoin d'un timer interne. Il utilise le timer 3A  pour E1 et le timer 4D pour E2.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, il faut initialiser les timers en mode PWM. Nous configurons le mode PWM avec des valeurs fréquemment utilisées pour la commande de moteurs.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* timer3 is used for phase-correct 8-bits PWM mode &lt;br /&gt;
and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_3_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* set timer3 prescale factor to 64 */&lt;br /&gt;
  TCCR3B = (1 &amp;lt;&amp;lt; CS31) | (1 &amp;lt;&amp;lt; CS30);&lt;br /&gt;
  /* put timer3 in phase correct PWM mode */&lt;br /&gt;
  TCCR3A = (1 &amp;lt;&amp;lt; WGM30);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* timer4 is used for phase and frequency correct 10-bits PWM mode &lt;br /&gt;
* and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_4_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  TC4H = 0;&lt;br /&gt;
  /* set timer4 prescale factor to 64 */&lt;br /&gt;
  TCCR4B = (1 &amp;lt;&amp;lt; CS42) | (1 &amp;lt;&amp;lt; CS41) | (1 &amp;lt;&amp;lt; CS40);&lt;br /&gt;
  /* put timer 4 in phase and frequency correct PWM mode */&lt;br /&gt;
  TCCR4D =(1 &amp;lt;&amp;lt; WGM40);&lt;br /&gt;
  /* not used */&lt;br /&gt;
  TCCR4E = 0;&lt;br /&gt;
  /* Set top to 0xFF */&lt;br /&gt;
  OCR4C = 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut activer les pins utilisées par le L298 (5:OC3A et 6:OC4D).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PC6(OC3A) pin as output pin */&lt;br /&gt;
  DDRC |= (1 &amp;lt;&amp;lt; PORTC6);&lt;br /&gt;
  /* enable OC3A pin as PWM pin */&lt;br /&gt;
  TCCR3A |= (1 &amp;lt;&amp;lt; COM3A1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PD7 pin as output pin */&lt;br /&gt;
  DDRD |= (1 &amp;lt;&amp;lt; PORTD7);&lt;br /&gt;
  /* enable OC4D pin as PWM pin */TCCR4C |= (1 &amp;lt;&amp;lt; PWM4D);&lt;br /&gt;
  TCCR4C |= (1 &amp;lt;&amp;lt; COM4D1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Nous avons ensuite créer des fonctions qui permettent au robot d'avancer, reculer et tourner en précisant la vitesse (de 0 à 255).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* stop */&lt;br /&gt;
void&lt;br /&gt;
stop(void)&lt;br /&gt;
{&lt;br /&gt;
  pwm_4D_write(0);&lt;br /&gt;
  pwm_3A_write(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* advance&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
advance(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* back off&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
back_off(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn left&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_left(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn right&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_right(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, les fonctions main() et setup()&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    turn_left(100);&lt;br /&gt;
    //advance(200);&lt;br /&gt;
    // stop();&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Categorie:Produits]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Carte_Romeo</id>
		<title>Carte Romeo</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Carte_Romeo"/>
				<updated>2013-06-25T19:01:47Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;categorytree mode=pages&amp;gt;Produits&amp;lt;/categorytree&amp;gt;&lt;br /&gt;
La carte ROMEO de DFROBOT est une carte tout-en-un conçue pour faire ses premiers pas vers la robotique. Cette carte très simple d'utilisation permet de commander 2 moteurs, d'interfacer des capteurs et de piloter le robot à distance via un module X-bee. Elle est basée sur un microcontroleur ATMEGA32u4 (V2.0 R3).&lt;br /&gt;
&lt;br /&gt;
Pour tester la carte ROMEO, nous avons utilisé la plateforme de développement Turtle 2WD de DFROBOT. Cette plateforme est équipée de 2 roues montées en direct sur 2 motoréducteurs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Commande des moteurs ==&lt;br /&gt;
&lt;br /&gt;
Le moteur à courant continu est l'élément principal qui permet au robot de se déplacer. Sa vitesse est proportionnelle à la tension d'alimentation. Plus la tension est élevée plus le moteur va tourner rapidement. Il faut donc créer une tension continue variable pour faire varier la vitesse du moteur. &lt;br /&gt;
&lt;br /&gt;
=== Signaux PWM ===&lt;br /&gt;
Les signaux PWM permettent de fournir une tension continue variable à partir de signaux numériques (0 et 5V). Le microcontroleur va générer un signal en forme de créneaux. En faisant varier le rapport cyclique, la tension moyenne va varier et le moteur va tourner plus ou moins vite.&lt;br /&gt;
&lt;br /&gt;
=== Electronique ===&lt;br /&gt;
La carte ROMEO est équipée d'un module de commande pour moteur à courant continu (L298). Ce pont H va fournir la puissance nécessaire au moteur pour tourner. Le microcontroleur va fournir un signal PWM et un signal de direction pour chaque moteur.&lt;br /&gt;
&lt;br /&gt;
=== Exemple de code ===&lt;br /&gt;
==== Langage Arduino ====&lt;br /&gt;
Le L298 utilise la pin 4 (M1 : direction) et 5 (E1 : PWM) pour le moteur 1 et la pin 6 (E2 : PWM) et 7 (M2 : direction) pour le moteur 2.&lt;br /&gt;
&lt;br /&gt;
Un exemple avec le langage ARDUINO est expliqué [http://www.dfrobot.com/wiki/index.php/DFRduino_Romeo-All_in_one_Controller_V1.1%28SKU:DFR0004%29 ici]&lt;br /&gt;
&lt;br /&gt;
==== Langage C ====&lt;br /&gt;
Pour générer un signal PWM, le microcontroleur a besoin d'un timer interne. Il utilise le timer 3A  pour E1 et le timer 4D pour E2.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps, il faut initialiser les timers en mode PWM. Nous configurons le mode PWM avec des valeurs fréquemment utilisées pour la commande de moteurs.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* timer3 is used for phase-correct 8-bits PWM mode &lt;br /&gt;
and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_3_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  /* set timer3 prescale factor to 64 */&lt;br /&gt;
  TCCR3B = (1 &amp;lt;&amp;lt; CS31) | (1 &amp;lt;&amp;lt; CS30);&lt;br /&gt;
  /* put timer3 in phase correct PWM mode */&lt;br /&gt;
  TCCR3A = (1 &amp;lt;&amp;lt; WGM30);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* timer4 is used for phase and frequency correct 10-bits PWM mode &lt;br /&gt;
* and with clock prescaled to system clock divided by 64 */&lt;br /&gt;
void&lt;br /&gt;
pwm_4_setup(void)&lt;br /&gt;
{&lt;br /&gt;
  TC4H = 0;&lt;br /&gt;
  /* set timer4 prescale factor to 64 */&lt;br /&gt;
  TCCR4B = (1 &amp;lt;&amp;lt; CS42) | (1 &amp;lt;&amp;lt; CS41) | (1 &amp;lt;&amp;lt; CS40);&lt;br /&gt;
  /* put timer 4 in phase and frequency correct PWM mode */&lt;br /&gt;
  TCCR4D =(1 &amp;lt;&amp;lt; WGM40);&lt;br /&gt;
  /* not used */&lt;br /&gt;
  TCCR4E = 0;&lt;br /&gt;
  /* Set top to 0xFF */&lt;br /&gt;
  OCR4C = 0xFF;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il faut activer les pins utilisées par le L298 (5:OC3A et 6:OC4D).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_3A_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PC6(OC3A) pin as output pin */&lt;br /&gt;
  DDRC |= (1 &amp;lt;&amp;lt; PORTC6);&lt;br /&gt;
  /* enable OC3A pin as PWM pin */&lt;br /&gt;
  TCCR3A |= (1 &amp;lt;&amp;lt; COM3A1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* enable OC4D (pin D6) as pwm output */&lt;br /&gt;
void&lt;br /&gt;
pwm_4D_enable(void)&lt;br /&gt;
{&lt;br /&gt;
  /* enable PD7 pin as output pin */&lt;br /&gt;
  DDRD |= (1 &amp;lt;&amp;lt; PORTD7);&lt;br /&gt;
  /* enable OC4D pin as PWM pin */TCCR4C |= (1 &amp;lt;&amp;lt; PWM4D);&lt;br /&gt;
  TCCR4C |= (1 &amp;lt;&amp;lt; COM4D1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Nous avons ensuite créer des fonctions qui permettent au robot d'avancer, reculer et tourner en précisant la vitesse (de 0 à 255).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/* stop */&lt;br /&gt;
void&lt;br /&gt;
stop(void)&lt;br /&gt;
{&lt;br /&gt;
  pwm_4D_write(0);&lt;br /&gt;
  pwm_3A_write(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* advance&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
advance(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* back off&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
back_off(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn left&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_left(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 0 */&lt;br /&gt;
  PORTE |= (1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 1 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* turn right&lt;br /&gt;
 * speed from 0 to 255 */&lt;br /&gt;
void&lt;br /&gt;
turn_right(char speed)&lt;br /&gt;
{&lt;br /&gt;
  PORTD |= (1 &amp;lt;&amp;lt; PORT4); /* E1 (PD4) = 1 */&lt;br /&gt;
  PORTE &amp;amp;= ~(1 &amp;lt;&amp;lt; PORT6); /* E2 (PE6) = 0 */&lt;br /&gt;
  pwm_4D_write(speed);&lt;br /&gt;
  pwm_3A_write(speed);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Pour finir, les fonctions main() et setup()&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
void&lt;br /&gt;
setup(void)&lt;br /&gt;
{&lt;br /&gt;
  pin_setup();&lt;br /&gt;
  pwm_3_setup();&lt;br /&gt;
  pwm_4_setup();&lt;br /&gt;
  pwm_3A_enable();&lt;br /&gt;
  pwm_4D_enable();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  setup();&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    turn_left(100);&lt;br /&gt;
    //advance(200);&lt;br /&gt;
    // stop();&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	<entry>
		<id>https://www.arobose.com/wiki/index.php?title=Cat%C3%A9gorie:Produits</id>
		<title>Catégorie:Produits</title>
		<link rel="alternate" type="text/html" href="https://www.arobose.com/wiki/index.php?title=Cat%C3%A9gorie:Produits"/>
				<updated>2013-06-25T18:59:03Z</updated>
		
		<summary type="html">&lt;p&gt;Ldoffe : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Présentation, Détails techniques, exemples d'utilisation de produits proposés sur notre site.&lt;br /&gt;
&lt;br /&gt;
[[Carte Romeo]]&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Sommaire]]&lt;/div&gt;</summary>
		<author><name>Ldoffe</name></author>	</entry>

	</feed>