RS485 Serial communication

Industruino INDIO's RS485 port

Tom

The Industruino INDIO has a half-duplex isolated RS485 transceiver, connected to the 'Serial' hardware serial ('Serial1' on the older 32u4 and 1286 boards). RS485 is a popular industrial standard for serial communications. It is often used with the Modbus protocol, as Modbus RTU. Using available libraries, this is relatively easy way to exchange data between Master/Slave(s) units, e.g. several INDIOs, or other sensors that support Modbus RTU.

In case you are just interested in serial communication, the RS485 port enables you to communicate over distances up to 1-2 km.

In the Industruino INDIO, the RS485 is connected to the hardware serial Serial (D0/D1) on D21G model (or Serial1 on the old 32u4/1286 models), so there is no need to use a software serial.

Note that RS485 is half-duplex, so we cannot send and receive at the same time. We need to use a TxEnablePin to switch between sending and receiving. This pin is connected to D9 on our MCU.

We have to connect 2 wires for the RS485: A to A, and B to B.

When available please connect the shield ground of the RS485 cable to the GND connection of the RS485 port to avoid common-mode voltages that could potentially damage equipments. 

In the picture on the left, the 2 INDIOs are powered from the same PSU so the GND connection is not neccesary.

The 2 sketches below are for a Sender that sends a single byte (increased by one, every second), and a Receiver that reads the byte and puts it on the LCD.

TESTED WITH 2x INDIO D21G

/*
 * Industruino INDIO RS485 serial demo  SENDER
 * INDIO has a half duplex RS485 port connected to hardware Serial
 * TxEnablePin is D9
 */

#include <UC1701.h>
static UC1701 lcd;

const int TxEnablePin = 9;
byte byte_sent = 1;

void setup() {
  pinMode(26, OUTPUT);
  digitalWrite(26, HIGH);   // LCD backlight
  lcd.begin();
  
  Serial.begin(9600);
  pinMode(TxEnablePin, OUTPUT);

  lcd.clear();
  lcd.print("INDIO RS485 sender");
  lcd.setCursor(0,3);
  lcd.print("Sending: ");
}

void loop() {
  
  lcd.setCursor(60,3);
  lcd.print(byte_sent);
  lcd.print("  ");
  
  digitalWrite(TxEnablePin, HIGH);
  Serial.write(byte_sent);
  delay(10);
  digitalWrite(TxEnablePin, LOW);

  delay(1000);
  byte_sent++;
}


/*
 * Industruino INDIO RS485 serial demo   RECEIVER
 * INDIO has a half duplex RS485 port connected to hardware Serial
 * TxEnablePin is D9
 */

#include <UC1701.h>
static UC1701 lcd;

const int TxEnablePin = 9;
byte byte_received;

void setup() {
  pinMode(26, OUTPUT);
  digitalWrite(26, HIGH);   // LCD backlight
  lcd.begin();

  Serial.begin(9600);
  pinMode(TxEnablePin, OUTPUT);
  digitalWrite(TxEnablePin, LOW);

  lcd.clear();
  lcd.print("INDIO RS485 receiver");
  lcd.setCursor(0, 3);
  lcd.print("Received:");
  
}

void loop() {

  if (Serial.available()) {
    byte_received = Serial.read();
    lcd.setCursor(60,3);
    lcd.print(byte_received);
    lcd.print("  ");
  }

}