TheodoreWS
TheodoreWS

Reputation: 23

Modbus implementation in C for embedded system lpcxpresso

I am new to modbus and I have to program a lpcxpresso baseboard as a master to collect readings from a powermeter using RS485 Modbus protocol.

I am familiar with the protocol (about the PDU ADU frame, function codes, master-slave) through reading of specifications from modbus.org. However I have difficulties in the implementation when writing the code in C.

So my questions are:

  1. Do I have to open connection, set the baud rate, etc when I am starting the connection?
  2. I am thinking to send the frame as byte[]. Is this correct? or are there any other ways to do it?
  3. Does the data send have to be in hexadecimal, or binary or integer?
  4. CRC generation and checking.

I will really appreciate all kind of help and assistance :) Sorry if the questions are not very specific or too basic

Upvotes: 2

Views: 3673

Answers (2)

LPs
LPs

Reputation: 16213

First of all: is ModBus RTu or ASCII?

  1. Yes, of course. You need to specify all things as specs describe.
  2. Yes, it is a unsigned char[]. The structure is described by specs.
  3. The question doesn't make sense: You always send info as "memory dump", but with RTU you send 1 byte per memory byte, in case of ASCII you send 2 byte per memory byte. Eg. if you have to send a byte 0xAE: RTU=0xAE - ASCII= 0x41 0x45. In case of RTU, if you have to send an int (4 byte) you will send those bytes as they are stored in memory, eg: 12345 will be sent as 0x00 0x00 0x30 0x39 (big endian), 0x39 0x30 0x00 0x00 (little endian).

enter image description here

  1. The calculation of CRC is explained in specs. Below the code of my old CBuilder component

    unsigned short TLPsComPort::Calculate_CRC16 ( int Message_Length, char *Message)
    {
            char Low_CRC;
            char Bit;
           // Constant of ModBus protocol
           unsigned short CONSTANT     = 0xA001;
           unsigned short CRC_REGISTER = 0xFFFF;
    
           for (int i=0; i<Message_Length; i++)
           {
              Low_CRC = CRC_REGISTER;
              Low_CRC = *(Message+i) ^ Low_CRC;
              CRC_REGISTER =  ((CRC_REGISTER & 0xFF00) | (Low_CRC & 0x00FF));
              for (int j=0; j<8;j++)
              {                                                                    
                 Bit = CRC_REGISTER & 0x0001;
                 CRC_REGISTER = (CRC_REGISTER >> 1) & 0x7FFF;
                 if (Bit) CRC_REGISTER = CRC_REGISTER ^ CONSTANT;
              }
           }
    
           return CRC_REGISTER;
        }
    

Upvotes: 2

user694733
user694733

Reputation: 16043

Step 1: Forget about energy meter and modbus for now. Most important thing is to get hardware working. RS485 is simply a serial port. Read manual on how to initialize serial port on your hardware, and send single byte to your PC and back. Then send hundreds of bytes to PC and back.

Setp 2: Get timer on your hardware working also. Modbus protocol has some requirements on timing so you'll need it too.

Step 3: Get modbus specification. It will explain protocol format and checksums. Use modbus library or write your own. Make sure you can make it work with PC, before you move on to the energy meter.

Step 4: If you have a problem, ask specific question about it on SO.

Upvotes: 2

Related Questions