Open kotyara12 opened 2 weeks ago
Hello @kotyara12,
I understand your use case and it is different from typical Modbus Master use case. However, I think there is relatively simple way to accomplish this.
The solution to the problem would be the ability to change the transmission speed directly during operation, that is, before accessing the adapter, set the speed to 19200, and after the communication session, return everything to 9600. Question for experts: is this possible and how to do it?
I think this would work. The object dictionary has the optional fields to keep the user information for each CID. You can use this field to store the baudrate of your modbus devices. Below just a simple approach that can be modified for actual use case.
const mb_parameter_descriptor_t device_parameters[] = {
// { CID, Param Name, Units, Modbus Slave Addr, Modbus Reg Type, Reg Start, Reg Size, Instance Offset, Data Type, Data Size, Parameter Options, Access Mode}
{ CID_INP_DATA_0, STR("Data_channel_0"), STR("Volts"), MB_DEVICE_ADDR1, MB_PARAM_INPUT,
TEST_INPUT_REG_START(input_data0), TEST_INPUT_REG_SIZE(input_data0),
INPUT_OFFSET(input_data0), PARAM_TYPE_FLOAT, 4,
OPTS( 0, 0, 19200), PAR_PERMS_READ_WRITE_TRIGGER },
/* This modbus slave at address MB_DEVICE_ADDR2 uses the different baud rate settings. */
{ CID_HOLD_DATA_0, STR("Humidity_1"), STR("%rH"), MB_DEVICE_ADDR2, MB_PARAM_HOLDING,
TEST_HOLD_REG_START(holding_data0), TEST_HOLD_REG_SIZE(holding_data0),
HOLD_OFFSET(holding_data0), PARAM_TYPE_FLOAT, 4,
OPTS( 0, 0, 9600 ), PAR_PERMS_READ_WRITE_TRIGGER },
}
.... other code
static void master_operation_func(void *arg) {
err = mbc_master_get_cid_info(master_handle, cid, ¶m_descriptor);
// .... Your other code, refer to example
// This will override the UART baud rate before sending the request
err = uart_set_baudrate(MB_PORT_NUM, (uint32_t)param_descriptor->param_opts.opt3);
.....
// The speed of UART is overriden, the request will be sent on optional baudrate
err = mbc_master_get_parameter(handle, param_descriptor->cid, (uint8_t *)pinst, &type);
// process your errors and data accordingly, refer to example
// Note: the response to request can be received later than CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND
// and the new request should not start earlier, otherwise it causes receive errors and then synchronization issues.
// The simple way is to just wait one more cycle of respond time before proceed.
vTaskDelay(CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND / portTICK_PERIOD_MS);
I think it is possible to avoid possible issues if they happen. Will this work for your case?
Hello @alisitsyn,
Yes, that should help. Thank you very much!!! After some time I will be able to check it and will write back / close the request. Thanks again
Hello!
At the moment I have encountered a problem with rs485/modbus. First, I will describe the situation in detail.
I have a small network of rs485/modbus sensors connected to the same physical RS485 bus and collecting data of different types. They all support a baud rate of 9600, and at this speed everything works fine.
But now I needed to connect a gas boiler adapter to the same bus, which works ONLY at a speed of 19200 and strictly at a specific address. There are no problems with the address, but with the baud rate - a big problem.
I tried to transfer all other devices on the bus to 19200. For most devices I succeeded. But there are some sensors bought on AliExpress (with a display), which either do not have a speed change register, or it is not documented. The seller pretends that "yours is mine, I do not understand", and refuses to help.
Now the question itself.
The solution to the problem would be the ability to change the transmission speed directly during operation, that is, before accessing the adapter, set the speed to 19200, and after the communication session, return everything to 9600. Question for experts: is this possible and how to do it?
PS: I work with ESP-IDF 5.2