The CRC value of the incoming data is the 23rd data value, and I need to generate this CRC value. However, I've tried using CRC-8, LRC, BCC, and checksum methods, but they all yield different results. I don't know what to add or modify to create the CRC value in the 23rd data. I really need help with this.
I have tried using CRC, LRC, checksum, and BCC with the below code. The values comments are the checksum values.
#include <stdio.h>
unsigned char a[19][22] =
{
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, //ad (checksum value)
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, //ad
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, //ad
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x04}, //b2
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x09,0x19,0x53,0x00,0x11,0x20,0x45,0x02,0x91}, //e1
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x29,0x20,0x43,0x00,0x11,0x20,0x46,0x03,0x01}, //d3
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x38,0x20,0x83,0x00,0x11,0x20,0x47,0x03,0x21}, //da
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x43,0x21,0x13,0x00,0x11,0x20,0x47,0x03,0x21}, //d0
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x47,0x21,0x23,0x00,0x11,0x20,0x47,0x03,0x21}, //d5
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x49,0x21,0x33,0x00,0x11,0x00,0x48,0x03,0x21}, //d7
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x51,0x21,0x43,0x00,0x11,0x00,0x48,0x03,0x21}, //d1
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x52,0x21,0x53,0x00,0x11,0x30,0x48,0x03,0x21}, //d6
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x52,0x21,0x63,0x00,0x11,0x20,0x48,0x03,0x31}, //d7
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x52,0x21,0x63,0x00,0x11,0x00,0x48,0x03,0x31}, //d5
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x20,0x48,0x03,0x21}, //d6
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x20,0x48,0x03,0x21}, //d6
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x30,0x48,0x03,0x21}, //d7
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x20,0x48,0x03,0x21}, //d6
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x00,0x48,0x03,0x21} //d4
};
unsigned char calculate_byte_sum(unsigned char *data, int length)
{
unsigned char checksum = 0;
int i;
for (i = 0; i< length; i++)
{
checksum += data[i];
}
return checksum;
}
unsigned char calculate_crc8(unsigned char *data, int length)
{
unsigned char crc = 0x00;
unsigned char polynomial = 0x07;
for (int i = 0; i < length; i++)
{
crc += data[i];
for (int j = 0; j < 8; j++)
{
if (crc & 0x80)
{
crc = (crc << 1) ^ polynomial;
}
else
{
crc <<= 1;
}
}
}
return crc;
}
unsigned char calculate_bcc(unsigned char *data, int length)
{
unsigned char bcc = 0;
for (int i = 0; i < length; i++)
{
bcc ^= data[i];
}
return bcc;
}
unsigned char calculate_lrc(unsigned char *data, int length)
{
unsigned char lrc = 0;
for (int i = 0; i < length; i++)
{
lrc += data[i];
}
return (unsigned char)((~lrc));
}
void fcs_test(unsigned char* data, unsigned int len)
{
unsigned char ch,ch1, ch2,ch3,ch4,ch5;
ch = calculate_byte_sum(data, len);
ch1 = calculate_crc8(data, len);
ch2 = calculate_bcc(data,len);
ch3= calculate_lrc(data,len);
printf("calculate_byte_sum = %02x calculate_crc8 = %02x calculate_bcc = %02x calculate_lrc = %02x\n", ch,ch1,ch2,ch3);
// printf("fcs = %02x \n", ch);
}
int main()
{
unsigned int i;
for (i=0 ; i < 19; i++)
{
fcs_test(&a[i][0], 22);
}
return 0;
}
Based on some observations described in Martin Brown's comments above, this may be simply a sum of nibbles, with some additional constant, like this (try it out on Godbolt as well):
#include <stdio.h>
#define NUM_ROWS 19
#define NUM_COLS 22
unsigned char arr[NUM_ROWS][NUM_COLS] =
{
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, // ad
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, // ad
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, // ad
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x04}, // b2
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x09,0x19,0x53,0x00,0x11,0x20,0x45,0x02,0x91}, // e1
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x29,0x20,0x43,0x00,0x11,0x20,0x46,0x03,0x01}, // d3
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x38,0x20,0x83,0x00,0x11,0x20,0x47,0x03,0x21}, // da
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x43,0x21,0x13,0x00,0x11,0x20,0x47,0x03,0x21}, // d0
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x47,0x21,0x23,0x00,0x11,0x20,0x47,0x03,0x21}, // d5
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x49,0x21,0x33,0x00,0x11,0x00,0x48,0x03,0x21}, // d7
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x51,0x21,0x43,0x00,0x11,0x00,0x48,0x03,0x21}, // d1
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x52,0x21,0x53,0x00,0x11,0x30,0x48,0x03,0x21}, // d6
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x52,0x21,0x63,0x00,0x11,0x20,0x48,0x03,0x31}, // d7
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x52,0x21,0x63,0x00,0x11,0x00,0x48,0x03,0x31}, // d5
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x20,0x48,0x03,0x21}, // d6
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x20,0x48,0x03,0x21}, // d6
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x30,0x48,0x03,0x21}, // d7
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x20,0x48,0x03,0x21}, // d6
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x00,0x48,0x03,0x21} // d4
};
unsigned char checksum(unsigned char *data, size_t length)
{
unsigned char result = 0;
for (size_t idx = 0; idx < length; ++idx)
{
result += (0x0F & data[idx]) + (data[idx] >> 4);
}
return result - 99;
}
int main(void)
{
for (size_t idx = 0; idx < NUM_ROWS; ++idx)
{
printf("%02x\n", checksum(&arr[idx][0], NUM_COLS));
}
}
Although I'm not sure about the constant 99
above: maybe the real algorithm uses something data lengh-related. But since all rows in your sample imput have the same length, I couldn't produce a better guess.