Help me to fix error RS485 with ModbusRTU Library

Hi...here I'm finishing a project. In this project I made a server room monitoring system using 2 slaves (slave 1 sent 1 sensor data and slave 2 sent 3 sensor data) using Arduino Nano to the master (Wemos D1 ESP8266). Here I use the max485 ttl to rs485 converter module and the modbusRtu Library from GitHub - smarmengol/Modbus-Master-Slave-for-Arduino: Modbus Master-Slave library for Arduino.

Here I have 2 examples of the master code that I made, the first slave code only sends data and the master prints data on the serial monitor. In this first code all slaves can be read by sensors. (results can be seen in the image below)

Then I developed the feature on the master by connecting to Telegram. Here I managed to connect the system to Telegram and Telegram was able to send messages as requested, but in this 2nd code, data from slave 2 could not be read and data that was successfully read when sent to Telegram still had a value of 0. (as shown below)

Here is the code for the master and each slave.
MASTER (Code 1)

// arduino mega master testing code
// modbus RS485 read and write register
// V1.1

// 1 master 2 slave,
// 1 slave : 1 input 1 output

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

#include <Wire.h>
#include <ModbusRtu.h>
#define slaveNumber 5
#define delayCom 15
#define maxQuery 2*2//slaveNumer*2
#define RX D3
#define TX D4
#define RTS D8
#include <SoftwareSerial.h>
//#include <LiquidCrystal_I2C.h>
SoftwareSerial mySerial(RX, TX);
//LiquidCrystal_I2C lcd(0x27,16,2);

char ssid[] = "BATU";     // diisi nama wifi
char password[] = "estehmanis";
WiFiClientSecure client;

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

uint16_t dataBus[7];
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, RTS); // 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;


  //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 = 5; // 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;


  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) {
    //print data to validate
//    Serial.print("Slave:");Serial.println(dataBus[0]);
//    Serial.print("Arus:");Serial.println(dataBus[1]);
//    Serial.print("Slave:");Serial.println(dataBus[3]);
//    Serial.print("Suhu:");Serial.println(dataBus[4]);
//    Serial.print("Kelembapan:");Serial.println(dataBus[5]);
//    Serial.print("Getaran:");Serial.println(dataBus[6]);
    Serial.print(dataBus[0]); Serial.print(":");
    Serial.print(dataBus[1]); Serial.print(":");
    Serial.print(dataBus[2]); Serial.print("\t:\t");
    Serial.print(dataBus[3]); Serial.print(":");
    Serial.print(dataBus[4]); Serial.print(":");
    Serial.print(dataBus[5]); Serial.print(":");
    Serial.print(dataBus[6]);
    Serial.println();
  }
}

void setup() {
  Serial.begin (9600); //baud rate of Serial PC
  mySerial.begin( 19200 ); // baud-rate of RS485
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);
  Serial.print("Connecting Wifi: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  
  Serial.println("");
  Serial.println("WiFi terhubung");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  init_modBus();
}

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

MASTER (Code 2 with Telegram)

// arduino mega master testing code
// modbus RS485 read and write register
// V1.1

// 1 master 2 slave,
// 1 slave : 1 input 1 output

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

#include <Wire.h>
#include <ModbusRtu.h>
#define slaveNumber 5
#define delayCom 15
#define maxQuery 2*2//slaveNumer*2
#define RX D3
#define TX D4
#define RTS D8
#include <SoftwareSerial.h>
//#include <LiquidCrystal_I2C.h>
SoftwareSerial mySerial(RX, TX);
//LiquidCrystal_I2C lcd(0x27,16,2);

const long utcOffsetInSeconds = 3600 * 7; //timer
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);
char daysOfTheWeek[7][12] = {"Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"};

char ssid[] = "BATU";     // diisi nama wifi
char password[] = "estehmanis";

#define BOTtoken "5404730433:AAFjsIjfVkY9IdEfhi2wOK59J_pFTAbMNKo" // diisi Token Bot (Dapat dari Telegram Botfather)
#define idChat "-1001841459091" //idbot

//int botRequestDelay = 1000;
unsigned long lastTimeBotRan;

WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);
uint8_t u8state; //!< machine state
uint8_t u8query; //!< pointer to message query

uint16_t dataBus[7];
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, RTS); // 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;

  //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 = 4; // 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;

  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) {
    //print data to validate
    Serial.print(dataBus[0]); Serial.print(":");
    Serial.print(dataBus[1]); Serial.print(":");
    Serial.print(dataBus[2]); Serial.print("\t:\t");
    Serial.print(dataBus[3]); Serial.print(":");
    Serial.print(dataBus[4]); Serial.print(":");
    Serial.print(dataBus[5]); Serial.print(":");
    Serial.print(dataBus[6]);
    Serial.println();
  }
}

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

  client.setInsecure();
  uint32_t notConnectedCounter = 0;

  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);

  Serial.print("Connecting Wifi: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  Serial.println("");
  Serial.println("WiFi terhubung");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  init_modBus();
}

void loop() {
  rtuState();
  printData();
  peringatan();
  //processData();
}

