Skip to content

Commit 0193f4e

Browse files
Support any Stream type
Interface remains the same so that existing code would compile, but likely will not work correctly due to breaking changes: - Serial has to be initialised manually - The provided serial baud rate and config are ignored - Use of the default RS485 instance will cause null dereference attempt - Serial is not stopped before pulling tx low in `sendBreak`
1 parent e82e6af commit 0193f4e

File tree

3 files changed

+88
-92
lines changed

3 files changed

+88
-92
lines changed

examples/RS485Sender/RS485Sender.ino

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
int counter = 0;
2323

2424
void setup() {
25+
Serial.begin(9600);
2526
RS485.begin(9600);
2627
}
2728

src/RS485.cpp

+46-49
Original file line numberDiff line numberDiff line change
@@ -19,97 +19,94 @@
1919

2020
#include "RS485.h"
2121

22-
RS485Class::RS485Class(HardwareSerial& hwSerial, int txPin, int dePin, int rePin) :
23-
_serial(&hwSerial),
24-
_txPin(txPin),
25-
_dePin(dePin),
26-
_rePin(rePin),
27-
_transmisionBegun(false)
22+
RS485Class::RS485Class(Stream &stream, int txPin, int dePin, int rePin) : _stream(&stream),
23+
_txPin(txPin),
24+
_dePin(dePin),
25+
_rePin(rePin),
26+
_transmissionBegun(false)
2827
{
2928
}
3029

31-
void RS485Class::begin(unsigned long baudrate)
30+
void RS485Class::begin(unsigned long _baudrate)
3231
{
33-
begin(baudrate, SERIAL_8N1, RS485_DEFAULT_PRE_DELAY, RS485_DEFAULT_POST_DELAY);
32+
begin(0, 0, RS485_DEFAULT_PRE_DELAY, RS485_DEFAULT_POST_DELAY);
3433
}
3534

36-
void RS485Class::begin(unsigned long baudrate, int predelay, int postdelay)
35+
void RS485Class::begin(unsigned long _baudrate, int predelay, int postdelay)
3736
{
38-
begin(baudrate, SERIAL_8N1, predelay, postdelay);
37+
begin(0, 0, predelay, postdelay);
3938
}
4039

41-
void RS485Class::begin(unsigned long baudrate, uint16_t config)
40+
void RS485Class::begin(unsigned long _baudrate, uint16_t _config)
4241
{
43-
begin(baudrate, config, RS485_DEFAULT_PRE_DELAY, RS485_DEFAULT_POST_DELAY);
42+
begin(0, 0, RS485_DEFAULT_PRE_DELAY, RS485_DEFAULT_POST_DELAY);
4443
}
4544

