Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Register Log in

[SOLVED] data transfer between PC & uC based on modbus

Status
Not open for further replies.

AliBahar

Member level 2
Joined
Feb 4, 2015
Messages
42
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
337
Hi
I have created C code which performs modbus request and response. the functions that perform these tasks are wrapped in the header file and they can be called by main program on microcontroller. I want to use simple modbus software which creates modbus request on PC then the created stream must be sent to uC using rs232.
so far I have used ModbusMat software. it is simple software and it can communicate with uc based on rs232. but some problems exist.
the first: finding the ending character of sent frame from software is challenging in my c code. because the length of frame varies in different requests.
the second problem: for same data array the crc bytes of my code is different from software's.
do you know the simple modbus software which the end character of it's frame can be determined certainly?
there are different methods for crc bytes generation. which of them is most common?
 

Kurenai_ryu

Advanced Member level 2
Joined
Jun 10, 2006
Messages
671
Helped
159
Reputation
316
Reaction score
99
Trophy points
1,308
Location
Bolivia
Activity points
5,913
I used the Modbus Poll to generate modbus request and both a device and configuration... after that I used the dotNET ShortBus library to develop my master on the PC...

on the device side, (after getting a hand with comercial hardware) I used the freemodbus in an AVR implementation which includes the dreaded CRC16 implementation...

about that, i think the CRC16 has only one polynomial of x^16+x^15+x^2+1 which theory could be reviewed here...
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
47,511
Helped
14,055
Reputation
28,365
Reaction score
12,716
Trophy points
1,393
Location
Bochum, Germany
Activity points
276,254
the first: finding the ending character of sent frame from software is challenging in my c code. because the length of frame varies in different requests.
How can this be a problem? Where each message ends is obvious if you decode the MODBUS protocol correctly.

for same data array the crc bytes of my code is different from software's.
Sounds like an implementation error.
 

paulfjujo

Advanced Member level 4
Joined
Jun 9, 2008
Messages
1,394
Helped
280
Reputation
560
Reaction score
268
Trophy points
1,363
Location
France 01800
Activity points
9,734
hello


the modbus message contains itself the number of data ..after the ID,type of request..
so as FvM said.. if correct decoding, you can know the lenght of the message

Be carrefull with
- use of unsigned char for buffering the modbus message
- if parity is used with RS232 link between Master and slave!
- reverse order of CRC16 when you want to check it.
- CRC16 method can differ with some PLC supplier.. so MODBUS protocol is not 100% strict applied.



This CRC16 used with a PIC18F as master and slave ITB remote I/O mobus.

Code:
//CRC 16 for modbus checksum 
unsigned int  CRC16(unsigned int dataLength,char check)
{
// trame 01 03 00 0A 00 01 A4 08    envoi  avec check=0
// trame 01 03 02 02 03 F9 25       reception avec check=1
unsigned int CheckSum;
unsigned int i,j;
CheckSum = 0xffff;
for (j=0; j<dataLength; j++)
{
CheckSum = CheckSum^(unsigned int)buffer[j];
for(i=8;i>0;i--)
     {
        if(CheckSum & 1)
        CheckSum = (CheckSum>>1)^0xa001;
        else
        CheckSum>>= 1;
     }   
}
// attention rangement Checksum inversé
CRC16_Value=CheckSum ;  // for checking purpose 
CRC16_H = CheckSum>>8;
CRC16_L = CheckSum & 0x00FF;
if (check==1)
  {
  if ( (buffer[dataLength] == CRC16_L) && (buffer[dataLength+1] ==CRC16_H  ))
    return CheckSum;
  else
    return 0;
  }
  else
  {
  buffer[dataLength] = CRC16_L;
  buffer[dataLength+1] = CRC16_H;
  return CheckSum;
  }
 }
example of request:
Envoi Trame (Hexa): 01 03 00 03 00 08 B4 0C
Recep.Trame (Hexa): 01 03 10 00 00 00 00 00 01 00 00 00 01 00 00 00 00 02 F3 B1 40 CRC16= B1 40
8 Voies Entrees Analogiques 10bits :
EA0= 0 EA1= 0 EA2= 1 EA3= 0 EA4= 1 EA5= 0 EA6= 0 EA7= 755
 

Status
Not open for further replies.
Toggle Sidebar

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top