(not another) Modbus Query

Hi All,

I'm looking for some help with a modbus query. We are currently using an rfid reader on our devices. Please see below for some snippets from the rfid reader manual:
image

image

We have been communicating with the reader using Serial1, where I am manually writing the command bytes to Serial1 with write. The main command we are using is the command in 4.1. After sending the command, I then check if Serial is available and manually read the bytes into an array, and then do the CRC check manually. I have a feeling that this manual approach may not be the optimal way to do it.

I have been trying to achieve the same functionality using the ModbusMaster library, but having some issues. Here is my current approach:

From the reader manual to read all tag data, I need to send the following command to the reader:
byte lookup_read_tag_data[] = {0x02, 0x03, 0x00, 0x16, 0x00, 0x0A, 0x24, 0x3A};

From this command we see the readers address is 02 and 03 represents the read function. From the ModbusMaster.h file it seems like this function code should correspond with:
// Modbus function codes for 16 bit access static const uint8_t ku8MBReadHoldingRegisters = 0x03; ///< Modbus function 0x03 Read Holding Registers

For the above reason I have been trying to get this to work with

result = node.readHoldingRegisters(0x16,10);
Serial.println("");
Serial.print("Read Coils Response: ");
Serial.println(result, HEX);

With node.enableDebug(); it looks like I am sending the correct command to the reader:

Read Coils Response: E0
TX: 2 3 0 16 0 A 24 3A  
RX: 81 74 31 2 3

Read Coils Response: E0
TX: 2 3 0 16 0 A 24 3A  
RX: FF 2 3 8 FF

Read Coils Response: E0
TX: 2 3 0 16 0 A 24 3A  
RX: 81 74 31 74 31

Read Coils Response: E0
TX: 2 3 0 16 0 A 24 3A  
RX: 54 2 3 8 FF

Read Coils Response: E0
TX: 2 3 0 16 0 A 24 3A  
RX: 81 74 31 2 3

Read Coils Response: E0
TX: 2 3 0 16 0 A 24 3A  
RX: FF 2 3 8 FF

Read Coils Response: E0
TX: 2 3 0 16 0 A 24 3A  
RX: 81 74 31 2 3

I know that the debug can break the comms, but it seems like I am sending the correct command to the reader. Based on the RX responses, I am pretty sure the issue here is a timing issue, as I can see repeating sequence on the RX outputs.

From the reader manual, the reader should respond to this command with 25 bytes. So my current questions are as follows:

  1. Should I stick to my homebrew Serial1.write and read solution rather than trying to implement the Modbus solution?
  2. Am i using the correct Modbus function to send the command to the reader, or should I be manually sending the bytes with a different command in the library?
  3. I am obviously not using the Modbus library correctly, as it thinks its getting the wrong reader address, but I think this is just as a result of the RX being out of sync. How do I offset, or tell modbus how many bytes the reader should be responding with? I have tried a few different values for the second argument in readHoldingRegisters, but this has not seemed to help much.

Any advice or help is greatly appreciated.
Thanks

Hello,

  1. Up to you, I would continue trying the modbus route since the response indicates there is an error occurring. Also, we did release a tutorial on Modbus with some example code I wrote that can be found here that you can use for your reference.

  2. The various modbus functions define which opcode to send. In this case you need to be sending 0x03 after the slave address which is achieved using the readHoldingRegisters() function which you are using correctly. My recommendation would be to continue using the function.

  3. The read coils response of 0xE0 indicates that the host did not receive the same client ID that matched the request. If you look at line 177 of the ModbusMaster.h you will find the response defined as shown below.


    How are you physically connecting the BSoM to the Modbus? Are you using a translation layer like I did for the example code?

1 Like

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.