void peringatan() {
  timeClient.update();
  Serial.print("Suhu saat ini : ");
  Serial.print(dataBus[2]);
  Serial.println(" *C\n");
  Serial.print("Kelembapan saat ini : ");
  Serial.print(dataBus[5]);
  Serial.println("%");
  Serial.print("Getaran saat ini : ");
  Serial.print(dataBus[6]);
  Serial.println();
  //
  //  if (timeClient.getHours() <= 9) {lcd.print("0");}
  //  if (timeClient.getMinutes() <= 9) {lcd.print("0");}
  //  if (timeClient.getSeconds() <= 9) {lcd.print("0");}

  if (timeClient.getHours() == 20 and timeClient.getMinutes() == 50 and timeClient.getSeconds() <= 15) {
    bot.sendChatAction(idChat, "Sedang mengetik...");

    String suhu = "KONDISI SUHU DAN KELEMBAPAN SAAT INI\n";
    suhu += "\nHari :  ";
    suhu += daysOfTheWeek[timeClient.getDay()];
    suhu += "\nPukul :  ";
    suhu += timeClient.getHours();
    suhu += ":";
    suhu += timeClient.getMinutes();
    suhu += ":";
    suhu += timeClient.getSeconds();
    suhu += " WIB";
    suhu += "\nSuhu : ";
    suhu += int(dataBus[2]);
    suhu += " *C\n";
    suhu += "Kelembapan : ";
    suhu += int(dataBus[5]);
    suhu += " %\n";
    suhu += "Getaran : ";
    suhu += int(dataBus[6]);

    bot.sendMessage(idChat, suhu, "");
    Serial.print("Mengirim data sensor ke telegram\n");
  }

  if (timeClient.getHours() == 21 and timeClient.getMinutes() == 00 and timeClient.getSeconds() <= 15) {
    bot.sendChatAction(idChat, "Sedang mengetik...");

    String suhu = "KONDISI SUHU DAN KELEMBAPAN SAAT INI\n";
    suhu += "\nHari :  ";
    suhu += daysOfTheWeek[timeClient.getDay()];
    suhu += "\nPukul :  ";
    suhu += timeClient.getHours();
    suhu += ":";
    suhu += timeClient.getMinutes();
    suhu += ":";
    suhu += timeClient.getSeconds();
    suhu += " WIB";
    suhu += "\nSuhu : ";
    suhu += int(dataBus[2]);
    suhu += " *C\n";
    suhu += "Kelembapan : ";
    suhu += int(dataBus[5]);
    suhu += " %\n";
    suhu += "Getaran : ";
    suhu += int(dataBus[6]);

    bot.sendMessage(idChat, suhu, "");
    Serial.print("Mengirim data sensor ke telegram\n");
  }

  if (dataBus[2] < 18) {
    if (timeClient.getMinutes() == 30 or timeClient.getMinutes() == 0) {
      bot.sendChatAction(idChat, "Sedang mengetik...");

      String suhu = "SUHU RUANGAN RENDAH\n";
      suhu += "\nHari :  ";
      suhu += daysOfTheWeek[timeClient.getDay()];
      suhu += "\n Pukul :  ";
      suhu += timeClient.getHours();
      suhu += ":";
      suhu += timeClient.getMinutes();
      suhu += ":";
      suhu += timeClient.getSeconds();
      suhu += " WIB";
      suhu += "Suhu : ";
      suhu += int(dataBus[2]);
      suhu += " *C\n";

      bot.sendMessage(idChat, suhu, "");
      Serial.print("Mengirim data sensor ke telegram\n");
    }
  }

  if (dataBus[5] < 40) {
    if (timeClient.getMinutes() == 30 or timeClient.getMinutes() == 0) {
      bot.sendChatAction(idChat, "Sedang mengetik...");

      String suhu = "KELEMBAPAN RUANGAN RENDAH\n";
      suhu += "\nHari :  ";
      suhu += daysOfTheWeek[timeClient.getDay()];
      suhu += "\nPukul :  ";
      suhu += timeClient.getHours();
      suhu += ":";
      suhu += timeClient.getMinutes();
      suhu += ":";
      suhu += timeClient.getSeconds();
      suhu += " WIB";
      suhu += "Kelembapan : ";
      suhu += int(dataBus[5]);
      suhu += " %\n";

      bot.sendMessage(idChat, suhu, "");
      Serial.print("Mengirim data sensor ke telegram\n");
    }
  }

  if (dataBus[2] > 27) {
    if (timeClient.getMinutes() == 5 or timeClient.getMinutes() == 10 or timeClient.getMinutes() == 15 or timeClient.getMinutes() == 20 or timeClient.getMinutes() == 25 or timeClient.getMinutes() == 30 or timeClient.getMinutes() == 35 or timeClient.getMinutes() == 40 or timeClient.getMinutes() == 45 or timeClient.getMinutes() == 50 or timeClient.getMinutes() == 55 or timeClient.getMinutes() == 0) {
      if (timeClient.getSeconds() <= 15) {
        bot.sendChatAction(idChat, "Sedang mengetik...");

        String suhu = "SUHU RUANGAN TINGGI\n";
        suhu += "\nHari :  ";
        suhu += daysOfTheWeek[timeClient.getDay()];
        suhu += "\nPukul :  ";
        suhu += timeClient.getHours();
        suhu += ":";
        suhu += timeClient.getMinutes();
        suhu += ":";
        suhu += timeClient.getSeconds();
        suhu += " WIB";
        suhu += "\nSuhu : ";
        suhu += int(dataBus[2]);
        suhu += " *C\n";

        bot.sendMessage(idChat, suhu, "");
        Serial.print("Mengirim data sensor ke telegram\n");
      }
    }
  }

  if (dataBus[5] > 60) {
    if (timeClient.getMinutes() == 5 or timeClient.getMinutes() == 10 or timeClient.getMinutes() == 15 or timeClient.getMinutes() == 20 or timeClient.getMinutes() == 25 or timeClient.getMinutes() == 30 or timeClient.getMinutes() == 35 or timeClient.getMinutes() == 40 or timeClient.getMinutes() == 45 or timeClient.getMinutes() == 50 or timeClient.getMinutes() == 55 or timeClient.getMinutes() == 0) {
      if (timeClient.getSeconds() <= 15) {
        bot.sendChatAction(idChat, "Sedang mengetik...");

        String suhu = "KELEMBAPAN RUANGAN TINGGI\n";
        suhu += "\nHari :  ";
        suhu += daysOfTheWeek[timeClient.getDay()];
        suhu += "\nPukul :  ";
        suhu += timeClient.getHours();
        suhu += ":";
        suhu += timeClient.getMinutes();
        suhu += ":";
        suhu += timeClient.getSeconds();
        suhu += " WIB";
        suhu += "\nKelembapan : ";
        suhu += int(dataBus[5]);
        suhu += " %\n";

        bot.sendMessage(idChat, suhu, "");
        Serial.print("Mengirim data sensor ke telegram\n");
      }
    }
  }

}                           

