{"id":355501,"date":"2024-05-20T23:10:01","date_gmt":"2024-05-20T23:10:01","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=355501"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=355501","title":{"rendered":"<span>\u041f\u0440\u043e\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b, Linux \u0438 \u0442\u043e\u043b\u044c\u043a\u043e C++. \u0427\u0430\u0441\u0442\u044c 1<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u0441\u0435\u043c \u0434\u043e\u0431\u0440\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0443\u0442\u043e\u043a. \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u043e\u043c \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u044f\u0442\u0438\u0438, \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0441\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0430. \u041e\u0447\u0435\u043d\u044c \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441 \u0412\u0430\u043c\u0438 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043d\u0430\u0440\u0430\u0431\u043e\u0442\u043a\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432 \u043f\u043e\u0432\u0441\u0435\u0434\u043d\u0435\u0432\u043d\u043e\u0439 \u0442\u0440\u0443\u0434\u043e\u0432\u043e\u0439 \u0436\u0438\u0437\u043d\u0438. \u041d\u0435 \u0441\u0443\u0434\u0438\u0442\u0435 \u0441\u0442\u0440\u043e\u0433\u043e, \u044d\u0442\u043e \u043c\u043e\u044f \u043f\u0435\u0440\u0432\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u044e&#8230;<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u043f\u0440\u043e\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u043e\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438, \u0442\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u044f\u0437\u044b\u043a\u0430\u043c\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430 \u041c\u042d\u041a 61131-3.<\/p>\n<p>\u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430 \u0432 \u043f\u0440\u043e\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0435 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u0435 \u043e\u0442:<\/p>\n<ul>\n<li>\n<p>ISaGRAF, Rockwell Automation (\u041c\u043e\u043d\u0440\u0435\u0430\u043b\u044c, \u041a\u0430\u043d\u0430\u0434\u0430)<\/p>\n<\/li>\n<li>\n<p>CoDeSYS, CODESYS GmbH (\u041a\u0435\u043c\u043f\u0442\u0435\u043d, \u0413\u0435\u0440\u043c\u0430\u043d\u0438\u044f)<\/p>\n<\/li>\n<li>\n<p>ISPSoft, Delta Electronics, Inc (\u0422\u0430\u0439\u0431\u044d\u0439, \u0422\u0430\u0439\u0432\u0430\u043d\u044c)<\/p>\n<\/li>\n<\/ul>\n<p>\u0410 \u043a\u0430\u043a \u0436\u0435 \u0431\u044b\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u0442\u0435\u0431\u0435 \u043d\u0435 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0438 \u0438\u043c\u0435\u0442\u044c \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u043c\u044b\u0439 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0442\u0440\u0443\u0434\u043e\u0437\u0430\u0442\u0440\u0430\u0442\u0430\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043d\u0430 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432, \u0438 \u0434\u0430\u0436\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0435?<\/p>\n<p>\u042f \u043d\u0430\u0448\u0435\u043b \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 Icp-Das LP-8&#215;21 \u043d\u0430 Ubuntu 12, \u043f\u0430\u0440\u0443 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432\u0432\u043e\u0434\u0430\/\u0432\u044b\u0432\u043e\u0434\u0430 MDS DIO-16BD \u0438 AIO-4 \u043e\u0442 \u041a\u043e\u043d\u0442\u0440\u0410\u0432\u0442 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432. \u0412\u043e\u0442 \u0443\u0436\u0435 \u0438 \u0435\u0441\u0442\u044c \u0441 \u0447\u0435\u043c \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/e16\/16b\/1af\/e1616b1af493a4b4c71409f2cf430321.jpg\" alt=\"\u0422\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u0441\u0431\u043e\u0440\u043a\u0430\" title=\"\u0422\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u0441\u0431\u043e\u0440\u043a\u0430\" width=\"1280\" height=\"720\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e16\/16b\/1af\/e1616b1af493a4b4c71409f2cf430321.jpg\" data-blurred=\"true\"\/><\/p>\n<div><figcaption>\u0422\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u0441\u0431\u043e\u0440\u043a\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u043b\u044f \u0441\u0432\u044f\u0437\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0438 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432\u0432\u043e\u0434\u0430\/\u0432\u044b\u0432\u043e\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0445 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u0432 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0441\u0432\u044f\u0437\u0438 &#8212; RS-485. \u0414\u0430\u043d\u043d\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b Modbus.<\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u043f\u043e\u0434 \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u0435\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440:<\/p>\n<pre><code class=\"bash\">sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf<\/code><\/pre>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0444\u0430\u0439\u043b\u044b \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 <code>libmodbus-dev<\/code>:<\/p>\n<pre><code class=\"bash\">sudo apt install libmodbus-dev apt source libmodbus-dev<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438 \u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043f\u043e\u0434 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0434\u043b\u044f <code>arm-linux-gnueabihf<\/code>:<\/p>\n<pre><code class=\"bash\">.\/autogen.sh .\/configure --host=arm-linux-gnueabihf --enable-shared --enable-static make<\/code><\/pre>\n<p>\u0412 \u043f\u0430\u043f\u043a\u0435 <code>.\/src\/.libs\/<\/code>\u00a0 \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0432\u0441\u0435 \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442. \u041d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0444\u0430\u0439\u043b <code>libmodbus.a<\/code>.<\/p>\n<p>\u0418\u0437 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432\u0432\u043e\u0434\u0430\/\u0432\u044b\u0432\u043e\u0434\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f. \u0414\u043b\u044f DIO-16BD \u044d\u0442\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440 258 \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u0430, \u0430 \u0434\u043b\u044f AIO-4 \u043c\u044b \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0435\u043c 4 \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u0432\u044b\u0445 \u0432\u0445\u043e\u0434\u0430 \u0441 \u0430\u0434\u0440\u0435\u0441\u0430 207. \u0422.\u043a. \u0442\u0430\u043c \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u044e\u0442\u0441\u044f 4 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 float, \u0442\u043e \u0431\u0443\u0434\u0435\u043c \u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 8 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u0432.\u00a0 \u0414\u043b\u044f \u043f\u0440\u043e\u0431\u044b \u0441\u043e\u0431\u0435\u0440\u0435\u043c \u043d\u0430 C++ \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<p>\u0424\u0430\u0439\u043b <code>main.cpp<\/code>:<\/p>\n<pre><code class=\"cpp\">#include &lt;modbus\/modbus.h> #include &lt;iostream> #include &lt;errno.h> #include \"util.h\"  using namespace std;  bool _stop=false;  void handle_signal(int i) {    printf(\"[MAIN] Terminating\\n\");     _stop=true; }  int main() {    signal(SIGINT, handle_signal);    signal(SIGTERM, handle_signal);    cout&lt;&lt;\"Start...\"&lt;&lt;endl;    uint16_t buffer[8];    modbus_t *ctx=modbus_new_rtu(\"\/dev\/ttyS2\",115200,'N',8,1);    if (modbus_connect(ctx) == -1)        cout&lt;&lt;\"Connection failed: \"&lt;&lt;modbus_strerror(errno)&lt;&lt;endl;    modbus_set_response_timeout(ctx, 1,0);    while(!_stop) {        modbus_set_slave(ctx,1);        int rc=modbus_read_registers(ctx,258,1,buffer);        if (rc == -1)            cout&lt;&lt;\"#1 MDS_DIO_16BD::Read() \"&lt;&lt;modbus_strerror(errno)&lt;&lt;endl;        else            cout&lt;&lt;\"#1 \"&lt;&lt;buffer[0]&lt;&lt;endl;        modbus_set_slave(ctx,2);        nsleep(10);        rc=modbus_read_registers(ctx,258,1,buffer);        if (rc == -1)            cout&lt;&lt;\"#2 MDS_DIO_16BD::Read() \"&lt;&lt;modbus_strerror(errno)&lt;&lt;endl;        else            cout&lt;&lt;\"#2 \"&lt;&lt;buffer[0]&lt;&lt;endl;        modbus_set_slave(ctx,3);        nsleep(10);        rc = modbus_read_input_registers(ctx, 207, 8, buffer);        if (rc == -1)            cout&lt;&lt;\"#3 MDS_AIO_4::Read() \"&lt;&lt;modbus_strerror(errno)&lt;&lt;endl;        else            cout&lt;&lt;\"#3 \"&lt;&lt;modbus_get_float_badc(buffer)&lt;&lt;\" \"&lt;&lt;modbus_get_float_badc(buffer+2)&lt;&lt;\" \"&lt;&lt;modbus_get_float_badc(buffer+4)&lt;&lt;\" \"&lt;&lt;modbus_get_float_badc(buffer+6)&lt;&lt;endl;        nsleep(10);    }      modbus_close(ctx);    modbus_free(ctx);    cout&lt;&lt;\"Stop...\"&lt;&lt;endl; }<\/code><\/pre>\n<p>\u0424\u0430\u0439\u043b <code>util.cpp<\/code>:<\/p>\n<pre><code class=\"cpp\">int nsleep(long miliseconds) {    struct timespec req, rem;    if(miliseconds > 999) {        req.tv_sec = (int)(miliseconds \/ 1000);        req.tv_nsec = (miliseconds - ((long)req.tv_sec * 1000)) * 1000000;    }    else {        req.tv_sec = 0;        req.tv_nsec = miliseconds * 1000000;    }    return nanosleep(&amp;req , &amp;rem); }<\/code><\/pre>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u0444\u0430\u0439\u043b \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043a\u043e\u043c\u0430\u043d\u0434:<\/p>\n<pre><code class=\"bash\">arm-linux-gnueabihf-g++ -std=c++11 -I .\/libmodbus -L. -o .\/main .\/*.cpp -lmodbus sshpass -p \"icpdas\" scp main root@192.168.0.2:\/root\/<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u0441\u043e\u0431\u0440\u0430\u043b\u043e\u0441\u044c \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b\u043e\u0441\u044c \u043d\u0430 \u041f\u041b\u041a. \u0415\u0441\u043b\u0438 \u0432\u0441\u0435 \u0443 \u043d\u0430\u0441 \u0441\u043e\u0431\u0440\u0430\u043d\u043e \u0438 \u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e, \u0442\u043e \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0442\u0430\u043a\u043e\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"bash\">#1 0 #2 0 #3 4.000000 4.000001 3.999998 4.000000<\/code><\/pre>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0432 \u0446\u0438\u043a\u043b\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0442\u0441\u044f \u043d\u0443\u0436\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u0412\u043e\u0442 \u043c\u044b \u0438 \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u201c\u043f\u043e\u043b\u044f\u201d.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u0440\u0438 \u0442\u0430\u043a\u0438\u0445 \u0442\u0430\u0439\u043c\u0438\u043d\u0433\u0430\u0445 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u043d\u0430 \u041f\u041b\u041a, \u0442\u043e \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043a\u0440\u0430\u0441\u0438\u0432\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u0443, \u0447\u0442\u043e 3 \u043c\u043e\u0434\u0443\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043d\u0430 10%. \u0412 \u0431\u043e\u0435\u0432\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0438 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e, \u0442.\u043a. \u0441\u0435\u0439\u0447\u0430\u0441 \u0435\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0447\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0433\u0434\u0435 \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0441\u044f\u0442\u043a\u0430 \u043b\u0438\u043d\u0438\u0439 \u0441 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043c\u043e\u0434\u0443\u043b\u0435\u0439 7-10 \u0448\u0442\u0443\u043a.<\/p>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u0412\u044b\u0437\u043e\u0432\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>top<\/code>:<\/p>\n<pre><code>top - 10:47:15 up  5:28,  2 users,  load average: 1.00, 1.01, 1.03 Tasks: 108 total,   1 running, 107 sleeping,   0 stopped,   0 zombie Cpu(s):  1.3%us, 14.4%sy,  0.0%ni, 84.0%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st Mem:506968k total,95152k used,   411816k free,    0k buffers Swap:    0k total,    0k used,    0k free,41316k cached    PID USER  PR  NI  VIRT  RES  SHR S %CPU %MEMTIME+  COMMAND  2079 root  20   0  2660 1004  860 S  9.5  0.2 0:09.09 main\u2026<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u043f\u043e\u0441\u043b\u0435 \u043e\u043f\u0440\u043e\u0441\u0430 \u0432\u0441\u0435\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432\u0432\u043e\u0434\u0430\/\u0432\u044b\u0432\u043e\u0434\u0430. \u0415\u0441\u043b\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u0432 300 \u043c\u0441., \u0442\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c 1.6% \u043d\u0430 \u0434\u0430\u043d\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443.<\/p>\n<p>\u041a\u0430\u043a \u0436\u0435 \u043d\u0430\u043c \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u0438 \u0443\u043d\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0440\u0430\u0437\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432? \u041d\u0430\u0434\u043e \u043f\u043e\u0439\u0442\u0438 \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044f. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f Modbus \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432:<\/p>\n<p>\u0424\u0430\u0439\u043b <code>ModbusModule.h<\/code>:<\/p>\n<pre><code class=\"cpp\">class ModbusModule { public:     ModbusModule(modbus_t *ctx, int addr);     virtual ~ModbusModule();     virtual void Read() {};     virtual void Write() {};     bool isError=true,isChanged=true;     int error=0; protected:     bool oldIsError=false;     int rc,olderror; protected:     void Set();     modbus_t *ctx;     int address; };<\/code><\/pre>\n<p>\u0424\u0430\u0439\u043b <code>ModbusModule.cpp<\/code>:<\/p>\n<pre><code class=\"cpp\">ModbusModule::ModbusModule(modbus_t *ctx, int addr) :     ctx{ctx},address{addr} { }  ModbusModule::~ModbusModule() { }  void ModbusModule::Set() {     modbus_flush(ctx);     modbus_set_slave(ctx,address);     nsleep(5); }<\/code><\/pre>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u043f\u0438\u0448\u0435\u043c \u0441\u0430\u043c\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 MDS DIO-16BD. \u041a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e. \u0418 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043c\u0435\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u044d\u0442\u0438\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c.<\/p>\n<p>\u0424\u0430\u0439\u043b <code>MDS-DIO-16BD.h<\/code>:<\/p>\n<pre><code class=\"cpp\">class MDS_DIO_16BD : public ModbusModule { public:     MDS_DIO_16BD(modbus_t *ctx, int addr,         volatile bool *rB1=NULL,volatile bool *rB2=NULL,volatile bool *rB3=NULL,volatile bool *rB4=NULL,         volatile bool *rB5=NULL,volatile bool *rB6=NULL,volatile bool *rB7=NULL,volatile bool *rB8=NULL,         volatile bool *rB9=NULL,volatile bool *rB10=NULL,volatile bool *rB11=NULL,volatile bool *rB12=NULL,         volatile bool *rB13=NULL,volatile bool *rB14=NULL,volatile bool *rB15=NULL,volatile bool *rB16=NULL,         volatile bool *wB1=NULL,volatile bool *wB2=NULL,volatile bool *wB3=NULL,volatile bool *wB4=NULL,         volatile bool *wB5=NULL,volatile bool *wB6=NULL,volatile bool *wB7=NULL,volatile bool *wB8=NULL,         volatile bool *wB9=NULL,volatile bool *wB10=NULL,volatile bool *wB11=NULL,volatile bool *wB12=NULL,         volatile bool *wB13=NULL,volatile bool *wB14=NULL,volatile bool *wB15=NULL,volatile bool *wB16=NULL,         volatile uint16_t *rC1=NULL,volatile uint16_t *rC2=NULL,volatile uint16_t *rC3=NULL,volatile uint16_t *rC4=NULL,         volatile bool *wReset1=NULL,volatile bool *wReset2=NULL,volatile bool *wReset3=NULL,volatile bool *wReset4=NULL);     ~MDS_DIO_16BD() override;     void Write() override;     void Read() override;     void setRev(int index);   private:     uint16_t *buffer;     volatile bool *rB1,*rB2,*rB3,*rB4,*rB5,*rB6,*rB7,*rB8,*rB9,*rB10,*rB11,*rB12,*rB13,*rB14,*rB15,*rB16,*wB1,*wB2,*wB3,*wB4,*wB5,*wB6,*wB7,*wB8,*wB9,*wB10,*wB11,*wB12,*wB13,*wB14,*wB15,*wB16;     volatile uint16_t *rC1,*rC2,*rC3,*rC4;     volatile bool *wReset1,*wReset2,*wReset3,*wReset4;     bool rev[16]; };<\/code><\/pre>\n<p>\u0424\u0430\u0439\u043b <code>MDS-DIO-16BD.cpp<\/code>:<\/p>\n<pre><code class=\"cpp\">MDS_DIO_16BD::MDS_DIO_16BD(modbus_t *ctx, int addr,     volatile bool *rB1,volatile bool *rB2,volatile bool *rB3,volatile bool *rB4,     volatile bool *rB5,volatile bool *rB6,volatile bool *rB7,volatile bool *rB8,     volatile bool *rB9,volatile bool *rB10,volatile bool *rB11,volatile bool *rB12,     volatile bool *rB13,volatile bool *rB14,volatile bool *rB15,volatile bool *rB16,     volatile bool *wB1,volatile bool *wB2,volatile bool *wB3,volatile bool *wB4,     volatile bool *wB5,volatile bool *wB6,volatile bool *wB7,volatile bool *wB8,     volatile bool *wB9,volatile bool *wB10,volatile bool *wB11,volatile bool *wB12,     volatile bool *wB13,volatile bool *wB14,volatile bool *wB15,volatile bool *wB16,     volatile uint16_t *rC1,volatile uint16_t *rC2,volatile uint16_t *rC3,volatile uint16_t *rC4,     volatile bool *wReset1,volatile bool *wReset2,volatile bool *wReset3,volatile bool *wReset4)     : rB1{rB1},rB2{rB2},rB3{rB3},rB4{rB4},rB5{rB5},rB6{rB6},rB7{rB7},rB8{rB8},     rB9{rB9},rB10{rB10},rB11{rB11},rB12{rB12},rB13{rB13},rB14{rB14},rB15{rB15},rB16{rB16},     wB1{wB1},wB2{wB2},wB3{wB3},wB4{wB4},wB5{wB5},wB6{wB6},wB7{wB7},wB8{wB8},     wB9{wB9},wB10{wB10},wB11{wB11},wB12{wB12},wB13{wB13},wB14{wB14},wB15{wB15},wB16{wB16},     rC1{rC1},rC2{rC2},rC3{rC3},rC4{rC4},     wReset1{wReset1},wReset2{wReset2},wReset3{wReset3},wReset4{wReset4},ModbusModule(ctx,addr) {     buffer = new uint16_t[16];     memset(buffer, 0, 16 * sizeof(uint16_t));     for(int i=0;i&lt;16;i++) rev[i]=false; } MDS_DIO_16BD::~MDS_DIO_16BD() {     delete[] buffer; }  void MDS_DIO_16BD::Write() {     uint16_t temp=0;     if(wB1!=NULL||wB2!=NULL||wB3!=NULL||wB4!=NULL||wB5!=NULL||wB6!=NULL||wB7!=NULL||wB8!=NULL||         wB9!=NULL||wB10!=NULL||wB11!=NULL||wB12!=NULL||wB13!=NULL||wB14!=NULL||wB15!=NULL||wB16!=NULL) {         temp=((wB1==NULL)?0:rev[0]?!(*wB1&lt;&lt;0):(*wB1&lt;&lt;0))|             ((wB2==NULL)?0:rev[1]?!(*wB2&lt;&lt;1):(*wB2&lt;&lt;1))|             ((wB3==NULL)?0:rev[2]?!(*wB3&lt;&lt;2):(*wB3&lt;&lt;2))|             ((wB4==NULL)?0:rev[3]?!(*wB4&lt;&lt;3):(*wB4&lt;&lt;3))|             ((wB5==NULL)?0:rev[4]?!(*wB5&lt;&lt;4):(*wB5&lt;&lt;4))|             ((wB6==NULL)?0:rev[5]?!(*wB6&lt;&lt;5):(*wB6&lt;&lt;5))|             ((wB7==NULL)?0:rev[6]?!(*wB7&lt;&lt;6):(*wB7&lt;&lt;6))|             ((wB8==NULL)?0:rev[7]?!(*wB8&lt;&lt;7):(*wB8&lt;&lt;7))|             ((wB9==NULL)?0:rev[8]?!(*wB9&lt;&lt;8):(*wB9&lt;&lt;8))|             ((wB10==NULL)?0:rev[9]?!(*wB10&lt;&lt;9):(*wB10&lt;&lt;9))|             ((wB11==NULL)?0:rev[10]?!(*wB11&lt;&lt;10):(*wB11&lt;&lt;10))|             ((wB12==NULL)?0:rev[11]?!(*wB12&lt;&lt;11):(*wB12&lt;&lt;11))|             ((wB13==NULL)?0:rev[12]?!(*wB13&lt;&lt;12):(*wB13&lt;&lt;12))|             ((wB14==NULL)?0:rev[13]?!(*wB14&lt;&lt;13):(*wB14&lt;&lt;13))|             ((wB15==NULL)?0:rev[14]?!(*wB15&lt;&lt;14):(*wB15&lt;&lt;14))|             ((wB16==NULL)?0:rev[15]?!(*wB16&lt;&lt;15):(*wB16&lt;&lt;15));         buffer[1]=temp;         Set();         rc = modbus_write_registers(ctx, 267, 1, buffer+1);         isError=(rc==-1);         if (rc == -1)             fprintf(stderr, \"#%d MDS_DIO_16BD::Write(... %s\\n\", address, modbus_strerror(errno));     }     if(wReset1!=NULL||wReset2!=NULL||wReset3!=NULL||wReset4!=NULL) {         temp=((wReset1==NULL)?0:(*wReset1&lt;&lt;0))|             ((wReset2==NULL)?0:(*wReset2&lt;&lt;1))|             ((wReset3==NULL)?0:(*wReset3&lt;&lt;2))|             ((wReset4==NULL)?0:(*wReset4&lt;&lt;3));         rc = modbus_write_register(ctx, 276, temp);         isError&amp;=(rc==-1);         if (rc == -1)             fprintf(stderr, \"#%d MDS_DIO_16BD::Write(... %s\\n\",address, modbus_strerror(errno));     } }  void MDS_DIO_16BD::Read() {     if(rB1!=NULL||rB2!=NULL||rB3!=NULL||rB4!=NULL||rB5!=NULL||rB6!=NULL||rB7!=NULL||rB8!=NULL||         rB9!=NULL||rB10!=NULL||rB11!=NULL||rB12!=NULL||rB13!=NULL||rB14!=NULL||rB15!=NULL||rB16!=NULL) {         Set();         rc = modbus_read_registers(ctx, 258, 1, buffer);         isError=(rc==-1);         if (rc == -1)             fprintf(stderr, \"#%d MDS_DIO_16BD::Read() %s\\n\",address, modbus_strerror(errno));         else {             if(rB1!=NULL) *rB1=(buffer[0]>>0)&amp;1;             if(rB2!=NULL) *rB2=(buffer[0]>>1)&amp;1;             if(rB3!=NULL) *rB3=(buffer[0]>>2)&amp;1;             if(rB4!=NULL) *rB4=(buffer[0]>>3)&amp;1;             if(rB5!=NULL) *rB5=(buffer[0]>>4)&amp;1;             if(rB6!=NULL) *rB6=(buffer[0]>>5)&amp;1;             if(rB7!=NULL) *rB7=(buffer[0]>>6)&amp;1;             if(rB8!=NULL) *rB8=(buffer[0]>>7)&amp;1;             if(rB9!=NULL) *rB9=(buffer[0]>>8)&amp;1;             if(rB10!=NULL) *rB10=(buffer[0]>>9)&amp;1;             if(rB11!=NULL) *rB11=(buffer[0]>>10)&amp;1;             if(rB12!=NULL) *rB12=(buffer[0]>>11)&amp;1;             if(rB13!=NULL) *rB13=(buffer[0]>>12)&amp;1;             if(rB14!=NULL) *rB14=(buffer[0]>>13)&amp;1;             if(rB15!=NULL) *rB15=(buffer[0]>>14)&amp;1;             if(rB16!=NULL) *rB16=(buffer[0]>>15)&amp;1;         }     }     if(rC1!=NULL||rC2!=NULL||rC3!=NULL||rC4!=NULL) {         rc = modbus_read_registers(ctx, 278, 4, buffer);         isError&amp;=(rc==-1);         if (rc == -1)             fprintf(stderr, \"#%d MDS_DIO_16BD::Read() %s\\n\",address, modbus_strerror(errno));         else {             if(rC1!=NULL) *rC1=buffer[0];             if(rC2!=NULL) *rC2=buffer[1];             if(rC3!=NULL) *rC3=buffer[2];             if(rC4!=NULL) *rC4=buffer[3];         }     } }  void MDS_DIO_16BD::setRev(int index) {     if(index&lt;0 || index>15) return;     rev[index]=!rev[index]; }<\/code><\/pre>\n<p>\u041f\u043e\u0440\u043e\u0436\u0434\u0430\u044e\u0449\u0438\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 \u043e\u043f\u0440\u043e\u0441\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432 \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0448\u0438\u043d\u0435 RS-485.<\/p>\n<p>\u0424\u0430\u0439\u043b <code>ModbusLine.h<\/code>:<\/p>\n<pre><code class=\"cpp\">class ModbusLine { public:     ModbusLine(modbus_t *ctx, long sleepTime=300);     ~ModbusLine();     MDS_DIO_16BD* addMDS_DIO_16BD(int address,         volatile bool *rB1=NULL,volatile bool *rB2=NULL,volatile bool *rB3=NULL,volatile bool *rB4=NULL,         volatile bool *rB5=NULL,volatile bool *rB6=NULL,volatile bool *rB7=NULL,volatile bool *rB8=NULL,         volatile bool *rB9=NULL,volatile bool *rB10=NULL,volatile bool *rB11=NULL,volatile bool *rB12=NULL,         volatile bool *rB13=NULL,volatile bool *rB14=NULL,volatile bool *rB15=NULL,volatile bool *rB16=NULL,         volatile bool *wB1=NULL,volatile bool *wB2=NULL,volatile bool *wB3=NULL,volatile bool *wB4=NULL,         volatile bool *wB5=NULL,volatile bool *wB6=NULL,volatile bool *wB7=NULL,volatile bool *wB8=NULL,         volatile bool *wB9=NULL,volatile bool *wB10=NULL,volatile bool *wB11=NULL,volatile bool *wB12=NULL,         volatile bool *wB13=NULL,volatile bool *wB14=NULL,volatile bool *wB15=NULL,volatile bool *wB16=NULL,         volatile uint16_t *rC1=NULL,volatile uint16_t *rC2=NULL,volatile uint16_t *rC3=NULL,volatile uint16_t *rC4=NULL,         volatile bool *wReset1=NULL,volatile bool *wReset2=NULL,volatile bool *wReset3=NULL,volatile bool *wReset4=NULL); protected:     void Thread();     modbus_t *ctx;     long sleepTime;     std::thread _t;     bool _stop=false;     std::vector&lt;ModbusModule*> devices; }; <\/code><\/pre>\n<p>\u0424\u0430\u0439\u043b <code>ModbusLine.cpp<\/code>:<\/p>\n<pre><code class=\"cpp\">ModbusLine::ModbusLine(modbus_t *ctx, long sleepTime) : ctx{ctx},sleepTime{sleepTime} {     _t=std::thread(&amp;ModbusLine::Thread,this);     printf(\"ModbusLine create\\n\"); } ModbusLine::~ModbusLine() {     _stop=true;     _t.join();     for(auto&amp; dev:devices) delete dev;     devices.clear();     modbus_close(ctx);     modbus_free(ctx);     printf(\"ModbusLine delete\\n\"); }  void ModbusLine::Thread() {     int isOpen=-1;     auto olderrno=errno;     while(!_stop) {         if (isOpen==-1) {             cout&lt;&lt;\"Try open port...\"&lt;&lt;endl;             if ((isOpen = modbus_connect(ctx)) == -1) {                 if(errno!=olderrno) {                     fprintf(stderr, \"Connection failed: %s\\n\",modbus_strerror(errno));                 }             }             modbus_set_error_recovery(ctx,  (modbus_error_recovery_mode)6);             modbus_set_response_timeout(ctx, 0,500);             olderrno=errno;             nsleep(1000);             continue;         }         bool err=true;         for(auto&amp; dev:devices) {             dev->Read();             if(dev->isError==false) err=false;             nsleep(10);             dev->Write();             if(dev->isError==false) err=false;             nsleep(10);         }         if(err) {             isOpen=-1;         }         nsleep(sleepTime);     } }  MDS_DIO_16BD* ModbusLine::addMDS_DIO_16BD(int address,     volatile bool *rB1,volatile bool *rB2,volatile bool *rB3,volatile bool *rB4,     volatile bool *rB5,volatile bool *rB6,volatile bool *rB7,volatile bool *rB8,     volatile bool *rB9,volatile bool *rB10,volatile bool *rB11,volatile bool *rB12,     volatile bool *rB13,volatile bool *rB14,volatile bool *rB15,volatile bool *rB16,     volatile bool *wB1,volatile bool *wB2,volatile bool *wB3,volatile bool *wB4,     volatile bool *wB5,volatile bool *wB6,volatile bool *wB7,volatile bool *wB8,     volatile bool *wB9,volatile bool *wB10,volatile bool *wB11,volatile bool *wB12,     volatile bool *wB13,volatile bool *wB14,volatile bool *wB15,volatile bool *wB16,     volatile uint16_t *rC1,volatile uint16_t *rC2,volatile uint16_t *rC3,volatile uint16_t *rC4,     volatile bool *wReset1,volatile bool *wReset2,volatile bool *wReset3,volatile bool *wReset4) {     auto out = new MDS_DIO_16BD(ctx,address,rB1,rB2,rB3,rB4,         rB5,rB6,rB7,rB8,rB9,rB10,rB11,rB12,rB13,rB14,rB15,rB16,         wB1,wB2,wB3,wB4,wB5,wB6,wB7,wB8,wB9,wB10,wB11,wB12,wB13,wB14,wB15,wB16,         rC1,rC2,rC3,rC4,wReset1,wReset2,wReset3,wReset4);     devices.push_back((ModbusModule*)out);     return out; }<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0448\u0438\u043d\u044b RS-485 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"cpp\">volatile bool b1=false,b2=false,b3=false; ModbusLine line1(modbus_new_rtu(\"\/dev\/ttyS2\", 115200, 'N', 8, 1)); line1.addMDS_DIO_16BD(1,&amp;b1,&amp;b2,&amp;b3);<\/code><\/pre>\n<p>\u0423 \u043d\u0430\u0441 \u043d\u0430 \u043a\u0430\u0436\u0434\u0443\u044e \u043b\u0438\u043d\u0438\u044e \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u043e\u043f\u0440\u043e\u0441\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432. \u0412 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u0437\u0430 \u044d\u0442\u043e \u0443 \u043d\u0430\u0441 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e volatile \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043c\u043e\u0436\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0438\u0437\u0432\u043d\u0435 \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e.<\/p>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 MQTT \u0434\u043b\u044f \u043e\u0431\u043c\u0435\u043d\u0430 \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438 \u043d\u0430 \u041f\u041b\u041a \u0438 \u043c\u043d\u0435\u043c\u043e\u0441\u0445\u0435\u043c\u043e\u0439.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/762576\/\"> https:\/\/habr.com\/ru\/articles\/762576\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u0441\u0435\u043c \u0434\u043e\u0431\u0440\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0443\u0442\u043e\u043a. \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u043e\u043c \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u044f\u0442\u0438\u0438, \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0441\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0430. \u041e\u0447\u0435\u043d\u044c \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441 \u0412\u0430\u043c\u0438 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043d\u0430\u0440\u0430\u0431\u043e\u0442\u043a\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432 \u043f\u043e\u0432\u0441\u0435\u0434\u043d\u0435\u0432\u043d\u043e\u0439 \u0442\u0440\u0443\u0434\u043e\u0432\u043e\u0439 \u0436\u0438\u0437\u043d\u0438. \u041d\u0435 \u0441\u0443\u0434\u0438\u0442\u0435 \u0441\u0442\u0440\u043e\u0433\u043e, \u044d\u0442\u043e \u043c\u043e\u044f \u043f\u0435\u0440\u0432\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u044e&#8230;<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u043f\u0440\u043e\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u043e\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438, \u0442\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u044f\u0437\u044b\u043a\u0430\u043c\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430 \u041c\u042d\u041a 61131-3.<\/p>\n<p>\u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430 \u0432 \u043f\u0440\u043e\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0435 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u0435 \u043e\u0442:<\/p>\n<ul>\n<li>\n<p>ISaGRAF, Rockwell Automation (\u041c\u043e\u043d\u0440\u0435\u0430\u043b\u044c, \u041a\u0430\u043d\u0430\u0434\u0430)<\/p>\n<\/li>\n<li>\n<p>CoDeSYS, CODESYS GmbH (\u041a\u0435\u043c\u043f\u0442\u0435\u043d, \u0413\u0435\u0440\u043c\u0430\u043d\u0438\u044f)<\/p>\n<\/li>\n<li>\n<p>ISPSoft, Delta Electronics, Inc (\u0422\u0430\u0439\u0431\u044d\u0439, \u0422\u0430\u0439\u0432\u0430\u043d\u044c)<\/p>\n<\/li>\n<\/ul>\n<p>\u0410 \u043a\u0430\u043a \u0436\u0435 \u0431\u044b\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u0442\u0435\u0431\u0435 \u043d\u0435 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0438 \u0438\u043c\u0435\u0442\u044c \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u043c\u044b\u0439 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0442\u0440\u0443\u0434\u043e\u0437\u0430\u0442\u0440\u0430\u0442\u0430\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043d\u0430 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432, \u0438 \u0434\u0430\u0436\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0435?<\/p>\n<p>\u042f \u043d\u0430\u0448\u0435\u043b \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 Icp-Das LP-8&#215;21 \u043d\u0430 Ubuntu 12, \u043f\u0430\u0440\u0443 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432\u0432\u043e\u0434\u0430\/\u0432\u044b\u0432\u043e\u0434\u0430 MDS DIO-16BD \u0438 AIO-4 \u043e\u0442 \u041a\u043e\u043d\u0442\u0440\u0410\u0432\u0442 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432. \u0412\u043e\u0442 \u0443\u0436\u0435 \u0438 \u0435\u0441\u0442\u044c \u0441 \u0447\u0435\u043c \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0422\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u0441\u0431\u043e\u0440\u043a\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u043b\u044f \u0441\u0432\u044f\u0437\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0438 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432\u0432\u043e\u0434\u0430\/\u0432\u044b\u0432\u043e\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0445 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u0432 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0441\u0432\u044f\u0437\u0438 &#8212; RS-485. \u0414\u0430\u043d\u043d\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b Modbus.<\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u043f\u043e\u0434 \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u0435\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440:<\/p>\n<pre><code class=\"bash\">sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf<\/code><\/pre>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0444\u0430\u0439\u043b\u044b \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 <code>libmodbus-dev<\/code>:<\/p>\n<pre><code class=\"bash\">sudo apt install libmodbus-dev apt source libmodbus-dev<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438 \u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043f\u043e\u0434 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0434\u043b\u044f <code>arm-linux-gnueabihf<\/code>:<\/p>\n<pre><code class=\"bash\">.\/autogen.sh .\/configure --host=arm-linux-gnueabihf --enable-shared --enable-static make<\/code><\/pre>\n<p>\u0412 \u043f\u0430\u043f\u043a\u0435 <code>.\/src\/.libs\/<\/code>\u00a0 \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0432\u0441\u0435 \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442. \u041d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0444\u0430\u0439\u043b <code>libmodbus.a<\/code>.<\/p>\n<p>\u0418\u0437 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432\u0432\u043e\u0434\u0430\/\u0432\u044b\u0432\u043e\u0434\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f. \u0414\u043b\u044f DIO-16BD \u044d\u0442\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440 258 \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u0430, \u0430 \u0434\u043b\u044f AIO-4 \u043c\u044b \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0435\u043c 4 \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u0432\u044b\u0445 \u0432\u0445\u043e\u0434\u0430 \u0441 \u0430\u0434\u0440\u0435\u0441\u0430 207. \u0422.\u043a. \u0442\u0430\u043c \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u044e\u0442\u0441\u044f 4 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 float, \u0442\u043e \u0431\u0443\u0434\u0435\u043c \u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 8 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u0432.\u00a0 \u0414\u043b\u044f \u043f\u0440\u043e\u0431\u044b \u0441\u043e\u0431\u0435\u0440\u0435\u043c \u043d\u0430 C++ \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<p>\u0424\u0430\u0439\u043b <code>main.cpp<\/code>:<\/p>\n<pre><code class=\"cpp\">#include &lt;modbus\/modbus.h> #include &lt;iostream> #include &lt;errno.h> #include \"util.h\"  using namespace std;  bool _stop=false;  void handle_signal(int i) {    printf(\"[MAIN] Terminating\\n\");     _stop=true; }  int main() {    signal(SIGINT, handle_signal);    signal(SIGTERM, handle_signal);    cout&lt;&lt;\"Start...\"&lt;&lt;endl;    uint16_t buffer[8];    modbus_t *ctx=modbus_new_rtu(\"\/dev\/ttyS2\",115200,'N',8,1);    if (modbus_connect(ctx) == -1)        cout&lt;&lt;\"Connection failed: \"&lt;&lt;modbus_strerror(errno)&lt;&lt;endl;    modbus_set_response_timeout(ctx, 1,0);    while(!_stop) {        modbus_set_slave(ctx,1);        int rc=modbus_read_registers(ctx,258,1,buffer);        if (rc == -1)            cout&lt;&lt;\"#1 MDS_DIO_16BD::Read() \"&lt;&lt;modbus_strerror(errno)&lt;&lt;endl;        else            cout&lt;&lt;\"#1 \"&lt;&lt;buffer[0]&lt;&lt;endl;        modbus_set_slave(ctx,2);        nsleep(10);        rc=modbus_read_registers(ctx,258,1,buffer);        if (rc == -1)            cout&lt;&lt;\"#2 MDS_DIO_16BD::Read() \"&lt;&lt;modbus_strerror(errno)&lt;&lt;endl;        else            cout&lt;&lt;\"#2 \"&lt;&lt;buffer[0]&lt;&lt;endl;        modbus_set_slave(ctx,3);        nsleep(10);        rc = modbus_read_input_registers(ctx, 207, 8, buffer);        if (rc == -1)            cout&lt;&lt;\"#3 MDS_AIO_4::Read() \"&lt;&lt;modbus_strerror(errno)&lt;&lt;endl;        else            cout&lt;&lt;\"#3 \"&lt;&lt;modbus_get_float_badc(buffer)&lt;&lt;\" \"&lt;&lt;modbus_get_float_badc(buffer+2)&lt;&lt;\" \"&lt;&lt;modbus_get_float_badc(buffer+4)&lt;&lt;\" \"&lt;&lt;modbus_get_float_badc(buffer+6)&lt;&lt;endl;        nsleep(10);    }      modbus_close(ctx);    modbus_free(ctx);    cout&lt;&lt;\"Stop...\"&lt;&lt;endl; }<\/code><\/pre>\n<p>\u0424\u0430\u0439\u043b <code>util.cpp<\/code>:<\/p>\n<pre><code class=\"cpp\">int nsleep(long miliseconds) {    struct timespec req, rem;    if(miliseconds > 999) {        req.tv_sec = (int)(miliseconds \/ 1000);        req.tv_nsec = (miliseconds - ((long)req.tv_sec * 1000)) * 1000000;    }    else {        req.tv_sec = 0;        req.tv_nsec = miliseconds * 1000000;    }    return nanosleep(&amp;req , &amp;rem); }<\/code><\/pre>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u0444\u0430\u0439\u043b \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043a\u043e\u043c\u0430\u043d\u0434:<\/p>\n<pre><code class=\"bash\">arm-linux-gnueabihf-g++ -std=c++11 -I .\/libmodbus -L. -o .\/main .\/*.cpp -lmodbus sshpass -p \"icpdas\" scp main root@192.168.0.2:\/root\/<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u0441\u043e\u0431\u0440\u0430\u043b\u043e\u0441\u044c \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b\u043e\u0441\u044c \u043d\u0430 \u041f\u041b\u041a. \u0415\u0441\u043b\u0438 \u0432\u0441\u0435 \u0443 \u043d\u0430\u0441 \u0441\u043e\u0431\u0440\u0430\u043d\u043e \u0438 \u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e, \u0442\u043e \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0442\u0430\u043a\u043e\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"bash\">#1 0 #2 0 #3 4.000000 4.000001 3.999998 4.000000<\/code><\/pre>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0432 \u0446\u0438\u043a\u043b\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0442\u0441\u044f \u043d\u0443\u0436\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u0412\u043e\u0442 \u043c\u044b \u0438 \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u201c\u043f\u043e\u043b\u044f\u201d.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u0440\u0438 \u0442\u0430\u043a\u0438\u0445 \u0442\u0430\u0439\u043c\u0438\u043d\u0433\u0430\u0445 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u043d\u0430 \u041f\u041b\u041a, \u0442\u043e \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043a\u0440\u0430\u0441\u0438\u0432\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u0443, \u0447\u0442\u043e 3 \u043c\u043e\u0434\u0443\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043d\u0430 10%. \u0412 \u0431\u043e\u0435\u0432\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0438 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e, \u0442.\u043a. \u0441\u0435\u0439\u0447\u0430\u0441 \u0435\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0447\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0433\u0434\u0435 \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0441\u044f\u0442\u043a\u0430 \u043b\u0438\u043d\u0438\u0439 \u0441 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043c\u043e\u0434\u0443\u043b\u0435\u0439 7-10 \u0448\u0442\u0443\u043a.<\/p>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u0412\u044b\u0437\u043e\u0432\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>top<\/code>:<\/p>\n<pre><code>top - 10:47:15 up  5:28,  2 users,  load average: 1.00, 1.01, 1.03 Tasks: 108 total,   1 running, 107 sleeping,   0 stopped,   0 zombie Cpu(s):  1.3%us, 14.4%sy,  0.0%ni, 84.0%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st Mem:506968k total,95152k used,   411816k free,    0k buffers Swap:    0k total,    0k used,    0k free,41316k cached    PID USER  PR  NI  VIRT  RES  SHR S %CPU %MEMTIME+  COMMAND  2079 root  20   0  2660 1004  860 S  9.5  0.2 0:09.09 main\u2026<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u043f\u043e\u0441\u043b\u0435 \u043e\u043f\u0440\u043e\u0441\u0430 \u0432\u0441\u0435\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432\u0432\u043e\u0434\u0430\/\u0432\u044b\u0432\u043e\u0434\u0430. \u0415\u0441\u043b\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u0432 300 \u043c\u0441., \u0442\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c 1.6% \u043d\u0430 \u0434\u0430\u043d\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443.<\/p>\n<p>\u041a\u0430\u043a \u0436\u0435 \u043d\u0430\u043c \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u0438 \u0443\u043d\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0440\u0430\u0437\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432? \u041d\u0430\u0434\u043e \u043f\u043e\u0439\u0442\u0438 \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044f. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f Modbus \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432:<\/p>\n<p>\u0424\u0430\u0439\u043b <code>ModbusModule.h<\/code>:<\/p>\n<pre><code class=\"cpp\">class ModbusModule { public:     ModbusModule(modbus_t *ctx, int addr);     virtual ~ModbusModule();     virtual void Read() {};     virtual void Write() {};     bool isError=true,isChanged=true;     int error=0; protected:     bool oldIsError=false;     int rc,olderror; protected:     void Set();     modbus_t *ctx;     int address; };<\/code><\/pre>\n<p>\u0424\u0430\u0439\u043b <code>ModbusModule.cpp<\/code>:<\/p>\n<pre><code class=\"cpp\">ModbusModule::ModbusModule(modbus_t *ctx, int addr) :     ctx{ctx},address{addr} { }  ModbusModule::~ModbusModule() { }  void ModbusModule::Set() {     modbus_flush(ctx);     modbus_set_slave(ctx,address);     nsleep(5); }<\/code><\/pre>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u043f\u0438\u0448\u0435\u043c \u0441\u0430\u043c\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 MDS DIO-16BD. \u041a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e. \u0418 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043c\u0435\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u044d\u0442\u0438\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c.<\/p>\n<p>\u0424\u0430\u0439\u043b <code>MDS-DIO-16BD.h<\/code>:<\/p>\n<pre><code class=\"cpp\">class MDS_DIO_16BD : public ModbusModule { public:     MDS_DIO_16BD(modbus_t *ctx, int addr,         volatile bool *rB1=NULL,volatile bool *rB2=NULL,volatile bool *rB3=NULL,volatile bool *rB4=NULL,         volatile bool *rB5=NULL,volatile bool *rB6=NULL,volatile bool *rB7=NULL,volatile bool *rB8=NULL,         volatile bool *rB9=NULL,volatile bool *rB10=NULL,volatile bool *rB11=NULL,volatile bool *rB12=NULL,         volatile bool *rB13=NULL,volatile bool *rB14=NULL,volatile bool *rB15=NULL,volatile bool *rB16=NULL,         volatile bool *wB1=NULL,volatile bool *wB2=NULL,volatile bool *wB3=NULL,volatile bool *wB4=NULL,         volatile bool *wB5=NULL,volatile bool *wB6=NULL,volatile bool *wB7=NULL,volatile bool *wB8=NULL,         volatile bool *wB9=NULL,volatile bool *wB10=NULL,volatile bool *wB11=NULL,volatile bool *wB12=NULL,         volatile bool *wB13=NULL,volatile bool *wB14=NULL,volatile bool *wB15=NULL,volatile bool *wB16=NULL,         volatile uint16_t *rC1=NULL,volatile uint16_t *rC2=NULL,volatile uint16_t *rC3=NULL,volatile uint16_t *rC4=NULL,         volatile bool *wReset1=NULL,volatile bool *wReset2=NULL,volatile bool *wReset3=NULL,volatile bool *wReset4=NULL);     ~MDS_DIO_16BD() override;     void Write() override;     void Read() override;     void setRev(int index);   private:     uint16_t *buffer;     volatile bool *rB1,*rB2,*rB3,*rB4,*rB5,*rB6,*rB7,*rB8,*rB9,*rB10,*rB11,*rB12,*rB13,*rB14,*rB15,*rB16,*wB1,*wB2,*wB3,*wB4,*wB5,*wB6,*wB7,*wB8,*wB9,*wB10,*wB11,*wB12,*wB13,*wB14,*wB15,*wB16;     volatile uint16_t *rC1,*rC2,*rC3,*rC4;     volatile bool *wReset1,*wReset2,*wReset3,*wReset4;     bool rev[16]; };<\/code><\/pre>\n<p>\u0424\u0430\u0439\u043b <code>MDS-DIO-16BD.cpp<\/code>:<\/p>\n<pre><code class=\"cpp\">MDS_DIO_16BD::MDS_DIO_16BD(modbus_t *ctx, int addr,     volatile bool *rB1,volatile bool *rB2,volatile bool *rB3,volatile bool *rB4,     volatile bool *rB5,volatile bool *rB6,volatile bool *rB7,volatile bool *rB8,     volatile bool *rB9,volatile bool *rB10,volatile bool *rB11,volatile bool *rB12,     volatile bool *rB13,volatile bool *rB14,volatile bool *rB15,volatile bool *rB16,     volatile bool *wB1,volatile bool *wB2,volatile bool *wB3,volatile bool *wB4,     volatile bool *wB5,volatile bool *wB6,volatile bool *wB7,volatile bool *wB8,     volatile bool *wB9,volatile bool *wB10,volatile bool *wB11,volatile bool *wB12,     volatile bool *wB13,volatile bool *wB14,volatile bool *wB15,volatile bool *wB16,     volatile uint16_t *rC1,volatile uint16_t *rC2,volatile uint16_t *rC3,volatile uint16_t *rC4,     volatile bool *wReset1,volatile bool *wReset2,volatile bool *wReset3,volatile bool *wReset4)     : rB1{rB1},rB2{rB2},rB3{rB3},rB4{rB4},rB5{rB5},rB6{rB6},rB7{rB7},rB8{rB8},     rB9{rB9},rB10{rB10},rB11{rB11},rB12{rB12},rB13{rB13},rB14{rB14},rB15{rB15},rB16{rB16},     wB1{wB1},wB2{wB2},wB3{wB3},wB4{wB4},wB5{wB5},wB6{wB6},wB7{wB7},wB8{wB8},     wB9{wB9},wB10{wB10},wB11{wB11},wB12{wB12},wB13{wB13},wB14{wB14},wB15{wB15},wB16{wB16},     rC1{rC1},rC2{rC2},rC3{rC3},rC4{rC4},     wReset1{wReset1},wReset2{wReset2},wReset3{wReset3},wReset4{wReset4},ModbusModule(ctx,addr) {     buffer = new uint16_t[16];     memset(buffer, 0, 16 * sizeof(uint16_t));     for(int i=0;i&lt;16;i++) rev[i]=false; } MDS_DIO_16BD::~MDS_DIO_16BD() {     delete[] buffer; }  void MDS_DIO_16BD::Write() {     uint16_t temp=0;     if(wB1!=NULL||wB2!=NULL||wB3!=NULL||wB4!=NULL||wB5!=NULL||wB6!=NULL||wB7!=NULL||wB8!=NULL||<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-355501","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/355501","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=355501"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/355501\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=355501"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=355501"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=355501"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}