Author Topic: MODBUS RTU query&response  (Read 4903 times)

garinchabraziliana

  • Guest
MODBUS RTU query&response
« on: June 11, 2008, 07:00:25 AM »
Hi,

i\'m beginner in MODBUS, so please help me.
i have a temperature regulator with MODBUS communication.
For example:
If  i want to read holding register e.g.: 0042 „Value of temperature“ from mentioned device, in my application for MODBUS-RTU communication which i was writte in
Microsoft Visual Studio 2005- VC#,
i made request -byte array:
{0x01,   0x03,  0x00,  0x29,  0x00,  0x01,  0x83,  0x01}
     

1- slave adress (configured in device)- 0x01
2.- function code(Read Holding Registers)- 0x03
3.- start adress Hi- 0x00
4.- start adress Lo- 0x29
5.- no. of registers Hi- 0x00
6.- no of registers Lo- 0x01
7.- error code- 0x83
8.- exception code- 0x01   

and sent that array to device. Label Rx blinks ,on the front panel of device, so device received my request, but i don\'t get any response, Tx doesn\'t blink!!!
For example:
If  holding register  0042 „Value of temperature“=555, response message from device should be:

{slave adress=0x01, function code= 0x03, byte count= 0x02, register value Hi= 0x02,
register value Lo= 0x2B,...          }  !!!????
But i get nothing!!!!
All other parameters like port name, baud rate, parity, data bits, stop bits,ReadTimeout, WriteTimeout and RS485/RS232 converter are O.K.
Plese, could You help me with some advice to get response from device and tell me what i do wrong.
Is my request -byte array O.K.??? (especialy last two bytes 0x83, 0x01- CRC)
 
Thank You very much.

Best regards!

davidcemin

  • Guest
MODBUS RTU query&response
« Reply #1 on: September 26, 2008, 02:21:27 PM »
Hi,

I am having almost the same problem of yours. I send a message to a PLC and it doesn\'t answer. The RX led blinks, but the TX stays quiet. I am suspecting that in my code the initialization of the rs232 driver is wrong. Maybe something related to the mode that is been used.

I am trying to understand what do you mean with the last two bytes of your datagram:

ť 7.- error code- 0x83
ť 8.- exception code- 0x01   

You mean that these are the CRC bytes, right?

There are serveral algorithms to calculate these values on the internet. I have implemented one, according to the definition of the modbus.org site, and a second one, according to the examples that they give in the specification. They have different results ..





ť Hi,
ť
ť i\'m beginner in MODBUS, so please help me.
ť i have a temperature regulator with MODBUS communication.
ť For example:
ť If  i want to read holding register e.g.: 0042 „Value of temperature“ from
ť mentioned device, in my application for MODBUS-RTU communication which i
ť was writte in
ť Microsoft Visual Studio 2005- VC#,
ť i made request -byte array:
ť {0x01,   0x03,  0x00,  0x29,  0x00,  0x01,  0x83,  0x01}
ť      
ť
ť 1- slave adress (configured in device)- 0x01
ť 2.- function code(Read Holding Registers)- 0x03
ť 3.- start adress Hi- 0x00
ť 4.- start adress Lo- 0x29
ť 5.- no. of registers Hi- 0x00
ť 6.- no of registers Lo- 0x01
ť 7.- error code- 0x83
ť 8.- exception code- 0x01   
ť
ť and sent that array to device. Label Rx blinks ,on the front panel of
ť device, so device received my request, but i don\'t get any response, Tx
ť doesn\'t blink!!!
ť For example:
ť If  holding register  0042 „Value of temperature“=555, response message
ť from device should be:
ť
ť {slave adress=0x01, function code= 0x03, byte count= 0x02, register value
ť Hi= 0x02,
ť register value Lo= 0x2B,...          }  !!!????
ť But i get nothing!!!!
ť All other parameters like port name, baud rate, parity, data bits, stop
ť bits,ReadTimeout, WriteTimeout and RS485/RS232 converter are O.K.
ť Plese, could You help me with some advice to get response from device and
ť tell me what i do wrong.
ť Is my request -byte array O.K.??? (especialy last two bytes 0x83, 0x01-
ť CRC)
ť  
ť Thank You very much.
ť
ť Best regards!

