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

[Solved] Help me to fix error RS485 with ModbusRTU Library

3 Posts
2 Users
0 Reactions
1,740 Views
(@Anonymous)
Joined: 1 second 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 2 years ago by Anonymous

   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2728
 

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: 11 years ago
Posts: 2728
 

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


   
ReplyQuote
Share: