Hi all..
I'm currently working on a project where I will send DHT11 and SW420 sensor data use RS485 Module from slaves 1 and 2 (using Arduino Nano) to the master (Arduino Uno). Here I use the modbus RTU library from GitHub - smarmengol/Modbus-Master-Slave-for-Arduino: Modbus Master-Slave library for Arduino.
When I try to use 1 slave, the data is successfully sent to the master. However, when I try to use 2 slaves, the data from the 2nd slave cannot be received by the master.
Can anyone provide a solution or suggestion regarding my problem?
MASTER
#include <Wire.h>
#include <ModbusRtu.h>
#define slaveNumber 5
#define delayCom 15
#define maxQuery 2*2//slaveNumer*2
#include <SoftwareSerial.h>
//#include <LiquidCrystal_I2C.h>
SoftwareSerial mySerial(2, 3);
//LiquidCrystal_I2C lcd(0x27,16,2);
uint8_t u8state; //!< machine state
uint8_t u8query; //!< pointer to message query
uint16_t dataBus[slaveNumber*5];
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,4); // 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 = 5; // 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 = 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+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 = 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;
// 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){
//print data to validate
Serial.print(dataBus[0]); Serial.print(":");
Serial.print(dataBus[1]); Serial.print(":");
Serial.print(dataBus[2]); Serial.print(":");
Serial.print(dataBus[3]); Serial.print(":");
Serial.print(dataBus[4]); Serial.print("\t:\t");
Serial.print(dataBus[5]); Serial.print(":");
Serial.print(dataBus[6]); Serial.print(":");
Serial.print(dataBus[7]); Serial.print(":");
Serial.print(dataBus[8]); Serial.print(":");
Serial.print(dataBus[9]);
Serial.println();
}
}
void processData(){
//data to be sent so slave 1 based on slave 2 data
dataBus[4] = dataBus[4]*0.25; //convert 1023 to 255
//data to be sent so slave 2 based on slave 1 data
dataBus[8] = dataBus[1]*0.25;
}
void setup() {
Serial.begin (9600); //baud rate of Serial PC
mySerial.begin( 19200 ); // baud-rate of RS485
init_modBus();
}
void loop() {
rtuState();
printData();
processData();
}
SLAVE 1 & 2 ( only different slave ID
#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[6] = {
slaveID, 225, 255,255, 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, 6 );
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.print(":");
Serial.print(au16data[4]); 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;
}
Result (Left : Slave1, Right : Master) :