RS485 Hardware Network 1 – Getting Started

For another project I’m currently working on, I need a way to control multiple microcontrollers in a multi-point, multi-drop network configuration. Luckily, we live in amazing times. As I write this, you you can buy a fully assembled breakout board for the MAX485 chip from Maxim Integrated for a mere $0.45 USD shipped from China.

I bought a 5 pack, here are some of the boards:

RS485 is an old protocol, but is the logical next step for devices I’m already communicating with via RS232. For this example, I’m using 4 Arduino boards of various types.

  • An Arduino Micro as the master
  • 2 Slave Arduino Leonardos
  • 1 Slave Arduino Pro Mini (5v)

Here is a video of the setup:

The schematic is really straightforward as well. The only tricky bit is that I’m using a software serial port on each of the Arduinos for ease of debugging. Here’s a schematic:

The code to acomplish this is really intuitive as well.

Here is the code for the master Arduino:

#include <SoftwareSerial.h>

int MAX485_Receiver_Output_PIN = 10;
int MAX485_Driver_Input_PIN = 11;
int MAX485_Driver_Output_Enable_PIN = 12;

int debug_led = 13;

SoftwareSerial software_serial (MAX485_Receiver_Output_PIN, MAX485_Driver_Input_PIN); // RX, TX

void setup()
{
  Serial.begin(9600); // begin hardware serial
  software_serial.begin(9600); // begin software serial
  
  pinMode(MAX485_Driver_Output_Enable_PIN, OUTPUT);
  digitalWrite(MAX485_Driver_Output_Enable_PIN, HIGH); // this disables Receiver Output Enable and enables Driver Output Enable
}

void loop()
{
  
  byte to_send = 0; // declare the byte to be sent to the slaves though, init as 0
  int rate;
  
  while (true) 
  {
    // invert the byte to be sent
    if (to_send == 1) to_send = 0;
    else if (to_send == 0) to_send = 1; 
    
    Serial.print("Sending: ");
    Serial.println(to_send);
    
    digitalWrite(debug_led, to_send);
    
    rate = map(analogRead(5), 0, 1023, 0, 1000);
    
    software_serial.write(to_send); // send our byte out to the MAX485
    
    delay(rate);
  }
}

This is the code for the slave Arduinos:

#include <SoftwareSerial.h>

int MAX485_Receiver_Output_PIN = 10;
int MAX485_Driver_Input_PIN = 11;
int MAX485_Driver_Output_Enable_PIN = 12;

int debug_led_PIN = 9; 

SoftwareSerial software_serial (MAX485_Receiver_Output_PIN, MAX485_Driver_Input_PIN); // RX, TX

void setup()
{
  software_serial.begin(9600); // begin software serial
  
  pinMode(MAX485_Driver_Output_Enable_PIN, OUTPUT);
  digitalWrite(MAX485_Driver_Output_Enable_PIN, LOW);
  
  pinMode(debug_led_PIN, OUTPUT);
  
}

void loop() // run over and over
{
  byte k;
  
  if (software_serial.available() > 0) // make sure there is something to read
  { 
    k = software_serial.read(); // read in a single byte from the serial port    
    digitalWrite(debug_led_PIN, k); 
  }
}

#include <SoftwareSerial.h>

int MAX485_Receiver_Output_PIN = 10;
int MAX485_Driver_Input_PIN = 11;
int MAX485_Driver_Output_Enable_PIN = 12;

int debug_led_PIN = 9; 

SoftwareSerial software_serial (MAX485_Receiver_Output_PIN, MAX485_Driver_Input_PIN); // RX, TX

void setup()
{
  software_serial.begin(9600); // begin software serial
  
  pinMode(MAX485_Driver_Output_Enable_PIN, OUTPUT);
  digitalWrite(MAX485_Driver_Output_Enable_PIN, LOW);
  
  pinMode(debug_led_PIN, OUTPUT);
  
}

void loop() // run over and over
{
  byte k;
  
  if (software_serial .available() &gt; 0) // make sure there is something to read
  { 
    k = software_serial.read(); // read in a single byte from the serial port    
    digitalWrite(debug_led_PIN, k); 
  }
}

In subsequent posts, things will start getting more advanced. For now however this should be enough to start from scratch.

Thanks for reading.

6 Comments

  1. how does the setup determine which one is master and which one is Slave. Does the master send only? and the slave receive only as well?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.