I’m building a DIY ESP32-S3 board that needs to communicate with an ATmega328P using MAX483 transceivers through an RJ12 port.
The goal is to send and receive data between the two microcontrollers.
The Problem
The communication works perfectly when I use an ESP32 DevKit V1,
but it does not work when I switch to my DIY ESP32-S3 board.
I can’t send or receive any data to/from the ATmega328P.
Hardware Setup
ESP32-S3 (DIY board)
ATmega328P
MAX483 transceivers (for RS-485)
RJ12 connector and cable
Notes
The same code works fine with ESP32 DevKit V1.
The problem appears only with the DIY ESP32-S3 board.
Checked power supply voltage and ground connections
Tested MAX483 modules individually
Confirmed cable continuity for RJ12
Extra Info
Arduino IDE version: 2.3.6
Board package: ESP32-S3-WROOM-1-N8
Library used: ICSC
Any suggestions on what could cause the ESP32-S3 to fail in RS-485 communication when the ESP32 DevKit V1 works fine? Could this be a hardware pin mapping or signal level issue?
You said the failing board is a DIY. In my language, that means Do It Yourself. I am not 100% sure I understand what that means in the Arduino world, but it is obviously where the problem is.
If I remember correctly the MAX483 uses 5V logic - the ESP32S3 uses 3.3V logic - you may have damaged the ESP32S3 by connecting it directly to the MAX483
consider using a RS485 transceiver which uses 3.3V logic such as the SP3485 3.3V Low Power Half-Duplex RS-485 Transceiver
have you an oscilloscope so you can check signals on your PCB?
Thanks for pointing that out. In my setup, the MAX483 is powered at 5 V, but its RO pin output to the ESP32-S3 RX passes through a voltage divider, reducing it to about 3.3 V, so the ESP32-S3 shouldn’t be receiving 5 V directly.
Is a voltage divider not ideal for this application?
Another challenge is that I don’t have an oscilloscope to test my PCB. I’ll post the code here if I can find it, as I may have deleted it since it wasn’t working.
that should be OK - this is where an oscilloscope can be used for checking such signals
I find also it useful to have a USB-RS485 module to monitor the A and B RS485 signals with a PC
this is a using a ESP32 to communicate with a RS485 module
should work with a ESP32-S3 change GPIO pins RXD2, TXD2, DE and RE to suit your PCB and replace serial monitor IO to send data every second as a test
// ESP32 Serial1 to RS485 bus
//
// see https://microcontrollerslab.com/rs485-serial-communication-arduino-tutorial/
#define RS485Serial Serial1 // hardware serial port on ESP32
// RS485 VCC ESP32 to to 3.3V
#define RXD2 16 // ESP32 Serial1 Receive pin 16 to RS485 RO (Receiver Output) /RXD
#define TXD2 17 // ESP32 Serial1 Transmit pin 17 to RS485 DI (Driver Input) /TXD
// RS485 DE (Driver Enable set HIGH to enable) and RE (Receiver Enable set LOW to enable) to ESP32 pins 18 and 19
#define DE 18 //RS485 Direction control pin
#define RE 19 //RS485 Direction control pin
#define RS485Transmit HIGH
#define RS485Receive LOW
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("ESP32 connect to RS485 bus - enter/receive text");
pinMode(DE, OUTPUT);
pinMode(RE, OUTPUT);
digitalWrite(DE, RS485Receive); // Disable RS485 Transmit
digitalWrite(RE, RS485Receive); // Disable RS485 Transmit
RS485Serial.begin(115200, SERIAL_8N1, RXD2, TXD2); // set the RS485 data rate
}
// loop sending data to RS485 and receiving data
void loop() {
if (Serial.available()) { // Arduino Serial data avaliable?
digitalWrite(DE, RS485Transmit); // Enable RS485 Transmit
digitalWrite(RE, RS485Transmit); // Enable RS485 Transmit
RS485Serial.write(Serial.read()); // Send byte to Remote Arduino
RS485Serial.flush(); // wait for byte to be transmitted
digitalWrite(DE, RS485Receive); // Disable RS485 Transmit
digitalWrite(RE, RS485Receive); // Disable RS485 Transmit
}
if (RS485Serial.available()) // RS485 serial data available?
Serial.write(RS485Serial.read()); // read character and display it
}
note the use of RS485Serial.flush(); which waits for the transmission to complete before switching DE and RE
I assume you can load and run a program on the ESP32-S3, e.g. blink the LED
try the following which transmits text on a ESP32-S3-DevKitC-1 U0TXD serial output every 5 seconds
// ESP32-S3-DevKitC-1 Serial to RS485 bus using SP3485 transceiver
// transmit text every 5 seconds
#define RS485Serial Serial // hardware serial port on ESP32S3
// RS485 VCC ESP32S3 to to 3.3V
//#define RXD2 18 // ESP32S3 Serial1 Receive pin 16 to SP3485 TXD (Receiver Output)
//#define TXD2 17 // ESP32S3 Serial1 Transmit pin 17 to SP3485 RXD (Driver Input)
// RS485 DE (Driver Enable set HIGH to enable) and RE (Receiver Enable set LOW to enable) to ESP32S3 pins 18 and 19
// NOTE: not used on the SP3485 module
#define DE 15 //RS485 Direction control pin
#define RE 16 //RS485 Direction control pin
#define RS485Transmit HIGH
#define RS485Receive LOW
void setup() {
Serial.begin(9600);
delay(1000);
//Serial.println("\n\nESP32-S3-DevKitC-1 connect to RS485 bus using SP3485 module \nenter/receive text");
pinMode(DE, OUTPUT);
pinMode(RE, OUTPUT);
digitalWrite(DE, RS485Receive); // Disable RS485 Transmit
digitalWrite(RE, RS485Receive); // Disable RS485 Transmit
// RS485Serial.begin(9600, SERIAL_8N1, RXD2, TXD2); // set the RS485 data rate
}
// loop sending data to RS485 and receiving data
void loop() {
static unsigned long timer1 = millis();
static char text[50]="hello 1\n";
if (millis() - timer1 > 5000) {
timer1 = millis();
digitalWrite(DE, RS485Transmit); // Enable RS485 Transmit
digitalWrite(RE, RS485Transmit); // Enable RS485 Transmit
RS485Serial.write(text); // Send byte to Remote Arduino
RS485Serial.flush(); // wait for byte to be transmitted
digitalWrite(DE, RS485Receive); // Disable RS485 Transmit
digitalWrite(RE, RS485Receive); // Disable RS485 Transmit
if(text[6] == '9')text[6]='0'; else text[6]++; // update test data
}
if (RS485Serial.available()) // RS485 serial data available?
Serial.write(RS485Serial.read()); // read character and display it
}
a Nano connected to RS485 displays on serial monitor
Nano to RS485 - Use Serial Monitor, type in upper window, ENTER
Use Serial Monitor, type in upper window, ENTER
hello 1
hello 2
hello 3
hello 4
hello 5
hello 6
hello 7
hello 8
hello 9
hello 0
hello 1
hello 2
hello 3
hello 4
hello 5