Two Unos over one pair
Two Arduino Unos, each with a MAX485 5V board, joined by A, B and GND. One sends ping, the other answers pong, and both take turns on the same pair. The Uno's one hardware UART is its USB link, so the bus goes through SoftwareSerial on pins 10 and 11.
What you need
- Two Arduino Unos (a Nano works the same, on the same pins).
- Two MAX485 5V boards, headers soldered.
- Three wires between the terminals: A, B and GND. A metre of twisted pair makes the point better than three jumpers, but either works.
Wire it
Each Uno to its own board:
| Board | Uno |
|---|---|
| GND | GND |
| 5V | 5V |
| TX | pin 10 |
| RX | pin 11 |
| DE | pin 2 |
The Uno's pins 0 and 1 are its hardware UART, and they are also the USB link to the Serial Monitor, so the bus goes on SoftwareSerial instead.
Taking turns
Each Uno holds pin 2 LOW, listening, except inside send(). The talker raises
it, sends a line, waits for the last byte and drops it. Only then can the
listener raise its own and answer. At no moment are both pins HIGH, which is
what half duplex asks.
What it prints
On the talker:
talker
reply pong 1
reply pong 2On the listener:
listener
heard ping 1
heard ping 2Every reply line is a message that crossed the pair twice, once each way, through both boards' drivers and both boards' receivers.
The code
The same sketch goes on both Unos. Set TALKER to true on one and false on the other. The talker sends ping once a second; the listener answers each ping with pong and the same number.
// RS485 ping-pong between two Unos, MAX485 (5V) boards.
//
// Wiring, each Uno to its own board:
// Board GND -> Uno GND Board 5V -> Uno 5V
// Board TX -> Uno pin 10 (the board's TX is the chip's RO)
// Board RX -> Uno pin 11
// Board DE -> Uno pin 2 (RE is joined to DE on the board)
// Terminals: A to A, B to B, GND to GND.
// Keep both 120R fitted: two boards are the two ends.
//
// Arduino IDE: Tools > Board > Arduino AVR Boards >
// Arduino Uno, then Tools > Port. Serial Monitor 9600.
// SoftwareSerial comes with the IDE.
//
// Upload with TALKER true to one Uno, false to the other.
#include <SoftwareSerial.h>
const bool TALKER = true;
const int DIR = 2;
SoftwareSerial bus(10, 11); // RX, TX
String line;
int count = 0;
unsigned long last = 0;
void send(const String &msg) {
digitalWrite(DIR, HIGH); // take the bus
delayMicroseconds(200);
bus.println(msg);
bus.flush();
digitalWrite(DIR, LOW); // let go
}
void setup() {
pinMode(DIR, OUTPUT);
digitalWrite(DIR, LOW); // listen first
Serial.begin(9600);
bus.begin(9600);
Serial.println(TALKER ? "talker" : "listener");
}
void loop() {
if (TALKER && millis() - last >= 1000) {
last = millis();
count++;
send("ping " + String(count));
}
while (bus.available()) {
char c = bus.read();
if (c != '\n') {
if (line.length() < 30) line += c;
continue;
}
line.trim();
if (!TALKER && line.startsWith("ping ")) {
Serial.println("heard " + line);
send("pong " + line.substring(5));
} else if (TALKER && line.startsWith("pong ")) {
Serial.println("reply " + line);
}
line = "";
}
}SoftwareSerial writes each byte bit by bit and returns only when its stop bit is out, so flush() is not strictly needed here. It stays in, because the same code on any hardware UART needs it.
When it does not work
The pong is going out while the talker's pin is still HIGH, or the talker's board cannot hear. Check the talker's pin 2 reaches DE or RE, and that its board's TX goes to pin 10. A talker sketch that holds the pin HIGH after sending blocks every answer.
Nothing is crossing the pair. Swap A and B at one terminal, check both boards' TX go to pin 10 and RX to pin 11, and that the GND screw is wired between the terminals as well as A and B.
On one computer both Unos share the computer's ground through USB, which hides a missing GND wire. On separate supplies the grounds can sit volts apart. Run GND between the terminals alongside A and B.
Yes. The bus carries only the difference between A and B, and both chips make and read it the same way. Use the ESP32 sketch's pins and HardwareSerial on that side, with the same 9600 baud and the same ping and pong lines.
Cable, ground and the shape of the run, once the boards leave the desk.
Wiring a real bus →Edit this page — content/books/rs485/two-unos.mdx
Questions about this product
See what other owners have asked, and read their solutions.
This page covers several products. Choose yours to see the right discussions.
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.