mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-26 22:22:16 +03:00
test ModBusAsync
This commit is contained in:
@@ -19,8 +19,8 @@ int8_t MODBUS_DIR_PIN = 0;
|
|||||||
|
|
||||||
// bool modBus_data_ready = false;
|
// bool modBus_data_ready = false;
|
||||||
uint32_t modBus_Token_count = 0; // Счетчик токенов для Нод, 0 - всегду у главного класса, дальше по порядку
|
uint32_t modBus_Token_count = 0; // Счетчик токенов для Нод, 0 - всегду у главного класса, дальше по порядку
|
||||||
//class ModbusNode;
|
class ModbusNode;
|
||||||
std::map<uint32_t, IoTItem *> MBNoneMap;
|
std::map<uint32_t, ModbusNode *> MBNoneMap;
|
||||||
ModbusClientRTU *MB = nullptr;
|
ModbusClientRTU *MB = nullptr;
|
||||||
|
|
||||||
ModbusClientRTU *instanceModBus(int8_t _DR)
|
ModbusClientRTU *instanceModBus(int8_t _DR)
|
||||||
@@ -38,6 +38,136 @@ ModbusClientRTU *instanceModBus(int8_t _DR)
|
|||||||
// ModbusClientRTU MB(_DIR_PIN);
|
// ModbusClientRTU MB(_DIR_PIN);
|
||||||
// ModbusClientRTU MB();
|
// ModbusClientRTU MB();
|
||||||
|
|
||||||
|
class ModbusNode : public IoTItem
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// Initialize the ModbusMaster object as node
|
||||||
|
// Инициализируем объект ModbusMaster как узел
|
||||||
|
|
||||||
|
uint8_t _addr = 0; // Адрес слейва от 1 до 247
|
||||||
|
String _regStr = ""; // Адрес регистра который будем дергать ( по коду от 0х0000 до 0х????)
|
||||||
|
String _funcStr = ""; // Функция ModBUS
|
||||||
|
uint8_t _func;
|
||||||
|
uint16_t _reg = 0;
|
||||||
|
uint8_t _countReg = 1;
|
||||||
|
uint32_t _token = 0;
|
||||||
|
bool _isFloat = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ModbusNode(String parameters) : IoTItem(parameters)
|
||||||
|
{
|
||||||
|
_addr = jsonReadInt(parameters, "addr"); // адреса slave прочитаем с веба
|
||||||
|
jsonRead(parameters, "reg", _regStr); // адреса регистров прочитаем с веба
|
||||||
|
jsonRead(parameters, "func", _funcStr); // Функция ModBUS
|
||||||
|
jsonRead(parameters, "isFloat", _isFloat);
|
||||||
|
_countReg = jsonReadInt(parameters, "count");
|
||||||
|
_func = hexStringToUint8(_funcStr);
|
||||||
|
_reg = hexStringToUint16(_regStr);
|
||||||
|
modBus_Token_count++;
|
||||||
|
_token = modBus_Token_count;
|
||||||
|
MBNoneMap[_token] = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doByInterval()
|
||||||
|
{
|
||||||
|
if (!MB)
|
||||||
|
{
|
||||||
|
Serial.printf("ModbusNode: ModbusClientAsync is NULL\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_func == 0x04) // vout = mb.readInputRegisters(1, "0х0000", 1, 0) - "Адрес","Регистр","Кличество регистров"
|
||||||
|
{
|
||||||
|
// val.valD = readFunctionModBus(0x04, _addr, _reg, count, isFloat);
|
||||||
|
Serial.printf("sending request with token %d\n", _token);
|
||||||
|
Error err;
|
||||||
|
err = MB->addRequest(_token, _addr, READ_INPUT_REGISTER, _reg, _countReg);
|
||||||
|
if (err != SUCCESS)
|
||||||
|
{
|
||||||
|
ModbusError e(err);
|
||||||
|
Serial.printf("Error creating request: %02X - %s\n", (int)e, (const char *)e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (_func == 0x03) // vout = mb.readHoldingRegisters(1, "0х0000", 2, 1) - "Адрес","Регистр","Кличество регистров"
|
||||||
|
{
|
||||||
|
Serial.printf("sending request with token %d\n", _token);
|
||||||
|
Error err;
|
||||||
|
err = MB->addRequest(_token, _addr, READ_HOLD_REGISTER, _reg, _countReg);
|
||||||
|
if (err != SUCCESS)
|
||||||
|
{
|
||||||
|
ModbusError e(err);
|
||||||
|
Serial.printf("Error creating request: %02X - %s\n", (int)e, (const char *)e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (_func == 0x01) // vout = mb.readCoils(1, \"0х0000\", 1) - "Адрес","Регистр","Кличество бит"
|
||||||
|
{
|
||||||
|
Serial.printf("sending request with token %d\n", _token);
|
||||||
|
Error err;
|
||||||
|
err = MB->addRequest(_token, _addr, READ_COIL, _reg, _countReg);
|
||||||
|
if (err != SUCCESS)
|
||||||
|
{
|
||||||
|
ModbusError e(err);
|
||||||
|
Serial.printf("Error creating request: %02X - %s\n", (int)e, (const char *)e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (_func == 0x02) // vout = mb.readDiscreteInputs(1, \"0х0000\", 1) - "Адрес","Регистр","Кличество бит"
|
||||||
|
{
|
||||||
|
Serial.printf("sending request with token %d\n", _token);
|
||||||
|
Error err;
|
||||||
|
err = MB->addRequest(_token, _addr, READ_DISCR_INPUT, _reg, _countReg);
|
||||||
|
if (err != SUCCESS)
|
||||||
|
{
|
||||||
|
ModbusError e(err);
|
||||||
|
Serial.printf("Error creating request: %02X - %s\n", (int)e, (const char *)e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseMB(ModbusMessage response)
|
||||||
|
{
|
||||||
|
if (MB)
|
||||||
|
{
|
||||||
|
if (_func == 0x02) // coil
|
||||||
|
{
|
||||||
|
uint16_t val;
|
||||||
|
response.get(3, val);
|
||||||
|
regEvent(val, "ModbusNode");
|
||||||
|
CoilData cd(_countReg);
|
||||||
|
cd.set(0, _countReg, (uint8_t *)response.data() + 3);
|
||||||
|
cd.print("Received : ", Serial);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_countReg == 2 && _isFloat)
|
||||||
|
{
|
||||||
|
float val;
|
||||||
|
response.get(3, val);
|
||||||
|
regEvent(val, "ModbusNode");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_countReg == 2)
|
||||||
|
{
|
||||||
|
uint16_t val1, val2;
|
||||||
|
response.get(3, val1);
|
||||||
|
response.get(4, val2);
|
||||||
|
long val = val1 | val2 << 16;
|
||||||
|
regEvent(val, "ModbusNode");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint16_t val;
|
||||||
|
response.get(3, val);
|
||||||
|
regEvent(val, "ModbusNode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~ModbusNode() {};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Define an onData handler function to receive the regular responses
|
// Define an onData handler function to receive the regular responses
|
||||||
// Arguments are received response message and the request's token
|
// Arguments are received response message and the request's token
|
||||||
void handleModBusData(ModbusMessage response, uint32_t token)
|
void handleModBusData(ModbusMessage response, uint32_t token)
|
||||||
@@ -53,10 +183,11 @@ void handleModBusData(ModbusMessage response, uint32_t token)
|
|||||||
// uint16_t offs = 3;
|
// uint16_t offs = 3;
|
||||||
// // The device has values all as IEEE754 float32 in two consecutive registers
|
// // The device has values all as IEEE754 float32 in two consecutive registers
|
||||||
// offs = response.get(offs, values[i]);
|
// offs = response.get(offs, values[i]);
|
||||||
uint16_t val;
|
// uint16_t val;
|
||||||
response.get(3, val);
|
// response.get(3, val);
|
||||||
if(MBNoneMap[token]){
|
if (MBNoneMap[token])
|
||||||
MBNoneMap[token]->regEvent(val,"ModMusNode resposne");
|
{
|
||||||
|
MBNoneMap[token]->parseMB(response);
|
||||||
}
|
}
|
||||||
// modBus_data_ready = true;
|
// modBus_data_ready = true;
|
||||||
}
|
}
|
||||||
@@ -83,7 +214,7 @@ private:
|
|||||||
int _addr = 0; // Адрес слейва от 1 до 247 ( вроде )
|
int _addr = 0; // Адрес слейва от 1 до 247 ( вроде )
|
||||||
String _regStr = ""; // Адрес регистра который будем дергать ( по коду от 0х0000 до 0х????)
|
String _regStr = ""; // Адрес регистра который будем дергать ( по коду от 0х0000 до 0х????)
|
||||||
uint16_t _reg = 0;
|
uint16_t _reg = 0;
|
||||||
bool _debug; // Дебаг
|
bool _debug; // Дебаг
|
||||||
uint32_t _token = 0; // Токен у главного класса весгда 0
|
uint32_t _token = 0; // Токен у главного класса весгда 0
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -130,7 +261,7 @@ public:
|
|||||||
MB->setTimeout(2000);
|
MB->setTimeout(2000);
|
||||||
// Start ModbusRTU background task
|
// Start ModbusRTU background task
|
||||||
MB->begin((HardwareSerial &)*_modbusUART);
|
MB->begin((HardwareSerial &)*_modbusUART);
|
||||||
MBNoneMap[_token] = this;
|
// MBNoneMap[_token] = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Комманды из сценария
|
// Комманды из сценария
|
||||||
@@ -142,6 +273,7 @@ public:
|
|||||||
|
|
||||||
uint16_t _reg = 0;
|
uint16_t _reg = 0;
|
||||||
uint8_t count = 1;
|
uint8_t count = 1;
|
||||||
|
/*
|
||||||
if (command == "readInputRegisters") // vout = mb.readInputRegisters(1, "0х0000", 1, 0) - "Адрес","Регистр","Кличество регистров","1-float, 0-long"
|
if (command == "readInputRegisters") // vout = mb.readInputRegisters(1, "0х0000", 1, 0) - "Адрес","Регистр","Кличество регистров","1-float, 0-long"
|
||||||
{
|
{
|
||||||
if (param.size())
|
if (param.size())
|
||||||
@@ -243,7 +375,8 @@ public:
|
|||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
else if (command == "writeSingleRegister") // vout = mb.writeSingleRegister(1,"0x0003", 1) - addr, register, state
|
else */
|
||||||
|
if (command == "writeSingleRegister") // vout = mb.writeSingleRegister(1,"0x0003", 1) - addr, register, state
|
||||||
{
|
{
|
||||||
if (param.size())
|
if (param.size())
|
||||||
{
|
{
|
||||||
@@ -373,90 +506,7 @@ public:
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModbusNode : public IoTItem
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
// Initialize the ModbusMaster object as node
|
|
||||||
// Инициализируем объект ModbusMaster как узел
|
|
||||||
|
|
||||||
uint8_t _addr = 0; // Адрес слейва от 1 до 247
|
|
||||||
String _regStr = ""; // Адрес регистра который будем дергать ( по коду от 0х0000 до 0х????)
|
|
||||||
String _funcStr = ""; // Функция ModBUS
|
|
||||||
uint8_t _func;
|
|
||||||
uint16_t _reg = 0;
|
|
||||||
uint8_t _countReg = 1;
|
|
||||||
uint32_t _token = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ModbusNode(String parameters) : IoTItem(parameters)
|
|
||||||
{
|
|
||||||
_addr = jsonReadInt(parameters, "addr"); // адреса slave прочитаем с веба
|
|
||||||
jsonRead(parameters, "reg", _regStr); // адреса регистров прочитаем с веба
|
|
||||||
jsonRead(parameters, "func", _funcStr); // Функция ModBUS
|
|
||||||
_countReg = jsonReadInt(parameters, "count");
|
|
||||||
_func = hexStringToUint8(_funcStr);
|
|
||||||
_reg = hexStringToUint16(_regStr);
|
|
||||||
modBus_Token_count++;
|
|
||||||
_token = modBus_Token_count;
|
|
||||||
MBNoneMap[_token] = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void doByInterval()
|
|
||||||
{
|
|
||||||
if (!MB)
|
|
||||||
{
|
|
||||||
Serial.printf("ModbusNode: ModbusClientAsync is NULL\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_func == 0x04) // vout = mb.readInputRegisters(1, "0х0000", 1, 0) - "Адрес","Регистр","Кличество регистров"
|
|
||||||
{
|
|
||||||
// val.valD = readFunctionModBus(0x04, _addr, _reg, count, isFloat);
|
|
||||||
Serial.printf("sending request with token %d\n", _token);
|
|
||||||
Error err;
|
|
||||||
err = MB->addRequest(_token, _addr, READ_INPUT_REGISTER, _reg, _countReg);
|
|
||||||
if (err != SUCCESS)
|
|
||||||
{
|
|
||||||
ModbusError e(err);
|
|
||||||
Serial.printf("Error creating request: %02X - %s\n", (int)e, (const char *)e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_func == 0x03) // vout = mb.readHoldingRegisters(1, "0х0000", 2, 1) - "Адрес","Регистр","Кличество регистров"
|
|
||||||
{
|
|
||||||
Serial.printf("sending request with token %d\n", _token);
|
|
||||||
Error err;
|
|
||||||
err = MB->addRequest(_token, _addr, READ_HOLD_REGISTER, _reg, _countReg);
|
|
||||||
if (err != SUCCESS)
|
|
||||||
{
|
|
||||||
ModbusError e(err);
|
|
||||||
Serial.printf("Error creating request: %02X - %s\n", (int)e, (const char *)e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_func == 0x01) // vout = mb.readCoils(1, \"0х0000\", 1) - "Адрес","Регистр","Кличество бит"
|
|
||||||
{
|
|
||||||
Serial.printf("sending request with token %d\n", _token);
|
|
||||||
Error err;
|
|
||||||
err = MB->addRequest(_token, _addr, READ_COIL, _reg, _countReg);
|
|
||||||
if (err != SUCCESS)
|
|
||||||
{
|
|
||||||
ModbusError e(err);
|
|
||||||
Serial.printf("Error creating request: %02X - %s\n", (int)e, (const char *)e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_func == 0x02) // vout = mb.readDiscreteInputs(1, \"0х0000\", 1) - "Адрес","Регистр","Кличество бит"
|
|
||||||
{
|
|
||||||
Serial.printf("sending request with token %d\n", _token);
|
|
||||||
Error err;
|
|
||||||
err = MB->addRequest(_token, _addr, READ_DISCR_INPUT, _reg, _countReg);
|
|
||||||
if (err != SUCCESS)
|
|
||||||
{
|
|
||||||
ModbusError e(err);
|
|
||||||
Serial.printf("Error creating request: %02X - %s\n", (int)e, (const char *)e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~ModbusNode() {};
|
|
||||||
};
|
|
||||||
|
|
||||||
void *getAPI_ModbusRTUasync(String subtype, String param)
|
void *getAPI_ModbusRTUasync(String subtype, String param)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"addr": 1,
|
"addr": 1,
|
||||||
"reg": "0x0000",
|
"reg": "0x0000",
|
||||||
"count": 1,
|
"count": 1,
|
||||||
|
"isFloat": 0,
|
||||||
"round": 0
|
"round": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -50,7 +51,7 @@
|
|||||||
"mbClient"
|
"mbClient"
|
||||||
],
|
],
|
||||||
"title": "ModbusAsync",
|
"title": "ModbusAsync",
|
||||||
"moduleDesc": "Позволяет управлять оборудованием по протоколу modbus",
|
"moduleDesc": "Позволяет управлять оборудованием по протоколу modbus. Чтение регситров через Ноды, Запись через функции сценария в ModbusAsunc",
|
||||||
"propInfo": {
|
"propInfo": {
|
||||||
"int": "Количество секунд между опросами датчика.",
|
"int": "Количество секунд между опросами датчика.",
|
||||||
"RX": "Пин RX",
|
"RX": "Пин RX",
|
||||||
@@ -58,30 +59,15 @@
|
|||||||
"DIR_PIN": "connect DR, RE pin of MAX485 to gpio, указать 0 если не нужен",
|
"DIR_PIN": "connect DR, RE pin of MAX485 to gpio, указать 0 если не нужен",
|
||||||
"baud": "скорость Uart",
|
"baud": "скорость Uart",
|
||||||
"protocol": "Протокол Uart: SERIAL_8N1 или SERIAL_8N2",
|
"protocol": "Протокол Uart: SERIAL_8N1 или SERIAL_8N2",
|
||||||
"debug": " 1 - включить вывод дебага , 0 - отключить дебаг"
|
"debug": " 1 - включить вывод дебага , 0 - отключить дебаг",
|
||||||
|
"isFloat": "Тип считываемых данных, если count=2, то данные могут быть long (указать 0) или float (указать 1). Числа Long не рекомендуются (на больших числах не будет точности), так как будет ограничено точность представление в IotManager идет во float",
|
||||||
|
"func": "Функция modbus",
|
||||||
|
"addr": "Адрес slav",
|
||||||
|
"reg": "Адрес регистра",
|
||||||
|
"count": "Количество регистров. В ModbusNode 16-разядные регистры можно считать не более 2 в ноде. Для битовых данных не более 16 бит в ноде. Значение поместится в value Ноды"
|
||||||
|
|
||||||
},
|
},
|
||||||
"funcInfo": [
|
"funcInfo": [
|
||||||
{
|
|
||||||
"name": "readCoils",
|
|
||||||
"descr": "Чтение койла (битового поля). Функция 0х01 протокола. Читает не более 16 бит за раз. Пример: mb.readCoils(1, \"0х0000\", 1)",
|
|
||||||
"params": ["Адрес","Регистр","Кличество бит"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "readDiscreteInputs",
|
|
||||||
"descr": "Чтение дискретного выхода (битового поля). Функция 0х02 протокола. Читает не более 16 бит за раз. Пример: mb.readDiscreteInputs(1, \"0х0000\", 8)",
|
|
||||||
"params": ["Адрес","Регистр","Кличество бит"]
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "readHoldingRegisters",
|
|
||||||
"descr": "Запрос данных регистра. Функция 0х03 протокола. Читает не более двух регистров за раз. Пример: mb.readHoldingRegisters(1, \"0х0000\", 1)",
|
|
||||||
"params": ["Адрес","Регистр","Кличество регистров"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "readInputRegisters",
|
|
||||||
"descr": "Запрос данных регистра. Функция 0х04 протокола. Читает не более двух регистров за раз. Пример: mb.readInputRegisters(1, \"0х0000\", 1)",
|
|
||||||
"params": ["Адрес","Регистр","Кличество регистров"]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "writeSingleCoils",
|
"name": "writeSingleCoils",
|
||||||
"descr": "Запись в койл (битовое поле) одного бита. Функция 0х05 протокола. Пример: mb.writeSingleCoils(1, \"0х0000\", 1)",
|
"descr": "Запись в койл (битовое поле) одного бита. Функция 0х05 протокола. Пример: mb.writeSingleCoils(1, \"0х0000\", 1)",
|
||||||
|
|||||||
Reference in New Issue
Block a user