Club robotique de Sophia-Antipolis

Accueil > POBOTpedia > Communications > Communications sans fil > Tester une communication série sans-fil

Tester une communication série sans-fil

lundi 20 mai 2013, par Julien H.

Remplacer les câbles par une liaison sans-fil, c’est devenu facile et peu onéreux avec des modules radio 433 MHz ou 2,4 GHz (802.15.4) mais hormis certains protocoles (Bluetooth, Wifi), il n’y a pas de correction d’erreurs. Il faut donc savoir mesurer les pertes auxquelles s’attendre.

Pour réaliser ce test, nous avons utilisé des modules XBee et des cartes Arduino parce que nous les avions sous la main, mais le code peut être utilisé avec toute autre liaison sans-fil (voire même filaire si vous pensez avoir des pertes de connexion).

D’autres solutions existent, notamment par la mesure de la puissance du signal. C’est aussi une donnée intéressante, surtout pour fixer des relais ou valider une solution antiparasites sur un robot mobile.

Matériel

 une carte Arduino Romeo V2 (pour son support intégré) dispo chez Zartronic
 un module à écran LCD keypad shield de DFRobot dispo chez Zartronic
 deux modules XBee série 1 (802.15.4) dispos chez MATLOG
 un support USB/XBee ou simple adaptateur dispo chez MATLOG
 câbles USB ou batteries pour pouvoir bouger

Il s’agit bien sûr de matériel de test réutilisable. Une solution moins onéreuse peut se faire si vous dédiez ces composants à un usage unique.

Assemblage

Plutôt que d’utiliser deux micro-contrôleurs, un de chaque côté, nous avons soudé un câble (on appelle ça un "shunt") entre la patte DO et DI (data out / data in) d’un des deux modules - ou plutôt sur le support - ce qui revient au même que de relier RX et TX (si vous utilisez une liaison série filaire). Ainsi, toute donnée envoyée par le module est aussitôt renvoyée, sans traitement. Comme ce n’est pas un test de débit mais un test de perte de signal, ce n’est pas impactant sur le résultat, et cela limite les erreurs.

Code source

L’archive est disponible en téléchargement :

#include <LiquidCrystal.h>

// déclaration de l'écran LCD connecté à l'Arduino
LiquidCrystal lcd(8,9,4,5,6,7);

// nombre de messages envoyés et reçus
long msg_envoi = 0;
long msg_recu = 0;

// nombre de ms à l'instant du dernier envoi et de la dernière réception (pour mesurer l'écart)
long last_sent = 0;
long last_seen = 0;

// caractère envoyé (s = sent) et reçu (r = receive)
int s = 0;
int r = 0;

// temps écoulé pour la dernière coupure
long last_err = 0;

// temps maximum écoulé pour une coupure
long max_err = 0;

// temps moyen d'une coupure
long moyenne = 0;

// nombre de coupures connues depuis le début
long count = 0;

boolean coupure = false;

void setup()
{
  // deux liaisons séries : celle de l'USB et celle du XBee
  Serial.begin(9600);
  Serial1.begin(9600); 

  // initialisation de l'écran I2C
  lcd.begin(16, 2);             
  lcd.setCursor(0,0);
  lcd.print("Test XBee"); 

  delay(1000);
  lcd.clear();

}

void loop()
{   
  Serial1.write(s);
  delay(10);

  lcd.setCursor(15,0);
  lcd.write(s);

  s++;
  msg_envoi++;
  last_sent = millis();

  while (Serial1.available() > 0) {

    // nouvelle réception    

    r = Serial1.read();

    last_seen = millis();

    lcd.setCursor(15,1);
    lcd.write(r);
    msg_recu++;

  }

  if (millis() < 3000) {

      // on ne prend pas en compte les 3 premières secondes

  } 
  else {

    // vérifier si on est en connexion ou en coupure 
    if (last_sent-last_seen > 1) 
    {  
      if (!coupure) {
        count++;
        coupure = true; 
      }
      last_err = last_sent-last_seen; 
      max_err = max(last_err,max_err);
    } 
    else {

      if (coupure) {
        // fin de la coupure
        coupure = false; 
        moyenne = (moyenne*(count-1)+last_err)/count;
      }
    }
  }

  // affichage des secondes

  lcd.setCursor(0,1);
  lcd.print(millis()/1000); 
  lcd.print("s ");

  // affichage du nombre d'erreurs depuis le début

  lcd.print(count);
  lcd.print(" erreurs");

  // affichage des stats

  lcd.setCursor(0,0);
  lcd.print(100*msg_recu/msg_envoi);
  lcd.print("% ");

  // alterner les affichages

  switch ((millis()/1000)%3) {
  case 0:
    if (max_err > 5000) {
      lcd.print(max_err/1000);
      lcd.print("s max ");
    } 
    else {
      lcd.print(max_err);
      lcd.print("ms max");      
    }
    break;
  case 1:
    if (moyenne > 5000) {
      lcd.print(moyenne/1000);
      lcd.print("s moy ");
    } 
    else {
      lcd.print(moyenne);
      lcd.print("ms moy");
    }
    break;
  case 2:
    if (last_err > 5000) {
      lcd.print(last_err/1000);
      lcd.print("s der ");
    } 
    else {
      lcd.print(last_err);
      lcd.print("ms der"); 
    }
    break;

  }

  if (coupure) {
    lcd.print("!");
  } 
  else {
    lcd.print(" ");
  }
}

A noter l’usage de la liaison série "Serial1" spécifique aux cartes Leonardo qui ont un port série sur l’USB et un port série disponible (ici connecté au XBee par la carte toute intégrée Romeo V2).

Résultats

Avec un émetteur et un récepteur séparés par 60 centimètres et un peu d’activité (ordinateurs, passage), voilà ce qu’on obtient sur un test de 180 secondes (3 minutes) :

 95% d’octets bien reçus
 31 erreurs
 une moyenne de 248 ms de durée d’interruption
 une interruption la plus longue de 6 secondes

Un autre test de même durée avec les modules sans-fil côte à côte n’a montré qu’une seule erreur de 22 ms, et toujours que 4 erreurs de même moyenne au bout de 812 secondes (le temps d’écrire cet article !)

Un message, un commentaire ?

modération a priori

Attention, votre message n’apparaîtra qu’après avoir été relu et approuvé.

Qui êtes-vous ?

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.