ESP32 Modbus RTU broadcast is not supported if it is
Posted: Fri Apr 19, 2024 1:08 pm
I'm porting an application to the ESP32 platform and the application uses ModBus RTU broadcasts (sending writing commands to slave address 0). I am not using the CID approach but use mbc_master_send_request() directly.
If the first command sent is a broadcast (slave addrss == 0) the ESP-IDF modbus implementation throws an error and crashes:
E (990) MB_PORT_COMMON: eMBMasterPoll(394): receive buffer initialization fail.
Steps to reproduce:
1) Create a simple modbus master project based on the template.
2) change the main function to
Running this will lead to:
However, if you FIRST address a "normal" slave device and then send a broadcast it works as intended:
Any ideas (other than do a dummy read / write first?)
Thanks.
Steven
If the first command sent is a broadcast (slave addrss == 0) the ESP-IDF modbus implementation throws an error and crashes:
E (990) MB_PORT_COMMON: eMBMasterPoll(394): receive buffer initialization fail.
Steps to reproduce:
1) Create a simple modbus master project based on the template.
2) change the main function to
Code: Select all
void app_main(void)
{
esp_err_t err = 0;
mb_param_request_t req = {};
uint16_t data[10];
data[0] = 0x03;
ESP_ERROR_CHECK(master_init());
vTaskDelay(5);
while (1)
{
// FIRST send the BROADCAST and THEN try to send to slave 25
// populate the modbus request
req.slave_addr = 0; // broadcast
req.reg_start = 0; // Start at 0
req.reg_size = 1; // 1 to test ??
req.command = MB_FUNC_WRITE_MULTIPLE_REGISTERS;
err = mbc_master_send_request(&req, (void *)&data[0]);
ESP_LOGI("TEST 0", "Modbus result code: (%d)", (int)err);
vTaskDelay(5);
// populate the modbus request
req.slave_addr = 25; // slave address
req.reg_start = 0; // Start at 0
req.reg_size = 1; // 1 to test ??
req.command = MB_FUNC_WRITE_MULTIPLE_REGISTERS;
err = mbc_master_send_request(&req, (void *)&data[0]);
ESP_LOGI("TEST 25", "Modbus result code: (%d)", (int)err);
vTaskDelay(1000);
}
}
Code: Select all
I (378) app_start: Starting scheduler on CPU0
I (383) app_start: Starting scheduler on CPU1
I (383) main_task: Started on CPU0
I (393) main_task: Calling app_main()
I (393) uart: queue free spaces: 20
I (453) MASTER_TEST: Modbus master stack initialized...
E (703) MB_PORT_COMMON: eMBMasterPoll(394): receive buffer initialization fail.
(and then nothing anymore)
Code: Select all
while (1)
{
// FIRST send to slave 25 and THEN do the BROADCAST
// populate the modbus request
req.slave_addr = 25; // slave address
req.reg_start = 0; // Start at 0
req.reg_size = 1; // 1 to test ??
req.command = MB_FUNC_WRITE_MULTIPLE_REGISTERS;
err = mbc_master_send_request(&req, (void *)&data[0]);
ESP_LOGI("TEST 25", "Modbus result code: (%d)", (int)err);
vTaskDelay(5);
// populate the modbus request
req.slave_addr = 0; // broadcast
req.reg_start = 0; // Start at 0
req.reg_size = 1; // 1 to test ??
req.command = MB_FUNC_WRITE_MULTIPLE_REGISTERS;
err = mbc_master_send_request(&req, (void *)&data[0]);
ESP_LOGI("TEST 0", "Modbus result code: (%d)", (int)err);
vTaskDelay(1000);
}
Code: Select all
I (378) app_start: Starting scheduler on CPU0
I (383) app_start: Starting scheduler on CPU1
I (383) main_task: Started on CPU0
I (393) main_task: Calling app_main()
I (393) uart: queue free spaces: 20
I (453) MASTER_TEST: Modbus master stack initialized...
I (513) TEST 25: Modbus result code: (0)
I (763) TEST 0: Modbus result code: (0)
I (10773) TEST 25: Modbus result code: (0)
I (11023) TEST 0: Modbus result code: (0)
Thanks.
Steven