davidcemin

  • Guest
MODBUS RTU query&response
« Reply #2 on: September 26, 2008, 02:22:10 PM »
#include
#include

static unsigned int modbusCRC(unsigned int *data, unsigned char dataLen)
{

   //Procedure:
   //1) Load a 16-bit register with FFFF. Call this the CRC Register
   //
   //2) Exclusive OR the first 8-bit byte of the message with the low-order byte
   //of the 16-bit CRC register, putting the result in the CRC register.   
   //
   //3) Shift the CRC register one bit to the right (toward the LSB), zero-filling the
   //MSB. Extract and examine the LSB.
   //
   //4) If LSB was 0: Repeat step 3 - noch einen shift
   //    If LSB was 1: Exclusive OR the CRC register with the polynomial value 0xA001
   //
   //5) Repeat Steps 3 and 4 until 8 shifts have been performed. When this is done, a
   // complete 8-bit byte will have been processed.
   //
   //6) Repeat Steps 2 through 5 for the next 8-bit byte of the message. Continue doing
   //this until all bytes have been processed.
   //
   //7) The final contents of the CRC register is the CRC value.
   
   //Step 1.
   unsigned int crc = 0xffff;
   unsigned int tempCRC;
   unsigned char tempLSB, flag;
   int i, j;

   for (i = 0; i < dataLen; i++) { //Bytes of the message
      tempLSB = 0x00FF & crc;
   
      //Step 2.
      crc = tempLSB ^ data;

      for (j = 0; j < 8; j++) {
         tempCRC = crc;
         //step 3.
         flag = tempCRC & 0x0001;
         crc = crc >> 1;

         //step 4.
         if (flag)
            crc = crc ^ 0xA001;
      } //step 5.

   } //Step 6.

   return crc; //step 7.
}

static void modbusCRCAppend(unsigned int *data, unsigned int dataLen, unsigned int crc)
{
   data[dataLen + 1] = crc >> 8;
   data[dataLen] = crc & 0xFF;
}

