Open yel-best opened 1 month ago
@yel-best ,
- I am currently doing modbus connection with some PLC devices. I need to see some detailed logs. For example, the sent message "01 03 A0 80 00 01 A7 E2" and then the
The logging for Modbus can be enabled in menuconfig setting the log verbosity. This enables the logging of sent/received PDU frames. The ADU frame logging is removed from the port layer because the log might get cluttered. It is also possible to remove some messages from log.
In addition, the example does not seem to explain how to convert the value.
The code you are looking for is not good example because it is test code and it should not be described for user. This uses the macro which is an analog of template function in CPP to be able to use the same scenario for all types of parameters from data dictionary.
The example of mapping in the data dictionary is described here. Once the characteristics are defined you can read and write the described parameter using the functions mbc_master_get_parameter, mbc_master_set_parameter.
It is selection of user how to store the data and how to save it but the API provides the methods to read/write data over modbus and store them as instructed.
mb_parameter_descriptor_t device_parameters[] = {
{ CID_HOLD_U16_AB, STR("U16_AB"), STR("--"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING,
HOLD_REG_START(holding_u16_ab), HOLD_REG_SIZE(holding_u16_ab),
0, PARAM_TYPE_U16_AB, (HOLD_REG_SIZE(holding_u16_ab) << 1),
OPTS( 0, USHRT_MAX, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
...
}
...
uint16_t my_data = 0;
...
esp_err_t err = mbc_master_set_parameter(CID_HOLD_U16_AB, "U16_AB", (uint8_t *)&my_data, &type);
if (err == ESP_OK) {
ESP_LOGI(TAG, "Set parameter data successfully.");
} else {
ESP_LOGE(TAG, "Set data fail, err = 0x%x (%s).", (int)err, (char*)esp_err_to_name(err));
}
assign the value to test_v and then I bring test_v into my business logic. There seems to be some problems and it doesn't feel optimal.
The temp_data_ptr
in this case gets the pointer to parameter instance in the parameter structure void *temp_data_ptr = master_get_param_data(param_descriptor); )
.
Th example with the parameters stored in data structures and the code saves the data to the appropriate field of the structure as defined in data dictionary.
...
#pragma pack(push, 1)
typedef struct
{
#if CONFIG_FMB_EXT_TYPE_SUPPORT
uint16_t holding_u16_ab[2];
uint16_t holding_u16_ba[2];
} holding_reg_params_t;
#pragma pack(pop)
...
// This structure keeps the values that can be accessed from Modbus master
holding_reg_params_t holding_reg_params = { 0 };
....
mb_parameter_descriptor_t device_parameters[] = {
{ CID_HOLD_U16_AB, STR("U16_AB"), STR("--"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING,
HOLD_REG_START(holding_u16_ab), HOLD_REG_SIZE(holding_u16_ab),
HOLD_OFFSET(holding_u16_ab), PARAM_TYPE_U16_AB, (HOLD_REG_SIZE(holding_u16_ab) << 1),
OPTS( 0, USHRT_MAX, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
...
}
const mb_parameter_descriptor_t* param_descriptor = NULL;
...
esp_err_t err = mbc_master_get_cid_info(cid, ¶m_descriptor); // get characteristic descriptor from data dictionary
...
void *temp_data_ptr = master_get_param_data(param_descriptor); // <<<< gets the pointer to the parameter instance as defined by offset HOLD_OFFSET(holding_u16_ab) in data dictionary.
...
// Send the data of the parameter stored in the holding_reg_params.holding_u16_ab to the slave.
esp_err_t err = mbc_master_set_parameter(CID_HOLD_U16_AB, "U16_AB", (uint8_t *)temp_data_ptr, &type);
if (err == ESP_OK) {
ESP_LOGI(TAG, "Set parameter data successfully.");
} else {
ESP_LOGE(TAG, "Set data fail, err = 0x%x (%s).", (int)err, (char*)esp_err_to_name(err));
}
Hi, Friend
Thank you very much for your answer. Based on your tips, I have a new understanding of the way to read data using modbus, but I encountered another problem. I wonder if you can help me.
My current environment
Currently I want to use modbus 485 to read device data and display it on an LCD screen using lvgl UI. I also use esp-idf WIFI & MQTT for data transfer. Currently I have no problem using lvgl UI, but when I After adding modbus, some exceptions will appear. I don’t know whether it is caused by a memory error or insufficient storage space. The prompts are as follows.
I don’t understand why I’m using the largestN16R8
version, and why there are still some memory exceptions and creation failures. Is it because my esp-idf setting causes moudbus to have some impact on lvgl? I don’t know if anyone has found similar problems. question
Guru Meditation Error: Core / panic'ed (Cache disabled but cached memory region accessed).
MMU entry fault error occurred while accessing the address 0x43ffef00 (invalid mmu entry)
Core 0 register dump:
PC : 0x40378340 PS : 0x00060f34 A0 : 0x82022ba8 A1 : 0x3fcbba40
0x40378340: _UserExceptionVector at E:/MyProject/IoT/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/xtensa_vectors.S:621
A2 : 0x3c12a900 A3 : 0x3fcbba70 A4 : 0x00000049 A5 : 0x0000006f
A6 : 0x00000000 A7 : 0x00000010 A8 : 0x82022add A9 : 0xffffef03
A10 : 0x3c12a900 A11 : 0x3fcbba70 A12 : 0x00000049 A13 : 0x0000006f
A14 : 0xffffffff A15 : 0x0000ffff SAR : 0x00000020 EXCCAUSE: 0x00000007
EXCVADDR: 0xffffef00 LBEG : 0x42024ea4 LEND : 0x42024ecb LCOUNT : 0x00000000
If you have time, I hope you can give me some help or suggestions, thanks
It's been bothering me for a week and I don't know what to do 🥲
I can not help you to identify the reason for the issue having just the information above. Ican give you some recommendations:
- IRAM_ATTR
Ok, I'll check it out. I think it's caused by insufficient stack space. Is there any way to get more stack space? for example, changing some settings
What I can determine so far is that when I use LVGL + modbus at the same time, there will be a problem of failure to create the moubus task. It is most likely due to insufficient memory.
@yel-best ,
The latest master now supports the user error handler function to expose the modbus buffers.
Please take a look to the documentation.
Have you been able to resolve your issue?
Have you been able to resolve your issue?
wow,thank you for your support. I have been able to solve my data format problem, but I will continue to test it and hope to provide you with more case help through testing. 😄
Hi My Friend.
1. I am currently doing modbus connection with some PLC devices. I need to see some detailed logs. For example, the sent message "01 03 A0 80 00 01 A7 E2" and then the received message "01 03 02 03 E8 B8 FA", I need to print to the console for output,I have been searching for a long time but I have not found how to open this part of the log.
2. In addition, the example does not seem to explain how to convert the value. For example, I have a float & u16 type value. How should I extract it for subsequent logic? I now use a very stupid way to do it, and I will *(uint16_t ) temp_data_ptr** for forced conversion, do you have any other suggestions?
I assign the value to
test_v
and then I bring test_v into my business logic. There seems to be some problems and it doesn't feel optimal.