Dear rwskinner
i am looking for a modbus (RTU) slave sample code for the PIC16F877A,
can you please share your code?
Dear rwskinner
i am looking for a modbus (RTU) slave sample code for the PIC16F877A,
can you please share your code?
Sorry, No. The company will not allow me to post source. However if you can tell us where your having problems at or post your code then maybe we can help.
I found most folks are not willing to help or share code for Industrial Protocols. Mainly because there is lots of money invested in development, or in sales.
Some code and Examples Can be found here:
http://www.modbus.pl/microchip.htm
Some Actual code can be found here on the list...
http://www.picbasic.co.uk/forum/show...=&threadid=316
It works but really needs to be doctored up some.
Modbus Specifications and Examples in C can be found here:
http://www.modbus.org/docs/Modbus_ov...al_line_V1.pdf
and
http://www.modbus.org/docs/PI_MBUS_300.pdf
Do yourself a favor and try real hard not to try and do the 3.5 character timeout. If your a slave, look for the 8 byte request, then check the ID, if good then check CRC, then Check FC and Process or Reject with Error Code. So on. Build the packet and ship back off and be done with it.
If your wanting to be the Master then there is a little more to it (not much) but some.
As in the documentation
RTU as follows:
Slave ID 1 byte, Function Code 1 Byte, Start Register 2 Bytes, Number of Regs to Get 2 Bytes, CRC16 2 Bytes
RTU example: 01 03 00 00 00 01 CRCH,CRCL
Ascii as follows:
Start of Message is a colon, Slave ID 1 byte, Function Code 1 Byte, Start Register 2 Bytes, Number of Regs to Get 2 Bytes, LRC 1 Byte, CRLF to end the message.
Ascii is sent as Ascii Hex. :01 03 00 00 00 01 LRC 0D 0A
I prefer to check the Slave ID first so I'm not checking CRC's all day long on other nodes messages.
You can handl ASCII and RTU with all the same routines, except for the following.
When Receiving the Data, you have to decode it a little differently
When Sending the Data, you have to encode it a little differently
LRC or CRC checks depending on the Protocol your using.
Under my Belt so Far.
Modbus RTU
Modbus ASCII
CAN STD and EXT
J1939
Numerous proprietary industrial protocols. Frick, Cat....
Suppose to Start on AB DF1 soon. Arghhhh Not looking forward to it.
Richard
As an additional thought, I normally use the HSERIN and grab all 8 bytes of the packet, then compare the Slave ID to my own, if it matchs, then check the CRC/LRC and go from there.
Since I'm having to use SERIN2 without the hardware USART, it might be better it I just check for the correct Slave ID in the Wait portion.
I'm not sure it will actually make any difference would it, if there is a 20ms timeout, its still going to sit there for 20ms waiting for the message regardless right? Ah, but I remove the over head of collecting data and checking the Slave ID each time when there is other traffic on the line.
receive:
Gosub GetADCReadings '8 of them
Serin2 stuff here - Timeout goes back to receive (Wait for : and grab all bytes)
If SlaveID doesn't match go back to receive else
Check CRC if Bad go back to receive
Start processing message
Send Reply
goto Receive
Seems to me, if the Serin2 waits for the Slave ID Byte I end up still in the wait for 20ms, but then I immediately exit back to receive, instead of processing every packet on the line, checking ID then going back to receive. Might make a little difference.
Thoughts
dear rwskinner
thank you for your reply.
at least can you please give me a working code for generating CRC for modbus RTU (in PICBASIC Pro)
assuming that i have received from the HSERIN these byte
BYTe_1 BYTe_2 BYTe_3 BYTe_4 BYTe_5 BYTe_6 CRC1 CRC2
for example
01 03 00 00 00 0A C5 CD
how to calculate the CRC1 and CRC2
i am using this with PIC16F877A
Best Regards
Yep, it was in the thread that said "working Code"
Here is my method of CRC which I believe came from that thread ???
And my method of LRC which works but could be improved upon.
Notes:
CRC is a WORD, LRC is a Byte
Buf is an array that contains all the bytes.
Len is the number of bytes in the array and you set that depending on what your doing.
When Receiving messages LEN has to be adjusted to Exclude the CRC or LRC Bytes.
CalcCRC:
CRC16=$FFFF
For i = 0 to Len
CRC16=CRC16^Buf[i]
For j = 1 to 8
IF CRC16.Bit0 = 1 Then
CRC16=$A001^(CRC16>>1)
ELSE
CRC16=CRC16>>1
EndIf
Next j
Next i
Return
CalcLRC:
'Procedure Builds LRC value from bytes
LRC = 0
For i = 0 TO Len
LRC = LRC + Buf[i]
Next i
LRC = $100 - LRC
Return
by the way: dear rwskinner
which company are you working for?
have you implemented the can or canopen protocol using the picbasic?
can you give me the specification of these two protocols?so i can do the implementation.
best regards
Bookmarks