LAN DS18B20 WEB Temperature Monitor 1 meter Cable
www.WEB-Relays.com
www.Facebook.com/KMtronic

Arduino: Function to calculate Modbus checksum

Spread the love

 

CRC-16 Modbus RTU protocol function

void Calc_CRC(unsigned char b, unsigned int* CRC)
{
   int carry, i ;

   CRC[0] ^= b & 0xFF;
   for (i=0; i<8; i++)
   {
      carry = CRC[0] & 0x0001;
      CRC[0]>>=1;
      if (carry) CRC[0] ^= GP;
   }
}

 

Example Arduino code with simple ModBus communication for show CRC-16 Modbus checksum calculation:

unsigned int CRC16, SEED, GP; //for CRC16
#define SEED 0xFFFF  //initialization for CRC16
#define GP   0xA001  //generating polynomial
int in_buffer[8]; // receiving buffer

#define CycleStart 2;  //MOD:0-D0
#define FeedHold 3;  //MOD:0-D1
#define StopFile 4;  //MOD:0-D2
#define SingleStep 5;  //MOD:0-D3
#define ResumeFile 6;  //MOD:0-D4
#define ZeroX 7;  //MOD:0-D5
#define ZeroY 8;  //MOD:0-D6
#define ZeroZ 9;  //MOD:0-D7


void setup()
{
  Serial.begin(9600);            // Init serial communication
  pinMode(2, INPUT);           // Set pin to input
  pinMode(3, INPUT);           // Set pin to input
  pinMode(4, INPUT);           // Set pin to input
  pinMode(5, INPUT);           // Set pin to input
  pinMode(6, INPUT);           // Set pin to input
  pinMode(7, INPUT);           // Set pin to input
  pinMode(8, INPUT);           // Set pin to input
  pinMode(9, INPUT);           // Set pin to input
  digitalWrite(2, HIGH);       // Turn on pullup resistor
  digitalWrite(3, HIGH);       // Turn on pullup resistor
  digitalWrite(4, HIGH);       // Turn on pullup resistor
  digitalWrite(5, HIGH);       // Turn on pullup resistor
  digitalWrite(6, HIGH);       // Turn on pullup resistor
  digitalWrite(7, HIGH);       // Turn on pullup resistor
  digitalWrite(8, HIGH);       // Turn on pullup resistor
  digitalWrite(9, HIGH);       // Turn on pullup resistor
}

void loop()
{
   if ( Serial.available() == 8 ) {
     
     // read ModBus command from Mach3
     for (int i=0; i < 8; i++) in_buffer[ i ] = Serial.read();
     
     if ((in_buffer[0]== 0x01)&(in_buffer[1]== 0x04))
         Reply_Inputs();
         else
         Reply_Error();
         
     Serial.flush();
 
   }   
}

/// ----------------------- Functions -----------------------
void Reply_Inputs()
{
   CRC16 = SEED;
   int Inputs[] ={0x01, 0x04, 0x0A, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0x00};

   Inputs[4] = ( 
               ((!digitalRead( 9 ))<<7) | 
               ((!digitalRead( 8 ))<<6) | 
               ((!digitalRead( 7 ))<<5) |
               ((!digitalRead( 6 ))<<4) |
               ((!digitalRead( 5 ))<<3) |
               ((!digitalRead( 4 ))<<2) |
               ((!digitalRead( 3 ))<<1) |
               ((!digitalRead( 2 ))   ) );

   for (int i = 0; i < 13; i++)
        {   
        Calc_CRC(Inputs[ i ], &CRC16); 
        }     
        
        Inputs[13]=CRC16 ;
        CRC16=CRC16>>8 ;
        Inputs[14]=CRC16 ;
   
   for (int i=0; i < 15; i++) Serial.write(Inputs[ i ]);
}
/// ---------------------------------------------------------
void Reply_Error()
{
   int Error[] ={0x01, 0x84, 0x00, 0x43, 0x00};
   for (int i=0; i < 5; i++) Serial.write(Error[ i ]);
}
/// ---------------------------------------------------------
void Calc_CRC(unsigned char b, unsigned int* CRC)
{
   int carry, i ;

   CRC[0] ^= b & 0xFF;
   for (i=0; i<8; i++)
   {
      carry = CRC[0] & 0x0001;
      CRC[0]>>=1;
      if (carry) CRC[0] ^= GP;
   }
}
/// ---------------------------------------------------------

 


KMtronic ModBus products

https://web-relays.com/en/blog/lan-ethernet-ip-8-channels-modbus-tcp-relay-board/

KMtronic Modbus RS485 RTU Serial to Modbus LAN TCP/IP Module Converter

 

KMtronic LAN WEB 8 Channel Relay board