CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Interrupt driven data streams on USART with MODBUS packets
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
rwskinner



Joined: 08 Dec 2006
Posts: 125
Location: Texas

View user's profile Send private message

PostPosted: Mon Jan 15, 2007 6:58 pm     Reply with quote

Yes, I think I understand it. If there are framing errors then we increment the Baud rate and let it try again, hopefully we land on the correct rate. Then it rolls over and starts again.
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Tue Jan 16, 2007 10:56 am     Reply with quote

rwskinner wrote:
Yes, I think I understand it. If there are framing errors then we increment the Baud rate and let it try again, hopefully we land on the correct rate. Then it rolls over and starts again.


I'm looking back at this now and notice there is no place that clears COMM1.Framming_Errors when a good packet is received. I'm updating my original post. In the event of line noise a framing error could occur and this should not cause baud to jump when errors are less than 8 per packet. A good packet verifies baud rate and should clear the error count.
rwskinner



Joined: 08 Dec 2006
Posts: 125
Location: Texas

View user's profile Send private message

PostPosted: Tue Jan 16, 2007 11:05 am     Reply with quote

Yes, I noticed that as well, And the Lock feature wasn't implemented for the Baud Rate. I tested the auto baud feature and it seems to work pretty good, however I ended up using Baud Selection Switches and disabled the Auto Baud feature although it was cool.

I also did numerous little tweaks like setup a constant for MaxRegs then inserted that in numerous places to reduce memory and allow the Invalid Register Range to continue to work properly.

By the way, the 485 stuff you were worried about works fine by setting the enable pin in the use RS232 parameters.
kender



Joined: 09 Aug 2004
Posts: 768
Location: Silicon Valley

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

Re: modbus byte interval arriving at UART
PostPosted: Tue Jan 23, 2007 12:57 pm     Reply with quote

Neutone wrote:
MODBUS specification states a maximum time between bytes within a packet.

Spec wrote:
In RTU mode, messages start with a silent interval of at least 3.5 character times....

The entire message frame must be transmitted as a continuous stream. If a silent
interval of more than 1.5 character times occurs before completion of the frame,
the receiving device flushes the incomplete message and assumes that the next
byte will be the address field of a new message.


Neutone, which document are you refrerring to? I've searched MODBUS Application Protocol Specification, but there's not a single mention of RTU.
rwskinner



Joined: 08 Dec 2006
Posts: 125
Location: Texas

View user's profile Send private message

PostPosted: Tue Jan 23, 2007 1:59 pm     Reply with quote

On the Modicon sight, in the Modbus implementation, under Serial Modbus you have the RTU and the ASCII flavors.

RTU uses a silent timeoout to detect the end of the message or error.
ASCII uses the ":" $3A to start the frame and the CRLF to end the message frame.

Honestly, very few people actually try to implement the precise timeout that is specified. Using a standard PC Timer you can't hardly get that kind of resolution. I've built lots of Modbus RTU devices, Masters and Slaves and never had an issue trying to communicate with any other equipment.

If your writing master software then just set a reply timeout for whatever you feel is safe. Most use anywhere from 50ms to 1000 ms. Since you are the Master your controlling the line state for the most part.

If your writing Slave software and your keeping it simple like FC3 or FC6 then just wait for an 8 byte string with a 50 ms timeout. If you get 8 bytes, check the CRC and Slave ID then Parse, if not, then go do your other stuff and check to see if have anything at the USART then grab 8 bytes or timeout.
rwskinner



Joined: 08 Dec 2006
Posts: 125
Location: Texas

View user's profile Send private message

PostPosted: Tue Jan 23, 2007 2:01 pm     Reply with quote

Here is a snip I found somewhere....

RTU Framing
In RTU mode, messages start with a silent interval of at least 3.5 character times. This is most easily implemented as a multiple of character times at the baud rate that is being used on the network (shown as T1-T2-T3-T4 in the figure below). The first field then transmitted is the device address.
The allowable characters transmitted for all fields are hexadecimal 0 ... 9, A ... F. Networked devices monitor the network bus continuously, including during the silent intervals. When the first field (the address field) is received, each device decodes it to find out if it is the addressed device.

Following the last transmitted character, a similar interval of at least 3.5 character times marks the end of the message. A new message can begin after this interval.
The entire message frame must be transmitted as a continuous stream. If a silent interval of more than 1.5 character times occurs before completion of the frame, the receiving device flushes the incomplete message and assumes that the next byte will be the address field of a new message.
Similarly, if a new message begins earlier than 3.5 character times following a previous message, the receiving device will consider it a continuation of the previous message. This will set an error, as the value in the final CRC field will not be valid for the combined messages. A typical message frame is shown below.

Start Address Function Data CRC End
3.5 Char time 16Bit 8Bit N * 8Bit 16Bit 3.5 Char time
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: modbus byte interval arriving at UART
PostPosted: Thu Jan 25, 2007 2:13 pm     Reply with quote

