RS-485 Half-Duplex Communication with MAX485 & Arduino
Overview
This tutorial is about RS-485 Half-Duplex Communication using MAX485 & Arduino. In our previous article, we learned how to implement Simplex RS-485 communication using the MAX485 IC with Arduino, ideal for one-way data flow over long distances. This tutorial will introduce you to Half-Duplex RS-485 communication, which allows two-way communication over the same pair of wires but not simultaneously.

The MAX485 IC is not only capable of Simplex but also adept at Half-Duplex communication, making it a versatile choice for projects involving RS-485 protocols. In this tutorial, we’ll set up an Arduino-based RS-485 network using MAX485 chips to demonstrate how devices can alternately send and receive messages.
We will provide a detailed wiring diagram to connect your Arduino boards using MAX485 modules for Half-Duplex communication. We’ll write and explain Arduino code to handle sending and receiving data.
MAX485 Module

The MAX485 IC is a low-power transceiver designed for RS-485 communication. It is widely used in industrial and commercial applications for robust, long-distance data transmission.

It operates on a 5V power supply and features both differential signaling and high noise immunity, making it ideal for environments with significant electrical interference. The MAX485 can achieve communication speeds of up to 2.5 Mbps over distances of up to 1200 meters, providing reliable and efficient data exchange.
This IC supports half-duplex communication, allowing data to be transmitted and received over a single pair of wires, though not simultaneously. It includes driver enable and receiver enable pins, which can be controlled to switch between transmitting and receiving modes. It is a half-duplex driver with a Unit Load (UL) rating of 1 and therefore you can have up to 32 MAX485s on a single RS-485 bus.
Specifications of MAX485 Module
- Configuration: Half-Duplex
- Data Rate: Up to 2.5 Mbps
- Data Rate at 1200 m: 110 Kbps
- Slew-rate Limited: No
- Quiescent Current: 300 µA
- Number of Receivers on the Bus: 32
- Pin Count: 8
- Working Voltage: 5V
- Driver Output Voltage Range: -7V to +12V
- Receiver Input Sensitivity: ±200 mV
- Receiver Input Voltage Range: -7V to +12V
- Thermal Shutdown Protection: Yes
- ESD Protection: ±15 kV (Human Body Model)
- Propagation Delay: 50 ns (Typical)
- Operating Temperature Range: -40°C to +85°C
- Package Types: PDIP, SOIC, and TSSOP
- Enable/Disable Time: 600 ns (Typical for driver enable), 200 ns (Typical for receiver enable)
- Short-circuit Current: 250 mA (Driver)
MAX485 Pinout Table

| Pin Number | Pin Name | Description |
| 1 | RO | Receiver Output: Outputs the received data to the microcontroller. |
| 2 | RE | Receiver Enable: Enables (low) or disables (high) the receiver. |
| 3 | DE | Driver Enable: Enables (high) or disables (low) the driver. |
| 4 | DI | Driver Input: Takes input data to be transmitted over the RS-485 bus. |
| 5 | GND | Ground: Provides the ground reference for the IC. |
| 6 | A | Non-inverting Driver Output/Receiver Input: One of the differential signal lines for RS-485 communication. |
| 7 | B | Inverting Driver Output/Receiver Input: The other differential signal line for RS-485 communication. |
| 8 | VCC | Power Supply: Should be connected to a 5V power source. |
MAX485 Module Schematic
The provided schematic shows how to set up RS-485 communication using the MAX485 IC, which helps in converting regular UART signals to differential signals. This conversion is important because differential signals can travel longer distances with less noise interference.

The design includes a 120Ω termination resistor (R7) between the A and B lines to match the bus impedance, which helps in reducing signal reflections and maintaining clear communication. Additionally, 20kΩ pull-up (R6) and pull-down (R5) resistors keep the A and B lines stable, preventing them from picking up noise when not in use.
For power stability, the schematic uses capacitors C1 (10µF) and C2 (0.1µF) to filter out any noise from the power supply, ensuring the MAX485 IC operates smoothly. An LED (D1) with a 1kΩ resistor (R8) is included to indicate when the circuit is powered, making it easier to troubleshoot and confirm that the device is on and working.
Half-Duplex Communication in RS-485
In Half-Duplex communication mode, data can flow in both directions between devices, but not simultaneously. This setup is common in systems where bi-directional information sharing is required, but only one device transmits at a time, such as in control or interactive systems.

- Sender side: The DI pin is connected to the transmitting data line from the microcontroller, and the DE pin is set high to enable data transmission, while the RE pin is set low. The sender’s RO pin is generally not used in transmitting mode.
- Receiver side: The RO pin is connected to the receiving data line of the microcontroller. The RE pin is tied low to enable the receiver, and the DE pin is set low, allowing it to accept transmitted data. The receiver’s DI pin is not utilized in receiving mode.
Example 1: Half-Duplex Communication using the MAX485 Module & Arduino
Let us interface the MAX485 Module with Arduino and enable RS-485 Half-Duplex Communication between two Arduino. Each Arduino will act alternately as a transmitter and a receiver.
Circuit Diagram & Connection
Here is the circuit diagram for demonstrating RS-485 Half-Duplex communication using Arduino boards and two MAX485 modules. The setup is designed to show Half-Duplex (two-way) communication, where each Arduino can act alternately as the sender and the receiver in the RS-485 network.

For the communication, connect the pins as follow:
| Pin on MAX485 | Function | Connected to Arduino Pin |
|---|---|---|
| DI (Driver Input) | Transmits data | 11 (TX of SoftwareSerial) |
| RO (Receiver Output) | Receives data | 10 (RX of SoftwareSerial) |
| DE (Driver Enable) | Enables transmission | 3 |
| RE (Receiver Enable) | Disables receiver | 2 |

Connect the A of the Sender MAX485 Module to A of the receiver MAX485 Module. Also connect the B of the Sender MAX485 Module to b of the receiver MAX485 Module. Power the module with 5V pin of Arduino.
Sender/Receiver Code
Here is the code for both sender and receiver. This Arduino sketch sets up RS-485 Half-Duplex communication using the MAX485 module. It allows the device to send and receive data.
When you enter data in the serial terminal, it switches to transmit mode and sends the data. When there’s data on the RS-485 line, it switches to receive mode and displays the received data on the serial monitor.
#include <SoftwareSerial.h>
// Define the pins for the MAX485
#define DE 3
#define RE 2
// Create a SoftwareSerial object to communicate with the MAX485
SoftwareSerial RS485Serial(10, 11); // RX, TX
void setup() {
// Initialize the serial communication
Serial.begin(9600);
RS485Serial.begin(9600);
// Set the DE and RE pins as outputs
pinMode(DE, OUTPUT);
pinMode(RE, OUTPUT);
// Set DE and RE low to enable receiving mode by default
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
Serial.println("Enter data to send or wait to receive:");
}
void loop() {
// Check if data is available in the serial terminal to send
if (Serial.available()) {
// Read the data from the serial terminal
String dataToSend = Serial.readStringUntil('\n');
// Switch to transmission mode
digitalWrite(DE, HIGH);
digitalWrite(RE, HIGH);
// Send the data over RS485
RS485Serial.println(dataToSend);
// Print the sent data to the serial monitor
Serial.print("Data sent: ");
Serial.println(dataToSend);
// Switch back to receiving mode
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
}
// Check if data is available to receive over RS485
if (RS485Serial.available()) {
// Read the received data
String receivedData = RS485Serial.readStringUntil('\n');
// Print the received data to the serial monitor
Serial.print("Data received: ");
Serial.println(receivedData);
// Print a successful message
Serial.println("Data successfully received.");
}
}
Upload the same code to sender and receiver Arduino board. Then open the Serial Monitor and set the baud rate to 9600.
Write some messages in Serial Terminal for first Arduino and hit send. The sent message will be displayed on the second Arduino Serial Monitor.

Similarly, type some messages in Serial Terminal for second Arduino and hit send. The sent message will be displayed on the first Arduino Serial Monitor.
Example 2: Controlling Servo & LED over RS-485 Half-Duplex using Arduino
In this second half-duplex communication example, we will control the Servo Motor at the Receiver end using the Potentiometer at transmitter end. Also the LED of transmitter will turn ON/OFF based on Servo Motor controlling.
Circuit Diagram & Connection
Here is the circuit diagram for connecting Servo Motor at receiver and LED & potentiometer at transmitter.

