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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
#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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#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); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#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); } } |
In subsequent posts, things will start getting more advanced. For now however this should be enough to start from scratch.
Thanks for reading.