Помогите мне с библиотекой Modbus RTU
В настоящее время я работаю над проектом, в котором я буду отправлять данные датчиков DHT11 и SW420 с использованием модуля RS485 от ведомых устройств 1 и данные датчиков SCT-013 от ведомых устройств 2 (ведомое устройство, использующее Arduino Nano) к ведущему устройству (Arduino Uno). Здесь я использую библиотеку modbus RTU из библиотеки ModbusRTU
Когда я запускаю систему, данные с ведомого устройства 1 не могут быть прочитаны ведущим устройством, в то время как данные с ведомого устройства 2 могут быть прочитаны ведущим устройством.
Я чувствую, что это проблема с указателем, я не понимаю, что такое Modbus, пожалуйста, помогите мне решить эту проблему.
спасибо Фатватул.
МАСТЕР-КОД
// тестовый код arduino mega master
// регистр чтения и записи Modbus RS485
// Версия 1.1
// 1 мастер 2 раб,
// 1 подчиненный: 1 вход 1 выход
#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; //!< состояние машины
uint8_t u8query; //!< указатель на запрос сообщения
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, серийный номер, 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;
////ВЕДОМЫЙ 1
// Считать 1 данные с ведомого устройства 11
telegram[num].u8id = slaveID[0]; // адрес подчиненного устройства
telegram[num].u8fct = 3; // код функции (это чтение регистров)
telegram[num].u16RegAdd = 0; // начальный адрес в слейве
telegram[num].u16CoilsNo = 3; // количество элементов (катушек или регистров) для чтения
telegram[num].au16reg = dataBus; // указатель на массив памяти в Arduino
num += 1;
addr += 2;
//ВЕДОМЫЙ 2
// Чтение 1 данных с ведомого устройства 2
telegram[num].u8id = slaveID[1]; // адрес подчиненного устройства
telegram[num].u8fct = 3; // код функции (это чтение регистров)
telegram[num].u16RegAdd = 0; // начальный адрес в слейве
telegram[num].u16CoilsNo = 4; // количество элементов (катушек или регистров) для чтения
telegram[num].au16reg = dataBus + 3; // указатель на массив памяти в Arduino
num += 1;
addr += 2;
master.start();
master.setTimeOut( 100 ); // если нет ответа в течение 100 мс, перевернуть
u32wait = millis() + 40;
u8state = u8query = 0;
}
void rtuState() {
switch ( u8state ) {
case 0:
if (millis() >= u32wait) u8state++; // состояние ожидания
break;
case 1:
master.query( telegram[u8query] ); // отправляем запрос (только один раз)
u8state++;
u8query++;
if (u8query >= maxQuery)
u8query = 0;
break;
case 2:
master.poll(); // проверяем входящие сообщения, если связь находится в состоянии ожидания
if (master.getState() == COM_IDLE) {
u8state = 0;
u32wait = millis() + delayCom; // задержка для следующего состояния
}
break;
}
}
void printData() {
if (millis() - lastPrint > 200) {
//выводим данные для проверки
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); // воспроизвести тон 550 Гц в фоновом режиме для 'onDuration'
}
}
void major() {
if (millis() - lastPeriodStart >= periodDurationMajor)
{
lastPeriodStart += periodDurationMajor;
tone(speakerPin, 550, onDurationMajor); // воспроизвести тон 550 Гц в фоновом режиме для 'onDuration'
}
}
void critical() {
if (millis() - lastPeriodStart >= periodDurationCritical)
{
lastPeriodStart += periodDurationCritical;
tone(speakerPin, 550, onDurationCritical); // воспроизвести тон 550 Гц в фоновом режиме для 'onDuration'
}
}
void setup() {
Serial.begin (9600); //скорость передачи последовательного ПК
mySerial.begin( 19200 ); // скорость передачи RS485
lcd.begin(16, 2);
lcd.init();
lcd.backlight();
init_modBus();
}
void loop() {
rtuState();
printData();
}
ВЕДОМЫЙ 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;
// массив данных для общего доступа к сети Modbus
uint16_t au16data[4] = {
slaveID, 225, 225, 9999};
Modbus slave(slaveID, mySerial, 4); // это slave @1 и RS-232 или USB-FTDI
void setup() {
Serial.begin(9600);
mySerial.begin( 19200 ); // скорость передачи 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(); //для ультразвукового датчика
}
void readSensor() {
double Irms = emon1.calcIrms(1480);
a = Irms*100;
d = Irms*tegangan;
Arus = a;
Daya = d;
au16data[1] = Arus;
au16data[2] = Daya;
}
ВЕДОМЫЙ 2 (DHT11 и 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;
// массив данных для общего доступа к сети Modbus
uint16_t au16data[5] = {
slaveID, 225, 255,255, 9999
};
Modbus slave(slaveID, mySerial, 4); // это slave @1 и RS-232 или USB-FTDI
void setup() {
Serial.begin(9600);
mySerial.begin( 19200 ); // скорость передачи 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(); //для ультразвукового датчика
}
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; //данные для отправки на ведомое устройство
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;
}
Последовательный монитор от подчиненного устройства 1
Мастер серийного монитора
@FATWATUL M R, 👍-1
0
- Основная связь Arduino ModBus RTU с проблемой измерителя мощности
- Мониторинг контроллера Modbus RTU с помощью Arduino и модуля RS485
- Связь Arduino master/slave с использованием RS485
- Проблема связи Arduino UNO и RS485
- Связь Arduino Uno и ESP32 с использованием RS485
- Управление VFD с помощью ModBus RTU через RS485 и Arduino
- Arduino RS485 shield к датчику температуры и влажности RS485
- Использование Modbus-RTU с Arduino и контроллером температуры