Skip to content
This repository was archived by the owner on Feb 28, 2024. It is now read-only.

Commit 078a330

Browse files
committed
Refactor RS485 support
1 parent c107e0a commit 078a330

File tree

7 files changed

+143
-274
lines changed

7 files changed

+143
-274
lines changed

Diff for: .github/workflows/compile-examples.yml

+5
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ jobs:
4242
fqbn: arduino:mbed_portenta:envie_m7
4343
platforms: |
4444
- name: arduino:mbed_portenta
45+
libraries: |
46+
- source-path: ./
47+
- name: ArduinoRS485
48+
sketch-paths: |
49+
- examples
4550
enable-deltas-report: true
4651
enable-warnings-report: true
4752
sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }}

Diff for: examples/RS485_fullduplex/RS485_fullduplex.ino

+30-16
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,25 @@
22
RS485 Full duplex communication
33
44
This sketch shows how to use the SP335ECR1 on the Machine
5-
Control as a full duplex RS485 interface, how to periodically
5+
Control as a full duplex (AB and YZ) RS485 interface, how to periodically
66
send a string on the RS485 TX channel and how to receive data
77
from the interface RX channel.
88
99
Circuit:
1010
- Portenta H7
1111
- Machine Control
1212
- A Slave device with RS485 interface
13+
- Connect TXP to A(+) and TXN to B(-)
14+
- Connect RXP to Y(+) and RXN to Z(-)
1315
1416
*/
1517

1618
#include "Arduino_MachineControl.h"
1719

1820
using namespace machinecontrol;
1921

22+
constexpr unsigned long sendInterval { 1000 };
23+
unsigned long sendNow { 0 };
2024
unsigned long counter = 0;
2125

2226
void setup()
@@ -29,37 +33,47 @@ void setup()
2933
delay(1000);
3034
Serial.println("Start RS485 initialization");
3135

32-
comm_protocols.rs485.begin(115200);
33-
comm_protocols.rs485.enable = 1; // SDHN_N
34-
comm_protocols.rs485.sel_485 = 1; // RS485_RS232_N
35-
comm_protocols.rs485.half_duplex = 0; // HALF_FULL_N
36-
comm_protocols.rs485.receive(); // RE_N
37-
comm_protocols.rs485.fd_tx_term = 1; // FD_TX_TERM - 120 ohm Y-Z termination enabled when both TERM and FD_TX_TERM are high
38-
comm_protocols.rs485.term = 1; // TERM - 120 ohm A-B termination enabled when high
36+
// Set the PMC Communication Protocols to default config
37+
comm_protocols.init();
38+
// RS485/RS232 default config is:
39+
// - RS485 mode
40+
// - Half Duplex
41+
// - No A/B and Y/Z 120 Ohm termination enabled
42+
43+
// Enable the RS485/RS232 system
44+
comm_protocols.rs485Enable(true);
45+
46+
// Enable Full Duplex mode
47+
// This will also enable A/B and Y/Z 120 Ohm termination resistors
48+
comm_protocols.rs485FullDuplex(true);
49+
50+
// Specify baudrate, and preamble and postamble times for RS485 communication
51+
comm_protocols.rs485.begin(115200, 0, 500);
52+
53+
// Start in receive mode
54+
comm_protocols.rs485.receive();
55+
3956

4057
Serial.println("Initialization done!");
4158
}
4259

