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

Add support to function 17 (0x11) Report Slave ID (IDFGH-13856) #76

Open
3 tasks done
ezamp opened this issue Oct 10, 2024 · 18 comments
Open
3 tasks done

Add support to function 17 (0x11) Report Slave ID (IDFGH-13856) #76

ezamp opened this issue Oct 10, 2024 · 18 comments
Assignees

Comments

@ezamp
Copy link

ezamp commented Oct 10, 2024

Checklist

  • Checked the issue tracker for similar issues to ensure this is not a duplicate.
  • Described the feature in detail and justified the reason for the request.
  • Provided specific use cases and examples.

Feature description

Add support for function 17 (0x11) to the mbc_master_send_request() function.

Use cases

It is often necessary to read the information that the device manufacturer makes available through the Device Information

Alternatives

No response

Additional context

No response

@github-actions github-actions bot changed the title Add support to function 17 (0x11) Report Slave ID Add support to function 17 (0x11) Report Slave ID (IDFGH-13856) Oct 10, 2024
@alisitsyn
Copy link
Collaborator

alisitsyn commented Oct 11, 2024

@ezamp,

Thanks for request. The function 0x11 Report Slave ID (Serial Line only) is supported by Master and slave. However, the serial master does not send the request for this command. This command is vendor specific and includes some vendor specific context that suppose some options of realization in user application instead of default stack implementation. I would advice you to implement it on your side. I can explain the way on how to implement this. Will this work for your project?

@alisitsyn alisitsyn self-assigned this Oct 11, 2024
@ezamp
Copy link
Author

ezamp commented Oct 11, 2024

When do you plan to release?
If you need help testing it, I'm available.
Thanks

@alisitsyn
Copy link
Collaborator

alisitsyn commented Oct 11, 2024

I will try to do the guide as soon as possible once I have a chance to switch to this. This will need to apply the change to the stack on your side. I will let you know soon. Do you need to use this for Master or Slave implementation or for both?

@ezamp
Copy link
Author

ezamp commented Oct 11, 2024

I need this only for master

@alisitsyn
Copy link
Collaborator

alisitsyn commented Oct 14, 2024

@ezamp ,

The update is below. The master is able to send the 0x17 command and get response using the mbc_master_send_request() function. I did not have time to adequately test this yet. Please try and report any issues observed. Let me know if you have any issues to patch the component (options are possible).

    mb_param_request_t req = {0};

    uint8_t info_buf[64] = {0}; // byte buffer to save the response from slave (spare bytes added).

    // Command - 17 (0x11) Report Slave ID (Serial Line only)
    req.command = 0x11; // The command get slave info
    // The command contains vendor specific data.
    // This version of command handler needs to define expected number of registers 
    // that will be returned from concrete slave (is not standardized).
    // The returned slave info data will be stored in the `info_buf` with expected number of registers.
    // The handler uses the standard callback function to read input registers.
    req.reg_size = 16;
    // This example will requires the slave info from slave UID = 1.
    // It can be modified accordingly for other slaves.
    req.slave_addr = 0x01;

    err = mbc_master_send_request(&req, &info_buf[0]);

master support for 17 (0x11) Report Slave ID command.

@ezamp
Copy link
Author

ezamp commented Oct 14, 2024

Thank you for the commit.
The request is sent and the master receives the response.
I have some doubts about the register size (reg_size) I need to enter in the request, from the log I can see that the master responds with 59 bytes.
I always get the error “ESP_ERR_INVALID_RESPONSE,” probably because I entered the wrong size.

Log:
D (5503) MB_PORT_COMMON: xMBMasterRunResTake:Take MB resource (500 ticks).
D (5513) MB_PORT_COMMON: xMBMasterRunResTake:Take MB resource (500 ticks).
D (5523) MB_PORT_COMMON: 4856483:EV_MASTER_FRAME_TRANSMIT
D (5523) POLL transmit buffer: 11
D (5533) MB_PORT_COMMON: eMBMasterRTUSend: Port enter critical.
D (5533) MB_PORT_COMMON: eMBMasterRTUSend: Port exit critical
D (5543) MB_PORT_COMMON: xMBMasterPortSerialSendRequest default
D (5543) MB_PORT_COMMON: vMBMasterPortTimersRespondTimeoutEnable Respond enable timeout.
D (5553) MB_MASTER_SERIAL: MB_TX_buffer sent: (5) bytes.
D (5563) MB_PORT_COMMON: vMBMasterRxSemaRelease:RX semaphore is free.
D (5563) MB_PORT_COMMON: 4856483:EV_MASTER_FRAME_SENT
D (5573) POLL sent buffer: 11
D (5593) MB_PORT_COMMON: xMBPortSerialWaitEvent, UART event: 0
D (5593) MB_MASTER_SERIAL: MB_uart[2] event:
D (5593) MB_MASTER_SERIAL: Data event, len: 62.
D (5603) MB_MASTER_SERIAL: Received data: 63(bytes in buffer)
D (5603) MB_MASTER_SERIAL: Timeout occured, processed: 63 bytes
D (5613) MB_PORT_COMMON: 4856483:EV_MASTER_FRAME_RECEIVED
D (5613) MB_PORT_COMMON: xMBMasterPortSerialGetResponse default
D (5623) MB_PORT_COMMON: eMBMasterRTUReceive: Port enter critical.
D (5623) MB_PORT_COMMON: eMBMasterRTUReceive: Port exit critical
D (5633) MB_PORT_COMMON: 4856483: Packet data received successfully (0).
D (5643) POLL receive buffer: 11 39 01 04 03 24 ff 04 0b 00 0a 30 30 30 30 30
D (5643) POLL receive buffer: 31 30 34 30 33 32 34 32 34 30 34 32 32 30 30 30
D (5653) POLL receive buffer: 32 37 33 00 00 00 00 00 00 00 00 00 00 00 00 00
D (5663) POLL receive buffer: 00 00 00 00 00 00 00 00 00 00 00
D (5663) MB_PORT_COMMON: 4856483:EV_MASTER_EXECUTE
D (5673) MB_PORT_COMMON: 4856483:EV_MASTER_ERROR_PROCESS
D (5683) MB_PORT_COMMON: vMBMasterErrorCBExecuteFunction:Callback execute data handler failure.
D (5683) MB_PORT_COMMON: Transaction (4856483), processing time(us) = 152365
D (5693) MB_PORT_COMMON: eMBMasterWaitRequestFinish: returned event = 0x400
E (5703) MB_CONTROLLER_MASTER: mbc_master_send_request(94): Master send request failure error=(0x108) (ESP_ERR_INVALID_RESPONSE).

@alisitsyn
Copy link
Collaborator

alisitsyn commented Oct 14, 2024

Thanks for feedback. Yes, the error seems appear because of incorrect size of response. I did use the input registers mapping callback function because there is pros of this for later implementation. I got your point and it worth to change it using its own mapping.
Unfortunately, I have some other high priority work for now and can not spend time for this. Could you wait some time or otherwise could you be able to update the handler function to use just bytes count in the response to map them to output data. The change is very simple.

@ezamp
Copy link
Author

ezamp commented Oct 17, 2024

Thanks for the support.

I made the following change in the eMBMasterFuncReportSlaveID function:
eRegStatus = eMBMasterRegInputCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], 0, ucByteCount );
instead of:
eRegStatus = eMBMasterRegInputCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], 0, (ucByteCount >> 1) );

I'm noticing a problem when I run two requests in sequence, specifically:
(Write multiple registers): 10 00 00 00 05 0a 00 05 e5 18 6d 16 5b ef 00 64 -> RX: 9 bytes
(Report server ID): 11 -> RX: 65 bytes instead of 57

It seems that the 9 bytes received with the first request are considered for as RX for the second request.

