Doble puerto serie simultáneo SoftwareSerial para arduino

Como las placas Arduino UNO, micro nano etc (todas las basadas en el ATMEGA328P) solo disponen de un puerto serie es necesario usar la librería “SoftwareSerial.h” del entorno Arduino para manejar más de un puertos serie.

Esa librería es multi instancia, pueden declararse varios objetos tipo “SoftwareSerial” pero solo se puede escuchar la recepción de UNO en cada momento (seleccioándolo mediante el procedimiento listen().

En el proyecto que estoy trabajando ahora necesito escuchar simultáneamente dos puertos, y la opción de conmutar mediante listen() no sirve porque pierde caracteres.

Para solucionarlo he creado esta bominación, una librería que he llamado “SoftwareSerial2RX.h” que permite tener DOS puertos serie de solo recepción (no necesito transmitir y he eliminado esa parte para no consumir pines) por cada instancia.

Es necesario que los dos pines de recepción se encuentren en el mismo puerto del micro, pero pueden crearse varias instancias con parejas de pines en puertos distintos y escuchar 2, 4 ó 6 puertos en un solo arduino. Este horror no permite la recepción concurrente: si esta recibiendo datos de un puerto y llegan por el otro se interrumpen las dos recepciones. No esta muy currado, pero para leer tarjetas RFID es suficiente porque el usuario pasa de nuevo la tarjeta por el lector si observa que no se ha leido correctamente. Como uso un puerto para el tarjetero de entrada y otro para el de salida no se usarán nunca los dos puertos a la vez.

Esta es la librería, con un ejemplo de utilización: SoftwareSerial2RX

Este es un ejemplo de utilización, los procedimientos estan duplicados, uno para cada puerto: available() y available1(), read() y read1() etc…

#include <SoftwareSerial2RX.h>
// Double software serial: RX0 = digital pin 2, RX1 = digital pin 3
SoftwareSerial2RX TwoPortSerial(2, 3); 

void setup() { 
// Open serial communications and wait for port to open: 
  Serial.begin(9600); 
  
  while (!Serial) {; // wait for serial port to connect. Needed for native USB port only 
  }
  Serial.println (F("SoftwareSerial2RX: Two simultaneous receive only serial ports"));
  // Start only RX serial ports 
  TwoPortSerial.begin(9600); 
} 

void loop() { 
// while there is data coming in, read it 
// and send to the hardware serial port: 
  if (TwoPortSerial.c() > 0) { 
    Serial.print (F("FromPort0: ")); 
    while (TwoPortSerial.available() > 0) { 
        char inByte = TwoPortSerial.read(); 
        Serial.write(inByte); 
      }
      Serial.println(); 
    } 

  if (TwoPortSerial.available1() > 0) { 
    Serial.print (F("FromPort1: ")); 
    while (TwoPortSerial.available1() > 0) { 
        char inByte = TwoPortSerial.read1(); 
        Serial.write(inByte); 
      } 
      Serial.println(); 
   } 
   delay (50); // Slow down! 
}