43-
constexpr unsigned long sendInterval { 1000 };
44-
unsigned long sendNow { 0 };
45-
46-
constexpr unsigned long halfFullInterval { 5000 };
47-
unsigned long halfFull { 0 };
48-
byte halfFullStatus { 0 };
49-
5060
void loop()
5161
{
52-
while (comm_protocols.rs485.available())
62+
if (comm_protocols.rs485.available())
5363
Serial.write(comm_protocols.rs485.read());
5464

5565
if (millis() > sendNow) {
66+
// Disable receive mode before transmission
5667
comm_protocols.rs485.noReceive();
68+
5769
comm_protocols.rs485.beginTransmission();
5870

5971
comm_protocols.rs485.print("hello ");
6072
comm_protocols.rs485.println(counter++);
6173

6274
comm_protocols.rs485.endTransmission();
75+
76+
// Re-enable receive mode after transmission
6377
comm_protocols.rs485.receive();
6478

6579
sendNow = millis() + sendInterval;

Diff for: examples/RS485_halfduplex/RS485_halfduplex.ino

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
RS485 Half Duplex communication
3+
4+
This sketch shows how to use the SP335ECR1 on the Machine
5+
Control as a half duplex (AB) RS485 interface, how to periodically
6+
send a string on the RS485 TX channel and how to receive data
7+
from the interface RX channel.
8+
9+
Circuit:
10+
- Portenta H7
11+
- Machine Control
12+
- A Slave device with RS485 interface
13+
- Connect TXP to A(+) and TXN to B(-)
14+
15+
*/
16+
17+
#include "Arduino_MachineControl.h"
18+
19+
using namespace machinecontrol;
20+
21+
constexpr unsigned long sendInterval { 1000 };
22+
unsigned long sendNow { 0 };
23+
24+
unsigned long counter { 0 };
25+
26+
void setup()
27+
{
28+
29+
Serial.begin(115200);
30+
// Wait for Serial or start after 2.5s
31+
for (auto const timeout = millis() + 2500; !Serial && timeout < millis(); delay(500))
32+
;
33+
34+
delay(2500);
35+
Serial.println("Start RS485 initialization");
36+
37+
// Set the PMC Communication Protocols to default config
38+
comm_protocols.init();
39+
40+
// RS485/RS232 default config is:
41+
// - RS485 mode
42+
// - Half Duplex
43+
// - No A/B and Y/Z 120 Ohm termination enabled
44+
45+
// Enable the RS485/RS232 system
46+
comm_protocols.rs485Enable(true);
47+
48+
// Specify baudrate, and preamble and postamble times for RS485 communication
49+
comm_protocols.rs485.begin(115200, 0, 500);
50+
// Start in receive mode
51+
comm_protocols.rs485.receive();
52+
53+
Serial.println("Initialization done!");
54+
}
55+
56+
void loop()
57+
{
58+
if (comm_protocols.rs485.available())
59+
Serial.write(comm_protocols.rs485.read());
60+
61+
if (millis() > sendNow) {
62+
// Disable receive mode before transmission
63+
comm_protocols.rs485.noReceive();
64+
65+
comm_protocols.rs485.beginTransmission();
66+
67+
comm_protocols.rs485.print("hello ");
68+
comm_protocols.rs485.println(counter++);
69+
70+
comm_protocols.rs485.endTransmission();
71+
72+
// Re-enable receive mode after transmission
73+
comm_protocols.rs485.receive();
74+
75+
sendNow = millis() + sendInterval;
76+
}
77+
}

Diff for: library.properties

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ category=Communication
88
url=https://github.com/arduino-libraries/Arduino_MachineControl
99
architectures=mbed, mbed_portenta
1010
includes=Arduino_MachineControl.h
11+
depends=ArduinoRS485

Diff for: src/Arduino_MachineControl.h

+30-8
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33

44
#include "utility/MAX31865/MAX31865.h"
55
#include "utility/THERMOCOUPLE/MAX31855.h"
6-
#include "utility/RS485/RS485.h"
6+
#include <ArduinoRS485.h>
77
#include "utility/QEI/QEI.h"
88
#include "utility/ioexpander/ArduinoIOExpander.h"
99
#include "utility/RTC/PCF8563T.h"
1010
#include "utility/RTC/PCF8563T.h"
1111

1212
#include "Arduino.h"
13+
#include "pinDefinitions.h"
1314
#include "mbed.h"
1415

1516
#include "USBHost.h"
@@ -57,11 +58,19 @@ class COMMClass {
5758
// to be tested: check if can be made a big pin initialization
5859
void init() {
5960
//SHUTDOWN OF RS485 LEDS
60-
digitalWrite(PA_0, LOW);
61-
digitalWrite(PI_9, LOW);
61+
digitalWrite(PinNameToIndex(PA_0), LOW);
62+
digitalWrite(PinNameToIndex(PI_9), LOW);
6263
//SHUTDOWN OF CAN LEDS
63-
digitalWrite(PB_8, LOW);
64-
digitalWrite(PH_13, LOW);
64+
digitalWrite(PinNameToIndex(PB_8), LOW);
65+
digitalWrite(PinNameToIndex(PH_13), LOW);
66+
67+
// SET DEFAULTS for RS485
68+
rs485Enable(false);
69+
rs485ModeRS232(false);
70+
rs485FullDuplex(false);
71+
rs485YZTerm(false);
72+
rs485ABTerm(false);
73+
rs485Slew(false);
6574
}
6675

6776
void enableCAN() {
@@ -74,11 +83,24 @@ class COMMClass {
7483
UART _UART4_ = arduino::UART(PA_0, PI_9, NC, NC);
7584
mbed::CAN& can = _can;
7685

77-
RS485Class rs485 = RS485Class(_UART4_,PA_0, PI_13,PI_10);
86+
RS485Class rs485 = RS485Class(_UART4_, PinNameToIndex(PA_0), PinNameToIndex(PI_13), PinNameToIndex(PI_10));
87+
88+
void rs485Enable(bool enable) { digitalWrite(PinNameToIndex(PG_9), enable ? HIGH : LOW); }
89+
void rs485ModeRS232(bool enable) { digitalWrite(PinNameToIndex(PA_10), enable ? LOW : HIGH); }
90+
void rs485YZTerm(bool enable) { digitalWrite(PinNameToIndex(PI_15), enable ? HIGH : LOW); }
91+
void rs485ABTerm(bool enable) { digitalWrite(PinNameToIndex(PI_14), enable ? HIGH : LOW); }
92+
void rs485Slew(bool enable) { digitalWrite(PinNameToIndex(PG_14), enable ? LOW : HIGH); }
93+
void rs485FullDuplex(bool enable) {
94+
digitalWrite(PinNameToIndex(PA_9), enable ? LOW : HIGH);
95+
if (enable) {
96+
// RS485 Full Duplex require YZ and AB 120 Ohm termination enabled
97+
rs485YZTerm(true);
98+
rs485ABTerm(true);
99+
}
100+
}
101+
78102
private:
79103
mbed::DigitalOut can_disable = mbed::DigitalOut(PA_13, 0);
80-
81-
82104
};
83105

84106
extern COMMClass comm_protocols;

0 commit comments

Comments
 (0)