Log:
D (347803) MB_PORT_COMMON: xMBMasterRunResTake:Take MB resource (500 ticks).
D (347813) MB_PORT_COMMON: xMBMasterRunResTake:Take MB resource (500 ticks).
D (347823) MB_PORT_COMMON: 347154823:EV_MASTER_FRAME_TRANSMIT
D (347823) POLL transmit buffer: 10 00 00 00 05 0a 00 05 e5 18 6d 16 5b ef 00 64
D (347833) MB_PORT_COMMON: eMBMasterRTUSend: Port enter critical.
D (347833) MB_PORT_COMMON: eMBMasterRTUSend: Port exit critical
D (347843) MB_PORT_COMMON: xMBMasterPortSerialSendRequest default
D (347853) MB_PORT_COMMON: vMBMasterPortTimersConvertDelayEnable Convert delay enable.
D (347863) MB_MASTER_SERIAL: MB_TX_buffer sent: (20) bytes.
D (347863) MB_PORT_COMMON: vMBMasterRxSemaRelease:RX semaphore is free.
D (347873) MB_PORT_COMMON: 347154823:EV_MASTER_FRAME_SENT
D (347873) POLL sent buffer: 10 00 00 00 05 0a 00 05 e5 18 6d 16 5b ef 00 64
D (347963) MB_PORT_COMMON: xMBPortSerialWaitEvent, UART event: 0
D (347963) MB_MASTER_SERIAL: MB_uart[2] event:
D (347963) MB_MASTER_SERIAL: Data event, len: 8.
D (347963) MB_MASTER_SERIAL: Received data: 9(bytes in buffer)
D (347973) MB_MASTER_SERIAL: Timeout occured, processed: 9 bytes
D (347973) MB_PORT_COMMON: 347154823:EV_MASTER_FRAME_RECEIVED
D (347983) MB_PORT_COMMON: xMBMasterPortSerialGetResponse default
D (347993) MB_PORT_COMMON: eMBMasterRTUReceive: Port enter critical.
D (347993) MB_PORT_COMMON: eMBMasterRTUReceive: Port exit critical
D (348003) MB_PORT_COMMON: 347154823: Packet data receive failed (addr=100)(0).
D (348013) MB_PORT_COMMON: 347154823:EV_MASTER_ERROR_PROCESS
D (348013) MB_PORT_COMMON: vMBMasterErrorCBReceiveData:Callback receive data failure.
D (348013) MB_PORT_COMMON: eMBMasterWaitRequestFinish: returned event = 0x200
E (348033) MB_CONTROLLER_MASTER: mbc_master_send_request(94): Master send request failure error=(0x108) (ESP_ERR_INVALID_RESPONSE).
D (348043) ModBusDriver: Send result 264, addr: 0, cmd: 10
D (348053) MB_PORT_COMMON: Transaction (347154823), processing time(us) = 182619
D (351053) MB_PORT_COMMON: xMBMasterRunResTake:Take MB resource (500 ticks).
D (351053) MB_PORT_COMMON: xMBMasterRunResTake:Take MB resource (500 ticks).
D (351053) MB_PORT_COMMON: 350393395:EV_MASTER_FRAME_TRANSMIT
D (351063) POLL transmit buffer: 11
D (351063) MB_PORT_COMMON: eMBMasterRTUSend: Port enter critical.
D (351073) MB_PORT_COMMON: eMBMasterRTUSend: Port exit critical
D (351083) MB_PORT_COMMON: xMBMasterPortSerialSendRequest default
D (351083) MB_PORT_COMMON: vMBMasterPortTimersRespondTimeoutEnable Respond enable timeout.
D (351093) MB_MASTER_SERIAL: MB_TX_buffer sent: (5) bytes.
D (351103) MB_PORT_COMMON: 350393395:EV_MASTER_FRAME_SENT
D (351103) POLL sent buffer: 11
D (351133) MB_PORT_COMMON: xMBPortSerialWaitEvent, UART event: 0
D (351133) MB_MASTER_SERIAL: MB_uart[2] event:
D (351133) MB_MASTER_SERIAL: Data event, len: 65.
D (351143) MB_MASTER_SERIAL: Received data: 66(bytes in buffer)
D (351143) MB_MASTER_SERIAL: Timeout occured, processed: 66 bytes
D (351153) MB_PORT_COMMON: 350393395:EV_MASTER_FRAME_RECEIVED
D (351153) MB_PORT_COMMON: xMBMasterPortSerialGetResponse default
D (351163) MB_PORT_COMMON: eMBMasterRTUReceive: Port enter critical.
D (351173) MB_PORT_COMMON: eMBMasterRTUReceive: Port exit critical
D (351173) MB_PORT_COMMON: 350393395: Packet data receive failed (addr=100)(5).
D (351183) MB_PORT_COMMON: 350393395:EV_MASTER_ERROR_PROCESS
D (351193) MB_PORT_COMMON: vMBMasterErrorCBReceiveData:Callback receive data failure.
D (351193) MB_PORT_COMMON: eMBMasterWaitRequestFinish: returned event = 0x200
E (351203) MB_CONTROLLER_MASTER: mbc_master_send_request(94): Master send request failure error=(0x108) (ESP_ERR_INVALID_RESPONSE).

@alisitsyn
Copy link
Collaborator

alisitsyn commented Oct 22, 2024

Sorry for the long delay with answer.

eRegStatus = eMBMasterRegInputCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], 0, ucByteCount );

The change is incorrect here. The callback function take the number of registers instead.
I will try to find a better way to fix these issues on your side with the odd number of bytes.

I'm noticing a problem when I run two requests in sequence, specifically:
(Write multiple registers): 10 00 00 00 05 0a 00 05 e5 18 6d 16 5b ef 00 64 -> RX: 9 bytes
(Report server ID): 11 -> RX: 65 bytes instead of 57

It seems the response to this command is processed with error then the input FIFO is cleared before further processing. The length of the response looks correct also. The mbc_master_send_request() should not take its input in spite of it does not clear the buffer on start. So, it looks a bit strange but I have an idea for this.

I will update implementation soon and will test it.

UPDATE is in progress
Fixes 0x17 command in serial master and slave. Still uses input register handling callback (transfers data in registers).

@alisitsyn
Copy link
Collaborator

alisitsyn commented Oct 22, 2024

@ezamp,

Could you send me the device manual or description of this command from your device manual? I see your response and can just guess now. This is the vendor specific part with 3 byte device ID and the number saved as string.

@ezamp
Copy link
Author

ezamp commented Oct 22, 2024

ModBus 0x11.xlsx
I have attached an extract from the datasheet.

@alisitsyn
Copy link
Collaborator

alisitsyn commented Oct 22, 2024

Could you check the update with your device? This should work just fine now with the limitation of only even number of bytes (Registers) are mapped into the value buffer. If you need the whole buffer this can be done using the custom vMBMasterErrorCBUserHandler handler.

@ezamp
Copy link
Author

ezamp commented Oct 22, 2024

I did a test with my device and now I can read the response bytes correctly.
However, I keep having the problem when I send two commands in sequence, the second one also takes the response of the first command as input.

Log command 0x11:
D (47526) MB_PORT_COMMON: xMBMasterRunResTake:Take MB resource (500 ticks).
D (47526) MB_PORT_COMMON: xMBMasterRunResTake:Take MB resource (500 ticks).
D (47526) MB_PORT_COMMON: 46863230:EV_MASTER_FRAME_TRANSMIT
D (47536) POLL transmit buffer: 11
D (47536) MB_PORT_COMMON: eMBMasterRTUSend: Port enter critical.
D (47546) MB_PORT_COMMON: eMBMasterRTUSend: Port exit critical
D (47546) MB_PORT_COMMON: xMBMasterPortSerialSendRequest default
D (47556) MB_PORT_COMMON: vMBMasterPortTimersRespondTimeoutEnable Respond enable timeout.
D (47566) MB_MASTER_SERIAL: MB_TX_buffer sent: (5) bytes.
D (47566) MB_PORT_COMMON: 46863230:EV_MASTER_FRAME_SENT
D (47576) POLL sent buffer: 11
D (47616) MB_PORT_COMMON: xMBPortSerialWaitEvent, UART event: 0
D (47616) MB_MASTER_SERIAL: MB_uart[2] event:
D (47616) MB_MASTER_SERIAL: Data event, len: 62.
D (47616) MB_MASTER_SERIAL: Received data: 63(bytes in buffer)
D (47626) MB_MASTER_SERIAL: Timeout occured, processed: 63 bytes
D (47626) MB_PORT_COMMON: 46863230:EV_MASTER_FRAME_RECEIVED
D (47636) MB_PORT_COMMON: xMBMasterPortSerialGetResponse default
D (47646) MB_PORT_COMMON: eMBMasterRTUReceive: Port enter critical.
D (47646) MB_PORT_COMMON: eMBMasterRTUReceive: Port exit critical
D (47656) MB_PORT_COMMON: 46863230: Packet data received successfully (0).
D (47666) POLL receive buffer: 11 39 01 04 03 49 00 02 0e 01 01 30 30 30 30 30
D (47666) POLL receive buffer: 31 30 34 30 33 34 39 32 34 30 34 32 32 30 30 30
D (47676) POLL receive buffer: 30 32 32 00 00 00 00 00 00 00 00 00 00 00 00 00
D (47686) POLL receive buffer: 00 00 00 00 00 00 00 00 00 00 00
D (47686) MB_PORT_COMMON: 46863230:EV_MASTER_EXECUTE
D (47696) FHANDLER_SET_SLAVE_ID: Master handler of slave info command 57 bytes.
D (47706) MB_PORT_COMMON: 46863230:set event EV_ERROR_OK
D (47706) MB_PORT_COMMON: 46863230:EV_MASTER_ERROR_PROCESS
D (47716) MB_PORT_COMMON: vMBMasterCBRequestSuccess: Callback request success.
D (47716) MB_PORT_COMMON: Transaction (46863230), processing time(us) = 177407
D (47726) MB_PORT_COMMON: eMBMasterWaitRequestFinish: returned event = 0x80
D (47736) ModBusDriver: Send result 0, addr: 100, cmd: 11