At the transmitter end, connect a potentiometer to A0 Pin of Arduino. Similarly connect the LED to pin 13 of Arduino via 330-ohm resistor.

On the receiver side connect the Servo motor PWM pin to the Pin 7 of Arduino. Connect the MAX485 A and B pins to other MAX485 A and B pins respectively.
Sender Code
Here is the sender code for RS-485 Arduino Half-Duplex Communication.
The transmitter code reads data from a potentiometer and maps it to a corresponding servo angle. It then sends this angle to the receiver over RS485 communication. Additionally, the transmitter receives sensor data from the receiver. Based on this received sensor data, it controls the built-in LED, turning it on or off depending on whether the data has reached a predefined threshold.
const int ledPin = 13; // Built-in LED
const int DE = 3;
const int RE = 2;
void setup()
{
Serial.begin(9600);
Serial.setTimeout(100);
pinMode(ledPin, OUTPUT);
pinMode(DE, OUTPUT);
pinMode(RE, OUTPUT);
digitalWrite(ledPin, LOW);
digitalWrite(DE, HIGH);
digitalWrite(RE, HIGH);
}
void loop()
{
int rdata = analogRead(0); //data from potentiometer
int angle= map(rdata, 0, 1023, 0, 180);
//transmitter data packet
Serial.print("I"); //initiate data packet
Serial.print("S"); //code for servo
Serial.print(angle); //servo angle data
Serial.print("F"); //finish data packet
delay(50);
//receiver data packet
Serial.print("I"); //initiate data packet
Serial.print("L"); //code for sensor
Serial.print("F"); //finish data packet
Serial.flush();
digitalWrite(DE, LOW); //RS485 as receiver
digitalWrite(RE, LOW);
if(Serial.find("i"))
{
int data=Serial.parseInt();
if(Serial.read()=='f') //finish reading
{
onLED(data);
}
}
digitalWrite(DE, HIGH); //RS485 as transmitter
digitalWrite(RE, HIGH);
}
void onLED(int data)
{
if(data>240)
digitalWrite(ledPin, LOW);
else
digitalWrite(ledPin, HIGH);
}
Receiver Code
Here is the receiver code for RS-485 Arduino Half-Duplex Communication.
The receiver code receives the servo angle from the transmitter and adjusts the servo position accordingly. It then reads the potentiometer value and sends this data back to the transmitter. After sending the data, the receiver waits for further commands.
#include <Servo.h>
Servo myservo;
const int DE = 3;
const int RE = 2;
void setup () {
Serial.begin (9600);
myservo.attach (7);
pinMode(DE, OUTPUT );
pinMode(RE, OUTPUT );
digitalWrite (DE, LOW );
digitalWrite (RE, LOW );
}
void loop (){
if ( Serial.available ()){
if ( Serial.read () == 'I' ){
char function = Serial.read ();
if (function == 'S' ){
int angle = Serial.parseInt ();
if ( Serial.read () == 'F' ){
if (angle <= 180) {
myservo.write (angle);
}
}
}
else if (function == 'L' ){
if ( Serial.read () == 'F' ){
int val = analogRead (0);
digitalWrite (DE, HIGH ); //enable to transmit
digitalWrite (RE, HIGH );
Serial.print ( "i" );
Serial.print (val);
Serial.println ( "f" );
Serial.flush ();
digitalWrite (DE, LOW ); //enable to receive
digitalWrite (RE, LOW );
}
}
}
}
delay (5);
}
After uploading the code to the both Arduino board, the Half-Duplex Communication using MAX485 is ready to test.

Rotate the potentiometer at the transmitter end. This will cause the servo motor at the receiver end to rotate to the corresponding angle. In response to this, the LED on the transmitter will turn ON or OFF based on the feedback value received from the potentiometer at the receiver.
This demonstrates how you can use RS-485 half-duplex communication with Arduino using the MAX485 module.