RS485 : Incorrect Data received with Software Serial Library and MAX485 IC with Arduino Mega

Hello Experts,

I am trying to do RS485 Communication between two Arduino Mega Boards. One of the Board is configured as a Transmitter and the other one is configured as a Receiver.

The connections are :

  • DI (data in) to pin 11
  • RO (receive out) to pin 10
  • DE (data enable) and RE (receive enable) jumpered together and to pin 3
  • Vcc and Gnd connected
  • A and B : the RS485 pair

The transmitted data packet is :
int packet[]={0x1, 0x2, 0x3, 0x4, 0x5, 0x6};

The received data packet is :
255 255 255 255 255 0

Can anyone help me with the reason, I am not getting the same packet as transmitted.

The transmitter sketch is :

#include <SoftwareSerial.h>

#define SSerialRX        10  //Serial Receive pin
#define SSerialTX        11  //Serial Transmit pin
#define SSerialTxControl 3   //RS485 Direction control
#define RS485Transmit    HIGH
#define RS485Receive     LOW
#define Pin13LED         13

SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX

int byteReceived;
int byteSend;
int packet[]={0x1, 0x2, 0x3, 0x4, 0x5, 0x6};
void setup()  
{
  
  Serial.begin(9600);
  pinMode(Pin13LED, OUTPUT);   
  pinMode(SSerialTxControl, OUTPUT);    
  
  digitalWrite(SSerialTxControl, RS485Receive);  // Init Transceiver   
  RS485Serial.begin(9600);   // set the data rate 

}

void loop()  
{
 
    int i = 0;
    for (i = 0; i<= 5; i++) {
    digitalWrite(SSerialTxControl, RS485Transmit);  // Enable RS485 Transmit   
    RS485Serial.write(byteReceived);          // Send byte to Remote Arduino
    }
    delay(10);
    digitalWrite(SSerialTxControl, RS485Receive);  // Enable RS485 Transmit   
    digitalWrite(Pin13LED, LOW);  // Show activity    
    digitalWrite(SSerialTxControl, RS485Receive);  // Disable RS485 Transmit       

delay(2000);

}

The Receiver Sketch is :

#include <SoftwareSerial.h>

#define SSerialRX        10  //Serial Receive pin
#define SSerialTX        11  //Serial Transmit pin
#define SSerialTxControl 3   //RS485 Direction control
#define RS485Transmit    HIGH
#define RS485Receive     LOW
#define Pin13LED         13

SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX

int byteReceived;
int byteSend;

void setup()  
{
  Serial.begin(9600);
  Serial.println("SerialRemote");  
  
  pinMode(Pin13LED, OUTPUT);   
  pinMode(SSerialTxControl, OUTPUT);  
  
  digitalWrite(SSerialTxControl, RS485Receive);  
   
  RS485Serial.begin(9600);   
}

void loop()  
{
  //Copy input data to output  
  while (RS485Serial.available()) 
  {
    byteSend = RS485Serial.read();   // Read the byte 
    Serial.print(byteSend);
    Serial.print(" ");
  }
  Serial.println("");
  delay(2000);
}

You can't use delay in the receiver sketch because you're using SoftwareSerial. During the delay, SoftwareSerial is not watching the DI/RO lines and will completely miss the sent data.

You have Megas, so why not use Serial1, 2 or 3 for the RS485 DI/RO lines?

Cheers,
/dev

Removing the delay statements does not help. I did try that.

Yes, Serial1, 2, 3 is a possibility. Actually I started with that and then followed some threads which were using the pin 10 and 11 for communication. But doesn't help.

Cleaned up some bugs in the sketch. However the packets received are junk and not valid. New updated sketch for master is

#include <SoftwareSerial.h>

#define SSerialRX        10  //Serial Receive pin
#define SSerialTX        11  //Serial Transmit pin
#define SSerialTxControl 3   //RS485 Direction control
#define RS485Transmit    HIGH
#define RS485Receive     LOW
#define Pin13LED         13

SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX

int byteReceived;
int byteSend;
int packet[]={0x1, 0x2, 0x3, 0x4, 0x5, 0x6};
void setup()  
{
  
  Serial.begin(9600);
  pinMode(Pin13LED, OUTPUT);   
  pinMode(SSerialTxControl, OUTPUT);    
  
  digitalWrite(SSerialTxControl, RS485Receive);  // Init Transceiver   
  RS485Serial.begin(9600);   // set the data rate 

}

void loop()  
{
 
    int i = 0;
    for (i = 0; i<= 5; i++) {
    digitalWrite(Pin13LED, HIGH);  // Show activity    
    digitalWrite(SSerialTxControl, RS485Transmit);  // Enable RS485 Transmit   
    RS485Serial.write(packet[i]);          // Send byte to Remote Arduino
    }
    delayMicroseconds(210);
    digitalWrite(SSerialTxControl, RS485Receive);  // Disable RS485 Transmit   
    digitalWrite(Pin13LED, LOW);  // Show activity    
    

delay(2000);

}

The accumulated output of many transmitted packets is :
108 128 0 255 0 0 0 0 62 0 0 0 0 0 0 0

You can't use delay in the receiver sketch because you're using SoftwareSerial.

This isn't some kind of vague guideline. This is just one problem that you must fix. There may be other problems, but you won't find them until you remove the delay.

Using Serial1 is strongly recommended. SoftwareSerial is a last resort for when you don't have any hardware ports available.