kender wrote:
Neutone wrote:
MODBUS specification states a maximum time between bytes within a packet.

Spec wrote:
In RTU mode, messages start with a silent interval of at least 3.5 character times....

The entire message frame must be transmitted as a continuous stream. If a silent
interval of more than 1.5 character times occurs before completion of the frame,
the receiving device flushes the incomplete message and assumes that the next
byte will be the address field of a new message.


Neutone, which document are you referring to? I've searched MODBUS Application Protocol Specification, but there's not a single mention of RTU.


This is a link to an older revision of the specification. The document is "PI MBUS 300". http://www.modbustools.com/PI_MBUS_300.pdf
The section I quoted is on page 9.

A couple things to consider.
With some slave equipment the reply is variable and the master has to be configured with timeouts to match the weakest link. If a masters timing is not any better than 20mS (I have never been able to get windows to do better than this), you will have to add that to your delays.

If you have 30 devices on a network and they take 250mS each to scan that will be 12 seconds between updates on each device. If each scan has to do multiple packets per device you can double that.

This begs the question "How fast is fast enough?" The answer is as fast as the protocol allows. With the ability to add delays to the slaves replies a slave device will be compatible with any network you put it on. With the ability to add delays to the masters queries a master device will be compatible with any network you put it on.
Will an end customer be happy if his Console updates every 12 seconds? It depends on the customer.
funmix



Joined: 27 Mar 2007
Posts: 33

View user's profile Send private message

PostPosted: Thu Mar 29, 2007 8:39 am     Reply with quote

Hi all,

currently doing a project which PIC18F4520 (master ) communicate with a few PICs(drive motor and sensor).

Basically i am thinking to use modbus.

the protocol will be like:

<slave><bufferlength><data><checksum>

can someone provide a sample c code for me to study?
both for master and slave.
funmix



Joined: 27 Mar 2007
Posts: 33

View user's profile Send private message

PostPosted: Thu Mar 29, 2007 9:22 am     Reply with quote

I'm just don't know how to write main() using modbus driver for master and slave. Can someone provide simple example with modbus?
ratgod



Joined: 27 Jan 2006
Posts: 69
Location: Manchester, England

View user's profile Send private message

PostPosted: Tue Sep 25, 2007 11:31 am     Reply with quote

how do you send and receive packets using this code? I don't see any send or receive functions.
Am I correct in assuming that you load a variable with the packet info and it just goes when its ready to? and you keep reading another variable for received packets?

I have to get a PIC communicationg with an IME Nemo 72L panel meter.

it states it is JBUS/MODBUS over 3-wire RS485, is this code right for this?

thanks
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Tue Sep 25, 2007 7:21 pm     Reply with quote

ratgod wrote:
how do you send and receive packets using this code? I don't see any send or receive functions.
Am I correct in assuming that you load a variable with the packet info and it just goes when its ready to? and you keep reading another variable for received packets?

I have to get a PIC communicationg with an IME Nemo 72L panel meter.

it states it is JBUS/MODBUS over 3-wire RS485, is this code right for this?

thanks


The code I posted is designed to run in a MODBUS slave device. It will respond to a masters query with the status of registers in the slave device. The the register map is an array of INT16 values. Any value that the MODBUS master is to read from the slave device must be located in the register map. For example if the slave is reading an analog value to control a PWM output, the analog value, the PWM frequency and duty cycle can all be stored in registers so the master device can read or modify the values. The thing is you have to decide what variable you need and of those what the master should have access to. This allows a great deal of flexibility. This allows debugging of things that need to run in near real time because you can monitor things that you could never single step through.

So for this example slave you would have a while loop that calls;
1 A function to service the MODBUS port. It does nothing unless a packet was received in the interrupt routines.
2 A function to read the analog input.
3 A function to adjust the PWM

If for example your analog reading stops working when the PWM is running because of some feedback that could be hard to debug if you can't watch it as its running. MODBUS is a generic method of reading and writing variables.

For master code you have to send a query and then wait for a reply. If you get a reply send another query. If you don't get a reply after waiting x amount of time send another query. I'm guessing your panel meter is a slave device so you will have to write master code. The packets are still going to be sent and received the same. The packets are a bit different but you still have to encode and decode packets the same way.
mana111



Joined: 07 Nov 2007
Posts: 1

View user's profile Send private message

PostPosted: Wed Nov 07, 2007 5:22 am     Reply with quote

hi

when i compile kypec code i get this error

A numeric expression must appear here

on this line

int16 mb_area[48]; //all the parameters and settings shared between modules reside here
int8 mb_buffer[57]; //array used for bus transfers

in the modbus_area.c file


any suggestions??

Thanks and Regards
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

PostPosted: Sun Nov 11, 2007 2:52 pm     Reply with quote

Where is int16 defined?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Nov 11, 2007 7:49 pm     Reply with quote

It's a built-in data type of the CCS compiler. It's been that way for
at least 5 years. See the CCS manual.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group