Rs485 communication between arduino

Hi I want to try mimicking rs485 communication with arduino. We want to test before purchasing a rs485 temp hum device at make sure this will works.

Currently I use nano as replacement for sensor and esp32 as gateway, the esp32 later will use mqtt to report to server.

I cannot get pass the rs485 communication part.
The connection is roughly like this

esp32 is power by usb from pc, since i need to debug using serial
all nano and max485 module is from mb102 that directly power from dc adapter

This is slave sketch, we use random value for now to replace temp hum
we use softwareserial since we want to debug using usb serial

// library from https://github.com/angeloc/simplemodbusng
#include <SoftwareSerial.h>
#include "SimpleModbusSlaveSoftwareSerial.h"

const int RS485_DE_RE = 2;

SoftwareSerial rs485Serial(3,4); //RX, TX

unsigned int holdingRegistry[2] = {0};


void setup() {
  randomSeed(analogRead(0));

  pinMode(RS485_DE_RE, OUTPUT);

  Serial.begin(115200);
  rs485Serial.begin(9600);

  // Slave 1
  modbus_configure(&rs485Serial, 9600, 1, RS485_DE_RE, 2);

  // Slave 2
  // modbus_configure(&rs485Serial, 9600, 2, RS485_DE_RE, 2);
}

void loop() {
  static unsigned long lastRead = 0;

  if (millis() - lastRead > 1000) {
    lastRead = millis();
  } else {
    return;
  }

  modbus_update(holdingRegistry);
      
  holdingRegistry[0] = (uint16_t)random(20,40);
  holdingRegistry[1] = (uint16_t)random(50,90);

  Serial.print("Temp: ");
  Serial.print(holdingRegistry[0]);
  Serial.print(" °C, Humidity: ");
  Serial.print(holdingRegistry[1]);
  Serial.println(" %");
}

This is our gateway code

#include <ModbusMaster.h>
#include <HardwareSerial.h>

const int MAX485_CTRL_PIN=4;
const int TX_PIN = 16; 
const int RX_PIN = 17;
const int NUM_SLAVES=2; // Move to EEPROM

typedef struct {
  ModbusMaster node;
  uint8_t slaveID;
  uint16_t startAddress;
  uint16_t quantity;
} ModbusSlave;

// Use Serial 2 for communication with rs485 slave
HardwareSerial RS485Serial(2);

// Move this to EEPROM
ModbusSlave slaves[NUM_SLAVES] = {
  {ModbusMaster(), 1, 0, 2},
  {ModbusMaster(), 2, 0, 2},
};

void preTransmission() {
  digitalWrite(MAX485_CTRL_PIN, HIGH);
}

void postTransmission() {
  digitalWrite(MAX485_CTRL_PIN, LOW);
}

void setup() {
  Serial.begin(115200);
  
  pinMode(MAX485_CTRL_PIN, OUTPUT);
  digitalWrite(MAX485_CTRL_PIN, 0);

  RS485Serial.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN);
  
  for (int i = 0; i < NUM_SLAVES; i++) {
    slaves[i].node.begin(slaves[i].slaveID, RS485Serial);
    slaves[i].node.preTransmission(preTransmission);
    slaves[i].node.postTransmission(preTransmission);
  }
}

void loop() {
  static unsigned long lastRead = 0;

  if (millis() - lastRead > 1000) {
    lastRead = millis();
  } else {
    return;
  }

  for (int i = 0; i < NUM_SLAVES; i++) {
    ModbusMaster &node = slaves[i].node;
    Serial.print("Reading from Slave ID "); 
    Serial.println(slaves[i].slaveID);

    uint8_t result = node.readHoldingRegisters(slaves[i].startAddress, slaves[i].quantity);

    Serial.print("Slave ");
    Serial.print(slaves[i].slaveID);
    if (result == node.ku8MBSuccess) {  
      Serial.print(" value: ");
      Serial.println(node.getResponseBuffer(0));
    } else {
      Serial.print(" error: ");
      Serial.println(result);
    }
  } 
}

When debug from slave it print out correctly the temp and hum
When debug from gateway it always print error

Reading from Slave ID 1
Salve 1 error : 226
Reading from Slave ID 2
Salve 2 error : 226

Just a couple of thoughts:

When I've played with RS485 in the past, I've started by sending a single ASCII character in upper case and programming each slave to respond to a specific ASCII character by changing the case of the character as a response. Once I was happy with that, then I expanded the functionality.

I'm pretty sure that the standard MAX485 modules (with the pin organisation as you have drawn) are 5V devices. These should be fine for your Nanos but I don't know about your ESP32. Is the ESP32 5V tolerant. There are other RS485 modules that use a transceiver that will operate at 3.3V.

Ah I see, hmm maybe i try using nano also as gateway instead of esp32

Your connection shows you are using hardware serial pins with Nano. Your code uses softwareserial on pins 3 and 4. That's not matching.

Also, use of esp32 default UART2 rx-pin for tx and default tx-pin for rx is confusing. Should work though..

From my experience those commonly available Max485 modules work reliably powered at 3.3V. No need to abuse your Esp32.

Your connection shows you are using hardware serial pins with Nano. Your code uses softwareserial on pins 3 and 4. That's not matching.

We use hardware serial built in usb to debug in IDE serial monitor. So we can only use software serial for Tx Rx which is in pin 3,4

From my experience those commonly available Max485 modules work reliably powered at 3.3V. No need to abuse your Esp32.

Haven't try this , will test this is easier

Rx Tx.
Ok, but your wiring still shows pins 0 and 1.

I'm pretty sure that the standard MAX485 modules (with the pin organisation as you have drawn) are 5V devices. These should be fine for your Nanos but I don't know about your ESP32. Is the ESP32 5V tolerant. There are other RS485 modules that use a transceiver that will operate at 3.3V.

I test powering max485 with 3.3 it looks online, but the error still the same.

my mistake the draw is not sync with the connection. fix now using 3,4 as RX,TX
The GND now is star connection for nano and esp32, except for max485 is still chain together

Error is still 226

Did you even try the master with only one slave? Without use of ModbusMaster in an array.

For sure this doesn't work :

This is in hex E2.
See the .h of the ModbusMaster Library what 0xE2 means.

ModbusMaster/src/ModbusMaster.h at master · 4-20ma/ModbusMaster · GitHub

--> your slave is not responding.

start with ONE Master and ONE Slave.

If you like the basic idea of the ModbusMaster, you can try my
[Arduino: Noiasca Modbus Server Library (Modbus Slave)]
(Arduino: Noiasca Modbus Server Library (Modbus Slave))

which shares the concept of callbacks like used in the Modbus Master Library.

There are slave examples which will work with master examples.