Help me understand modbus RTU

nettogrisen

Lifetime Supporting Member
Join Date
Mar 2007
Location
Here
Posts
383
I'm trying to understand how the modbus RTU protocol works.

From what I understand after reading the Modbus over serial line specification and implementation guide:

Each 8-bit byte in a message contains two 4-bit hexadecimal characters.

- So good so far

It then reads:

The format ( 11 bits ) for each bye in RTU mode is:
Coding system:
8-bit binary
Bits per byte:
1 start bit
8 data bits, least significant bit sent first
1 bit for parity completion
1 stop bit

- Does every 8-bit byte, including the slave address, function code and CRC need start, stop and parity bits, or is this only for the data part of the frame?
I'm really not getting this part... Do I need to transmit 11 bits per byte?

- Am I correct that the startbit is always low, and the stopbit is always high, or are they calculated somehow?

Could a message look like this?:


<3.5 char wait>
0x0001 (Slave address 1)
0x0001 (Function code 1, read coils)
0 (Low bit for start bit)
0x0000 (Starting address 0)
1 (Parity bit)
1 (High bit for stop bit)
0 (Low bit for start bit)
0x0005 (Read 5 coils)
1 (Parity bit)
1 (High bit for stop bit)
0x0000 (CRC low byte)
0x0000 (CRC high byte)
<3.5 char wait>



These are the questions that I could come up with right now.

Am I way off course? Any help would be appreciated.
 
Unless you are trying to code at an incredibly low level don't worry about the start bit, bits per byte, parity bit or stop bit. These are merely paramaters for the serial transmitting chip in a computer.

Yes, each byte, including each of those in address, function code, data and CRC are wrapped with these bits for transmission. Again, unless you have an incredibly quick CPU or are designing your own ACIA chip you don't need to worry about the parameters you have noted.

What hardware were you planning to connect using MODBUS?
 
Thank you bernie.

My ultimate goal is actually to write a modbus RTU master in c++ using the build in c++ serial control library.
 
- Does every 8-bit byte, including the slave address, function code and CRC need start, stop and parity bits, or is this only for the data part of the frame?

No. Each byte is part of 2 byte register address, register value, modbus command, number of values requested or CRC value. Slave addresses are one byte only. I can't recall what format errors take on.

Each byte in Modbus RTU has a format, characterized by something like 8-N-1: 8 data bits, No parity, 1 stop bit; so every byte has parity, every byte has even, odd, or no parity.
Modbus RTU is, by definition, 8 data bits (Modbus ASCII is, by definition, 7 data bits)

The parity and stop selection is up to the field implementation, although the Modbus spec says no parity shall have 2 stop bits, many implementations of Modbus ignore that and allow 1 stop bit with no parity. Most systems allow some changes for parity selection.

As Bernie, says, the data bits, stop bits and parity are aspects of serial communication, not unique to Modbus that are usually handled below the level of Modbus programming.

Addresses require 2 words, for instance, 10002, where the leading 1 is understood, not actually transmitted.

For command 01, read coils, you need to specify the address and the number of coils:

A byte is 2 digit hex, for example, 0xFE, where the 8 bit FE byte would be 1111 1110

Your example is a message, consisting of various combinations of bytes, and would look like:

0x01 (Slave address 1) (one byte in 8-N-1 format)
0x01 (Function code 1) read coils (one byte in 8-N-1 format)
0x00 (Starting address hi) (one byte in 8-N-1 format)
0x02 (Starting address Lo) (one byte in 8-N-1 format)
0x00 (number of coils requested, high) (one byte in 8-N-1 format)
0x05 (number of coils requested, low) (one byte in 8-N-1 format)
0xYY (CRC low byte) I'm not sure whether CRC high or low is first (one byte in 8-N-1 format)
0xZZ (CRC high byte) (one byte in 8-N-1 format)

Be sure to check out
http://modbus-ida.org/docs/Modbus_over_serial_line_V1_02.pdf

- Am I correct that the startbit is always low, and the stopbit is always high, or are they calculated somehow?

I can't recall, it's part of the serial comm protocol.

Dan
 
Am I correct that the startbit is always low, and the stopbit is always high, or are they calculated somehow?

The resting status of the quiet communication line is the same as the stopbit. Thus the start bit indicates the start of the character. The stopbit is to ensure at least one bit time in the resting state between characters. Various protocols may require more (quiet time between characters).
 
I second ndzied1's recommendation. I have it on my bookshelf. If you read nothing but the first few chapters on serial communications you will be way ahead. The chapters on error correction and modems are also great. Even if there was no C programming it would still be worth the purchase. (Though I did learn a lot about structured programming from the book also.)
 
Thank you very much Dan, Bernie and ndzied1, that definitely helped alot.

Only having to be concerned with the "8-bit modbus part" makes this alot easier to understand.

I'll order the book today. That'll be the 6th C/C++ book this month. I'll need to get a bigger bookshelf soon ;)

More questions to follow...
 
- Does every 8-bit byte, including the slave address, function code and CRC need start, stop and parity bits, or is this only for the data part of the frame?

I answered No before, but the answer is yes.

Each word in a Modbus RTU message will have a start bit, 8 data bits (one byte), maybe a parity bit (depends on even, odd or none), and either 1 or two stops bits.

I was thinking message, not data word in the previous post.

Dan
 
Yes, I figued as I don't control the start, stop and parity bits individually.

What I got from your post was that I just open the com port, and then stream 8-bit modbus commands. The c++ serial port library will handle the star, stop and parity bits.

What I don't get now is that the data part of the frame can be from 0 - 252 bytes long.
How does the receiving end know when the data part ends and the CRC part starts?
 
Yeah, you got the part about letting the library handle the serial part.

I'm an implementer of Modbus, not a programmer, but I can make a guess about data frame size.

Slaves only implement certain commands.

For instance, a radio base station that I'm familiar with is designed to handle field transmitters so it does not handle commands 01 or 02, because data from field transmitter is assumed to be analog, so the base station does only 03 (holding register) commands for data retrieval [possibly 0x10 or 16(dec) also]. It does do (undocumented) 04 (input registers) which happen to map to 03 memory. The documentation spells out which other commands the slave will handle.

The Modbus Application Protocol spec (V1.1b) provides a flow chart for handling messages:

2yyuz2q.jpg


I'm guessing that given that the slave has been programmed to implement only specific commands, that the slave, under "request processing"
- has already decoded the 'command' byte to see what the command instruction is
- from the command instruction determines either
- a message size from the specified command format, ie, the command format specified in the Modbus spec, or
- uses the 'byte count' words which determine how much information follows (if the command is a write command from the master requiring the slave to accept data)

In your example, "number of coils requested" would be reflected in the reply and would be used to determine how many Modbus data words would follow in the reply.

The command 05 is "write a single coil", so the command is always of a fixed length.

06 doesn't have the byte count, but 04 does and its flow diagram shows it:

2lldni9.jpg

I hope this helps.

Dan
 
Thank you Dan for that excelent explanation.

I see what you mean, that the length of the data part is ofcourse defined by the function, and that sending more or less bytes will result in an error.

For my first project I'm going to attempt to control an Altivar 61/71 as I have done this alot with PLCs, and am fairly confident with it.

I'm going to need to read/write holding registers, but am possibly going to implement read/write single coils too this is not needed though.

More questions to follow... :)
 
I've done alot of googeling on this subject, and have found that page before.
It's alittle advanced for me though. I find it a bit hard to follow, and to distinguish what's modbus TCP and whats modbus RTU/ASCII.
It's a good refrence though, and I'm sure that I'll be able to use some of it.

Thanks :)
 
FYI, I just ran into a document that spells out the order of the CRC bytes (low first, then high):

syat93.jpg



2rw3jtj.jpg
 

Similar Topics

I have a device I am trying to collect data from via modbus into controllogix system. I am using a prosoft mvi56-mcm card and have established...
Replies
7
Views
2,623
Hiya, In the past I have worked with AB PLCs, Citect, DH+ but I have recently changed jobs and struggling with the changes. Sometimes dont know...
Replies
2
Views
1,676
If a programmable controller controls the operation of a motor, what connects motor control to the PC? A) Line voltage B) I/O device C) Modem D)...
Replies
27
Views
7,093
Okay. On a semi-impulse, I scored one of these units relatively inexpensively. A development rig upgrade over my L320ERM: 5MB user memory, 120...
Replies
4
Views
1,446
OK, so am wanting to move 100+ tags into a new UDT. I figured the easiest way to do this is to copy and paste the tags into excel. Then...
Replies
5
Views
1,914
Back
Top Bottom