I made a small library that I use for rs485 communication, nothing too fancy. The library can use either the hardware or a software serial port. My code works but I am 'doing it wrong'.
The top part is as follows:
#include "message.h"
#define SOFTWARE_SERIAL
#ifdef SOFTWARE_SERIAL
#include <SoftwareSerial.h>
const int Rx = 3 ;
const int Tx = 4 ;
SoftwareSerial RS485( Rx, Tx ) ;
#else
#define RS485 Serial
#endif
bool writeBlock ;
char message[32] ;
uint16_t COMMAND ;
uint16_t SLAVE_ID ;
uint16_t DATA1 ;
uint16_t DATA2 ;
uint8_t rs485dir ;
void initializeSerialport( uint8_t pin )
{
rs485dir = pin ;
pinMode( rs485dir, OUTPUT ) ;
RS485.begin( 9600 ) ;
}
void sendMessage( uint8_t ID,
uint8_t COMMAND,
uint8_t DATA1,
uint8_t DATA2,
uint8_t blockCode )
{
if( COMMAND == 0 ) return ; // prevents 'empty' initialization messages from being transmitted
digitalWrite( rs485dir, HIGH ) ;
RS485.print( ID ) ; RS485.write(',') ;
RS485.print( COMMAND ) ; RS485.write(',') ;
RS485.print( DATA1 ) ; RS485.write(',') ;
RS485.println( DATA2 ) ;
if( blockCode ) // during initialization, the code is blocked so no overflow can occur
{
RS485.flush() ;
digitalWrite( rs485dir, LOW ) ;
}
}
The problem is that I have to define or not define SOFTWARE_SERIAL in the library's source file in order to select a serial port.
I would prefer to use the function initializeSerialport() to pass a pointer to a serial object instead. This would also allow me to re-use this library for boards that have more than 1 hardware serial port without having to alter the source file. But I do not know how to do this.
For instance. I am guessing that my library needs a static serial object? How do I declare that?
static Stream *RS485 ; // ?
I get that I must call initializeSerialPort() with
initializeSerialPort( pin, &Serial ) ; // or &mySoftWareSerial, or &Serial1 etc
..
void initializeSerialPort( uint8_t pin, Stream *port)
{
RS485 = &port ; // ??
}
..
..
void sendMessage( uint8_t ID,
uint8_t COMMAND,
uint8_t DATA1,
uint8_t DATA2,
uint8_t blockCode )
{
if( COMMAND == 0 ) return ; // prevents 'empty' initialization messages from being transmitted
digitalWrite( rs485dir, HIGH ) ;
RS485->print( ID ) ; RS485->write(',') ; // from . to ->
RS485->print( COMMAND ) ; RS485->write(',') ;
RS485->print( DATA1 ) ; RS485->write(',') ;
RS485->println( DATA2 ) ;
if( blockCode ) // during initialization, the code is blocked so no overflow can occur
{
RS485->flush() ;
digitalWrite( rs485dir, LOW ) ;
}
}
I am aware that software serial tends to block the entire code. For my application that is not really important. I also will not receiving and transmitting at the same time.
Any 'pointers' about my code will be appreciated.
Kind regards,
Bas