Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    QModbusRtuSerialMaster CRC calculation problem

    General and Desktop
    4
    9
    5519
    Loading More Posts
    • 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
      Bremenpl last edited by

      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 Reply Quote 0
      • mrdebug
        mrdebug last edited by

        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 Reply Quote 1
        • B
          Bremenpl last edited by

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

          lprzenioslo.zut.edu.pl

          1 Reply Last reply Reply Quote 0
          • ?
            A Former User last edited by

            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 Reply Quote 2
            • B
              Bremenpl last edited by

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

              lprzenioslo.zut.edu.pl

              1 Reply Last reply Reply Quote 1
              • K
                Karsten Heimrich last edited by

                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 Reply Quote 1
                • B
                  Bremenpl @Karsten Heimrich last edited by Bremenpl

                  @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 Reply Quote 0
                  • K
                    Karsten Heimrich last edited by

                    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 Reply Quote 2
                    • B
                      Bremenpl last edited by

                      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 Reply Quote 0
                      • First post
                        Last post