SLAVE 1 (send 1 data)

#include <ModbusRtu.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
#include <DHT.h>

#define slaveID 11
#define DHTPIN 7
#define DHTTYPE DHT11
int SWPIN=8;
DHT dht(DHTPIN,DHTTYPE);
int t;
int h;
int g;


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
  dht.begin();
  pinMode (SWPIN, INPUT);
  slave.start();
  delay(10);
}

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();
  }
  readSensor(); //for ultrasonic sensor
}

//long vibration(){
//  long g=pulseIn (SWPIN, HIGH);
//  return g;
//}
void readSensor() {
  t = dht.readTemperature();
  h = dht.readHumidity();

  if (isnan(h) || isnan (t)){
    au16data[1] = 0;
  }
  
  Suhu = t;
  au16data[1] = Suhu; //data to be sent to slave device
  
}

SLAVE 2 (Send 3 data to master)

#include <ModbusRtu.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
#include <DHT.h>

#define slaveID 12
#define DHTPIN 7
#define DHTTYPE DHT11
int SWPIN=8;
DHT dht(DHTPIN,DHTTYPE);
int t;
int h;
int g;


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[5] = {
  slaveID, 225, 255,255, 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
  dht.begin();
  pinMode (SWPIN, INPUT);
  slave.start();
  delay(10);
}

void loop() {
  slave.poll( au16data, 5 );
  if (millis() - lastPrint > 200) {
    Serial.print(au16data[0]); Serial.print(":");
    Serial.print(au16data[1]); Serial.print(":");
    Serial.print(au16data[2]); Serial.print(":");
    Serial.print(au16data[3]); Serial.println();
    lastPrint = millis();
  }
  readSensor(); //for ultrasonic sensor
}

long vibration(){
  long g=pulseIn (SWPIN, HIGH);
  return g;
}
void readSensor() {
  t = dht.readTemperature();
  h = dht.readHumidity();
  g = vibration();
  cekGetar();

  if (isnan(h) || isnan (t)){
    au16data[1] = 0;
    au16data[2] = 0;
  }
  
  Suhu = t;
  Lembab = h;
  au16data[1] = Suhu; //data to be sent to slave device
  au16data[2] = Lembab;
  au16data[3] = Getar;
  
}

void cekGetar(){
  if (g==0){
    Getar = 0;
  }
  if (g>0 && g<=1000){
    Getar = 1;
  }
  if (g>1000 && g<=10000){
    Getar = 2;
  }
  if (g>10000){
    Getar = 3;
  }
  return Getar;
}

I hope someone can help me because I'm being chased by having a deadline of 3 days :(.

Thanks,
Fatwatul

That's probably for the Nano, but what module do you use for the ESP8266 as the 5V of that module are too high for the ESP?

Never post text information as images!

Maybe read but definitely not displayed. And as in your other thread you did the pointer arithmetic wrong. Please don't use that and allocated separate arrays for the two Modbus requests you make. The code you use will write over boundaries, so expect it to be unreliable.

As you did the same error in your second sketch (Telegram) you might just see the strange symptoms such errors may result in.

Just opening another thread without fixing the error I showed you already doesn't help to catch the deadline.

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