int main()
{
   unsigned int data[10], len, crc;
   int i;

   printf(\"Digite a quantidade de bytes para o CRC: \");
   scanf(\"%d\", &len);

   for (i = 0; i < len; i++) {
      printf(\"Digite o valor do %d° byte(hexa): \", i + 1);
      scanf(\"%x\", &data);
   }

   printf(\"Data: 0x%\");
   for (i = 0; i < len; i++)
      printf(\"%x\", data);
   printf(\"\\n\\r\");

   crc = modbusCRC(data, len);
   modbusCRCAppend(data, len, crc);

   printf(\"Crc: 0x%x\\n\\r\", crc);

   printf(\"DataCRCAppend: 0x%\");    
   for (i = 0; i < len + 2; i++)
      printf(\"%x\", data);
   printf(\"\\n\\r\");

   return 0;
}



===

davidcemin

  • Guest
MODBUS RTU query&response
« Reply #3 on: September 26, 2008, 02:23:06 PM »
#include
#include

/* Table of CRC values for high¿order byte */
static unsigned char auchCRCHi[] = {
   0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
   0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
   0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
   0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
   0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
   0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
   0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
   0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
   0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
   0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
   0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
   0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
   0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
   0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
   0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
   0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
   0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
   0x40
} ;


/* Table of CRC values for low¿order byte */
static char auchCRCLo[] = {
   0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
   0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
   0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
   0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
   0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
   0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
   0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
   0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
   0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
   0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
   0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
   0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
   0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
   0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
   0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
   0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
   0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
   0x40
} ;


static unsigned short CRC16(puchMsg, usDataLen)
{
   unsigned char uchCRCHi = 0xFF ; /* high byte of CRC initialized */
   unsigned char uchCRCLo = 0xFF ; /* low byte of CRC initialized */
   unsigned uIndex ; /* will index into CRC lookup table */
   while (usDataLen--) /* pass through message buffer */
   {
      uIndex = uchCRCHi ^ puchMsg++ ; /* calculate the CRC */
      uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;
      uchCRCLo = auchCRCLo[uIndex] ;
   }
   return (uchCRCHi << 8 | uchCRCLo) ;
}

unsigned short crc16( unsigned char *p, unsigned char n )
{
    unsigned char  i;
    unsigned short crc = 0xFFFF;

    while (n--)
    {
        crc ^= *p++;

        for (i = 8; i != 0; i--)
        {
            if (crc & 1)
                crc = (crc >> 1) ^ 0xA001;
            else
                crc >>= 1;
        }
    }

    return (crc);
}

int main()
{
   unsigned char data[10];
   unsigned char len;
   unsigned int crc;
   int i;

   printf(\"Digite a quantidade de bytes para o CRC: \");
   scanf(\"%d\", &len);

   for (i = 0; i < len; i++) {
      printf(\"Digite o valor do %d° byte(hexa): \", i + 1);
      scanf(\"%x\", &data);
   }

   crc = crc16(data, len);

   printf(\"Crc: 0x%x\\n\\r\", crc);

   return 0;
}

first code: 0xc1c0
second code: 0xc255

I think that the first is correct, because it implements the definition of the CRC algorithm .. but who knows.

We can exchange some of our problems and maybe we can solve both our problems.

Please, send me an email then it will be easier.

davidcemin@gmail.com

--
David

salihtolga

  • Guest
MODBUS RTU query&response
« Reply #4 on: October 14, 2008, 02:40:17 PM »
Hi,
Using activeX
http://www.fultek.com.tr/index_dosyalar/modbus_rtu_activex.htm
http://www.fultek.com.tr/index_dosyalar/Modbus_Rtu.zip

ť Hi,
ť
ť i\'m beginner in MODBUS, so please help me.
ť i have a temperature regulator with MODBUS communication.
ť For example:
ť If  i want to read holding register e.g.: 0042 „Value of temperature“ from
ť mentioned device, in my application for MODBUS-RTU communication which i
ť was writte in
ť Microsoft Visual Studio 2005- VC#,
ť i made request -byte array:
ť {0x01,   0x03,  0x00,  0x29,  0x00,  0x01,  0x83,  0x01}
ť      
ť
ť 1- slave adress (configured in device)- 0x01
ť 2.- function code(Read Holding Registers)- 0x03
ť 3.- start adress Hi- 0x00
ť 4.- start adress Lo- 0x29
ť 5.- no. of registers Hi- 0x00
ť 6.- no of registers Lo- 0x01
ť 7.- error code- 0x83
ť 8.- exception code- 0x01   
ť
ť and sent that array to device. Label Rx blinks ,on the front panel of
ť device, so device received my request, but i don\'t get any response, Tx
ť doesn\'t blink!!!
ť For example:
ť If  holding register  0042 „Value of temperature“=555, response message
ť from device should be:
ť
ť {slave adress=0x01, function code= 0x03, byte count= 0x02, register value
ť Hi= 0x02,
ť register value Lo= 0x2B,...          }  !!!????
ť But i get nothing!!!!
ť All other parameters like port name, baud rate, parity, data bits, stop
ť bits,ReadTimeout, WriteTimeout and RS485/RS232 converter are O.K.
ť Plese, could You help me with some advice to get response from device and
ť tell me what i do wrong.
ť Is my request -byte array O.K.??? (especialy last two bytes 0x83, 0x01-
ť CRC)
ť  
ť Thank You very much.
ť
ť Best regards!