modbus FC 15 versus FC 5

Hello All, I am a beginner in learning the TCP Modbus protocol. I was wondering if it should be possible to set a single coil using function code 15. If yes, does it mean that I do not necessarily need FC 5 anymore to set a single coil ? The reason I am asking this is because I am seeing odd results when I try to set a single coil status using function code 15. For my tests I am using the "Free" mod_RSsim.exe simulator. I tried to following

Step 1: I send the following byte stream (in decimal) to set address 0 to ON. This was OK ( I saw address 0 becoming "1")
169 91 0 0 0 8 255 15 0 0 0 1 1 1

Step 2: I send the following byte stream (in decimal) to set address 2 to ON. This was OK. I saw address 0 en 2 both being '1')
125 28 0 0 0 8 255 15 0 2 0 1 1 1

Step 3: I send the following byte stream (in decimal) to set address 3 to ON. This was OK. I saw address 0, 2 and 3 all being '1')
76 46 0 0 0 8 255 15 0 3 0 1 1 1

Step 4: I send the following byte stream (in decimal) to set address 2 to OFF (At least that was my plan). Now instead of seeing only address 2 going to '0' and address 0 and 3 remaining "1'" I saw both address 2 and 3 becoming "0".
77 146 0 0 0 8 255 15 0 2 0 1 1 0

Can anyone explain to me what I am doing wrong ?
Regards,

Pluto Mars
 
Sorry, but forum will not format in Courier fixed spacing, so the columns do not work. The data below is your message, decimal in one column, hex in the next column but the formatting is just all mashed together.

Your decimal string: 15 0 2 0 1 1 0
field Decimal Hex
Function Code 15 0Fh
coil address Hi 0 00
coil address Low 2 01 ? address = 0001h is coil #2, address 0003h is coil #4
Qty coils Hi 0 00
Qty coils Low 1 01 0001 coils = one coil
Byte Count 1 01 one byte of data to write
Write data 0 00 address 0001h (coil #2) = Logic 0, coil #3 = Logic 0,
coils 4 through 10 = Logic 0

Remember, this is Function Code 15, Write Multiple Coils. Your data word is 8 bits and each bit is written to its coil.

The byte that you wrote, 00h, is binary 0000 0000.
Since you started at coil #2, coil #2 and the next 7 coils will be written to Logic 0, because that's what you told it to do.

coil #2 = 0 (bit 0)
coil #3 = 0 (bit 1)
coil #4 = 0 (bit 2)
coil #5 = 0 (bit 3)
coil #6 = 0 (bit 4)
coil #7 = 0 (bit 5)
coil #9 = 0 (bit 6)
coil #10 = 0 (bit 7)

To keep higher numbered coils at their present state, you need to write the current logic state as part of the write data.
To keep coil 3 at a Logic 1, your data byte should have been 0000 0010 = 02h or 2 decimal.
 
Hi.
But the request says Quantity = 1! I don't think it is correct that the following 7 coils will change too. This is a bug in mod_RSsim.

With start address and quantity, the range of coils being modified (ON/1 or OFF/0) is explicitly stated.
 
Hi.
But the request says Quantity = 1! I don't think it is correct that the following 7 coils will change too. This is a bug in mod_RSsim.

With start address and quantity, the range of coils being modified (ON/1 or OFF/0) is explicitly stated.
You are quite correct. The quantity should prevent further writing of coil data.

I have published a tutorial on Modbus slave firmware design in C. The tutorial does not cover writing/reading coils but is very informative about all other aspects of a RTU design. The code described in the tutorial is robust and complies with the tight timing requirements of an RTU slave.


Art
 
Top