Envoyer/Interpréter des commandes par Port Série

Introduction
Le but de cet article est d'allumer ou éteindre une LED (pin 13) en fonction d'une commande reçue via la port série d'Arduino (par l'intermédiaire du Moniteur Série d'Arduino IDE).

Ce petit projet peut sembler futile de prime abord mais relève pourtant d'une importance capitale dans l'interfaçage de composants avancés.

Pourquoi est-ce important?
A titre d'exemple, MC Hobby s'apprête à commercialiser un GSM/GPRS shield de GeekOnFire pour Arduino.
Ce shield utilise une communication série et un UART pour recevoir ses ordres et retourner des résultats. Un UART est un des éléments principaux impliqué dans la communication série.
Pour les plus curieux, je vous propose de jeter un petit coup d'œil sur la documentation francophone du GPRS Shield actuellement en cours d'élaboration.

Un module GPS est aussi en prévision, ces derniers utilisent également des communications séries.

Vous l'aurez compris, pouvoir réceptionner et traiter des informations via un port série (depuis Arduino) est donc un savoir-faire important.

Montage
Le montage est des plus élémentaires. Le but étant ici de se concentrer sur la réception des ordres.


Principe de fonctionnement
Une ligne de commande est composé d'un ensemble de caractères reçus via la liaison série.
Chaque caractère est empilé dans un buffer (mémoire tampon) de commande en attendant le caractère de fin de commande (celui qui exécutera la commande).
La fin de commande attendu est le caractère Carriage Return (aussi noté <CR>) correspondant à la touche de Entrée/Return/Enter sur un clavier. C'est la touche de retour chariot.
La valeur numérique de <CR> est 13.
Le retour chariot étant utilisé comme caractère de fin de commande vérifiez que le moniteur série d'Arduino IDE soit bien configuré sur Carriage return
Une fois le caractère de fin de commande détecté, la commande est envoyée à la fonction "ProcessCmd" en charge de la détection de la commande et de son exécution.


Le code source
/* String Command In Serial Port using String 
  
    Le programme attend qu'une commande arrive sur le moniteur série.
    Assurez vous que le moniteur série d'Arduino soit bien configuré sur "Carriage Return"
      Entrer 'on' allume la LED connectée sur la pin 13.
      Entrer 'off' éteint la LED connectée sur la pin 13.
    Cela fournit une alternative à Bitlash.
    
    Le circuit:
    La Pin 13 est connectée à une résistance de 220-ohm, qui est alors 
    connecté à une LED et ensuite à la masse (GND). Comme alternative,
    vous pouvez regarder la LED "L" visible sur la carte Arduino et 
    déjà raccordée sur la broche 13.
    
    Créé le July 21, 2010, par Mark Aosawa. mark.aosawa@yahoo.com
    Modifié en profondeur April 7, 2012 par MC Hobby, info@mchobby.be    
    
  */
  
  //String buffer/mémoire tampon
  String cmd = String("");
  
  // Initialiser la LED de la pin 13 comme sortie (OUTPUT)
  int ledPin = 13;
  
  void setup() {
  // Initialise la communication série (et baud rate à 9600):
  Serial.begin(9600);

  pinMode(ledPin, OUTPUT);
  // Affiche un message quand le port série est ouvert.
  // Permet de vérifier que le programme est bien en court de fonctionnement
  Serial.println("Serial communication is ready.");
  }

  void loop() {

    // Vérifier si des caractères sont reçu sur le port série
    if (Serial.available() > 0) {
      
       // Variable temporaire pour copier le caractère lu
       char SerialInByte;
       // Lire un caractère (un Byte)
       SerialInByte = Serial.read();
      
       // Si c'est  --> traiter la commande
       if(SerialInByte==13){ 
          ProcessCmd();
       }else{
          // sinon, ajouter le caractère à la mémoire tampon (cmd)
          cmd += String(SerialInByte);
          
          // et afficher un message de déboggage
          Serial.print( "SerialInByte: " );
          Serial.print( SerialInByte, DEC );
          Serial.print( ", Buffer " );
          Serial.println( cmd );
       }
    }
  }
  
  // Renvoyer la commande (contenu du buffer) sur le port série
  void printCmd(){
    Serial.println(cmd);
  }
  
  // Réinitialiser le buffer (et vider le port série)
  void clearCmd(){
    cmd="";
    Serial.flush();
  }
  
  // Interpréter la commande reçue
  //
  void ProcessCmd() {
    // Un petit message de débogage. La commande est entourée avec [] pour clairement
    // identifier chacun des caractères qui la compose (même les espaces).
    Serial.print( "ProcessCmd for [" );
    Serial.print( cmd );
    Serial.println( "]" );
    
    if(cmd.equals("on")){
         printCmd();
         digitalWrite(ledPin, HIGH);
         clearCmd();
    }else if(cmd.equals("off")){
        printCmd();
        digitalWrite(ledPin, LOW);
        clearCmd();
    }else{
         // toutes les autres commandes sont ignorées.
         Serial.println("unknown command!");
         clearCmd();
    }
}

Le résultat
La LED 13 s'allume et s'éteint lorsque la commande "on" ou "off" est reçue.
Outre cette modification de la Pin 13, les messages suivants sont également visible sur le moniteur série.
La séquence de commandes (chacune terminée par la touche Entrée) utilisé dans cet exemple est:
  1. on
  2. off
  3. test

Serial communication is ready.
SerialInByte: 111, Buffer o
SerialInByte: 110, Buffer on
ProcessCmd for [on]
on
SerialInByte: 111, Buffer o
SerialInByte: 102, Buffer of
SerialInByte: 102, Buffer off
ProcessCmd for [off]
off
SerialInByte: 116, Buffer t
SerialInByte: 101, Buffer te
SerialInByte: 115, Buffer tes
SerialInByte: 116, Buffer test
ProcessCmd for [test]
unknown command!

Je n'ai pas de vidéo pour cet exemple en particulier.
Par contre, la base de ce code à servi à réaliser "SmsCommand" pour interpréter les commandes reçues par SMS et allumer la LED quand "on" est reçu et éteindre la LED quand "off" est reçu.
En attendant la sortie du GSM/GPRS Shield sur MC Hobby, je vous invite à vous rincer l'œil sur cette version élaborée.

Source