[CODE]
unsigned int crc_fn(unsigned char *dpacket,unsigned int len) // CRC Function(Error calcualtion)
{
unsigned int crc = 0xffff,poly = 0xa001;
unsigned int i=0;
for(i=0;i<len;i++)
{
crc^= dpacket[i];
for(j=0;j<8;j++)
{
if(crc & 0x01)
{
crc >>= 1;
crc ^= poly;
}
else
crc >>= 1;
}
}
return (crc);
}
void ChecksumCal(char No_Bytes)
{
unsigned char highbyte,lowbyte;
unsigned short crc,thisbyte,i,shift,lastbit; /* 16 bit word values */
/* compute the CRC over the first 6 chars of the message*/
crc = 0xFFFF;
No_Bytes = No_Bytes -1;
for(i=0;i<=No_Bytes;i++)
{
thisbyte = rxbuf[i];
crc = crc^thisbyte;
for(shift=1;shift<=8;shift++)
{
lastbit = crc&0x0001;
crc = (crc>>1)&0x7fff;
if(lastbit==0x0001)
{
crc=crc^0xa001;
}
}
}
lowbyte = (crc>>8)&0xff;
highbyte = crc & 0xff;
crc_msb = highbyte;
crc_lsb = lowbyte;
}
void Serial_Request()
{
unsigned int address,crc1,crc2;
unsigned char length,i,j=0;
// Serial_1_Send_byte(rxbuf[0]);
crc2=crc_fn(&rxbuf[0],6); //crc function for received protocol from request
__delay_ms(10); // Changed on 20.01.2017
if((rxbuf[6]==(unsigned char)(crc2))&&(rxbuf[7]==((unsigned char)(crc2>>8))))
{
if(rxbuf[0]==device_ID)
{
//Serial_1_Send_byte(rxbuf[0]);
if(rxbuf[1]==READ_REG)
{
address=(((unsigned int)(rxbuf[2]<<8))+((unsigned int)(rxbuf[3])));
if(rxbuf[5]>=1)
{
// changes i made for function1, if i used i get an error.
length=(rxbuf[5]/8);// function code 1
address=0X01;// function code 1
[B] // original function 3 code, if i keep below code it works fine for function 3
// length=(rxbuf[5]*2);// function 3
// address=(address*2);// function 3
[/B]
ser_data[0]=device_ID;
ser_data[1]=rxbuf[1];
ser_data[2]=length;
crc_data[0]=device_ID;
crc_data[1]=rxbuf[1];
crc_data[2]=length;
j=3;
for(i=address;i<((address+length));i++)
{
crc_data[j++]=ser_data[i+3];
}
crc1 =crc_fn(&crc_data[0],(length+3)); //crc function for response protocol from the device
Serial_1_Send_byte(ser_data[0]);
Serial_1_Send_byte(rxbuf[1]);
Serial_1_Send_byte(ser_data[2]);
for(i=address;i<((address+length));i++)
{
Serial_1_Send_byte(ser_data[i+3]);
}
Serial_1_Send_byte((unsigned char)crc1);
Serial_1_Send_byte((unsigned char)(crc1>>8));
}
}
__delay_ms(5);
}
}
index=0;
rec_flag = 0;
}
I am getting improper modbus response error.
Makes no sense. A request with invalid CRC isn't answered by the a MODBUS server at all. What do you mean by "invalid response"? An invalid response can be only send by a faulty MODBUS server. Or is the server sending an exception code like illegal data address? Holding registers (read function 3) and coils (read function 1) don't necessarily share the same address range.invalid response or CRC error
unsigned int crc_fn(unsigned char *dpacket,unsigned int len) // CRC Function(Error calcualtion)
{
unsigned int crc = 0xffff,poly = 0xa001;
unsigned int i=0;
for(i=0;i<len;i++)
{
crc^= dpacket[i];
for(j=0;j<8;j++)
{
if(crc & 0x01)
{
crc >>= 1;
crc ^= poly;
}
else
crc >>= 1;
}
}
return (crc);
}
/* Tried changes with crc function */
#define READ_REG 1
static const unsigned long crc16_tab[] = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
};
unsigned short crc16(char * buf, unsigned short size)
{
unsigned int crc = 0;
while (size--)
crc = (crc << 8) ^ crc16_tab[(crc >> 8) ^ * buf++];
return crc;
}
void Serial_Request()
{
unsigned int address,crc1,crc2;
unsigned char length,i,j=0;
// Serial_1_Send_byte(rxbuf[0]);
crc2=crc_fn(&rxbuf[0],6); //crc function for received protocol from request
__delay_ms(10); // Changed on 20.01.2017
if((rxbuf[6]==(unsigned char)(crc2))&&(rxbuf[7]==((unsigned char)(crc2>>8))))
{
if(rxbuf[0]==device_ID)
{
//Serial_1_Send_byte(rxbuf[0]);
if(rxbuf[1]==READ_REG)
{
address=(((unsigned int)(rxbuf[2]<<8))+((unsigned int)(rxbuf[3])));
if(rxbuf[5]>=1)
{
// changes i made for function1, if i used i get an error.
length=(rxbuf[5]/8);// function code 1
address=0X01;// function code 1
// original function 3 code, if i keep below code it works fine for function 3
length=(rxbuf[5]*2);// function 3
address=(address*2);// function 3
ser_data[0]=device_ID;
ser_data[1]=rxbuf[1];
ser_data[2]=length;
ser_data[3]=0;
ser_data[4]=0;
ser_data[5]=0;
ser_data[6]=0;
ser_data[7]=0;
ser_data[8]=0;
ser_data[9]=0;
ser_data[10]=0;
ser_data[11]=0;
ser_data[12]=length;
ser_data[13]=0;
ser_data[14]=0;
ser_data[15]=0;
ser_data[16]=0;
ser_data[17]=0;
ser_data[18]=0;
ser_data[19]=0;
ser_data[20]=0;
ser_data[21]=0;
crc_data[0]=device_ID;
crc_data[1]=rxbuf[1];
crc_data[2]=length;
j=3;
for(i=address;i<((address+length));i++)
{
crc_data[j++]=ser_data[i+3];
}
crc1 =crc_fn(&crc_data[0],(length+3)); //crc function for response protocol from the device
Serial_1_Send_byte(ser_data[0]);
Serial_1_Send_byte(rxbuf[1]);
Serial_1_Send_byte(ser_data[2]);
for(i=address;i<((address+length));i++)
{
Serial_1_Send_byte(ser_data[i+3]);
}
Serial_1_Send_byte((unsigned char)crc1);
Serial_1_Send_byte((unsigned char)(crc1>>8));
}
}
__delay_ms(5);
}
}
index=0;
rec_flag = 0;
}
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 void Serial_Request() { unsigned int address,crc1,crc2; unsigned char length,i,j=0; // Serial_1_Send_byte(rxbuf[0]); crc2=crc_fn(&rxbuf[0],6); //crc function for received protocol from request __delay_ms(10); // Changed on 20.01.2017 if((rxbuf[6]==(unsigned char)(crc2))&&(rxbuf[7]==((unsigned char)(crc2>>8)))) { if(rxbuf[0]==device_ID) { //Serial_1_Send_byte(rxbuf[0]); if(rxbuf[1]==READ_REG) { address=(((unsigned int)(rxbuf[2]<<8))+((unsigned int)(rxbuf[3]))); if(rxbuf[5]>=1) { // changes i made for function1, if i used i get an error. length=(rxbuf[5]/8);// function code 1 address=0X01;// function code 1 // original function 3 code, if i keep below code it works fine for function 3 length=(rxbuf[5]*2);// function 3 address=(address*2);// function 3 ser_data[0]=device_ID; ser_data[1]=rxbuf[1]; ser_data[2]=length; ser_data[3]=0; ser_data[4]=0; ser_data[5]=0; ser_data[6]=0; ser_data[7]=0; ser_data[8]=0; ser_data[9]=0; ser_data[10]=0; ser_data[11]=0; ser_data[12]=length; ser_data[13]=0; ser_data[14]=0; ser_data[15]=0; ser_data[16]=0; ser_data[17]=0; ser_data[18]=0; ser_data[19]=0; ser_data[20]=0; ser_data[21]=0; crc_data[0]=device_ID; crc_data[1]=rxbuf[1]; crc_data[2]=length; j=3; for(i=address;i<((address+length));i++) { crc_data[j++]=ser_data[i+3]; } crc1 =crc_fn(&crc_data[0],(length+3)); //crc function for response protocol from the device Serial_1_Send_byte(ser_data[0]); Serial_1_Send_byte(rxbuf[1]); Serial_1_Send_byte(ser_data[2]); for(i=address;i<((address+length));i++) { Serial_1_Send_byte(ser_data[i+3]); } Serial_1_Send_byte((unsigned char)crc1); Serial_1_Send_byte((unsigned char)(crc1>>8)); } } __delay_ms(5); } } index=0; rec_flag = 0; }
length=(rxbuf[5]/8);
crc_data[0]=device_ID;
crc_data[1]=rxbuf[1];
crc_data[2]=length;
j=3;
for(i=address;i<((address+length));i++)
{
crc_data[j++]=ser_data[i+3];
}
crc1 =crc_fn(&crc_data[0],(length+3)); //crc function for response protocol from the device
Serial_1_Send_byte(ser_data[0]);
Serial_1_Send_byte(rxbuf[1]);
Serial_1_Send_byte(ser_data[2]);
for(i=address;i<((address+length));i++)
{
Serial_1_Send_byte(ser_data[i+3]);
}
Serial_1_Send_byte((unsigned char)crc1);
Serial_1_Send_byte((unsigned char)(crc1>>8));
0..32 means 33 items.I want to read totally 32 coil register , starting from 0-32 min.
That code does not work as you expect as it will be performed using integer arithmetic. That means that for values of 'rxbuf[5]' from 0 to 7, the value of 'length' will be 0 and not 1 as you would require. You need to use the formula such as the one I gave earlier (post #10).length i got from length=(rxbuf[5]/8); or length=(rxbuf[5]-rxbuf[3])/8
You will send:
- 0x0007 (the address of the first coil)
- 0x0031 (the number of coils)
You will get back
- 0x01 (an 8 bit value telling you that there is 1 byte to follow)
- 0x0n (see below)
0x0000 (the address of the first coil)
0x0031 (the number of coils)
You will get back
I am requesting for 50 coils . i should receive 6 byte of data and send in 2 byte
0x0000 (the address of the first coil)
0x0032 (the number of coils to read - 50 decimal in this case)
#include <stdint.h>
#define CRC16 0x8005
uint16_t gen_crc16(const uint8_t *data, uint16_t size)
{
uint16_t out = 0;
int bits_read = 0, bit_flag;
/* Sanity check: */
if(data == NULL)
return 0;
while(size > 0)
{
bit_flag = out >> 15;
/* Get next bit: */
out <<= 1;
out |= (*data >> (7 - bits_read)) & 1;
/* Increment bit counter: */
bits_read++;
if(bits_read > 7)
{
bits_read = 0;
data++;
size--;
}
/* Cycle check: */
if(bit_flag)
out ^= CRC16;
}
return out;
}
[CODE]
int bitsCount(unsigned x)
{
int b;
for (b = 0; x != 0; x >>= 1)
if (x & 01)
b++;
return b;
}
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?