mirror of
https://github.com/esphome/esphome.git
synced 2026-10-06 10:56:43 +00:00
Add support for acting as Modbus server (#4874)
Co-authored-by: Jeroen van Oort <jeroen.vanoort@webparking.nl> Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
co-authored by
Jeroen van Oort
Jesse Hills
parent
76abf2200c
commit
1ca7c2d7dd
@@ -77,7 +77,13 @@ bool Modbus::parse_modbus_byte_(uint8_t byte) {
|
||||
ESP_LOGD(TAG, "Modbus user-defined function %02X found", function_code);
|
||||
|
||||
} else {
|
||||
// the response for write command mirrors the requests and data startes at offset 2 instead of 3 for read commands
|
||||
// data starts at 2 and length is 4 for read registers commands
|
||||
if (this->role == ModbusRole::SERVER && (function_code == 0x3 || function_code == 0x4)) {
|
||||
data_offset = 2;
|
||||
data_len = 4;
|
||||
}
|
||||
|
||||
// the response for write command mirrors the requests and data starts at offset 2 instead of 3 for read commands
|
||||
if (function_code == 0x5 || function_code == 0x06 || function_code == 0xF || function_code == 0x10) {
|
||||
data_offset = 2;
|
||||
data_len = 4;
|
||||
@@ -123,6 +129,9 @@ bool Modbus::parse_modbus_byte_(uint8_t byte) {
|
||||
// Ignore modbus exception not related to a pending command
|
||||
ESP_LOGD(TAG, "Ignoring Modbus error - not expecting a response");
|
||||
}
|
||||
} else if (this->role == ModbusRole::SERVER && (function_code == 0x3 || function_code == 0x4)) {
|
||||
device->on_modbus_read_registers(function_code, uint16_t(data[1]) | (uint16_t(data[0]) << 8),
|
||||
uint16_t(data[3]) | (uint16_t(data[2]) << 8));
|
||||
} else {
|
||||
device->on_modbus_data(data);
|
||||
}
|
||||
@@ -164,16 +173,18 @@ void Modbus::send(uint8_t address, uint8_t function_code, uint16_t start_address
|
||||
std::vector<uint8_t> data;
|
||||
data.push_back(address);
|
||||
data.push_back(function_code);
|
||||
data.push_back(start_address >> 8);
|
||||
data.push_back(start_address >> 0);
|
||||
if (function_code != 0x5 && function_code != 0x6) {
|
||||
data.push_back(number_of_entities >> 8);
|
||||
data.push_back(number_of_entities >> 0);
|
||||
if (this->role == ModbusRole::CLIENT) {
|
||||
data.push_back(start_address >> 8);
|
||||
data.push_back(start_address >> 0);
|
||||
if (function_code != 0x5 && function_code != 0x6) {
|
||||
data.push_back(number_of_entities >> 8);
|
||||
data.push_back(number_of_entities >> 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (payload != nullptr) {
|
||||
if (function_code == 0xF || function_code == 0x10) { // Write multiple
|
||||
data.push_back(payload_len); // Byte count is required for write
|
||||
if (this->role == ModbusRole::SERVER || function_code == 0xF || function_code == 0x10) { // Write multiple
|
||||
data.push_back(payload_len); // Byte count is required for write
|
||||
} else {
|
||||
payload_len = 2; // Write single register or coil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user