46-
void RS485Class::begin(unsigned long baudrate, uint16_t config, int predelay, int postdelay)
45+
void RS485Class::begin(unsigned long _baudrate, uint16_t _config, int predelay, int postdelay)
4746
{
48-
_baudrate = baudrate;
49-
_config = config;
50-
5147
// Set only if not already initialized with ::setDelays
5248
_predelay = _predelay == 0 ? predelay : _predelay;
5349
_postdelay = _postdelay == 0 ? postdelay : _postdelay;
5450

55-
if (_dePin > -1) {
51+
if (_dePin > -1)
52+
{
5653
pinMode(_dePin, OUTPUT);
5754
digitalWrite(_dePin, LOW);
5855
}
5956

60-
if (_rePin > -1) {
57+
if (_rePin > -1)
58+
{
6159
pinMode(_rePin, OUTPUT);
6260
digitalWrite(_rePin, HIGH);
6361
}
6462

65-
_transmisionBegun = false;
66-
67-
_serial->begin(baudrate, config);
63+
_transmissionBegun = false;
6864
}
6965

7066
void RS485Class::end()
7167
{
72-
_serial->end();
73-
74-
if (_rePin > -1) {
68+
if (_rePin > -1)
69+
{
7570
digitalWrite(_rePin, LOW);
7671
pinMode(_dePin, INPUT);
7772
}
78-
79-
if (_dePin > -1) {
73+
74+
if (_dePin > -1)
75+
{
8076
digitalWrite(_dePin, LOW);
8177
pinMode(_rePin, INPUT);
8278
}
8379
}
8480

8581
int RS485Class::available()
8682
{
87-
return _serial->available();
83+
return _stream->available();
8884
}
8985

9086
int RS485Class::peek()
9187
{
92-
return _serial->peek();
88+
return _stream->peek();
9389
}
9490

9591
int RS485Class::read(void)
9692
{
97-
return _serial->read();
93+
return _stream->read();
9894
}
9995

10096
void RS485Class::flush()
10197
{
102-
return _serial->flush();
98+
return _stream->flush();
10399
}
104100

105101
size_t RS485Class::write(uint8_t b)
106102
{
107-
if (!_transmisionBegun) {
103+
if (!_transmissionBegun)
104+
{
108105
setWriteError();
109106
return 0;
110107
}
111108

112-
return _serial->write(b);
109+
return _stream->write(b);
113110
}
114111

115112
RS485Class::operator bool()
@@ -119,58 +116,60 @@ RS485Class::operator bool()
119116

120117
void RS485Class::beginTransmission()
121118
{
122-
if (_dePin > -1) {
119+
if (_dePin > -1)
120+
{
123121
digitalWrite(_dePin, HIGH);
124-
if (_predelay) delayMicroseconds(_predelay);
122+
if (_predelay)
123+
delayMicroseconds(_predelay);
125124
}
126125

127-
_transmisionBegun = true;
126+
_transmissionBegun = true;
128127
}
129128

130129
void RS485Class::endTransmission()
131130
{
132-
_serial->flush();
131+
_stream->flush();
133132

134-
if (_dePin > -1) {
135-
if (_postdelay) delayMicroseconds(_postdelay);
133+
if (_dePin > -1)
134+
{
135+
if (_postdelay)
136+
delayMicroseconds(_postdelay);
136137
digitalWrite(_dePin, LOW);
137138
}
138139

139-
_transmisionBegun = false;
140+
_transmissionBegun = false;
140141
}
141142

142143
void RS485Class::receive()
143144
{
144-
if (_rePin > -1) {
145+
if (_rePin > -1)
146+
{
145147
digitalWrite(_rePin, LOW);
146148
}
147149
}
148150

149151
void RS485Class::noReceive()
150152
{
151-
if (_rePin > -1) {
153+
if (_rePin > -1)
154+
{
152155
digitalWrite(_rePin, HIGH);
153156
}
154157
}
155158

156159
void RS485Class::sendBreak(unsigned int duration)
157160
{
158-
_serial->flush();
159-
_serial->end();
161+
_stream->flush();
160162
pinMode(_txPin, OUTPUT);
161163
digitalWrite(_txPin, LOW);
162164
delay(duration);
163-
_serial->begin(_baudrate, _config);
164165
}
165166

166167
void RS485Class::sendBreakMicroseconds(unsigned int duration)
167168
{
168-
_serial->flush();
169-
_serial->end();
169+
_stream->flush();
170170
pinMode(_txPin, OUTPUT);
171171
digitalWrite(_txPin, LOW);
172172
delayMicroseconds(duration);
173-
_serial->begin(_baudrate, _config);
174173
}
175174

176175
void RS485Class::setPins(int txPin, int dePin, int rePin)
@@ -185,5 +184,3 @@ void RS485Class::setDelays(int predelay, int postdelay)
185184
_predelay = predelay;
186185
_postdelay = postdelay;
187186
}
188-
189-
RS485Class RS485(SERIAL_PORT_HARDWARE, RS485_DEFAULT_TX_PIN, RS485_DEFAULT_DE_PIN, RS485_DEFAULT_RE_PIN);

src/RS485.h

+41-43
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#ifdef PIN_SERIAL1_TX
2626
#define RS485_DEFAULT_TX_PIN PIN_SERIAL1_TX
2727
#else
28-
#define RS485_DEFAULT_TX_PIN 1
28+
#define RS485_DEFAULT_TX_PIN 1
2929
#endif
3030

3131
#ifdef __AVR__
@@ -36,52 +36,50 @@
3636
#define RS485_DEFAULT_RE_PIN A5
3737
#endif
3838

39-
4039
#define RS485_DEFAULT_PRE_DELAY 50
4140
#define RS485_DEFAULT_POST_DELAY 50
4241

43-
class RS485Class : public Stream {
44-
public:
45-
RS485Class(HardwareSerial& hwSerial, int txPin, int dePin, int rePin);
46-
47-
virtual void begin(unsigned long baudrate);
48-
virtual void begin(unsigned long baudrate, uint16_t config);
49-
virtual void begin(unsigned long baudrate, int predelay, int postdelay);
50-
virtual void begin(unsigned long baudrate, uint16_t config, int predelay, int postdelay);
51-
virtual void end();
52-
virtual int available();
53-
virtual int peek();
54-
virtual int read(void);
55-
virtual void flush();
56-
virtual size_t write(uint8_t b);
57-
using Print::write; // pull in write(str) and write(buf, size) from Print
58-
virtual operator bool();
59-
60-
void beginTransmission();
61-
void endTransmission();
62-
void receive();
63-
void noReceive();
64-
65-
void sendBreak(unsigned int duration);
66-
void sendBreakMicroseconds(unsigned int duration);
67-
68-
void setPins(int txPin, int dePin, int rePin);
69-
70-
void setDelays(int predelay, int postdelay);
71-
72-
private:
73-
HardwareSerial* _serial;
74-
int _txPin;
75-
int _dePin;
76-
int _rePin;
77-
int _predelay = 0;
78-
int _postdelay = 0;
79-
80-
bool _transmisionBegun;
81-
unsigned long _baudrate;
82-
uint16_t _config;
42+
class RS485Class : public Stream
43+
{
44+
public:
45+
RS485Class(Stream &stream, int txPin, int dePin, int rePin);
46+
47+
virtual void begin(unsigned long baudrate);
48+
virtual void begin(unsigned long baudrate, uint16_t config);
49+
virtual void begin(unsigned long baudrate, int predelay, int postdelay);
50+
virtual void begin(unsigned long baudrate, uint16_t config, int predelay, int postdelay);
51+
virtual void end();
52+
virtual int available();
53+
virtual int peek();
54+
virtual int read(void);
55+
virtual void flush();
56+
virtual size_t write(uint8_t b);
57+
using Print::write; // pull in write(str) and write(buf, size) from Print
58+
virtual operator bool();
59+
60+
void beginTransmission();
61+
void endTransmission();
62+
void receive();
63+
void noReceive();
64+
65+
void sendBreak(unsigned int duration);
66+
void sendBreakMicroseconds(unsigned int duration);
67+
68+
void setPins(int txPin, int dePin, int rePin);
69+
70+
void setDelays(int predelay, int postdelay);
71+
72+
private:
73+
Stream *_stream;
74+
int _txPin;
75+
int _dePin;
76+
int _rePin;
77+
int _predelay = 0;
78+
int _postdelay = 0;
79+
80+
bool _transmissionBegun;
8381
};
8482

85-
extern RS485Class RS485;
83+
#define RS485 *((RS485Class *)NULL)
8684

8785
#endif

0 commit comments

Comments
 (0)