{"id":120,"date":"2019-06-20T19:55:06","date_gmt":"2019-06-20T11:55:06","guid":{"rendered":"http:\/\/www.sanburs.xyz\/?p=120"},"modified":"2019-06-20T19:55:06","modified_gmt":"2019-06-20T11:55:06","slug":"qmodbusclient","status":"publish","type":"post","link":"https:\/\/www.sanburs.xyz\/index.php\/2019\/06\/20\/qmodbusclient\/","title":{"rendered":"QModbusClient"},"content":{"rendered":"<p>\u4ee5\u4f7f\u7528Modbus Tcp\u4e3a\u4f8b\u770b\u770b\u5ba2\u6237\u7aef\u600e\u4e48\u5199\u7a0b\u5e8f<\/p>\n<h2>\u9996\u5148\u8fde\u63a5\u5230\u670d\u52a1\u7aef<\/h2>\n<pre><code class=\"\">QModbusTcpClient *client = new QModbusTcpClient();\nclient-&gt;setConnectionParameter(QModbusDevice::NetworkAddressParameter, \"192.168.0.1\");\nclient-&gt;setConnectionParameter(QModbusDevice::NetworkPortParameter, 502);\nclient-&gt;connectDevice();\n<\/code><\/pre>\n<p>\u8fd9\u6837\u5c31\u8fde\u63a5\u4e0a\u670d\u52a1\u7aef\u4e86\uff0c\u4e0b\u9762\u53ef\u4ee5\u53d1\u9001\u8bf7\u6c42\u4e86<\/p>\n<h2>\u53d1\u9001\u8bfb\u6216\u5199\u8bf7\u6c42\u5230\u670d\u52a1\u7aef<\/h2>\n<h3>\u5199\u8bf7\u6c42<\/h3>\n<pre><code class=\"\">QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters, 40003, 1); \/\/ write 1 value in address 40003\nwriteUnit.setValue(0, 0x253); \n\/\/\u8fd9\u91cc\u5148\u5efa\u597dQModbusDataUnit\n\nif (auto *reply = client-&gt;sendWriteRequest(writeUnit, 1))\n\/\/\u53d1\u9001\u5199\u8bf7\u6c42\n{\n    if (!reply-&gt;isFinished())\n    {\n        connect(reply, &amp;QModbusReply::finished, this, [this, reply]() \n        {\n            if (reply-&gt;error() != QModbusDevice::NoError)               \n                    \/\/ error in reply\n\n                reply-&gt;deleteLater();\n            });\n    }\n    else\n    {\n        if (reply-&gt;error() != QModbusDevice::NoError)           \n            \/\/ error in reply\n\n        \/\/ broadcast replies return immediately\n        reply-&gt;deleteLater();\n    }\n}\nelse\n{\n    \/\/ error in request\n}\n<\/code><\/pre>\n<p>\u5148\u5efa\u4e2aQModbusDataUnit\uff0c\u4e0b\u9762\u662fQt\u5e2e\u52a9\u6587\u6863\u4e2d\u7684\u4ecb\u7ecd<br \/>\n<strong>QModbusDataUnit is a container class representing single bit and 16 bit word entries in the Modbus register.QModbusDataUnit can be used for read and write operations<\/strong><br \/>\n\u7ed9QModbusDataUnit\u8d4b\u597d\u503c\u540e\u53d1\u9001\u5199\u8bf7\u6c42sendWriteRequest\uff0c\u5199\u5230\u76f8\u5e94\u5bc4\u5b58\u5668\u4e2d\u7684\u76f8\u5e94\u4f4d\u7f6e<br \/>\n\u5982\u679c\u6ca1\u6709\u53d1\u751f\u9519\u8bef\u7684\u8bddsendWriteRequest\u5c06\u8fd4\u56de\u4e00\u4e2aQModbusReply\uff0c\u5426\u5219\u8fd4\u56de\u7a7a\u6307\u9488\u3002<br \/>\n\u5f53reply\u5b8c\u6210\u6216\u653e\u5f03\u540ereply->isFinished()\u5c06\u8fd4\u56detrue\u3002<\/p>\n<h3>\u8bfb\u8bf7\u6c42<\/h3>\n<pre><code class=\"\">QModbusDataUnit readUnit(QModbusDataUnit::InputRegisters, 40006, 1); \/\/ just read input register 40006 \n\nif (auto *reply = client-&gt;sendReadRequest(readUnit, 255)) \/\/ client id 255\n{\n    if (!reply-&gt;isFinished())\n    {\n        \/\/ connect the finished signal of the request to your read slot\n        connect(reply, &amp;QModbusReply::finished, this, &amp;YourClass::readReady);\n    }\n    else\n    {\n        delete reply; \/\/ broadcast replies return immediately\n    }\n}\nelse\n{\n    \/\/ request error\n}\nYourClass::readReady\n{\n    QModbusReply *reply = qobject_cast&lt;QModbusReply *&gt;(sender());\n    if (!reply)\n        return;\n\n    if (reply-&gt;error() == QModbusDevice::NoError)\n    {\n        const QModbusDataUnit unit = reply-&gt;result();\n        int startAddress = unit.startAddress(); \/\/ the start address, here 40006\n        int value = unit.value(0); \/\/ value of the start address + 0\n        ... \n\n    }\n    else\n    {\n        \/\/ reply error\n    }\n\n    reply-&gt;deleteLater(); \/\/ delete the reply \n}\n<\/code><\/pre>\n<h2>\u5e94\u8be5\u6ce8\u610f\u7684\u95ee\u9898<\/h2>\n<p>\u770b\u770bQModbusClient\u5e2e\u52a9\u6587\u6863\u4e2d\u7684\u4e00\u53e5\u8bdd<br \/>\n<strong>QModbusClient has an asynchronous API. When the finished slot is called, the parameter it takes is the QModbusReply object containing the PDU as well as meta-data (Addressing, etc.).<\/strong><br \/>\n\u8fd9\u610f\u5473\u7740<\/p>\n<blockquote><p>\n  The API of the QModbusDevice classes are asynchronous. That means when you callclient->connectDevice() your client is not \"really\" connected to your server. The function just send an event to the event loop. When the application enters the event loop the event will be executed.The QModbusDevice class has some signals to control your connection state and error message.\n<\/p><\/blockquote>\n<p>\u6240\u4ee5\u6211\u4eec\u5e94\u8be5<\/p>\n<blockquote><p>\n  Check the client state with yout slot. Before reading registers ensure that the client is in connected state.\n<\/p><\/blockquote>\n<p>\u56e0\u6b64\u6240\u6709\u4ee3\u7801\u5728\u4e00\u4e2a\u51fd\u6570\u4e2d\u662f\u4e0d\u5bf9\u7684\uff0c\u50cf\u8fd9\u6837<\/p>\n<pre><code class=\"\">YourClass::connect()\n{\nQModbusTcpClient *client=new QModbusTcpClient();\nclient-&gt;setConnectionParameter(QModbusDevice::NetworkAddressParameter,\"192.168.0.201\");\nclient-&gt;setConnectionParameter(QModbusDevice::NetworkPortParameter,502);\nclient-&gt;connectDevice();\n\nQModbusDataUnit readUnit(QModbusDataUnit::Coils,00000,4);\nif (auto *reply=client-&gt;sendReadRequest(readUnit,255)){\n\n...\n}\n<\/code><\/pre>\n<p>\u5e94\u8be5<\/p>\n<pre><code class=\"\">MyClass::connectToModbusServer()\n{\n   QModbusTcpClient *client=new QModbusTcpClient();\n   client-&gt;setConnectionParameter(QModbusDevice::NetworkAddressParameter,\"192.168.0.201\");\n   client-&gt;setConnectionParameter(QModbusDevice::NetworkPortParameter,502);\n\n   if (client-&gt;connectDevice())\n   {\n      connect(client, &amp;QModbusTcpClient::stateChanged, this, &amp;MyClass::onStateChanged); \n      connect(client, &amp;QModbusTcpClient::errorOccurred, this, &amp;MyClass::onErrorOccurred); \n   }\n   else\n      qDebug() &lt;&lt; client-&gt;errorString();\n}\n\nMyClass::readCoil()\n{\n   QModbusDataUnit readUnit(QModbusDataUnit::Coils,00000,4);\n\n<\/code><\/pre>\n<p>\u672c\u6587\u5185\u5bb9\u6458\u81ea<a href=\"https:\/\/forum.qt.io\/topic\/67565\/how-to-use-qmodbus-class-to-get-the-data-on-a-daq-card\" target=\"_blank\"  rel=\"nofollow\" >\u8fd9\u91cc<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4ee5\u4f7f\u7528Modbus Tcp\u4e3a\u4f8b\u770b\u770b\u5ba2\u6237\u7aef\u600e\u4e48\u5199\u7a0b\u5e8f \u9996\u5148\u8fde\u63a5\u5230\u670d\u52a1\u7aef QModbusTcpClient *client = new &#8230;<\/p>","protected":false},"author":1,"featured_media":121,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/www.sanburs.xyz\/index.php\/wp-json\/wp\/v2\/posts\/120"}],"collection":[{"href":"https:\/\/www.sanburs.xyz\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sanburs.xyz\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sanburs.xyz\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sanburs.xyz\/index.php\/wp-json\/wp\/v2\/comments?post=120"}],"version-history":[{"count":2,"href":"https:\/\/www.sanburs.xyz\/index.php\/wp-json\/wp\/v2\/posts\/120\/revisions"}],"predecessor-version":[{"id":123,"href":"https:\/\/www.sanburs.xyz\/index.php\/wp-json\/wp\/v2\/posts\/120\/revisions\/123"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.sanburs.xyz\/index.php\/wp-json\/wp\/v2\/media\/121"}],"wp:attachment":[{"href":"https:\/\/www.sanburs.xyz\/index.php\/wp-json\/wp\/v2\/media?parent=120"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sanburs.xyz\/index.php\/wp-json\/wp\/v2\/categories?post=120"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sanburs.xyz\/index.php\/wp-json\/wp\/v2\/tags?post=120"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}