How to handle function read coils if they are defined in an array of integers (16 bits)


Thread Starter


In my application (MODBUS interface) i use a uController (PIC18F662 from Microchip) which is not capable of defining a bit array to use for coils or discrete inputs.

Now i have declared an array of 5 integers (16 bits) to define the 90 coils (5 x 16 bits) i need for my application.

My application automatically detects which device (2 types of burner controls can be used) is connected to the interface board and automatically knows which coils belong to which device.

So it could be that for example coils 1 to 32 belongs to device 1 and coils 33 to 90 to device 2.

What will be the exception code if device 1 is connected and the MODBUS unit asks for coils between 33 and 90 (which belongs to another device)? Is this exception code 2?

Is exception code 3 only used if the address is outside the allowable MODBUS address range?

The replied coils in the response of a read coil command must be placed in bytes. What is the method to put for example the status of coils 37 to 53 in the bytes of the response

Thanks in advance!
Exception 2 is where you tried to read an address that was outside the range of the address table. So, if you tried to read coil 33 and coil 33 did not exist (because the coils only went from 0 to 31), then that would be exception 2.

Exception 3 (for function 1 - read coils) is where you tried to read more than 2000 coils at once or you asked for zero coils. The limit on the number of coils is to limit the size of the Modbus message. The fact that you only have 32 coils doesn't matter at this step because you are just checking for a quantity which is legal for the protocol.

There is a flow chart in the spec for each function. You are supposed to check for each exception in the order listed (1, 3, 2, 4). If someone asks for 2001 coils, they should get an exception 3, not exception 2.

Keep in mind that Modbus exceptions are for protocol errors. They aren't for application errors. If you are trying to signal an application error (something wrong in your module), you need to do that by turning on some coils (or setting a register value) that you are defining as error flags. As long as someone is sending valid supported Modbus commands and they are reading from (or writing to) valid addresses, they should not get a Modbus exception.

As for putting coils into "bytes", you can have the coils and the holding registers overlay each other. That is, you can have coils 0 to 15 in holding register 0, and coils 16 to 31 in holding register 1, etc. In this example reading coils 0 to 15 or reading register 0 would be reading the same data (just interpreted differently). There is an example of this in section 4.3 of the spec.

You can also split up the data in other ways. One thing you can do is to duplicate some of the data. For example, you might have coils 0 to 31 also appear as holding register 0, plus have coils 28 to 31 also appear in discrete inputs 500 to 503, and also put a copy of coil 12 in input register 1234.

You don't want to make some coils magically "disappear" when you read them. If you read a coil, the coil should turn up in the expected place in the client. Making that coil also turn on another bit or a register however isn't a problem.
Thanks for your information.

The problem is that more devices (burner controls) can be connected to 1 modbus interface board.

I want to use 1 memory map for all the compatible devices (burner controls) and define a table which says which coil/register belongs to which device (burner control).

for example:
Coil 1 belongs to device 1
coil 2 belongs to device 1
Coil 3 belongs to device 2
coil 4 belongs to device 4
Coil 5 belongs to device 3
coil 6 belongs to device 3
Coil 7 belongs to device 1
coil 8 belongs to device 1

So in fact it should be possible to read/write only 1 coil.

To give a reaction on your answer overlapping is no solution.
I need an easy method.