Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QModbusRtuSerialMaster CRC calculation problem
Forum Updated to NodeBB v4.3 + New Features

QModbusRtuSerialMaster CRC calculation problem

Scheduled Pinned Locked Moved General and Desktop
9 Posts 4 Posters 6.9k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Bremenpl
    wrote on last edited by
    #1

    Hello there,
    I am using qt version 5.6.2. I am trying to write an application that works as ModBus RTU master device. I am using QModbusRtuSerialMaster for that purpose. For tests purposes I am running an example code from serialbus/modbus/master. My problem is that I think that the CRC calculation mechanism for the slave response ins not working properly. For example: I am trying to read holding registers (slave address i 0x05) from address 0, in quantity of 1. For this the master message looks like this:

    hex values
    05 03 00 00 00 01 85 8E
    

    And the example master application is sending this message indeed. The problem occurs when I answer from my slave. My answer should look like this:

    Hex values
    05 03 01 00 00 B9 84
    

    For the CRC calculation, I am using the exact same alghoritm as in here: https://code.woboq.org/qt5/qtserialbus/src/serialbus/qmodbusadu_p.h.html#_ZNK16QModbusSerialAdu4dataEv

    Now here is the console output of the QModbusRtuSerialMaster module when receiving answer from slave:

    qt.modbus: (RTU client) Sent Serial PDU: 0x0300000001
    qt.modbus.lowlevel: (RTU client) Sent Serial ADU: 0x050300000001858e
    qt.modbus: (RTU client) Send successful: 0x0300000001
    qt.modbus.lowlevel: (RTU client) Response buffer: "05"
    qt.modbus: (RTU client) Modbus ADU not complete
    qt.modbus.lowlevel: (RTU client) Response buffer: "0503"
    qt.modbus: (RTU client) Cannot calculate PDU size for function code: 3 , delaying pending frame
    qt.modbus.lowlevel: (RTU client) Response buffer: "050301"
    qt.modbus: (RTU client) Incomplete ADU received, ignoring
    qt.modbus.lowlevel: (RTU client) Response buffer: "05030100"
    qt.modbus: (RTU client) Cannot calculate PDU size for function code: 3 , delaying pending frame
    qt.modbus.lowlevel: (RTU client) Response buffer: "0503010000"
    qt.modbus: (RTU client) Incomplete ADU received, ignoring
    qt.modbus.lowlevel: (RTU client) Response buffer: "0503010000b9"
    qt.modbus: (RTU client) Received ADU: "0503010000b9"
    qt.modbus: (RTU client) Discarding response with wrong CRC, received: 185 , calculated CRC: 61816
    qt.modbus.lowlevel: (RTU client) Response buffer: "84"
    qt.modbus: (RTU client) Modbus ADU not complete
    qt.modbus: (RTU client) Receive timeout: 0x0300000001
    

    As you see, at the point of first CRC byte arrival, the module already states that the CRC is wrong and shows a wrongly calculated CRC. I even tried to hardcode the CRC for the slave answer to match the one that master calculates, but he still says its wrong at the first CRC byte, not waiting for the other.
    The modbus QT module is quite complicated for me, I am now wondering either it wouldnt be faster to write my own qt modbus rtu master library, with limited functionality. Unless it is possible to find the error here somehow. I would really appreciate all help regarding this issue. Is the library bugged?

    lprzenioslo.zut.edu.pl

    1 Reply Last reply
    0
    • mrdebugM Offline
      mrdebugM Offline
      mrdebug
      wrote on last edited by
      #2

      I'm using a my own component. please have a look at these functions that work perfectly:

      bool QThModbusManager::Crc16In(QByteArray &QBABytes) {
          if (QBABytes.length()> 2) {
              bool Ok;
              int BccIn= QBABytes.mid(QBABytes.length()- 2, 2).toHex().toInt(&Ok, 16);
              int buffer_length= QBABytes.length()- 2;
              unsigned char *buffer= (unsigned char*)QBABytes.data();
              unsigned char crc_hi = 0xFF; /* high CRC byte initialized */
              unsigned char crc_lo = 0xFF; /* low CRC byte initialized */
              int i; /* will index into CRC lookup */
              while (buffer_length--) {
                  i = crc_hi ^ *buffer++; /* calculate the CRC  */
                  crc_hi = crc_lo ^ table_crc_hi[i];
                  crc_lo = table_crc_lo[i];
              }
              if (crc_hi== (BccIn & 0xff00) / 0x100 && crc_lo== (BccIn & 0xff)) return true;
              else return false;
          } else return false;
      }
      
      void QThModbusManager::Crc16Out(QByteArray &QBABytes) {
          int buffer_length= QBABytes.length();
          unsigned char *buffer= (unsigned char*)QBABytes.data();
          unsigned char crc_hi = 0xFF; /* high CRC byte initialized */
          unsigned char crc_lo = 0xFF; /* low CRC byte initialized */
          int i; /* will index into CRC lookup */
          while (buffer_length--) {
              i = crc_hi ^ *buffer++; /* calculate the CRC  */
              crc_hi = crc_lo ^ table_crc_hi[i];
              crc_lo = table_crc_lo[i];
          }
          QBABytes.append(crc_hi);
          QBABytes.append(crc_lo);
      }
      

      Regards.

      Need programmers to hire?
      www.labcsp.com
      www.denisgottardello.it
      GMT+1
      Skype: mrdebug

      1 Reply Last reply
      1
      • B Offline
        B Offline
        Bremenpl
        wrote on last edited by
        #3

        Thank you for answer, but I am wondering either the ones in QModbusRtuSerialMaster are working correctly.

        lprzenioslo.zut.edu.pl

        1 Reply Last reply
        0
        • ? Offline
          ? Offline
          A Former User
          wrote on last edited by
          #4

          Hi! As the module is still a technology preview, chances are high that you found a bug or something isn't implemented yet. I'd ask the developers on the mailing list.

          1 Reply Last reply
          2
          • B Offline
            B Offline
            Bremenpl
            wrote on last edited by
            #5

            https://bugreports.qt.io/browse/QTBUG-57402

            lprzenioslo.zut.edu.pl

            1 Reply Last reply
            1
            • K Offline
              K Offline
              Karsten Heimrich
              wrote on last edited by
              #6

              Hi,

              it would be really nice if you could share your implementation or provide a broken down example how you generate the response.

              Regards, Karsten

              B 1 Reply Last reply
              1
              • K Karsten Heimrich

                Hi,

                it would be really nice if you could share your implementation or provide a broken down example how you generate the response.

                Regards, Karsten

                B Offline
                B Offline
                Bremenpl
                wrote on last edited by Bremenpl
                #7

                @Karsten-Heimrich I am using the modbus master example from qt creator. As for th slace answer I could give you the code for the platform I use but it would be hard for you to create an experimental setup like that. You will be better of sending this slave response manually from a terminal app, like realterm.

                lprzenioslo.zut.edu.pl

                1 Reply Last reply
                0
                • K Offline
                  K Offline
                  Karsten Heimrich
                  wrote on last edited by
                  #8

                  Hi, while looking at your response you posted:

                  Hex values: 05 03 01 00 00 B9 84
                  

                  I think it does not what the spec predicts. It should look like this:

                  Address:       1 Byte          -> 05
                  Function code: 1 Byte          -> 03
                  Byte count:    1 Byte          -> 01
                  Register value: N* x 2 Bytes
                      High Byte                  -> 00
                      Low Byte                   -> 00
                  

                  So obviously your Byte count is wrong, you have to send always a minimum byte count of 2, not 1.

                  Your response should look like this:

                  Hex values: 05 03 02 00 00 49 84
                  

                  You can lookup the spec at http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf page 15

                  Regards, Karsten

                  1 Reply Last reply
                  2
                  • B Offline
                    B Offline
                    Bremenpl
                    wrote on last edited by
                    #9

                    You are right, i have corrected this later on, but forgot to test it again, as i already started to write my own implementation. Thank you for help, sorry for trouble.

                    lprzenioslo.zut.edu.pl

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved