Modbus RTU RS485 Multislave

hello!
i am looking for some help with a project,the project I'm currently working on using

  • Arduino Mega (MASTER)
  • Arduino Nano (SLAVE) with SW420 (Vibration Sensor) and DHT11 (Temperature and Humidity Sensor) (2)
  • Max485 Ttl To Rs485 Converter Module (3)

pin configuration:

Master :
MASTER (Arduino Mega):
RS485 Module

  • Pin A,B Master to A,B Slave
  • VCC Ground to 5V and Ground
  • Pin DE,RE to Pin 2
  • Pin RO to Pin 11
  • Pin DI to Pin 12

SLAVE (Arduino Nano):
RS485 Module

  • Pin A,B Master to A,B Slave
  • VCC Ground to 5V and Ground
  • Pin DE,RE to Pin D4
  • Pin RO to Pin D3
  • Pin DI to Pin D2

DHT11

  • VCC Ground to 5V and Ground
  • Pin Data to Pin D8

SW420

  • VCC Ground to 5V and Ground
  • Pin Data to Pin D9

Here I try to use the Modbus RTU Library.
I've been trying this for 3 weeks :frowning: But, the result is still the same still can't send data. What's wrong with my code or the microcontroller or what?

Here is the code and the result

MASTER

#include <ModbusRtu.h>
#define slaveNumber 5
#define delayCom 15
#define maxQuery 2*2//slaveNumer*2
#include <SoftwareSerial.h>
SoftwareSerial mySerial(11,12);


uint8_t u8state; //!< machine state
uint8_t u8query; //!< pointer to message query

uint16_t dataBus[slaveNumber*2];
uint16_t lastPrint=100;
int slaveID[slaveNumber] = {11,12,13,14,15};
/**
 *  Modbus object declaration
 *  u8id : node id = 0 for master, = 1..247 for slave
 *  port : Serial1 port
 *  u8txenpin : 0 for RS-232 and USB-FTDI 
 *               or any pin number > 1 for RS-485
 */
Modbus master(0,mySerial,2); // ID, seriapNumber, enablePin

/**
 * This is an structe which contains a query to an slave device
 */
modbus_t telegram[slaveNumber*2];

unsigned long u32wait;

void init_modBus(){
  int num=0;
  int addr=0;
////SLAVE 1
  // Read 1 data from Slave 11
  telegram[num].u8id = slaveID[0]; // slave address
  telegram[num].u8fct = 3; // function code (this one is registers read)
  telegram[num].u16RegAdd = 0; // start address in slave
  telegram[num].u16CoilsNo = 2; // number of elements (coils or registers) to read
  telegram[num].au16reg = dataBus; // pointer to a memory array in the Arduino
  num+=1;
  addr+=2;
  
  // Write 1 data to Slave 11
  telegram[num].u8id = slaveID[0]; // slave address
  telegram[num].u8fct = 6; // function code (this one is write a multiple register)
  telegram[num].u16RegAdd = 2; // start address in slave
  telegram[num].u16CoilsNo = 1; // number of elements (coils or registers) to write
  telegram[num].au16reg = dataBus+2; // pointer to a memory array in the Arduino
  num+=1;
  addr+=1;
//
////SLAVE 2
//  // Read 1 data from Slave 2
//  telegram[num].u8id = slaveID[1]; // slave address
//  telegram[num].u8fct = 3; // function code (this one is registers read)
//  telegram[num].u16RegAdd = 0; // start address in slave
//  telegram[num].u16CoilsNo = 2; // number of elements (coils or registers) to read
//  telegram[num].au16reg = dataBus+3; // pointer to a memory array in the Arduino
//  num+=1;
//  addr+=2;
//  
//  // Write 1 data to Slave 2
//  telegram[num].u8id = slaveID[1]; // slave address
//  telegram[num].u8fct = 16; // function code (this one is write a multiple register)
//  telegram[num].u16RegAdd = 2; // start address in slave
//  telegram[num].u16CoilsNo = 1; // number of elements (coils or registers) to write
//  telegram[num].au16reg = dataBus+5; // pointer to a memory array in the Arduino
//  num+=1;
//  addr+=1;

  master.start();
  master.setTimeOut( 100 ); // if there is no answer in 100 ms, roll over
  u32wait = millis() + 40;
  u8state = u8query = 0; 
  
}

void rtuState(){
  switch( u8state ) {
  case 0: 
    if (millis() >= u32wait) u8state++; // wait state
    break;
  case 1: 
    master.query( telegram[u8query] ); // send query (only once)
    u8state++;
    u8query++;
    if (u8query >= maxQuery) 
      u8query = 0;
    break;
  case 2:
    master.poll(); // check incoming messages if communication in idle state
    if (master.getState() == COM_IDLE) {
      u8state = 0;
      u32wait = millis() + delayCom;  //delay for next state
    }
    break;
  }
}
void printData(){
  if (millis() - lastPrint>200){
    Serial.print(dataBus[0]); Serial.print(":");
    Serial.print(dataBus[1]); Serial.print(":");
    Serial.print(dataBus[2]); Serial.print("\t:\t");
    Serial.println();
  }
}

void setup() {
  Serial.begin (9600); //baud rate of Serial PC
  mySerial.begin(19200); // baud-rate of RS485
  init_modBus();
}

void loop() {
  rtuState();
  printData();
}

SLAVE

//SLAVE MENGIRIM DATA DETAK JANTUNG//
#include <ModbusRtu.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
#include "DHT.h"
 
#define slaveID 11
//#define trigPin 9
//#define echoPin 10//CARI EN PIN NOMOR BERAPA
#define DHTPIN 8
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

int vs=9; //pin vibration
uint16_t suhu =0;
uint16_t lembab=0;
uint16_t getar=0;
unsigned long lastPrint=0;

// data array for modbus network sharing
uint16_t au16data[4] = {
  slaveID, 225, 8888,9999};

Modbus slave(slaveID,mySerial,4); // this is slave @1 and RS-232 or USB-FTDI

void setup() {
  Serial.begin(9600);
  mySerial.begin( 19200 ); // baud-rate at 19200
  slave.start();
  delay(10);
  dht.begin();
}

void loop() {
  slave.poll( au16data, 4 );
  if (millis() - lastPrint>200){
    Serial.print(au16data[0]); Serial.print(":");
    Serial.print(au16data[1]); Serial.print(":");
    Serial.print(au16data[2]); Serial.println();
    lastPrint = millis();
  }
  suhu = dht.readHumidity();
  au16data[1] = suhu;
}

Result

Are there any suggestions for what I can do and references I should study?

What basic testing did you do on your setup?

I would forget Modbus for now and simply print a few characters from the master and see if your slaves can receive them. Then i would make each slave the mater and repeat the process checking out the low level basics first.

I would highly recommend you get an RS485-USB dongle too so you can look at the actual data on you RS485 bus.

And, by Arduino Mega, did you mean a MEGA2560 based board?

A SoftwareSerial is not really useful in your project.

A Mega has enough hardware Serial ports, no need to use SoftwareSerial on your master.

Previously I used "Serial1" and I tried to use SoftwareSerial but still can't

Try a Mega and hardware Serial for both master and slave. If that doesn't work for you, too, then start searching for other problems in your code and hardware.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.