One ESP32, two boards
One ESP32, two MAX3485 boards and three short wires between their terminals. One board talks on UART1, the other listens on UART2, and the Serial Monitor prints what crossed the pair. It proves the boards, the wiring and the direction pin before any second microcontroller is involved.
What you need
- An ESP32 or ESP32-S3 dev board.
- Two MAX3485 3V3 boards, with their bottom headers soldered.
- A breadboard, jumper wires, and three short wires for A, B and GND.
Leave the 120 Ω fitted on both. Two boards on one cable are its two ends.
Wire it
| Board A | ESP32 | Board B | ESP32 |
|---|---|---|---|
| GND | GND | GND | GND |
| 3V3 | 3V3 | 3V3 | 3V3 |
| TX | GPIO 16 | TX | GPIO 18 |
| RX | GPIO 17 | RX | GPIO 5 |
| DE | GPIO 4 | DE | GPIO 21 |
Then the bus: board A's A to board B's A, B to B, and GND to GND, through the screw terminals.
The one line that matters
Serial1.println() only hands the text to the UART and returns. The bits take
about a millisecond per character to leave. Drop the direction pin then and the
driver switches off mid-message. flush() waits until the last stop bit has
gone, and the pin goes LOW straight after, so the bus is free again as soon as
it can be.
What it prints
A talks, B listens
A sent hello 1
B heard hello 1
A sent hello 2
B heard hello 2Each "B heard" line crossed the pair: out of GPIO 17, into board A, onto A and B as a difference, into board B, and back into GPIO 18. If you see these, both boards, their direction pins and the wiring all work.
The receiver prints only lines that start with hello, which is the idle-bus
rule from When nobody talks in two lines of
code.
The code
Board A sends a numbered line once a second. Board B listens and prints each complete line it hears, so a stray byte on the idle bus never reaches the Serial Monitor.
// One ESP32, two MAX3485 (3V3) boards: A talks, B listens.
//
// Wiring. Both boards: 3V3 -> ESP32 3V3, GND -> ESP32 GND.
// Board A TX -> GPIO16 (the board's TX is the chip's RO)
// RX -> GPIO17
// DE -> GPIO4 (RE is joined to DE on the board)
// Board B TX -> GPIO18
// RX -> GPIO5
// DE -> GPIO21
// Terminals: A to A, B to B, GND to GND.
// Keep both 120R fitted: two boards are the two ends.
//
// Arduino IDE: Tools > Board > esp32 > ESP32 Dev Module
// (or ESP32S3 Dev Module), then Tools > Port.
// Serial Monitor at 115200. No libraries.
const int A_RO = 16, A_DI = 17, A_DIR = 4;
const int B_RO = 18, B_DI = 5, B_DIR = 21;
const long BAUD = 9600;
String line;
int count = 0;
uint32_t last = 0;
void setup() {
// Direction pins first: listen until there is
// something to say.
pinMode(A_DIR, OUTPUT);
digitalWrite(A_DIR, LOW);
pinMode(B_DIR, OUTPUT);
digitalWrite(B_DIR, LOW);
Serial.begin(115200);
Serial1.begin(BAUD, SERIAL_8N1, A_RO, A_DI);
Serial2.begin(BAUD, SERIAL_8N1, B_RO, B_DI);
delay(500);
Serial.println("A talks, B listens");
}
void loop() {
if (millis() - last >= 1000) {
last = millis();
count++;
digitalWrite(A_DIR, HIGH); // A takes the bus
delayMicroseconds(100); // a clean idle first
Serial1.print("hello ");
Serial1.println(count);
Serial1.flush(); // wait for the stop bit
digitalWrite(A_DIR, LOW); // let go
Serial.printf("A sent hello %d\n", count);
}
// B collects bytes and prints only whole lines.
while (Serial2.available()) {
char c = Serial2.read();
if (c == '\n') {
line.trim();
if (line.startsWith("hello")) {
Serial.print("B heard ");
Serial.println(line);
}
line = "";
} else if (line.length() < 40) {
line += c;
}
}
}Serial1 and Serial2 both accept any pins in begin(), on the classic ESP32 and the ESP32-S3 alike, and these six are free on both. flush() waits for the last stop bit, so the direction pin drops the moment the line has left.
When it does not work
Check board B's TX goes to GPIO18 and board A's RX to GPIO17; TX to TX is the usual cause. Then check A, B and GND run terminal to terminal, and that GPIO4 really reaches board A's DE or RE hole.
A line was damaged on the way, and the sketch threw it away rather than print garbage. On a short wire that is usually a loose jumper or a direction pin that drops early. If you changed the sketch, make sure flush() still comes before the pin goes LOW.
A and B are crossed between the terminals, which turns every bit over. Swap the two wires at one terminal. If the text is still wrong, both Serial1 and Serial2 must be at the same BAUD.
An ESP32-C3 or C6 has only two UARTs, one of them the USB serial. Use a classic ESP32 or an ESP32-S3 for this build, or run each board on its own microcontroller as in the Uno build.
The 5 V boards, two microcontrollers, and a reply coming back the other way.
Two Unos over one pair →Edit this page — content/books/rs485/one-esp32-two-boards.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.