Compatibilidad y Problemas Puertos Series Software y Hardware

Estoy viendo en varios ejemplos como éste: https://www.arduino.cc/en/Tutorial/SoftwareSerialExample

Que en la placa ARDUINO UNO, el puerto serie Hardware supuestamente puede ser usado simultáneamente con algún otro puerto serie emulado por Software (librería "SoftwareSerial.h"), pero esto de momento no funciona en mi placa ARDUINO UNO. Cuando leo caracteres del puerto HW y luego en otra función más adelate leo caracteres del puerto SW, el programa parece colgarse.

Sin embargo, pude conseguir que funcione de otro modo, usando únicamente dos puertos serie defindos ambos por la librería comentada "SoftwareSerial.h" (Arduino-1.6.7):

  • SerialOne en pines 0,1 (sí, usando los mismos pines que usaría el Puerto Serie Hardware y por tanto no usando la sentencia "Serial.begin(9600)", sino la sentencia SerialOne.begin(9600)).

  • SerialTwo en los pines 8, 9-

Cuando en la función "loop()" ejecuto la condición "if (SerialOne.available()) {... // leer SerialOne...}" y luego la condición "if (SerialTwo.available()) {... // leer SerialTwo...}" funciona bien siempre que use previamente la funcion "listen()" antes de cada condición respectiva como se muestra en este otro ejemplo:

https://www.arduino.cc/en/Reference/SoftwareSerialListen

Pero veo que la función "listen()" no funciona si intento usarla con las sentencias de manejo del puerto serie Hardware (Sentencias "Serial. ...") en vez de con las sentencias del puerto serie Software (Sentencias "SerialOne. ...") en los pines 0 y 1.

Así que me pregunto ¿Qué está ocurriendo con los puertos serie Hardware y Software en el mismo código de la ARDUINO UNO ?

¿Podrían ser usados "simultáneamente" para leer datos (Quiero decir, uno cada vez en el mismo código, pero sin que la ARDUINO UNO se cuelgue (como en el ejemplo del primer enlace que he puesto)?

¿ O debo obligatoriamente usar la solución de los 2 puertos serie Software con la sentencia "listen()" antes mencionada (no usando así las sentencias del puerto serie Hardware para los pines 0,1)?

Gracias de antemano...

El puerto serie 2 (pines 8,9) y el puerto serie Hardware se definen sin errores y se inician correctamente, pero todo falla aquí:

void loop()
{
...
...
  if (gps.available()>0)
  {
       byteGPS = gps.read();
      Serial.print((char)byteGPS);
    }

  
  if (Serial.available()>0)
      letra=Serial.read();
    else
    return;
...
...
}

Interesante tu pregunta ya que no sabía de este comportamiento porque no suelo usar SoftwareSerial. Según mi investigación rápida el problema es que siemrpe queda activa un puerto serie a través dle pin RX asociado a una Interrupción y al buffer serie. Pero el otro no. Ya que habitualmente no se supera 9600 baudios existe una demora de 1mseg entre caracter y caracter de modo que es inteligente poner un delay de 2 mseg luego de un listen() para asegurarnos que trabaje tranquilo. un ejemplo seria

void loop()
{

    SerialOne.listen();
    delay(2);
    while (SerialOne.available() > 0) {
        char inByte = SerialOne.read();
        Serial.write(inByte);
        delay(1);
    }

    SerialTwo.listen();
    delay(2);
    while (SerialTwo.available() > 0) {
        char inByte = SerialTwo.read();
        Serial.write(inByte);
        delay(1);
    }
    Serial.println();
}

prueba y nos cuentas

Gracias surbyte.

El código que me presentas me funciona perfectamente en la ARDUINO UNO. Incluso sin esos delays. Aunque por lo que comentas, si los añado, quizá funcione hasta mejor (intentaré seguir tu recomendación).

Ese es, que yo sepa, el código que hace uso de la función "listen()" de la librería "SoftwareSerial.h" que te comentaba.

Pero ahora imaginemos que, de los 2 puertos serie que queremos usar en el mismo código, no quiero que ambos sean Software, es decir, no quiero que se definan ambos por el soporte de dicha librería, sino sólo 1: Así de los 2 puertos serie: - Sólo 1 se definirá por la librería "SoftwareSerial.h", - Mientras que el otro será el puerto serie Hardware, que no necesitaría usar tal librería.

Tal es el ejemplo de este enlace (que es el que indiqué en mi anterior post): https://www.arduino.cc/en/Tutorial/SoftwareSerialExample

En este caso: 1º No tiene sentido usar la función "listen()" para conmutar de un puerto serie a otro, ya que esta función es exclusiva de la librería "SoftwareSerial.h" y no del puerto serie Hardware (no lo he visto en ningún ejemplo y el compliador tampoco lo admite). 2º Entiendo que dicho ejemplo debería funcionar ya que además está publicado en la propia web de arduino.cc 3º Sin embargo extrapolando el ejemplo del enlace de arriba, a mi proyecto, a mí no me funciona: la ARDUINO UNO, no responde.

Con alguna versión anterior al entorno de programación de la Arduino-1.6.7, creo recordar que hace bastante tiempo probé el mismo caso y malfuncionaba a trompicones, pero con ésta versión ahora nada.

Por eso no sé si es que el ejemplo que indico y que se publica en arduino.cc puede hacerse funcionar de alguna manera o no.

No sé si realmente la Arduino sporta o no 2 puertos serie "simultáneos" en el caso de que sean 1 Hardware y otro Software o qué: Con 2 puertos serie software con la función "listen()" - "SoftwareSerial.h" - está claro que sí los soporta, porque ya había probado tu ejemplo y lo había visto.

Pero insisito: ¿Qué pasa o qué hay que tener en cuenta cuando 1 puerto serie es Hardware y el otro es Software? De esto no he encontrado nada en la web salvo diversos ejempos ya elaborados que dan por hecho que funciona y que por lo demás no explican ni detallan nada a este respecto. Pero a mí no me funciona... ¿Debería funcionarme...?

Gracias de nuevo, Jorge

A mi me llamó la atención la pregunta. Y la primera impresión fue que era una solución vieja. Luego busqué respuestas pero no miré las fechas, y de nuevo me entra la duda. Hace tiempo que SoftwareSerial ya viene integrado al IDE. Antes había que usar una librería externa. Tal vez ahi esté el problema.

¿Qué pasa o qué hay que tener en cuenta cuando 1 puerto serie es Hardware y el otro es Software? De esto no he encontrado nada en la web salvo diversos ejempos ya elaborados que dan por hecho que funciona y que por lo demás no explican ni detallan nada a este respecto. Pero a mí no me funciona... ¿Debería funcionarme...?

Que pasa? Nada. Todos los días vemos códigos donde un UNO lee un GPS y envia datos por un shield GSM/GPRS usando SoftwareSerial y todavia le queda el puerto hard para BT por ejemplo.