Comunicación Serial HalfDuplex en dos pines

Hola a todos, Soy nuevo en este foro y me gustaría hacer una pregunta, he estado buscando por todo el foro y Google pero no he encontrado nada al respecto. Para el proyecto que estoy desarrollando me es necesario establecer una comunicación Half Duplex con dos periféricos diferentes. He encontrado una librería modificada del SoftwareSerial que permite establecer esta conexión Half Duplex que necesito. El problema que encuentro es que solo me deja establecer uno de los pines digitales para este tipo de comunicación. Cuando llamo dos veces a la función de la librería que configura el pin para la comunicación, solo configura el pin que he establecido en la segunda llamada, asi que al final solo tengo uno de los pines para la comunicación.

¿Hay alguna manera de configurar dos pines diferentes y que dicha configuración quede guardada para poder usar los dos pines a la vez?

Espero haber sido claro, si no preguntad lo que haga falta.

Gracias por vuestra ayuda.

Un saludo!

Maravillosa tu consulta, y la librería, el enlace? Porque no planteas tu consulta con la máxima información posible para poder darte una buena respuesta. Ya te envié un Mensaje Privado MP, lee las normas. Plantea tus consultas con amplitud de detalles.

Acaso tu comunicación es del tipo RS485?

Perdona por no poner tanto detalle, no veía necesario incluirla. Sabiendo que hay que hacerlo, incluyo todos los detalles para ayudar al entendimiento.

La librería que he encontrado tiene el siguiente código:

#ifndef SoftwareSerialWithHalfDuplex_h
#define SoftwareSerialWithHalfDuplex_h

#include <inttypes.h>
#include <Stream.h>

/******************************************************************************
* Definitions
******************************************************************************/

#define _SS_MAX_RX_BUFF 64 // RX buffer size
#ifndef GCC_VERSION
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif

class SoftwareSerialWithHalfDuplex : public Stream
{
private:
  // per object data
  uint8_t _receivePin;
  uint8_t _receiveBitMask;
  volatile uint8_t *_receivePortRegister;
  uint8_t _transmitPin;								//NS Added
  uint8_t _transmitBitMask;
  volatile uint8_t *_transmitPortRegister;
  
  uint16_t _rx_delay_centering;
  uint16_t _rx_delay_intrabit;
  uint16_t _rx_delay_stopbit;
  uint16_t _tx_delay;

  uint16_t _buffer_overflow:1;
  uint16_t _inverse_logic:1;
  uint16_t _full_duplex:1;							//NS Added

  // static data
  static char _receive_buffer[_SS_MAX_RX_BUFF]; 
  static volatile uint8_t _receive_buffer_tail;
  static volatile uint8_t _receive_buffer_head;
  static SoftwareSerialWithHalfDuplex *active_object;

  // private methods
  void recv();
  uint8_t rx_pin_read();
  void tx_pin_write(uint8_t pin_state);
  void setTX(uint8_t transmitPin);
  void setRX(uint8_t receivePin);

  // private static method for timing
  static inline void tunedDelay(uint16_t delay);

public:
  // public methods
  SoftwareSerialWithHalfDuplex(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false, bool full_duplex = true);
  ~SoftwareSerialWithHalfDuplex();
  void begin(long speed);
  bool listen();
  void end();
  bool isListening() { return this == active_object; }
  bool overflow() { bool ret = _buffer_overflow; _buffer_overflow = false; return ret; }
  int peek();

  virtual size_t write(uint8_t byte);
  virtual int read();
  virtual int available();
  virtual void flush();
  
  using Print::write;

  // public only for easy access by interrupt handlers
  static inline void handle_interrupt();
};

// Arduino 0012 workaround
#undef int
#undef char
#undef long
#undef byte
#undef float
#undef abs
#undef round

#endif

La conexión que uso es mediante protocolo ccTalk el cual se comunica en serie de modo Half Duplex, el periférico manda un mensaje y espera a la respuesta del arduino. Esta conexión la realizo a través de los pines digitales del arduino y uniendo la tierra del periférico a la del arduino para que todo funcione.
Para configurar uno de los pines para su uso half duplex añado la librería al proyecto y llamo a la función necesaria:

#include <SoftwareSerialWithHalfDuplex.h>
#define comPinMon 2
SoftwareSerialWithHalfDuplex puertoMon(comPinMon,comPinMon,false,false);

Esto hace que el pin 2 se pueda usar de manera que se comunique en half duplex. Al necesitar esta comunicación para dos periféricos diferentes me es necesario configurar dos pines diferentes de este modo. He intentado hacerlo así ya que creía que era la manera correcta:

#include <SoftwareSerialWithHalfDuplex.h>
#define comPinMon 2
#define comPinR 3
SoftwareSerialWithHalfDuplex puertoMon(comPinMon,comPinMon,false,false);
SoftwareSerialWithHalfDuplex puertoR(comPinR,comPinR,false,false);

Pero me he dado cuenta de que no es así, al realizar la llamada dos veces, solo se queda configurado (o solo me permite la conexión half duplex) a través del pin 3.
¿Hay alguna manera de hacerlo para que funcione en ambos pines?

He probado a modo “chapuza” a llamar a la función en el Loop para que fuese abriendo la comunicación por un puerto y cerrándola en el otro, pero no funciona. De todos modos, esa “solución” no era muy eficiente…

Gracias por la ayuda. Espero haber adjuntado todo lo necesario, si no es así, pide lo que sea.

Un saludo!

Lo primero que se me ocurrre preguntarte es : Porque si tienes que usar 2 o mas puertos series, recurres a SoftwareSerial y no pensaste en usar un Mega como mínimo? Vale la pena romperse la cabeza usando una librería de sofware para hacer un trabajo normalmente pensado para hacerse con UARTs.

Acá hay un caso similar al tuyo Proyecto de comunicación serie con Arduino UNO que recordé haber respondido.