<strike id="kiyse"></strike>
  • <tr id="kiyse"></tr>
  • <strike id="kiyse"></strike><samp id="kiyse"><tbody id="kiyse"></tbody></samp>
    <strike id="kiyse"><s id="kiyse"></s></strike>
    <tr id="kiyse"></tr>
    <noframes id="kiyse"><code id="kiyse"></code></noframes>
    <th id="kiyse"></th>
    <samp id="kiyse"></samp>
  • <th id="kiyse"><s id="kiyse"></s></th>
  • ESM6802支持Qt MODBUS程序開發

     2017-5-27     作者:廖光澤         
    文章標簽:C/C++QtESM6802

      ESM6802使用iMX6DL作為CPU,支持硬件圖形加速,使得用戶可以開發具有較好圖形界面的工業控制程序。Qt是嵌入式開發中常用的圖形庫,MODBUS作為工控中常用的通信協議,已經作為Qt的模塊引入了Qt中。我們在ESM6802上移植了最新的Qt 5.8.0版本,包括MODBUS模塊,用戶在使用中可以方便的調用Qt提供的API進行MODBUS協議相關的程序編寫。Qt對于MODBUS協議的封裝使得用戶能夠更加便捷快速的進行MODBUS應用程序開發,我們將在下面根據Qt源碼中的modbusmaster例程簡單介紹Qt的MODBUS相關函數接口。文中使用的程序可以在http://doc.qt.io/qt-5/qtserialbus-modbus-master-example.html獲取或向我們的工程師索取。


      在使用Qt提供的MODBUS相關API時需要使用Qt提供的MODBUS數據類:QModbusDataUnit,類中有公共數據RegisterType表示此數據代表的MODBUS數據類型:

      enum    RegisterType { Invalid, DiscreteInputs, Coils, InputRegisters, HoldingRegisters }


      可以使用構造函數進行初始化:

      QModbusDataUnit(RegisterType type, int address, quint16 size)


      對于MODBUS client相關的函數,Qt將其封裝在類QModbusClient中,部分函數如下:

      int  numberOfRetries() const

      QModbusReply *      sendRawRequest(const QModbusRequest &request, int serverAddress)

      QModbusReply *      sendReadRequest(const QModbusDataUnit &read, int serverAddress)

      QModbusReply *      sendReadWriteRequest(const QModbusDataUnit &read, const QModbusDataUnit &write, int serverAddress)

      QModbusReply *      sendWriteRequest(const QModbusDataUnit &write, int serverAddress)

      void       setNumberOfRetries(int number)

      void       setTimeout(int newTimeout)

      int  timeout() const


      其中numberOfRetries以及setTimeout是用于設置重試次數和超時時間的。send*Request系列函數是用于發送MODBUS數據包的函數,其中數據相關的都用之前介紹的QModbusDataUnit類對象作為函數參數。


      截取部分Qt例程modbusmaster發送讀請求的代碼如下:


      首先設置連接類型(RTU/TCP)、重試次數、超時時間等,然后建立連接:

      if (static_cast<ModbusConnection> (ui->connectType->currentIndex()) == Serial) {

             modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,

          ui->portEdit->text());

             modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,

          m_settingsDialog->settings().parity);

             modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,

          m_settingsDialog->settings().baud);

             modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,

          m_settingsDialog->settings().dataBits);

             modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,

          m_settingsDialog->settings().stopBits);

      } else {

        const QUrl url = QUrl::fromUserInput(ui->portEdit->text());

        modbusDevice->setConnectionParameter(QModbusDevice::NetworkPortParameter, url.port());

        modbusDevice->setConnectionParameter(QModbusDevice::NetworkAddressParameter, url.host());

      }

      modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);

      modbusDevice->setNumberOfRetries(m_settingsDialog->settings().numberOfRetries);

      if (!modbusDevice->connectDevice()) {

        statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString(), 5000);

      }


      設置讀取數據類型、地址等參數:

      QModbusDataUnit MainWindow::readRequest() const

      {

        const auto table =

        static_cast<QModbusDataUnit::RegisterType> (ui->writeTable->currentData().toInt());

        int startAddress = ui->readAddress->value();

        Q_ASSERT(startAddress >= 0 && startAddress < 65535);

        // do not go beyond 10 entries

        int numberOfEntries = qMin(ui->readSize->currentText().toInt(), 65535 - startAddress);

        return QModbusDataUnit(table, startAddress, numberOfEntries);

      }


      發送讀數據請求:

      void MainWindow::on_readButton_clicked()

      {

      if (!modbusDevice)

        return;

      ui->readValue->clear();

      statusBar()->clearMessage();

      if (auto *reply = modbusDevice->sendReadRequest(readRequest(), ui->serverEdit->value())) {

        if (!reply->isFinished())

          connect(reply, &QModbusReply::finished, this, &MainWindow::readReady);

        else

          delete reply; // broadcast replies return immediately

      } else {

        statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000);

        }

      }


      可以看到使用Qt提供的API進行MODBUS通訊編程很便捷,只需要首先設置數據QModbusDataUnit,然后調用相應的Request函數發送請求即可。

      modbusmaster程序運行效果如下圖:

    ESM6802支持Qt-MODBUS程序開發.gif


      我們使用ESM6802連接ADAM模塊進行測試連接圖如下:

    ESM6802支持Qt-MODBUS程序開發.gif


      ADAM-4117進行電流采集時電流輸入量程為4~20mA,對應的采樣值為0x0000~0xffff。有關AMAM-4117的介紹可以參考我們官網上的文章:《4~20mA模擬電流采集應用方案》。當輸入12.0mA(半量程)時讀到采樣值為0x8007,可見modbusmaster與AMAM模塊正確進行了數據通信。

      更多Qt MODBUS相關內容請參考Qt官方資料:http://doc.qt.io/qt-5/qtmodbus-backends.html。

    文章標簽:C/C++QtESM6802
    国产精品电影一区| 久久久精品视频免费观看| 久久国产精品久久精| 国产A√精品区二区三区四区| 99re热久久这里只有精品首页| 青青草国产精品久久久久| 偷拍精品视频一区二区三区| 亚洲欧美日韩国产精品一区| 久久精品水蜜桃av综合天堂| 国产精品亚洲A∨天堂不卡 | 久久亚洲av无码精品浪潮| 国产精品自在线天天看片| 精品91自产拍在线| 99精品视频在线观看免费播放| 手机在线观看精品国产片| 伊人精品视频在线| 最新国产精品自在线观看| 99久久国产亚洲综合精品| 精品无码一区二区三区爱欲| 日本精品久久久中文字幕| 久久久久这里只有精品 | 尤物yw午夜国产精品视频| 九九这里只有精品视频| 日韩精品免费电影| 欧美日韩久久久精品A片| 国产香蕉精品视频| 国产69精品久久久久777| 精品综合久久久久久98| 69国产成人精品视频软件| 91亚洲精品视频| 69久久夜色精品国产69小说| 精品亚洲成a人片在线观看| 日本伊人精品一区二区三区| 无码国产精品一区二区免费vr| 国产AV国片精品有毛| 久久精品免费电影| 一本久久a久久精品综合夜夜| 无码精品久久久天天影视| 99re5在线精品视频热线| 91精品国产三级在线观看| 亚洲精品无码久久久久久久|