-1

I'm currently working on a project where I will send DHT11 and SW420 sensor data use RS485 Module from slaves 1 and SCT-013 sensor data from slave 2 (slave using Arduino Nano) to the master (Arduino Uno). Here I use the modbus RTU library from ModbusRTU Library

When I run the system, the data from slave 1 cannot be read by the master while the data on slave 2 can be read by the master.

I feel this is problem in pointer, I don't understand about modbus, please help me to solve this problem.

thanks Fatwatul.

MASTER CODE

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

// 1 master 2 slave,
// 1 slave : 1 input 1 output
#include <Wire.h>
#include <ModbusRtu.h>
#define slaveNumber 2
#define delayCom 15
#define maxQuery 8//slaveNumer*2
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
SoftwareSerial mySerial(2, 3);
int lcdColumns = 16;
int lcdRows = 2;
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);

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

uint16_t dataBus[8];
uint16_t lastPrint = 100;
int slaveID[slaveNumber] = {11, 12};

const byte speakerPin = 9;
unsigned long lastPeriodStart;
const int onDurationMinor = 500;
const int periodDurationMinor = 5000;
const int onDurationMajor = 500;
const int periodDurationMajor = 1000;
const int onDurationCritical = 250;
const int periodDurationCritical = 500;

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 = 3; // 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();
  }

  String Arus = String(dataBus[1]);
  String Daya = String(dataBus[2]);
  String Suhu = String(dataBus[4]);
  String Lembab = String(dataBus[5]);
  String Getar = String(dataBus[6]);
  lcd.setCursor(0, 0);
  lcd.print(Arus);
  lcd.print(":");
  lcd.print(Daya);
  lcd.setCursor(0, 1);
  lcd.print(Suhu);
  lcd.print(":");
  lcd.print(Lembab);
  lcd.print(":");
  lcd.print(Getar);
}

void minor() {
  if (millis() - lastPeriodStart >= periodDurationMinor)
  {
    lastPeriodStart += periodDurationMinor;
    tone(speakerPin, 550, onDurationMinor); // play 550 Hz tone in background for 'onDuration'
  }
}

void major() {
  if (millis() - lastPeriodStart >= periodDurationMajor)
  {
    lastPeriodStart += periodDurationMajor;
    tone(speakerPin, 550, onDurationMajor); // play 550 Hz tone in background for 'onDuration'
  }
}

void critical() {
  if (millis() - lastPeriodStart >= periodDurationCritical)
  {
    lastPeriodStart += periodDurationCritical;
    tone(speakerPin, 550, onDurationCritical); // play 550 Hz tone in background for 'onDuration'
  }
}

void setup() {
  Serial.begin (9600); //baud rate of Serial PC
  mySerial.begin( 19200 ); // baud-rate of RS485
  lcd.begin(16, 2);
  lcd.init();
  lcd.backlight();
  init_modBus();
}

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

SLAVE 1 (SCT-013)

#include <ModbusRtu.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
#include <Wire.h>
#include "EmonLib.h"

#define slaveID 11
#define SCT_PIN 1
EnergyMonitor emon1;
int tegangan = 220.0;

int a;
int d;

uint16_t Arus = 0;
uint16_t Daya = 0;
unsigned long lastPrint = 0;

// data array for modbus network sharing
uint16_t au16data[4] = {
  slaveID, 225, 225, 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
  emon1.current(SCT_PIN, 60);
  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
}

void readSensor() {
  double Irms = emon1.calcIrms(1480);
  a = Irms*100;
  d = Irms*tegangan;
  
  Arus = a;
  Daya = d;
  au16data[1] = Arus;
  au16data[2] = Daya;
}

SLAVE 2 (DHT11 and SW420)

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

#define slaveID 12
#define DHTPIN 7
#define SWPIN 8
#define DHTTYPE DHT11

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;
}

Serial Monitor from Slave 1 Slave 1

Serial Monitor Master Master

New contributor
FATWATUL M R is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

0

Your Answer

FATWATUL M R is a new contributor. Be nice, and check out our Code of Conduct.

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.