<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
    国产精品亚洲天堂| 亚洲欧洲久久精品| 国产精品酒店视频免费看| 久久青青成人亚洲精品| 成人国内精品久久久久影院| 国产精品爽黄69天堂a| 久久亚洲精品中文字幕三区| 午夜精品久久久久蜜桃| 无码精品A∨在线观看免费 | 精品亚洲AV无码一区二区| 国产一区麻豆剧传媒果冻精品| 亚洲国产精品ⅴa在线观看| 日本伊人精品一区二区三区| 久久国产综合精品五月天| 国产精品久久久福利| 精品国精品无码自拍自在线| 囯产精品一品二区三区| 精品一区二区无码AV| 国产伦精品一区二区三区精品 | 国产精品免费视频一区| 国产精品久久亚洲不卡动漫| 久久久精品人妻一区亚美研究所| 精品人妻少妇嫩草AV无码专区| 国产精品高清m3u8在线播放| 99精品一区二区三区无码吞精| 亚洲国产精品第一区二区| 亚洲愉拍99热成人精品热久久| 亚洲av无码成人精品区在线播放 | 久久久久成人精品免费播放动漫| 久久精品中文字幕有码| 精品视频在线观看一区二区| 久久精品无码一区二区三区不卡| 亚洲欧洲精品在线| 人妻精品久久久久中文字幕69 | 久久精品国产只有精品2020| 久久93精品国产91久久综合| 亚洲AV蜜桃永久无码精品| 四虎成人国产精品视频| 国产成人精品综合| 国产精品久久久久999| 国内精品久久久久影视|