I am trying to develop Modbus RTU function 1 , i.e read coil register.
Below peice of code written for Modbus RTu with function code 3 .i.e holding register.
.
function 1- uses bit values
function 3 uses byte value to store.
Now i am having 50 digital io status to be read. the status of digital io are 0 or 1.
my request goes like this
Serial_Request()
Is function i am calling in interrupt. I am checking first 8 byte of messages 01 01 00 00 00 31 fd de
rxbuf[0]= 01 //device Id always
rxbuf[1]= 01 //Functional code
rxbuf[2]= 00 //higher byte of start address
rxbuf[3]= 00 //Lower byte of start address
rxbuf[4]= 00 //higher byte of end address
rxbuf[5]= 31 //Lower byte of end address
rxbuf[6]= FD //CRC1
rxbuf[7]= DE //CRC2
First i will check CRC1 & CRC2 is Valid or not if valid
Get rxbuf[0]= 01 match with device ID then
rxbuf[1]= 01 match with function code
Then calculate length assign start address & length
Store the values & check CRC again.
1) how can i store bit value of digital io in byte and call for legth
2)how can i pack data & send for CRC check
3)how can i calculate length of bits
i need simple modified code below.Here receiving data no issue. CRC check no issue. only need modofiation in length,store bit value & pack the data
length= first byte =0000in hex
sec byte =0031 in hex
length = 31/8 = 6 in hex
6 byte of data where first 8 bit packed in first byte i.e 8 digital io status in first byte and 2nd 8 bit data in sec byte & so on...
Then pack data & send for CRC check
CRC check function
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>= 1;
crc ^= poly;
}
else
crc >>= 1;
}
}
return (crc);
}
below function designed for function3
Code:
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;
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;
}