<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
    正在播放国产精品每日更新| 国产乱人伦偷精品视频下| 国产精品高清在线观看| 国产精品久久久久9999高清| 99久久精品国内| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 亚洲精品国产日韩无码AV永久免费网| 久久精品国产亚洲AV嫖农村妇女| 日本午夜精品理论片A级APP发布| 337p日本欧洲亚洲大胆精品555588| 亚洲精品无码99在线观看| 99久久人妻无码精品系列蜜桃 | a级亚洲片精品久久久久久久| 久久久g0g0午夜无码精品| 久久99精品久久久久久首页| 精品乱码久久久久久夜夜嗨| 国产精品成人免费视频网站京东 | 99re热这里只有精品视频中文字幕| 好男人视频社区精品免费| 久久亚洲中文字幕精品有坂深雪 | 久久精品青青草原伊人| 日韩精品无码免费专区午夜不卡| 精品视频免费在线| 成人区精品一区二区不卡亚洲| 日韩精品无码一区二区三区| 99精品在线观看| 国产精品免费观看视频| 国产国产成人久久精品杨幂| 精品国产这么小也不放过| 精品少妇ay一区二区三区| 午夜精品久久久久久中宇| 水蜜桃精品一二三| 国产精品亚洲αv天堂无码| 国产精品亚洲色婷婷99久久精品| 午夜福利麻豆国产精品| 五月天婷婷精品视频| 精品无码一区二区三区亚洲桃色| 久久99九九99九九精品| 亚洲精品~无码抽插| 法国性xxxx精品hd| 国产色无码精品视频免费|