@alisitsyn
Copy link
Collaborator

I did a test with my device and now I can read the response bytes correctly.
However, I keep having the problem when I send two commands in sequence, the second one also takes the response of the first command as input.

Thanks for the update. The issue with two commands in sequence will be fixed as ASAP. I also will need your test.

@ezamp
Copy link
Author

ezamp commented Oct 23, 2024

Thanks.
Can I suggest to extend the maximum size of the buffer (MB_FUNC_OTHER_REP_SLAVEID_BUF)?
32 might be a bit small in some cases, in my tests I extended it to 64.

@alisitsyn
Copy link
Collaborator

alisitsyn commented Oct 23, 2024

Can I suggest to extend the maximum size of the buffer (MB_FUNC_OTHER_REP_SLAVEID_BUF)?
32 might be a bit small in some cases, in my tests I extended it to 64.

Yes, sure, this size can be defined in the kconfig actually. I missed this initially and left as it was. This will be updated as soon as I complete some other work.
BTW: Is the endianness of the data correct? The data in the command is represented in the frame as per spec in network big-endian format, but since data context is vendor specific it might be handled differently in your device. Do you see the values set correctly in your info_buf[] buffer?

@ezamp
Copy link
Author

ezamp commented Oct 23, 2024

The bytes I read are not in the sequence indicated by the manufacturer. Each byte pair (uint16) is represented in little endian.

For example:
From the documentation, position 0 should contain the value 0x01 but in the buffer that value is in position 1. Consequently, the value in position in 1 (on the doc) is in position 0 in the buffer...

In the log below you can see the “swaps” of positions:
D (52705) POLL receive buffer: 11 39 01 04 03 49 00 02 0e 01 01 30 30 30 30 30
D (52715) POLL receive buffer: 31 30 34 30 33 34 39 32 34 30 34 32 32 30 30 30
D (52725) POLL receive buffer: 30 32 32 00 00 00 00 00 00 00 00 00 00 00 00 00
D (52735) POLL receive buffer: 00 00 00 00 00 00 00 00 00 00 00
D (52735) MB_PORT_COMMON: 51913212:EV_MASTER_EXECUTE
D (52745) FHANDLER_SET_SLAVE_ID: Master handler of slave info command 57 bytes.
D (52755) MB_PORT_COMMON: 51913212:set event EV_ERROR_OK
D (52755) MB_PORT_COMMON: 51913212:EV_MASTER_ERROR_PROCESS
D (52765) MB_PORT_COMMON: vMBMasterCBRequestSuccess: Callback request success.
D (52765) MB_PORT_COMMON: Transaction (51913212), processing time(us) = 176458
D (52775) MB_PORT_COMMON: eMBMasterWaitRequestFinish: returned event = 0x80
D (52785) ModBusDriver: Send result 0, addr: 100, cmd: 11
I (52785) Devices: 04 01 49 03 02 00 01 0e 30 01 30 30 30 30 30 31
I (52795) Devices: 30 34 34 33 32 39 30 34 32 34 30 32 30 30 32 30
I (52805) Devices: 00 32 00 00 00 00 00 00 00 00 00 00 00 00 00 00
I (52815) Devices: 00 00 00 00 00 00 00 00 00

@alisitsyn
Copy link
Collaborator

alisitsyn commented Oct 23, 2024

Ah, I see and was expecting this as per your log but it is really vendor specific things. I can do this different way but I think it will not satisfy the specification because all the data in the frame satisfy network format of big-endian. It might be safer to take buffer of the command and process it as required for your device. I will make a decision on how to implement it and will do a bit later.

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