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!