Arduino SoftwareSerial : c'est pas du FullDuplex = LoopBack interdit

SoftwareSerial permet de créer un deuxième port série de type logiciel sur un Arduino UNO. Pratique pour utiliser du matériel série (comme un module LORA avec UART) si l'on désire garder le port Série natif d'Arduino pour le débogage.

Au cours de nos péripéties avec Arduino, nos module Lora UART et SoftwareSerial, nous en étions arrivé à faire une boucle de retour (dit loopback) sous SoftwareSerial pour tester la communication Software sérial... et c'est là que les choses ont franchement dérapés!
Loopback interdit sous SoftwareSerial

Une boucle de retour sur un UART est super pratique pour tester un canal de communication car tout ce que l'on envoi sur TX doit revenir en écho sur RX.
Donc tout ce que l'on tape au clavier doit apparaître en retour.
Sauf que cela ne fonctionne pas sous SoftwareSerial!

Bien mal nous en à pris, nous avons perdu beaucoup de temps à chercher une autre raisons à notre problème de dysfonctionnement avec nos modules Lora!

SoftwareSerial ne fonctionne pas en FullDuplex
La raison pour laquelle SoftwareSerial ne fonctionne pas en Loopback c'est que la bibliothèque n'est pas en Full Duplex.

Dans SoftwareSerial, lorsque l'on reçoit un octet, une interruption prend en charge la réception de tous les bits séries pour reconstituer un octet.

Plus important encore, SoftwareSerial désactive les interruptions durant tout le temps nécessaire à l'envoi d'un octet. De sorte que Software Serial ne peut pas envoyer (broche TX) et recevoir (broches RX) un octet en même temps!

Autre point découlant de cette information est qu'il est préférable de travailler à débit élevé avec SoftwareSerial pour limiter le temps d'inactivation des interruptions.
Contrairement à ce que l'on pourrait penser, diminuer le débit du port série sous SoftwareSerial entrave plus le croquis qu'il ne pourrait l'aider.

Tester Software Serial
Pour tester nos communications et nous assurer que la transmission à 57600 bauds fonctionne comme attendu, il a été nécessaire d'utiliser deux Arduino.
  • Un arduino EMITTER qui envoi un message "Ping x" envoyé toutes les secondes
  • Un seconde arduino  RECEIVER qui reçoit les messages en software Serial puis renvoi les octets sur le port série USB.

Et nous pouvons récupérer les messages sur le moniteur série de l'Arduino du bas.
 


Avec ces deux éléments en main, nous avons pu fiablement tester nos problèmes de communication avec le module LORA UART...

Code de l'Emitter 
L'Emiter ne fait qu'envoyer des messages à 57600 baud via SoftwareSerial. Ce code est basé sur l'exemple Arduino "SoftwareSerial > SoftwareSerialSample".

#include <softwareserial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

int valeur = 0;
int ledPin =13;

void setup()
{
  // set the data rate for the SoftwareSerial port
  mySerial.begin(57600);
  mySerial.println("Hello, world?");
  pinMode( ledPin, OUTPUT );
  digitalWrite( ledPin, LOW );
}

void loop() // run over and over
{
   mySerial.print("ping " );
   mySerial.println( valeur );
   digitalWrite( ledPin, HIGH );
   delay( 1000 );
   digitalWrite( ledPin, LOW );
   delay( 200 );
   valeur = valeur +1;
}

Avec ce code, nous avons pu remplacer le module LORA Uart et vérifier que les messages étaient bien reçu sur la plateforme hôte du module.

Code du Receiver
Le Receiver reçoit les octets via SoftwareSerial. Ces octets sont ensuite relayés vers le moniteur série d'Arduino (dans les deux sens).
Ce code est basé sur l'exemple Arduino "SoftwareSerial > SoftwareSerialSample".

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(57600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.println("Goodnight moon!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(57600);
  mySerial.println("Hello, world?");
}

void loop() // run over and over
{
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());
}

Avec ce code, nous avons pu tester directement la communication avec notre LORA avec interface UART.

AltSoftSerial
Durant nos recherches, nous avons eu l'occasion de rencontrer AltSoftSerial, un bibliothèque Arduino Like (sur Teensy mais compatible Arduino) permettant une communication série logiciel RX/TX en simultané. La vitesse étant limitée à 31250 baud sur une horloge à 16 Mhz.
Vous trouverez plus d'information ici.
 

Conclusion
Avec tous ces divers éléments, nous étions enfin capable de vérifier -étape par étape- les différents éléments de communication d'un projet LORA à l'aide de simples Arduino.
Notre seule erreur a été de considérer que SoftwareSerial fonctionnait exactement comme un vrai UART matériel... et que nous pouvions donc utiliser un loopback pour tester nos propres programmes Arduino SoftwareSerial... de quoi nous emmener en perdition sur de fausses pistes.