Page 1 of 1
Forum

Welcome to the Tweaking4All community forums!
When participating, please keep the Forum Rules in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
For example “MacOS X – Your question“, or “MS Word – Your Tip or Trick“.

Please note that switching to another language when reading a post will not bring you to the same post, in Dutch, as there is no translation for that post!




Help me to fix erro...
 
Share:
Notifications
Clear all

Help me to fix error RS485 with ModbusRTU Library

3 Posts
2 Users
0 Likes
809 Views
Joined: 53 years ago
Posts: 0
Topic starter  

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 https://github.com/smarmengol/Modbus-Master-Slave-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. 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. 

Here is the code for the master and each slave.
MASTER(CODE 1, just receive data form slave)

// 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 (Sent 1  sensor data to master)

#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 (Sent 3 sensor 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

This topic was modified 7 months ago by

   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 10 years ago
Posts: 2460
 

This seems like a quite specific debugging issue.
My first test would be to have the code for slave 2 stick with a different value (not zero).
See if that even reaches the master. 
This way you can see where you need to look for debugging.


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 10 years ago
Posts: 2460
 

p.s. updated the github link, since it failed as the period was included in the link 😊 


   
ReplyQuote

Like what you see and you'd like to help out? 

The best way to help is of course by assisting others with their questions here in the forum, but you can also help us out in other ways:

- Do your shopping at Amazon, it will not cost you anything extra but may generate a small commission for us,
- send a cup of coffee through PayPal ($5, $10, $20, or custom amount),
- become a Patreon,
- donate BitCoin (BTC), or BitCoinCash (BCH).

Share: