Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send request not updating buffer (IDFGH-14966) #108

Closed
3 tasks done
RoootNoodle opened this issue Mar 27, 2025 · 9 comments
Closed
3 tasks done

Send request not updating buffer (IDFGH-14966) #108

RoootNoodle opened this issue Mar 27, 2025 · 9 comments

Comments

@RoootNoodle
Copy link

RoootNoodle commented Mar 27, 2025

Checklist

  • Checked the issue tracker for similar issues to ensure this is not a duplicate.
  • Provided a clear description of your suggestion.
  • Included any relevant context or examples.

Issue or Suggestion Description

I want to read a 32bit float holding register value using the library as a master. As shown in the images, the correct value is received from the slave but does not get loaded into the buffer. I am not sure whether there is a bug on the library side or if made a mistake in the configuration. Please note the the guide provided by the link is very outdated and not all the functions shown in the link is available in the latest release.

https://docs.espressif.com/projects/esp-modbus/en/stable/esp32/overview_messaging_and_mapping.html

The image below show the code sent to the slave: 00 03 00 00 00 02 c5 da
With a reply: 00 03 04 41 45 70 a4 cb 61
The reply should be decoded as 12.34 but as seen the Float value = 0

Image

The above values is confirmed by the image below

Image

The loop to continuously send a request

Image

The setup code

Image

I also tried implementing a descriptor, but the result was the same, with only a 0 on return. As per my understanding, the mbc_master_send_request() function should trigger a callback function mbc_reg_holding_master_cb() to update the buffer value, which does not happen. The mbc_reg_holding_master_cb() is defined as a weak function, which im not certain whether to include some reference to it in my main.c.

I could not find help or a guide on the internet, any advice would be appreciated

@github-actions github-actions bot changed the title Send request not updating buffer Send request not updating buffer (IDFGH-14966) Mar 27, 2025
@alisitsyn
Copy link
Collaborator

alisitsyn commented Mar 28, 2025

Hello @RoootNoodle,

Thank you for your report. I can see in your log the response has been correctly received, but the data is mapped incorrectly.

I also tried implementing a descriptor, but the result was the same, with only a 0 on return. As per my understanding, the mbc_master_send_request() function should trigger a callback function mbc_reg_holding_master_cb() to update the buffer value, which does not happen. The mbc_reg_holding_master_cb() is defined as a weak function, which im not certain whether to include some reference to it in my main.c.

This issue can be due to incorrect linking of the mbc_reg_holding_master_cb in the library (mbm_controller_iface->mb_base->rw_cbs.mbc_reg_holding_master_cb). In normal use case you don't need to reference the callback in your code. The issue will be checked accordingly.

Could you let me know some aspects:

  1. Which version of esp-idf, esp-modbus you are using?
  2. Please send me the your_project_name.map file from your build folder?
  3. Can you repeat this issue with other readings of parameters (input registers for example)?

Thanks.

@alisitsyn alisitsyn self-assigned this Mar 28, 2025
@RoootNoodle
Copy link
Author

RoootNoodle commented Mar 28, 2025

I am using version 2.0.2
I tested with input registers, but the error persists

MAP.zip

Should I make use of the mb_parameter_descriptor if the data is being read with mbc_master_send_request()?

@alisitsyn
Copy link
Collaborator

alisitsyn commented Mar 28, 2025

Thank you for the update. I will take a look to it and investigate when possible. Which esp-idf version is used?

Should I make use of the mb_parameter_descriptor if the data is being read with mbc_master_send_request()?

It actually does not matter if you setup reading using the data dictionary or send the request directly (the read data shall be stored to parameter buffer). The mapping rw callback function shall be executed from the command handler from the event task context in both cases. The mapping function is correctly linked as per your map file and should be called from the handler. I need to reproduce this behavior but it is called on my side and maps the data correctly.

The call below shall do the job:

    uint16_t holding_registers[2] = {0};
    req.slave_addr = MB_DEVICE_ADDR1;              // the slave UID to send the request
    req.command = 0x03;                            // the function code,
    req.reg_start = 0;                                   // start register,
    req.reg_size = 2;                                    // length of the data to send (registers)
    
    err = mbc_master_send_request(master_handle, &req, (void *)&holding_registers[0]);
    if (err != ESP_OK) {
        ESP_LOGE("CUSTOM_DATA", "Send custom request fail.");
    } else {
        ESP_LOG_BUFFER_HEX_LEVEL("READ_DATA", (void*)holding_registers, sizeof(holding_registers), ESP_LOG_WARN);
    } 

Could you try to make sure that the callback mbc_reg_holding_master_cb() is called when you read the data? You can move the managed_components to the components folder and add logging from the callback function.

@RoootNoodle
Copy link
Author

I am using ESP-IDF v5.4.0, I used the same code as provided but the data still did not map.

I will move the library and try again.

@RoootNoodle
Copy link
Author

Image

I added the first two lines, there is still no change in the output. Could the problem with the setup in my code or is this library orientated?

I'm attaching my main.c

main.zip

@alisitsyn
Copy link
Collaborator

alisitsyn commented Mar 28, 2025

It is required to move library first to components folder!

If it does not print the strings, please remove the weak attribute in the function prototype to check it instantiation:
esp_modbus_master.h:

mb_err_enum_t mbc_reg_holding_master_cb(mb_base_t *inst, uint8_t *reg_buffer, uint16_t address, uint16_t n_regs, mb_reg_mode_enum_t mode) __attribute__ ((weak)); //  >>>>>>>>> please remove `__attribute__ ((weak))` here

then check if the function is called on request.

@RoootNoodle
Copy link
Author

The changes have been made, there is still not change. The callback is not being executed.

Image

The output after removing weak attribute and adding logs inside the callback.

Should the library be moved to components folder every time or is this done only for testing?

@alisitsyn
Copy link
Collaborator

alisitsyn commented Mar 31, 2025

Should the library be moved to components folder every time or is this done only for testing?

This is just to check the reason on your side.
Please let me know which chip (module) is used on your side. Send me whole log/ of the communication instead of picture.
Do you send also request to slave UID other then zero? If not, this is the broadcast address and slaves do not respond to this address and Modbus library correctly respond with the correct error code. Your code is misleading and req.slave_addr = MB_DEVICE_ADDR1; were the MB_DEVICE_ADDR1 = 0. Please update your example to send correct request.

The image below show the code sent to the slave: 00 03 00 00 00 02 c5 da
With a reply: 00 03 04 41 45 70 a4 cb 61

What kind of slave do you use? According to standard the slave should not respond to the broadcast request.

Thanks.

@RoootNoodle
Copy link
Author

RoootNoodle commented Apr 1, 2025

I got it working, thank you very much. The problem was with broadcasting the request to all the slaves and not requesting data from an individual slave. Changing the req.slave_addr = 1 fixed the problem.

Thanks for the assistance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants