Commit da87669697ae0e4397356665dafd151bb6d4795a
1 parent
ef3c4bc9
Rewrite documentation with Material for mkdocs
- remove doc build from autotools - don't depend anymore on asciidoc - don't provide man pages anymore - new illustrations - provide mkdocs instructions
Showing
138 changed files
with
3680 additions
and
3483 deletions
Too many changes.
To preserve performance only 100 of 138 files are displayed.
.gitignore
| @@ -10,11 +10,10 @@ | @@ -10,11 +10,10 @@ | ||
| 10 | .libs | 10 | .libs |
| 11 | .DS_Store | 11 | .DS_Store |
| 12 | 12 | ||
| 13 | -# Emacs | ||
| 14 | -GPATH | ||
| 15 | -GRTAGS | ||
| 16 | -GSYMS | ||
| 17 | -GTAGS | 13 | +# Editors |
| 14 | +/*.sublime-* | ||
| 15 | +/.vscode | ||
| 16 | +/.venv | ||
| 18 | 17 | ||
| 19 | # Generated by Autotools | 18 | # Generated by Autotools |
| 20 | INSTALL | 19 | INSTALL |
| @@ -28,17 +27,17 @@ Makefile.in | @@ -28,17 +27,17 @@ Makefile.in | ||
| 28 | /configure.scan | 27 | /configure.scan |
| 29 | /depcomp | 28 | /depcomp |
| 30 | /install-sh | 29 | /install-sh |
| 30 | +/libmodbus.pc | ||
| 31 | /libtool | 31 | /libtool |
| 32 | /ltmain.sh | 32 | /ltmain.sh |
| 33 | /missing | 33 | /missing |
| 34 | -/libmodbus.pc | ||
| 35 | /stamp-h1 | 34 | /stamp-h1 |
| 36 | src/modbus-version.h | 35 | src/modbus-version.h |
| 37 | src/win32/modbus.dll.manifest | 36 | src/win32/modbus.dll.manifest |
| 38 | tests/unit-test.h | 37 | tests/unit-test.h |
| 39 | 38 | ||
| 40 | -/*.sublime-* | ||
| 41 | -/.vscode | 39 | +# mkdocs |
| 40 | +/site | ||
| 42 | 41 | ||
| 43 | # Binary | 42 | # Binary |
| 44 | tests/bandwidth-client | 43 | tests/bandwidth-client |
| @@ -50,8 +49,3 @@ tests/unit-test-client | @@ -50,8 +49,3 @@ tests/unit-test-client | ||
| 50 | tests/unit-test-server | 49 | tests/unit-test-server |
| 51 | tests/version | 50 | tests/version |
| 52 | tests/stamp-h2 | 51 | tests/stamp-h2 |
| 53 | - | ||
| 54 | -# Documentation | ||
| 55 | -doc/*.html | ||
| 56 | -doc/*.3 | ||
| 57 | -doc/*.7 |
CONTRIBUTING.md
| @@ -4,7 +4,7 @@ How Do I Submit A Good Bug Report? | @@ -4,7 +4,7 @@ How Do I Submit A Good Bug Report? | ||
| 4 | Please, don't send direct emails to Stéphane Raimbault unless you want | 4 | Please, don't send direct emails to Stéphane Raimbault unless you want |
| 5 | commercial support. | 5 | commercial support. |
| 6 | 6 | ||
| 7 | -Take care to read the documentation at http://libmodbus.org/documentation/. | 7 | +Take care to read the documentation at http://libmodbus.org/. |
| 8 | 8 | ||
| 9 | - *Be sure it's a bug before creating an issue*, in doubt, post a message on | 9 | - *Be sure it's a bug before creating an issue*, in doubt, post a message on |
| 10 | https://groups.google.com/forum/#!forum/libmodbus or send an email to | 10 | https://groups.google.com/forum/#!forum/libmodbus or send an email to |
| @@ -24,6 +24,6 @@ the clients are connected (TCP, RTU, ASCII) and the source code you are using. | @@ -24,6 +24,6 @@ the clients are connected (TCP, RTU, ASCII) and the source code you are using. | ||
| 24 | 24 | ||
| 25 | - *Enable the debug mode*, libmodbus provides a function to display the content | 25 | - *Enable the debug mode*, libmodbus provides a function to display the content |
| 26 | of the Modbus messages and it's very convenient to analyze issues | 26 | of the Modbus messages and it's very convenient to analyze issues |
| 27 | -(http://libmodbus.org/docs/latest/modbus_set_debug.html). | 27 | +(http://libmodbus.org/docs/modbus_set_debug/). |
| 28 | 28 | ||
| 29 | Good bug reports provide right and quick fixes! | 29 | Good bug reports provide right and quick fixes! |
ISSUE_TEMPLATE.md
| @@ -34,7 +34,7 @@ When you get here and you are still convinced that you want to report a bug: | @@ -34,7 +34,7 @@ When you get here and you are still convinced that you want to report a bug: | ||
| 34 | 34 | ||
| 35 | - *Enable the debug mode*, libmodbus provides a function to display the content | 35 | - *Enable the debug mode*, libmodbus provides a function to display the content |
| 36 | of the Modbus messages and it's very convenient to analyze issues | 36 | of the Modbus messages and it's very convenient to analyze issues |
| 37 | - (<http://libmodbus.org/docs/latest/modbus_set_debug.html>). | 37 | + (<http://libmodbus.org/docs/modbus_set_debug/>). |
| 38 | 38 | ||
| 39 | Good bug reports provide right and quick fixes! | 39 | Good bug reports provide right and quick fixes! |
| 40 | 40 |
Makefile.am
| @@ -9,7 +9,7 @@ CLEANFILES += libmodbus.pc | @@ -9,7 +9,7 @@ CLEANFILES += libmodbus.pc | ||
| 9 | 9 | ||
| 10 | dist_doc_DATA = MIGRATION README.md AUTHORS NEWS | 10 | dist_doc_DATA = MIGRATION README.md AUTHORS NEWS |
| 11 | 11 | ||
| 12 | -SUBDIRS = src doc | 12 | +SUBDIRS = src |
| 13 | 13 | ||
| 14 | if BUILD_TESTS | 14 | if BUILD_TESTS |
| 15 | SUBDIRS += tests | 15 | SUBDIRS += tests |
README.md
| 1 | -A groovy modbus library | ||
| 2 | -======================= | 1 | +# A groovy modbus library |
| 3 | 2 | ||
| 4 |  | 3 |  |
| 5 | 4 | ||
| 6 | -Overview | ||
| 7 | --------- | 5 | +## Overview |
| 8 | 6 | ||
| 9 | libmodbus is a free software library to send/receive data with a device which | 7 | libmodbus is a free software library to send/receive data with a device which |
| 10 | respects the Modbus protocol. This library can use a serial port or an Ethernet | 8 | respects the Modbus protocol. This library can use a serial port or an Ethernet |
| @@ -15,21 +13,15 @@ Protocol Reference Guide which can be obtained from [www.modbus.org](http://www. | @@ -15,21 +13,15 @@ Protocol Reference Guide which can be obtained from [www.modbus.org](http://www. | ||
| 15 | 13 | ||
| 16 | The license of libmodbus is *LGPL v2.1 or later*. | 14 | The license of libmodbus is *LGPL v2.1 or later*. |
| 17 | 15 | ||
| 18 | -The documentation is available as manual pages (`man libmodbus` to read general | ||
| 19 | -description and list of available functions) or Web pages | ||
| 20 | -[www.libmodbus.org/documentation/](http://libmodbus.org/documentation/). The | ||
| 21 | -documentation is licensed under the Creative Commons Attribution-ShareAlike | ||
| 22 | -License 3.0 (Unported) (<http://creativecommons.org/licenses/by-sa/3.0/>). | ||
| 23 | - | ||
| 24 | -The official website is [www.libmodbus.org](http://www.libmodbus.org). | 16 | +The official website is [www.libmodbus.org](http://www.libmodbus.org). The |
| 17 | +website contains the latest version of the documentation. | ||
| 25 | 18 | ||
| 26 | The library is written in C and designed to run on Linux, Mac OS X, FreeBSD, Embox, | 19 | The library is written in C and designed to run on Linux, Mac OS X, FreeBSD, Embox, |
| 27 | QNX and Windows. | 20 | QNX and Windows. |
| 28 | 21 | ||
| 29 | You can use the library on MCUs with Embox RTOS. | 22 | You can use the library on MCUs with Embox RTOS. |
| 30 | 23 | ||
| 31 | -Installation | ||
| 32 | ------------- | 24 | +## Installation |
| 33 | 25 | ||
| 34 | You will only need to install automake, autoconf, libtool and a C compiler (gcc | 26 | You will only need to install automake, autoconf, libtool and a C compiler (gcc |
| 35 | or clang) to compile the library and asciidoc and xmlto to generate the | 27 | or clang) to compile the library and asciidoc and xmlto to generate the |
| @@ -59,19 +51,7 @@ automake libtool`. | @@ -59,19 +51,7 @@ automake libtool`. | ||
| 59 | 51 | ||
| 60 | To build under Embox, you have to use its build system. | 52 | To build under Embox, you have to use its build system. |
| 61 | 53 | ||
| 62 | -Documentation | ||
| 63 | -------------- | ||
| 64 | - | ||
| 65 | -The documentation is available [online](http://libmodbus.org/documentation) or | ||
| 66 | -as manual pages after installation. | ||
| 67 | - | ||
| 68 | -The documentation is based on | ||
| 69 | -[AsciiDoc](http://www.methods.co.nz/asciidoc/). Only man pages are built | ||
| 70 | -by default with `make` command, you can run `make htmldoc` in *doc* directory | ||
| 71 | -to generate HTML files. | ||
| 72 | - | ||
| 73 | -Testing | ||
| 74 | -------- | 54 | +## Testing |
| 75 | 55 | ||
| 76 | Some tests are provided in *tests* directory, you can freely edit the source | 56 | Some tests are provided in *tests* directory, you can freely edit the source |
| 77 | code to fit your needs (it's Free Software :). | 57 | code to fit your needs (it's Free Software :). |
| @@ -87,7 +67,15 @@ By default, all TCP unit tests will be executed (see --help for options). | @@ -87,7 +67,15 @@ By default, all TCP unit tests will be executed (see --help for options). | ||
| 87 | 67 | ||
| 88 | It's also possible to run the unit tests with `make check`. | 68 | It's also possible to run the unit tests with `make check`. |
| 89 | 69 | ||
| 90 | -To report a bug or to contribute | ||
| 91 | --------------------------------- | 70 | +## To report a bug or to contribute |
| 92 | 71 | ||
| 93 | See [CONTRIBUTING](CONTRIBUTING.md) document. | 72 | See [CONTRIBUTING](CONTRIBUTING.md) document. |
| 73 | + | ||
| 74 | +## Documentation | ||
| 75 | + | ||
| 76 | +You can serve the local documentation with: | ||
| 77 | + | ||
| 78 | +```shell | ||
| 79 | +pip install mkdocs-material | ||
| 80 | +mkdocs serve | ||
| 81 | +``` |
acinclude.m4 deleted
| 1 | -dnl ############################################################################## | ||
| 2 | -dnl # AC_LIBMODBUS_CHECK_BUILD_DOC # | ||
| 3 | -dnl # Check whether to build documentation and install man-pages # | ||
| 4 | -dnl ############################################################################## | ||
| 5 | -AC_DEFUN([AC_LIBMODBUS_CHECK_BUILD_DOC], [{ | ||
| 6 | - # Allow user to disable doc build | ||
| 7 | - AC_ARG_WITH([documentation], [AS_HELP_STRING([--without-documentation], | ||
| 8 | - [disable documentation build even if asciidoc and xmlto are present [default=no]])]) | ||
| 9 | - | ||
| 10 | - if test "x$with_documentation" = "xno"; then | ||
| 11 | - ac_libmodbus_build_doc="no" | ||
| 12 | - else | ||
| 13 | - # Determine whether or not documentation should be built and installed. | ||
| 14 | - ac_libmodbus_build_doc="yes" | ||
| 15 | - # Check for asciidoc and xmlto and don't build the docs if these are not installed. | ||
| 16 | - AC_CHECK_PROG(ac_libmodbus_have_asciidoc, asciidoc, yes, no) | ||
| 17 | - AC_CHECK_PROG(ac_libmodbus_have_xmlto, xmlto, yes, no) | ||
| 18 | - if test "x$ac_libmodbus_have_asciidoc" = "xno" -o "x$ac_libmodbus_have_xmlto" = "xno"; then | ||
| 19 | - ac_libmodbus_build_doc="no" | ||
| 20 | - fi | ||
| 21 | - fi | ||
| 22 | - | ||
| 23 | - AC_MSG_CHECKING([whether to build documentation]) | ||
| 24 | - AC_MSG_RESULT([$ac_libmodbus_build_doc]) | ||
| 25 | - if test "x$ac_libmodbus_build_doc" = "xno"; then | ||
| 26 | - AC_MSG_WARN([The tools to build the documentation aren't installed]) | ||
| 27 | - fi | ||
| 28 | - AM_CONDITIONAL(BUILD_DOC, test "x$ac_libmodbus_build_doc" = "xyes") | ||
| 29 | -}]) |
configure.ac
| @@ -94,9 +94,6 @@ AC_CHECK_HEADERS([ \ | @@ -94,9 +94,6 @@ AC_CHECK_HEADERS([ \ | ||
| 94 | unistd.h \ | 94 | unistd.h \ |
| 95 | ]) | 95 | ]) |
| 96 | 96 | ||
| 97 | -# Check whether to build docs / install man pages | ||
| 98 | -AC_LIBMODBUS_CHECK_BUILD_DOC | ||
| 99 | - | ||
| 100 | # Cygwin defines IPTOS_LOWDELAY but can't handle that flag so it's necessary to | 97 | # Cygwin defines IPTOS_LOWDELAY but can't handle that flag so it's necessary to |
| 101 | # workaround that problem and Cygwin doesn't define MSG_DONTWAIT. | 98 | # workaround that problem and Cygwin doesn't define MSG_DONTWAIT. |
| 102 | AC_CHECK_DECLS([__CYGWIN__]) | 99 | AC_CHECK_DECLS([__CYGWIN__]) |
| @@ -161,7 +158,6 @@ AC_CONFIG_FILES([ | @@ -161,7 +158,6 @@ AC_CONFIG_FILES([ | ||
| 161 | src/modbus-version.h | 158 | src/modbus-version.h |
| 162 | src/win32/modbus.dll.manifest | 159 | src/win32/modbus.dll.manifest |
| 163 | tests/Makefile | 160 | tests/Makefile |
| 164 | - doc/Makefile | ||
| 165 | libmodbus.pc | 161 | libmodbus.pc |
| 166 | ]) | 162 | ]) |
| 167 | 163 | ||
| @@ -179,6 +175,5 @@ AC_MSG_RESULT([ | @@ -179,6 +175,5 @@ AC_MSG_RESULT([ | ||
| 179 | cflags: ${CFLAGS} | 175 | cflags: ${CFLAGS} |
| 180 | ldflags: ${LDFLAGS} | 176 | ldflags: ${LDFLAGS} |
| 181 | 177 | ||
| 182 | - documentation: ${ac_libmodbus_build_doc} | ||
| 183 | tests: ${enable_tests} | 178 | tests: ${enable_tests} |
| 184 | ]) | 179 | ]) |
doc/Makefile.am deleted
| 1 | -TXT3 = \ | ||
| 2 | - modbus_close.txt \ | ||
| 3 | - modbus_connect.txt \ | ||
| 4 | - modbus_flush.txt \ | ||
| 5 | - modbus_free.txt \ | ||
| 6 | - modbus_get_indication_timeout.txt \ | ||
| 7 | - modbus_get_slave.txt \ | ||
| 8 | - modbus_get_byte_from_bits.txt \ | ||
| 9 | - modbus_get_byte_timeout.txt \ | ||
| 10 | - modbus_get_float.txt \ | ||
| 11 | - modbus_get_float_abcd.txt \ | ||
| 12 | - modbus_get_float_badc.txt \ | ||
| 13 | - modbus_get_float_cdab.txt \ | ||
| 14 | - modbus_get_float_dcba.txt \ | ||
| 15 | - modbus_get_header_length.txt \ | ||
| 16 | - modbus_get_response_timeout.txt \ | ||
| 17 | - modbus_get_socket.txt \ | ||
| 18 | - modbus_mapping_free.txt \ | ||
| 19 | - modbus_mapping_new.txt \ | ||
| 20 | - modbus_mapping_new_start_address.txt \ | ||
| 21 | - modbus_mask_write_register.txt \ | ||
| 22 | - modbus_new_rtu.txt \ | ||
| 23 | - modbus_new_tcp_pi.txt \ | ||
| 24 | - modbus_new_tcp.txt \ | ||
| 25 | - modbus_read_bits.txt \ | ||
| 26 | - modbus_read_input_bits.txt \ | ||
| 27 | - modbus_read_input_registers.txt \ | ||
| 28 | - modbus_read_registers.txt \ | ||
| 29 | - modbus_receive_confirmation.txt \ | ||
| 30 | - modbus_receive.txt \ | ||
| 31 | - modbus_reply_exception.txt \ | ||
| 32 | - modbus_reply.txt \ | ||
| 33 | - modbus_report_slave_id.txt \ | ||
| 34 | - modbus_rtu_get_serial_mode.txt \ | ||
| 35 | - modbus_rtu_set_serial_mode.txt \ | ||
| 36 | - modbus_rtu_get_rts.txt \ | ||
| 37 | - modbus_rtu_set_rts.txt \ | ||
| 38 | - modbus_rtu_set_custom_rts.txt \ | ||
| 39 | - modbus_rtu_get_rts_delay.txt \ | ||
| 40 | - modbus_rtu_set_rts_delay.txt \ | ||
| 41 | - modbus_send_raw_request.txt \ | ||
| 42 | - modbus_set_bits_from_bytes.txt \ | ||
| 43 | - modbus_set_bits_from_byte.txt \ | ||
| 44 | - modbus_set_byte_timeout.txt \ | ||
| 45 | - modbus_set_debug.txt \ | ||
| 46 | - modbus_set_error_recovery.txt \ | ||
| 47 | - modbus_set_float.txt \ | ||
| 48 | - modbus_set_float_abcd.txt \ | ||
| 49 | - modbus_set_float_badc.txt \ | ||
| 50 | - modbus_set_float_cdab.txt \ | ||
| 51 | - modbus_set_float_dcba.txt \ | ||
| 52 | - modbus_set_indication_timeout.txt \ | ||
| 53 | - modbus_set_response_timeout.txt \ | ||
| 54 | - modbus_set_slave.txt \ | ||
| 55 | - modbus_set_socket.txt \ | ||
| 56 | - modbus_strerror.txt \ | ||
| 57 | - modbus_tcp_accept.txt \ | ||
| 58 | - modbus_tcp_pi_accept.txt \ | ||
| 59 | - modbus_tcp_listen.txt \ | ||
| 60 | - modbus_tcp_pi_listen.txt \ | ||
| 61 | - modbus_write_and_read_registers.txt \ | ||
| 62 | - modbus_write_bits.txt \ | ||
| 63 | - modbus_write_bit.txt \ | ||
| 64 | - modbus_write_registers.txt \ | ||
| 65 | - modbus_write_register.txt | ||
| 66 | -TXT7 = libmodbus.txt | ||
| 67 | - | ||
| 68 | -EXTRA_DIST = asciidoc.conf $(TXT3) $(TXT7) | ||
| 69 | - | ||
| 70 | -MAN3 = $(TXT3:%.txt=%.3) | ||
| 71 | -MAN7 = $(TXT7:%.txt=%.7) | ||
| 72 | - | ||
| 73 | -if BUILD_DOC | ||
| 74 | -man3_MANS = $(MAN3) | ||
| 75 | -man7_MANS = $(MAN7) | ||
| 76 | -endif | ||
| 77 | - | ||
| 78 | -HTML = $(TXT3:%.txt=%.html) $(TXT7:%.txt=%.html) | ||
| 79 | - | ||
| 80 | -htmldoc: $(HTML) | ||
| 81 | - | ||
| 82 | -.txt.html: | ||
| 83 | - asciidoc -d manpage -b xhtml11 -f asciidoc.conf -alibmodbus_version=@LIBMODBUS_VERSION@ $< | ||
| 84 | - | ||
| 85 | -.txt.3 .txt.7: | ||
| 86 | - a2x --doctype manpage --format manpage -alibmodbus_version=@LIBMODBUS_VERSION@ $< | ||
| 87 | - | ||
| 88 | -CLEANFILES = *.3 *.7 *.html |
doc/asciidoc.conf deleted
| 1 | -[paradef-default] | ||
| 2 | -literal-style=template="literalparagraph" | ||
| 3 | - | ||
| 4 | -[macros] | ||
| 5 | -(?su)[\\]?(?P<name>linkmb):(?P<target>\S*?)\[(?P<attrlist>.*?)\]= | ||
| 6 | - | ||
| 7 | -ifdef::backend-docbook[] | ||
| 8 | -[linkmb-inlinemacro] | ||
| 9 | -{0%{target}} | ||
| 10 | -{0#<citerefentry>} | ||
| 11 | -{0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>} | ||
| 12 | -{0#</citerefentry>} | ||
| 13 | -endif::backend-docbook[] | ||
| 14 | - | ||
| 15 | -ifdef::backend-xhtml11[] | ||
| 16 | -[linkmb-inlinemacro] | ||
| 17 | -<a href="{target}.html">{target}{0?({0})}</a> | ||
| 18 | -endif::backend-xhtml11[] | ||
| 19 | - | ||
| 20 | -ifdef::doctype-manpage[] | ||
| 21 | -ifdef::backend-docbook[] | ||
| 22 | -[header] | ||
| 23 | -template::[header-declarations] | ||
| 24 | -<refentry> | ||
| 25 | -<refmeta> | ||
| 26 | -<refentrytitle>{mantitle}</refentrytitle> | ||
| 27 | -<manvolnum>{manvolnum}</manvolnum> | ||
| 28 | -<refmiscinfo class="source">libmodbus</refmiscinfo> | ||
| 29 | -<refmiscinfo class="version">v{libmodbus_version}</refmiscinfo> | ||
| 30 | -<refmiscinfo class="manual">libmodbus Manual</refmiscinfo> | ||
| 31 | -</refmeta> | ||
| 32 | -<refnamediv> | ||
| 33 | - <refname>{manname}</refname> | ||
| 34 | - <refpurpose>{manpurpose}</refpurpose> | ||
| 35 | -</refnamediv> | ||
| 36 | -endif::backend-docbook[] | ||
| 37 | -endif::doctype-manpage[] | ||
| 38 | - | ||
| 39 | -ifdef::backend-xhtml11[] | ||
| 40 | -[footer] | ||
| 41 | -</div> | ||
| 42 | -{disable-javascript%<div id="footnotes"><hr /></div>} | ||
| 43 | -<div id="footer"> | ||
| 44 | -<div id="footer-text"> | ||
| 45 | -libmodbus {libmodbus_version}<br /> | ||
| 46 | -Last updated {docdate} {doctime} | ||
| 47 | -</div> | ||
| 48 | -</div> | ||
| 49 | -</body> | ||
| 50 | -</html> | ||
| 51 | -endif::backend-xhtml11[] |
doc/libmodbus.txt deleted
| 1 | -libmodbus(7) | ||
| 2 | -============ | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -libmodbus - a fast and portable Modbus library | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*#include <modbus.h>* | ||
| 13 | - | ||
| 14 | -*cc* 'files' \`pkg-config --cflags --libs libmodbus` | ||
| 15 | - | ||
| 16 | -DESCRIPTION | ||
| 17 | ------------ | ||
| 18 | -libmodbus is a library to send/receive data with a device which respects the | ||
| 19 | -Modbus protocol. This library contains various backends to communicate over | ||
| 20 | -different networks (eg. serial in RTU mode or Ethernet in TCP/IPv6). The | ||
| 21 | -http://www.modbus.org site provides documentation about the protocol at | ||
| 22 | -http://www.modbus.org/specs.php. | ||
| 23 | - | ||
| 24 | -libmodbus provides an abstraction of the lower communication layers and offers | ||
| 25 | -the same API on all supported platforms. | ||
| 26 | - | ||
| 27 | -This documentation presents an overview of libmodbus concepts, describes how | ||
| 28 | -libmodbus abstracts Modbus communication with different hardware and platforms | ||
| 29 | -and provides a reference manual for the functions provided by the libmodbus | ||
| 30 | -library. | ||
| 31 | - | ||
| 32 | - | ||
| 33 | -Contexts | ||
| 34 | -~~~~~~~~ | ||
| 35 | -The Modbus protocol contains many variants (eg. serial RTU or Ethernet TCP), to | ||
| 36 | -ease the implementation of a variant, the library was designed to use a backend | ||
| 37 | -for each variant. The backends are also a convenient way to fulfill other | ||
| 38 | -requirements (eg. real-time operations). Each backend offers a specific function | ||
| 39 | -to create a new 'modbus_t' context. The 'modbus_t' context is an opaque | ||
| 40 | -structure containing all necessary information to establish a connection with | ||
| 41 | -other Modbus devices according to the selected variant. | ||
| 42 | - | ||
| 43 | -You can choose the best context for your needs among: | ||
| 44 | - | ||
| 45 | -RTU Context | ||
| 46 | -^^^^^^^^^^^ | ||
| 47 | -The RTU backend (Remote Terminal Unit) is used in serial communication and makes | ||
| 48 | -use of a compact, binary representation of the data for protocol | ||
| 49 | -communication. The RTU format follows the commands/data with a cyclic redundancy | ||
| 50 | -check checksum as an error check mechanism to ensure the reliability of | ||
| 51 | -data. Modbus RTU is the most common implementation available for Modbus. A | ||
| 52 | -Modbus RTU message must be transmitted continuously without inter-character | ||
| 53 | -hesitations (extract from Wikipedia, Modbus, http://en.wikipedia.org/wiki/Modbus | ||
| 54 | -(as of Mar. 13, 2011, 20:51 GMT). | ||
| 55 | - | ||
| 56 | -The Modbus RTU framing calls a slave, a device/service which handle Modbus | ||
| 57 | -requests, and a master, a client which send requests. The communication is | ||
| 58 | -always initiated by the master. | ||
| 59 | - | ||
| 60 | -Many Modbus devices can be connected together on the same physical link so | ||
| 61 | -before sending a message, you must set the slave (receiver) with | ||
| 62 | -linkmb:modbus_set_slave[3]. If you're running a slave, its slave number will be | ||
| 63 | -used to filter received messages. | ||
| 64 | - | ||
| 65 | -The libmodbus implementation of RTU isn't time based as stated in original | ||
| 66 | -Modbus specification, instead all bytes are sent as fast as possible and a | ||
| 67 | -response or an indication is considered complete when all expected characters | ||
| 68 | -have been received. This implementation offers very fast communication but you | ||
| 69 | -must take care to set a response timeout of slaves less than response timeout of | ||
| 70 | -master (ortherwise other slaves may ignore master requests when one of the slave | ||
| 71 | -is not responding). | ||
| 72 | - | ||
| 73 | -Create a Modbus RTU context:: | ||
| 74 | - - linkmb:modbus_new_rtu[3] | ||
| 75 | - | ||
| 76 | - | ||
| 77 | -Set the serial mode:: | ||
| 78 | - - linkmb:modbus_rtu_get_serial_mode[3] | ||
| 79 | - - linkmb:modbus_rtu_set_serial_mode[3] | ||
| 80 | - - linkmb:modbus_rtu_get_rts[3] | ||
| 81 | - - linkmb:modbus_rtu_set_rts[3] | ||
| 82 | - - linkmb:modbus_rtu_set_custom_rts[3] | ||
| 83 | - - linkmb:modbus_rtu_get_rts_delay[3] | ||
| 84 | - - linkmb:modbus_rtu_set_rts_delay[3] | ||
| 85 | - | ||
| 86 | - | ||
| 87 | -TCP (IPv4) Context | ||
| 88 | -^^^^^^^^^^^^^^^^^^ | ||
| 89 | -The TCP backend implements a Modbus variant used for communications over | ||
| 90 | -TCP/IPv4 networks. It does not require a checksum calculation as lower layer | ||
| 91 | -takes care of the same. | ||
| 92 | - | ||
| 93 | -Create a Modbus TCP context:: | ||
| 94 | - - linkmb:modbus_new_tcp[3] | ||
| 95 | - | ||
| 96 | - | ||
| 97 | -TCP PI (IPv4 and IPv6) Context | ||
| 98 | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| 99 | -The TCP PI (Protocol Independent) backend implements a Modbus variant used for | ||
| 100 | -communications over TCP IPv4 and IPv6 networks. It does not require a checksum | ||
| 101 | -calculation as lower layer takes care of the same. | ||
| 102 | - | ||
| 103 | -Contrary to the TCP IPv4 only backend, the TCP PI backend offers hostname | ||
| 104 | -resolution but it consumes about 1Kb of additional memory. | ||
| 105 | - | ||
| 106 | -Create a Modbus TCP context:: | ||
| 107 | - - linkmb:modbus_new_tcp_pi[3] | ||
| 108 | - | ||
| 109 | - | ||
| 110 | -Common | ||
| 111 | -^^^^^^ | ||
| 112 | -Before using any libmodbus functions, the caller must allocate and initialize a | ||
| 113 | -'modbus_t' context with functions explained above, then the following functions | ||
| 114 | -are provided to modify and free a 'context': | ||
| 115 | - | ||
| 116 | -Free libmodbus context:: | ||
| 117 | - - linkmb:modbus_free[3] | ||
| 118 | - | ||
| 119 | -Set slave ID:: | ||
| 120 | - - linkmb:modbus_set_slave[3] | ||
| 121 | - | ||
| 122 | -Enable debug mode:: | ||
| 123 | - - linkmb:modbus_set_debug[3] | ||
| 124 | - | ||
| 125 | -Timeout settings:: | ||
| 126 | - - linkmb:modbus_get_byte_timeout[3] | ||
| 127 | - - linkmb:modbus_set_byte_timeout[3] | ||
| 128 | - - linkmb:modbus_get_response_timeout[3] | ||
| 129 | - - linkmb:modbus_set_response_timeout[3] | ||
| 130 | - | ||
| 131 | -Error recovery mode:: | ||
| 132 | - - linkmb:modbus_set_error_recovery[3] | ||
| 133 | - | ||
| 134 | -Setter/getter of internal socket:: | ||
| 135 | - - linkmb:modbus_set_socket[3] | ||
| 136 | - - linkmb:modbus_get_socket[3] | ||
| 137 | - | ||
| 138 | -Information about header:: | ||
| 139 | - - linkmb:modbus_get_header_length[3] | ||
| 140 | - | ||
| 141 | -Macros for data manipulation:: | ||
| 142 | - | ||
| 143 | - - MODBUS_GET_HIGH_BYTE(data), extracts the high byte from a byte | ||
| 144 | - - MODBUS_GET_LOW_BYTE(data), extracts the low byte from a byte | ||
| 145 | - - MODBUS_GET_INT64_FROM_INT16(tab_int16, index), builds an int64 from the four | ||
| 146 | - first int16 starting at tab_int16[index] | ||
| 147 | - - MODBUS_GET_INT32_FROM_INT16(tab_int16, index), builds an int32 from the two | ||
| 148 | - first int16 starting at tab_int16[index] | ||
| 149 | - - MODBUS_GET_INT16_FROM_INT8(tab_int8, index), builds an int16 from the two | ||
| 150 | - first int8 starting at tab_int8[index] | ||
| 151 | - - MODBUS_SET_INT16_TO_INT8(tab_int8, index, value), set an int16 value into | ||
| 152 | - the two first bytes starting at tab_int8[index] | ||
| 153 | - - MODBUS_SET_INT32_TO_INT16(tab_int16, index, value), set an int32 value into | ||
| 154 | - the two first int16 starting at tab_int16[index] | ||
| 155 | - - MODBUS_SET_INT64_TO_INT16(tab_int16, index, value), set an int64 value into | ||
| 156 | - the four first int16 starting at tab_int16[index] | ||
| 157 | - | ||
| 158 | -Handling of bits and bytes:: | ||
| 159 | - - linkmb:modbus_set_bits_from_byte[3] | ||
| 160 | - - linkmb:modbus_set_bits_from_bytes[3] | ||
| 161 | - - linkmb:modbus_get_byte_from_bits[3] | ||
| 162 | - | ||
| 163 | -Set or get float numbers:: | ||
| 164 | - - linkmb:modbus_get_float_abcd[3] | ||
| 165 | - - linkmb:modbus_set_float_abcd[3] | ||
| 166 | - - linkmb:modbus_get_float_badc[3] | ||
| 167 | - - linkmb:modbus_set_float_badc[3] | ||
| 168 | - - linkmb:modbus_get_float_cdab[3] | ||
| 169 | - - linkmb:modbus_set_float_cdab[3] | ||
| 170 | - - linkmb:modbus_get_float_dcba[3] | ||
| 171 | - - linkmb:modbus_set_float_dcba[3] | ||
| 172 | - - linkmb:modbus_get_float[3] (deprecated) | ||
| 173 | - - linkmb:modbus_set_float[3] (deprecated) | ||
| 174 | - | ||
| 175 | - | ||
| 176 | - | ||
| 177 | -Connection | ||
| 178 | -~~~~~~~~~~ | ||
| 179 | -The following functions are provided to establish and close a connection with | ||
| 180 | -Modbus devices: | ||
| 181 | - | ||
| 182 | -Establish a connection:: | ||
| 183 | - - linkmb:modbus_connect[3] | ||
| 184 | - | ||
| 185 | -Close a connection:: | ||
| 186 | - - linkmb:modbus_close[3] | ||
| 187 | - | ||
| 188 | -Flush a connection:: | ||
| 189 | - - linkmb:modbus_flush[3] | ||
| 190 | - | ||
| 191 | - | ||
| 192 | -Client | ||
| 193 | -~~~~~~ | ||
| 194 | -The Modbus protocol defines different data types and functions to read and write | ||
| 195 | -them from/to remote devices. The following functions are used by the clients to | ||
| 196 | -send Modbus requests: | ||
| 197 | - | ||
| 198 | -Read data:: | ||
| 199 | - - linkmb:modbus_read_bits[3] | ||
| 200 | - - linkmb:modbus_read_input_bits[3] | ||
| 201 | - - linkmb:modbus_read_registers[3] | ||
| 202 | - - linkmb:modbus_read_input_registers[3] | ||
| 203 | - - linkmb:modbus_report_slave_id[3] | ||
| 204 | - | ||
| 205 | -Write data:: | ||
| 206 | - - linkmb:modbus_write_bit[3] | ||
| 207 | - - linkmb:modbus_write_register[3] | ||
| 208 | - - linkmb:modbus_write_bits[3] | ||
| 209 | - - linkmb:modbus_write_registers[3] | ||
| 210 | - | ||
| 211 | -Write and read data:: | ||
| 212 | - - linkmb:modbus_write_and_read_registers[3] | ||
| 213 | - | ||
| 214 | -Raw requests:: | ||
| 215 | - - linkmb:modbus_send_raw_request[3] | ||
| 216 | - - linkmb:modbus_receive_confirmation[3] | ||
| 217 | - | ||
| 218 | -Reply an exception:: | ||
| 219 | - - linkmb:modbus_reply_exception[3] | ||
| 220 | - | ||
| 221 | - | ||
| 222 | -Server | ||
| 223 | -~~~~~~ | ||
| 224 | -The server is waiting for request from clients and must answer when it is | ||
| 225 | -concerned by the request. The libmodbus offers the following functions to | ||
| 226 | -handle requests: | ||
| 227 | - | ||
| 228 | -Data mapping:: | ||
| 229 | - - linkmb:modbus_mapping_new[3] | ||
| 230 | - - linkmb:modbus_mapping_free[3] | ||
| 231 | - | ||
| 232 | -Receive:: | ||
| 233 | - - linkmb:modbus_receive[3] | ||
| 234 | - | ||
| 235 | -Reply:: | ||
| 236 | - - linkmb:modbus_reply[3] | ||
| 237 | - - linkmb:modbus_reply_exception[3] | ||
| 238 | - | ||
| 239 | - | ||
| 240 | -ERROR HANDLING | ||
| 241 | --------------- | ||
| 242 | -The libmodbus functions handle errors using the standard conventions found on | ||
| 243 | -POSIX systems. Generally, this means that upon failure a libmodbus function | ||
| 244 | -shall return either a NULL value (if returning a pointer) or a negative value | ||
| 245 | -(if returning an integer), and the actual error code shall be stored in the | ||
| 246 | -'errno' variable. | ||
| 247 | - | ||
| 248 | -The *modbus_strerror()* function is provided to translate libmodbus-specific | ||
| 249 | -error codes into error message strings; for details refer to | ||
| 250 | -linkmb:modbus_strerror[3]. | ||
| 251 | - | ||
| 252 | - | ||
| 253 | -MISCELLANEOUS | ||
| 254 | -------------- | ||
| 255 | -The _LIBMODBUS_VERSION_STRING_ constant indicates the libmodbus version the | ||
| 256 | -program has been compiled against. The variables 'libmodbus_version_major', | ||
| 257 | -'libmodbus_version_minor', 'libmodbus_version_micro' give the version the | ||
| 258 | -program is linked against. | ||
| 259 | - | ||
| 260 | - | ||
| 261 | -AUTHORS | ||
| 262 | -------- | ||
| 263 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 264 | -<stephane.raimbault@gmail.com> | ||
| 265 | - | ||
| 266 | - | ||
| 267 | -RESOURCES | ||
| 268 | ---------- | ||
| 269 | -Main web site: <http://www.libmodbus.org/> | ||
| 270 | - | ||
| 271 | -Report bugs on the issue tracker at | ||
| 272 | -<http://github.com/stephane/libmodbus/issues>. | ||
| 273 | - | ||
| 274 | - | ||
| 275 | -COPYING | ||
| 276 | -------- | ||
| 277 | -Free use of this software is granted under the terms of the GNU Lesser General | ||
| 278 | -Public License (LGPL v2.1+). For details see the file `COPYING.LESSER` included | ||
| 279 | -with the libmodbus distribution. |
doc/modbus_close.txt deleted
| 1 | -modbus_close(3) | ||
| 2 | -=============== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_close - close a Modbus connection | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*void modbus_close(modbus_t *'ctx');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_close()* function shall close the connection established with the | ||
| 18 | -backend set in the context. | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -RETURN VALUE | ||
| 22 | ------------- | ||
| 23 | -There is no return value. | ||
| 24 | - | ||
| 25 | - | ||
| 26 | -EXAMPLE | ||
| 27 | -------- | ||
| 28 | -[source,c] | ||
| 29 | -------------------- | ||
| 30 | -modbus_t *ctx; | ||
| 31 | - | ||
| 32 | -ctx = modbus_new_tcp("127.0.0.1", 502); | ||
| 33 | -if (modbus_connect(ctx) == -1) { | ||
| 34 | - fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); | ||
| 35 | - modbus_free(ctx); | ||
| 36 | - return -1; | ||
| 37 | -} | ||
| 38 | - | ||
| 39 | -modbus_close(ctx); | ||
| 40 | -modbus_free(ctx); | ||
| 41 | -------------------- | ||
| 42 | - | ||
| 43 | -SEE ALSO | ||
| 44 | --------- | ||
| 45 | -linkmb:modbus_connect[3] | ||
| 46 | - | ||
| 47 | - | ||
| 48 | -AUTHORS | ||
| 49 | -------- | ||
| 50 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 51 | -<stephane.raimbault@gmail.com> |
doc/modbus_connect.txt deleted
| 1 | -modbus_connect(3) | ||
| 2 | -================= | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_connect - establish a Modbus connection | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_connect(modbus_t *'ctx');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_connect()* function shall establish a connection to a Modbus server, | ||
| 18 | -a network or a bus using the context information of libmodbus context given in | ||
| 19 | -argument. | ||
| 20 | - | ||
| 21 | - | ||
| 22 | -RETURN VALUE | ||
| 23 | ------------- | ||
| 24 | -The function shall return 0 if successful. Otherwise it shall return -1 and set | ||
| 25 | -errno to one of the values defined by the system calls of the underlying | ||
| 26 | -platform. | ||
| 27 | - | ||
| 28 | - | ||
| 29 | -EXAMPLE | ||
| 30 | -------- | ||
| 31 | -[source,c] | ||
| 32 | -------------------- | ||
| 33 | -modbus_t *ctx; | ||
| 34 | - | ||
| 35 | -ctx = modbus_new_tcp("127.0.0.1", 502); | ||
| 36 | -if (modbus_connect(ctx) == -1) { | ||
| 37 | - fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); | ||
| 38 | - modbus_free(ctx); | ||
| 39 | - return -1; | ||
| 40 | -} | ||
| 41 | -------------------- | ||
| 42 | - | ||
| 43 | - | ||
| 44 | -SEE ALSO | ||
| 45 | --------- | ||
| 46 | -linkmb:modbus_close[3] | ||
| 47 | - | ||
| 48 | - | ||
| 49 | -AUTHORS | ||
| 50 | -------- | ||
| 51 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 52 | -<stephane.raimbault@gmail.com> |
doc/modbus_flush.txt deleted
| 1 | -modbus_flush(3) | ||
| 2 | -=============== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_flush - flush non-transmitted data | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_flush(modbus_t *'ctx');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_flush()* function shall discard data received but not read to the | ||
| 18 | -socket or file descriptor associated to the context 'ctx'. | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -RETURN VALUE | ||
| 22 | ------------- | ||
| 23 | -The function shall return 0 or the number of flushed bytes if | ||
| 24 | -successful. Otherwise it shall return -1 and set errno. | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -AUTHORS | ||
| 28 | -------- | ||
| 29 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 30 | -<stephane.raimbault@gmail.com> |
doc/modbus_free.txt deleted
| 1 | -modbus_free(3) | ||
| 2 | -============== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_free - free a libmodbus context | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*void modbus_free(modbus_t *'ctx');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_free()* function shall free an allocated modbus_t structure. | ||
| 18 | - | ||
| 19 | - | ||
| 20 | -RETURN VALUE | ||
| 21 | ------------- | ||
| 22 | -There is no return values. | ||
| 23 | - | ||
| 24 | - | ||
| 25 | -SEE ALSO | ||
| 26 | --------- | ||
| 27 | -linkmb:libmodbus[3] | ||
| 28 | - | ||
| 29 | - | ||
| 30 | -AUTHORS | ||
| 31 | -------- | ||
| 32 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 33 | -<stephane.raimbault@gmail.com> |
doc/modbus_get_byte_from_bits.txt deleted
| 1 | -modbus_get_byte_from_bits(3) | ||
| 2 | -============================ | ||
| 3 | - | ||
| 4 | -NAME | ||
| 5 | ----- | ||
| 6 | -modbus_get_byte_from_bits - get the value from many bits | ||
| 7 | - | ||
| 8 | - | ||
| 9 | -SYNOPSIS | ||
| 10 | --------- | ||
| 11 | -*uint8_t modbus_get_byte_from_bits(const uint8_t *'src', int 'index', unsigned int 'nb_bits');* | ||
| 12 | - | ||
| 13 | - | ||
| 14 | -DESCRIPTION | ||
| 15 | ------------ | ||
| 16 | -The *modbus_get_byte_from_bits()* function shall extract a value from many | ||
| 17 | -bits. All _nb_bits_ bits from _src_ at position _index_ will be read as a | ||
| 18 | -single value. To obtain a full byte, set nb_bits to 8. | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -RETURN VALUE | ||
| 22 | ------------- | ||
| 23 | -The function shall return a byte containing the bits read. | ||
| 24 | - | ||
| 25 | - | ||
| 26 | -SEE ALSO | ||
| 27 | --------- | ||
| 28 | -linkmb:modbus_set_bits_from_byte[3] | ||
| 29 | -linkmb:modbus_set_bits_from_bytes[3] | ||
| 30 | - | ||
| 31 | - | ||
| 32 | -AUTHORS | ||
| 33 | -------- | ||
| 34 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 35 | -<stephane.raimbault@gmail.com> |
doc/modbus_get_byte_timeout.txt deleted
| 1 | -modbus_get_byte_timeout(3) | ||
| 2 | -========================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_get_byte_timeout - get timeout between bytes | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_get_byte_timeout(modbus_t *'ctx', uint32_t *'to_sec', uint32_t *'to_usec');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_get_byte_timeout()* function shall store the timeout interval | ||
| 18 | -between two consecutive bytes of the same message in the _to_sec_ and _to_usec_ | ||
| 19 | -arguments. | ||
| 20 | - | ||
| 21 | - | ||
| 22 | -RETURN VALUE | ||
| 23 | ------------- | ||
| 24 | -The function shall return 0 if successful. Otherwise it shall return -1 and set | ||
| 25 | -errno. | ||
| 26 | - | ||
| 27 | - | ||
| 28 | -EXAMPLE | ||
| 29 | -------- | ||
| 30 | -[source,c] | ||
| 31 | -------------------- | ||
| 32 | -uint32_t to_sec; | ||
| 33 | -uint32_t to_usec; | ||
| 34 | - | ||
| 35 | -/* Save original timeout */ | ||
| 36 | -modbus_get_byte_timeout(ctx, &to_sec, &to_usec); | ||
| 37 | -------------------- | ||
| 38 | - | ||
| 39 | - | ||
| 40 | -SEE ALSO | ||
| 41 | --------- | ||
| 42 | -linkmb:modbus_set_byte_timeout[3] | ||
| 43 | -linkmb:modbus_get_response_timeout[3] | ||
| 44 | -linkmb:modbus_set_response_timeout[3] | ||
| 45 | - | ||
| 46 | - | ||
| 47 | -AUTHORS | ||
| 48 | -------- | ||
| 49 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 50 | -<stephane.raimbault@gmail.com> |
doc/modbus_get_float.txt deleted
| 1 | -modbus_get_float(3) | ||
| 2 | -=================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_get_float - get a float value from 2 registers | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*float modbus_get_float(const uint16_t *'src');* | ||
| 13 | - | ||
| 14 | -Warning, this function is *deprecated* since libmodbus v3.2.0 and has been | ||
| 15 | -replaced by *modbus_get_float_dcba()*. | ||
| 16 | - | ||
| 17 | -DESCRIPTION | ||
| 18 | ------------ | ||
| 19 | -The *modbus_get_float()* function shall get a float from 4 bytes in Modbus | ||
| 20 | -format (DCBA byte order). The _src_ array must be a pointer on two 16 bits | ||
| 21 | -values, for example, if the first word is set to 0x4465 and the second to | ||
| 22 | -0x229a, the float value will be 916.540649. | ||
| 23 | - | ||
| 24 | - | ||
| 25 | -RETURN VALUE | ||
| 26 | ------------- | ||
| 27 | -The function shall return a float. | ||
| 28 | - | ||
| 29 | - | ||
| 30 | -SEE ALSO | ||
| 31 | --------- | ||
| 32 | -linkmb:modbus_set_float[3] | ||
| 33 | -linkmb:modbus_set_float_dcba[3] | ||
| 34 | -linkmb:modbus_get_float_dcba[3] | ||
| 35 | - | ||
| 36 | -AUTHORS | ||
| 37 | -------- | ||
| 38 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 39 | -<stephane.raimbault@gmail.com> |
doc/modbus_get_float_abcd.txt deleted
| 1 | -modbus_get_float_abcd(3) | ||
| 2 | -======================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_get_float_abcd - get a float value from 2 registers in ABCD byte order | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*float modbus_get_float_abcd(const uint16_t *'src');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_get_float_abcd()* function shall get a float from 4 bytes in usual | ||
| 18 | -Modbus format. The _src_ array must be a pointer on two 16 bits values, for | ||
| 19 | -example, if the first word is set to 0x0020 and the second to 0xF147, the float | ||
| 20 | -value will be read as 123456.0. | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -RETURN VALUE | ||
| 24 | ------------- | ||
| 25 | -The function shall return a float. | ||
| 26 | - | ||
| 27 | - | ||
| 28 | -SEE ALSO | ||
| 29 | --------- | ||
| 30 | -linkmb:modbus_set_float_abcd[3] | ||
| 31 | -linkmb:modbus_get_float_badc[3] | ||
| 32 | -linkmb:modbus_get_float_cdab[3] | ||
| 33 | -linkmb:modbus_get_float_dcba[3] | ||
| 34 | - | ||
| 35 | - | ||
| 36 | -AUTHORS | ||
| 37 | -------- | ||
| 38 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 39 | -<stephane.raimbault@gmail.com> |
doc/modbus_get_float_badc.txt deleted
| 1 | -modbus_get_float_badc(3) | ||
| 2 | -======================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_get_float_badc - get a float value from 2 registers in BADC byte order | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*float modbus_get_float_badc(const uint16_t *'src');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_get_float_badc()* function shall get a float from 4 bytes with | ||
| 18 | -swapped bytes (BADC instead of ABCD). The _src_ array must be a pointer on two | ||
| 19 | -16 bits values, for example, if the first word is set to 0x2000 and the second | ||
| 20 | -to 0x47F1, the float value will be read as 123456.0. | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -RETURN VALUE | ||
| 24 | ------------- | ||
| 25 | -The function shall return a float. | ||
| 26 | - | ||
| 27 | - | ||
| 28 | -SEE ALSO | ||
| 29 | --------- | ||
| 30 | -linkmb:modbus_set_float_badc[3] | ||
| 31 | -linkmb:modbus_get_float_abcd[3] | ||
| 32 | -linkmb:modbus_get_float_cdab[3] | ||
| 33 | -linkmb:modbus_get_float_dcba[3] | ||
| 34 | - | ||
| 35 | - | ||
| 36 | -AUTHORS | ||
| 37 | -------- | ||
| 38 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 39 | -<stephane.raimbault@gmail.com> |
doc/modbus_get_float_cdab.txt deleted
| 1 | -modbus_get_float_cdab(3) | ||
| 2 | -======================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_get_float_cdab - get a float value from 2 registers in CDAB byte order | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*float modbus_get_float_cdab(const uint16_t *'src');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_get_float_cdab()* function shall get a float from 4 bytes with | ||
| 18 | -swapped words (CDAB order instead of ABCD). The _src_ array must be a pointer on | ||
| 19 | -two 16 bits values, for example, if the first word is set to F147 and the second | ||
| 20 | -to 0x0020, the float value will be read as 123456.0. | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -RETURN VALUE | ||
| 24 | ------------- | ||
| 25 | -The function shall return a float. | ||
| 26 | - | ||
| 27 | - | ||
| 28 | -SEE ALSO | ||
| 29 | --------- | ||
| 30 | -linkmb:modbus_set_float_cdab[3] | ||
| 31 | -linkmb:modbus_get_float_abcd[3] | ||
| 32 | -linkmb:modbus_get_float_badc[3] | ||
| 33 | -linkmb:modbus_get_float_dcba[3] | ||
| 34 | - | ||
| 35 | - | ||
| 36 | -AUTHORS | ||
| 37 | -------- | ||
| 38 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 39 | -<stephane.raimbault@gmail.com> |
doc/modbus_get_float_dcba.txt deleted
| 1 | -modbus_get_float_dcba(3) | ||
| 2 | -======================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_get_float_dcba - get a float value from 2 registers in DCBA byte order | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*float modbus_get_float_dcba(const uint16_t *'src');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_get_float_dcba()* function shall get a float from 4 bytes in | ||
| 18 | -inversed Modbus format (DCBA order instead of ABCD). The _src_ array must be a | ||
| 19 | -pointer on two 16 bits values, for example, if the first word is set to 0x47F1 | ||
| 20 | -and the second to 0x2000, the float value will be read as 123456.0. | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -RETURN VALUE | ||
| 24 | ------------- | ||
| 25 | -The function shall return a float. | ||
| 26 | - | ||
| 27 | - | ||
| 28 | -SEE ALSO | ||
| 29 | --------- | ||
| 30 | -linkmb:modbus_set_float_dcba[3] | ||
| 31 | -linkmb:modbus_get_float_abcd[3] | ||
| 32 | -linkmb:modbus_get_float_badc[3] | ||
| 33 | -linkmb:modbus_get_float_cdab[3] | ||
| 34 | - | ||
| 35 | - | ||
| 36 | -AUTHORS | ||
| 37 | -------- | ||
| 38 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 39 | -<stephane.raimbault@gmail.com> |
doc/modbus_get_header_length.txt deleted
| 1 | -modbus_get_header_length(3) | ||
| 2 | -=========================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_get_header_length - retrieve the current header length | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_get_header_length(modbus_t *'ctx');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_get_header_length()* function shall retrieve the current header | ||
| 18 | -length from the backend. This function is convenient to manipulate a message and | ||
| 19 | -so its limited to low-level operations. | ||
| 20 | - | ||
| 21 | - | ||
| 22 | -RETURN VALUE | ||
| 23 | ------------- | ||
| 24 | -The header length as integer value. | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -SEE ALSO | ||
| 28 | --------- | ||
| 29 | -linkmb:libmodbus[7] | ||
| 30 | - | ||
| 31 | - | ||
| 32 | -AUTHORS | ||
| 33 | -------- | ||
| 34 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 35 | -<stephane.raimbault@gmail.com> |
doc/modbus_get_indication_timeout.txt deleted
| 1 | -modbus_get_indication_timeout(3) | ||
| 2 | -================================ | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_get_indication_timeout - get timeout used to wait for an indication (request received by a server). | ||
| 8 | - | ||
| 9 | -SYNOPSIS | ||
| 10 | --------- | ||
| 11 | -*int modbus_get_indication_timeout(modbus_t *'ctx', uint32_t *'to_sec', uint32_t *'to_usec');* | ||
| 12 | - | ||
| 13 | - | ||
| 14 | -DESCRIPTION | ||
| 15 | ------------ | ||
| 16 | - | ||
| 17 | -The *modbus_get_indication_timeout()* function shall store the timeout interval | ||
| 18 | -used to wait for an indication in the _to_sec_ and _to_usec_ arguments. | ||
| 19 | -Indication is the term used by the Modbus protocol to designate a request | ||
| 20 | -received by the server. | ||
| 21 | - | ||
| 22 | -The default value is zero, it means the server will wait forever. | ||
| 23 | - | ||
| 24 | - | ||
| 25 | -RETURN VALUE | ||
| 26 | ------------- | ||
| 27 | -The function shall return 0 if successful. Otherwise it shall return -1 and set | ||
| 28 | -errno. | ||
| 29 | - | ||
| 30 | - | ||
| 31 | -EXAMPLE | ||
| 32 | -------- | ||
| 33 | -[source,c] | ||
| 34 | -------------------- | ||
| 35 | -uint32_t to_sec; | ||
| 36 | -uint32_t to_usec; | ||
| 37 | - | ||
| 38 | -/* Save original timeout */ | ||
| 39 | -modbus_get_indication_timeout(ctx, &to_sec, &to_usec); | ||
| 40 | -------------------- | ||
| 41 | - | ||
| 42 | - | ||
| 43 | -SEE ALSO | ||
| 44 | --------- | ||
| 45 | -linkmb:modbus_set_indication_timeout[3] | ||
| 46 | -linkmb:modbus_get_response_timeout[3] | ||
| 47 | -linkmb:modbus_set_response_timeout[3] | ||
| 48 | - | ||
| 49 | - | ||
| 50 | -AUTHORS | ||
| 51 | -------- | ||
| 52 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 53 | -<stephane.raimbault@gmail.com> |
doc/modbus_get_response_timeout.txt deleted
| 1 | -modbus_get_response_timeout(3) | ||
| 2 | -============================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_get_response_timeout - get timeout for response | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_get_response_timeout(modbus_t *'ctx', uint32_t *'to_sec', uint32_t *'to_usec');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_get_response_timeout()* function shall return the timeout interval | ||
| 18 | -used to wait for a response in the _to_sec_ and _to_usec_ arguments. | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -RETURN VALUE | ||
| 22 | ------------- | ||
| 23 | -The function shall return 0 if successful. Otherwise it shall return -1 and set | ||
| 24 | -errno. | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -EXAMPLE | ||
| 28 | -------- | ||
| 29 | -[source,c] | ||
| 30 | -------------------- | ||
| 31 | -uint32_t old_response_to_sec; | ||
| 32 | -uint32_t old_response_to_usec; | ||
| 33 | - | ||
| 34 | -/* Save original timeout */ | ||
| 35 | -modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); | ||
| 36 | - | ||
| 37 | -/* Define a new and too short timeout! */ | ||
| 38 | -modbus_set_response_timeout(ctx, 0, 0); | ||
| 39 | -------------------- | ||
| 40 | - | ||
| 41 | - | ||
| 42 | -SEE ALSO | ||
| 43 | --------- | ||
| 44 | -linkmb:modbus_set_response_timeout[3] | ||
| 45 | -linkmb:modbus_get_byte_timeout[3] | ||
| 46 | -linkmb:modbus_set_byte_timeout[3] | ||
| 47 | - | ||
| 48 | - | ||
| 49 | -AUTHORS | ||
| 50 | -------- | ||
| 51 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 52 | -<stephane.raimbault@gmail.com> |
doc/modbus_get_slave.txt deleted
| 1 | -modbus_get_slave(3) | ||
| 2 | -=================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_get_slave - get slave number in the context | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_get_slave(modbus_t *'ctx');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_get_slave()* function shall get the slave number in the libmodbus | ||
| 18 | -context. | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -RETURN VALUE | ||
| 22 | ------------- | ||
| 23 | -The function shall return the slave number if successful. Otherwise it shall return -1 | ||
| 24 | -and set errno to one of the values defined below. | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -ERRORS | ||
| 28 | ------- | ||
| 29 | -*EINVAL*:: | ||
| 30 | -The libmodbus context is undefined. | ||
| 31 | - | ||
| 32 | - | ||
| 33 | -SEE ALSO | ||
| 34 | --------- | ||
| 35 | -linkmb:modbus_set_slave[3] | ||
| 36 | - | ||
| 37 | - | ||
| 38 | -AUTHORS | ||
| 39 | -------- | ||
| 40 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 41 | -<stephane.raimbault@gmail.com> |
doc/modbus_get_socket.txt deleted
| 1 | -modbus_get_socket(3) | ||
| 2 | -==================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_get_socket - get the current socket of the context | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_get_socket(modbus_t *'ctx');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_get_socket()* function shall return the current socket or file | ||
| 18 | -descriptor of the libmodbus context. | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -RETURN VALUE | ||
| 22 | ------------- | ||
| 23 | -The function returns the current socket or file descriptor of the context if | ||
| 24 | -successful. Otherwise it shall return -1 and set errno. | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -SEE ALSO | ||
| 28 | --------- | ||
| 29 | -linkmb:modbus_set_socket[3] | ||
| 30 | - | ||
| 31 | - | ||
| 32 | -AUTHORS | ||
| 33 | -------- | ||
| 34 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 35 | -<stephane.raimbault@gmail.com> |
doc/modbus_mapping_free.txt deleted
| 1 | -modbus_mapping_free(3) | ||
| 2 | -===================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_mapping_free - free a modbus_mapping_t structure | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*void modbus_mapping_free(modbus_mapping_t *'mb_mapping');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The function shall free the four arrays of mb_mapping_t structure and finally | ||
| 18 | -the mb_mapping_t referenced by _mb_mapping_. | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -RETURN VALUE | ||
| 22 | ------------- | ||
| 23 | -There is no return values. | ||
| 24 | - | ||
| 25 | - | ||
| 26 | -SEE ALSO | ||
| 27 | --------- | ||
| 28 | -linkmb:modbus_mapping_new[3] | ||
| 29 | - | ||
| 30 | - | ||
| 31 | -AUTHORS | ||
| 32 | -------- | ||
| 33 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 34 | -<stephane.raimbault@gmail.com> |
doc/modbus_mapping_new.txt deleted
| 1 | -modbus_mapping_new(3) | ||
| 2 | -===================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_mapping_new - allocate four arrays of bits and registers | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*modbus_mapping_t* modbus_mapping_new(int 'nb_bits', int 'nb_input_bits', int 'nb_registers', int 'nb_input_registers');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_mapping_new()* function shall allocate four arrays to store bits, | ||
| 18 | -input bits, registers and inputs registers. The pointers are stored in | ||
| 19 | -modbus_mapping_t structure. All values of the arrays are initialized to zero. | ||
| 20 | - | ||
| 21 | -This function is equivalent to a call of the | ||
| 22 | -linkmb:modbus_mapping_new_start_address[3] function with all start addresses to | ||
| 23 | -`0`. | ||
| 24 | - | ||
| 25 | -If it isn't necessary to allocate an array for a specific type of data, you can | ||
| 26 | -pass the zero value in argument, the associated pointer will be NULL. | ||
| 27 | - | ||
| 28 | -This function is convenient to handle requests in a Modbus server/slave. | ||
| 29 | - | ||
| 30 | - | ||
| 31 | -RETURN VALUE | ||
| 32 | ------------- | ||
| 33 | -The function shall return the new allocated structure if successful. Otherwise | ||
| 34 | -it shall return NULL and set errno. | ||
| 35 | - | ||
| 36 | - | ||
| 37 | -ERRORS | ||
| 38 | ------- | ||
| 39 | -*ENOMEM*:: | ||
| 40 | -Not enough memory | ||
| 41 | - | ||
| 42 | - | ||
| 43 | -EXAMPLE | ||
| 44 | -------- | ||
| 45 | -[source,c] | ||
| 46 | -------------------- | ||
| 47 | -/* The first value of each array is accessible from the 0 address. */ | ||
| 48 | -mb_mapping = modbus_mapping_new(BITS_ADDRESS + BITS_NB, | ||
| 49 | - INPUT_BITS_ADDRESS + INPUT_BITS_NB, | ||
| 50 | - REGISTERS_ADDRESS + REGISTERS_NB, | ||
| 51 | - INPUT_REGISTERS_ADDRESS + INPUT_REGISTERS_NB); | ||
| 52 | -if (mb_mapping == NULL) { | ||
| 53 | - fprintf(stderr, "Failed to allocate the mapping: %s\n", | ||
| 54 | - modbus_strerror(errno)); | ||
| 55 | - modbus_free(ctx); | ||
| 56 | - return -1; | ||
| 57 | -} | ||
| 58 | -------------------- | ||
| 59 | - | ||
| 60 | -SEE ALSO | ||
| 61 | --------- | ||
| 62 | -linkmb:modbus_mapping_free[3] | ||
| 63 | -linkmb:modbus_mapping_new_start_address[3] | ||
| 64 | - | ||
| 65 | - | ||
| 66 | -AUTHORS | ||
| 67 | -------- | ||
| 68 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 69 | -<stephane.raimbault@gmail.com> |
doc/modbus_mapping_new_start_address.txt deleted
| 1 | -modbus_mapping_new_start_address(3) | ||
| 2 | -=================================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_mapping_new_start_address - allocate four arrays of bits and registers accessible from their starting addresses | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*modbus_mapping_t* modbus_mapping_new_start_address(int 'start_bits', int 'nb_bits', | ||
| 13 | - int 'start_input_bits', int 'nb_input_bits', | ||
| 14 | - int 'start_registers', int 'nb_registers', | ||
| 15 | - int 'start_input_registers', int 'nb_input_registers');* | ||
| 16 | - | ||
| 17 | - | ||
| 18 | -DESCRIPTION | ||
| 19 | ------------ | ||
| 20 | -The _modbus_mapping_new_start_address()_ function shall allocate four arrays to | ||
| 21 | -store bits, input bits, registers and inputs registers. The pointers are stored | ||
| 22 | -in modbus_mapping_t structure. All values of the arrays are initialized to zero. | ||
| 23 | - | ||
| 24 | -The different starting addresses make it possible to place the mapping at any | ||
| 25 | -address in each address space. This way, you can give access to values stored | ||
| 26 | -at high addresses without allocating memory from the address zero, for eg. to | ||
| 27 | -make available registers from 10000 to 10009, you can use: | ||
| 28 | - | ||
| 29 | -[source,c] | ||
| 30 | -------------------- | ||
| 31 | -mb_mapping = modbus_mapping_new_start_address(0, 0, 0, 0, 10000, 10, 0, 0); | ||
| 32 | -------------------- | ||
| 33 | - | ||
| 34 | -With this code, only 10 registers (`uint16_t`) are allocated. | ||
| 35 | - | ||
| 36 | -If it isn't necessary to allocate an array for a specific type of data, you can | ||
| 37 | -pass the zero value in argument, the associated pointer will be NULL. | ||
| 38 | - | ||
| 39 | -This function is convenient to handle requests in a Modbus server/slave. | ||
| 40 | - | ||
| 41 | - | ||
| 42 | -RETURN VALUE | ||
| 43 | ------------- | ||
| 44 | -The _modbus_mapping_new_start_address()_ function shall return the new allocated structure if | ||
| 45 | -successful. Otherwise it shall return NULL and set errno. | ||
| 46 | - | ||
| 47 | - | ||
| 48 | -ERRORS | ||
| 49 | ------- | ||
| 50 | -ENOMEM:: | ||
| 51 | -Not enough memory | ||
| 52 | - | ||
| 53 | - | ||
| 54 | -EXAMPLE | ||
| 55 | -------- | ||
| 56 | -[source,c] | ||
| 57 | -------------------- | ||
| 58 | -/* The first value of each array is accessible at the defined address. | ||
| 59 | - The end address is ADDRESS + NB - 1. */ | ||
| 60 | -mb_mapping = modbus_mapping_new_start_address(BITS_ADDRESS, BITS_NB, | ||
| 61 | - INPUT_BITS_ADDRESS, INPUT_BITS_NB, | ||
| 62 | - REGISTERS_ADDRESS, REGISTERS_NB, | ||
| 63 | - INPUT_REGISTERS_ADDRESS, INPUT_REGISTERS_NB); | ||
| 64 | -if (mb_mapping == NULL) { | ||
| 65 | - fprintf(stderr, "Failed to allocate the mapping: %s\n", | ||
| 66 | - modbus_strerror(errno)); | ||
| 67 | - modbus_free(ctx); | ||
| 68 | - return -1; | ||
| 69 | -} | ||
| 70 | -------------------- | ||
| 71 | - | ||
| 72 | -SEE ALSO | ||
| 73 | --------- | ||
| 74 | -linkmb:modbus_mapping_new[3] | ||
| 75 | -linkmb:modbus_mapping_free[3] | ||
| 76 | - | ||
| 77 | - | ||
| 78 | -AUTHORS | ||
| 79 | -------- | ||
| 80 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 81 | -<stephane.raimbault@gmail.com> |
doc/modbus_mask_write_register.txt deleted
| 1 | -modbus_mask_write_register(3) | ||
| 2 | -============================= | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_mask_write_register - mask a single register | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_mask_write_register(modbus_t *'ctx', int 'addr', uint16_t 'and', uint16_t 'or');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_mask_write_register()* function shall modify the value of the | ||
| 18 | -holding register at the address 'addr' of the remote device using the algorithm: | ||
| 19 | - | ||
| 20 | - new value = (current value AND 'and') OR ('or' AND (NOT 'and')) | ||
| 21 | - | ||
| 22 | -The function uses the Modbus function code 0x16 (mask single register). | ||
| 23 | - | ||
| 24 | - | ||
| 25 | -RETURN VALUE | ||
| 26 | ------------- | ||
| 27 | -The function shall return 1 if successful. Otherwise it shall return -1 and set | ||
| 28 | -errno. | ||
| 29 | - | ||
| 30 | - | ||
| 31 | -SEE ALSO | ||
| 32 | --------- | ||
| 33 | -linkmb:modbus_read_registers[3] | ||
| 34 | -linkmb:modbus_write_registers[3] | ||
| 35 | - | ||
| 36 | - | ||
| 37 | -AUTHORS | ||
| 38 | -------- | ||
| 39 | -Martijn de Gouw <martijn.de.gouw@prodrive.nl> | ||
| 40 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 41 | -<stephane.raimbault@gmail.com> |
doc/modbus_new_rtu.txt deleted
| 1 | -modbus_new_rtu(3) | ||
| 2 | -================= | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_new_rtu - create a libmodbus context for RTU | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*modbus_t *modbus_new_rtu(const char *'device', int 'baud', char 'parity', int 'data_bit', int 'stop_bit');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | - | ||
| 16 | -DESCRIPTION | ||
| 17 | ------------ | ||
| 18 | -The *modbus_new_rtu()* function shall allocate and initialize a _modbus_t_ | ||
| 19 | -structure to communicate in RTU mode on a serial line. | ||
| 20 | - | ||
| 21 | -The _device_ argument specifies the name of the serial port handled by the OS, | ||
| 22 | -eg. "/dev/ttyS0" or "/dev/ttyUSB0". On Windows, it's necessary to prepend COM | ||
| 23 | -name with "\\.\" for COM number greater than 9, eg. "\\\\.\\COM10". See | ||
| 24 | -http://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx for details | ||
| 25 | - | ||
| 26 | -The _baud_ argument specifies the baud rate of the communication, eg. 9600, | ||
| 27 | -19200, 57600, 115200, etc. | ||
| 28 | - | ||
| 29 | -The _parity_ argument can have one of the following values::: | ||
| 30 | -* _N_ for none | ||
| 31 | -* _E_ for even | ||
| 32 | -* _O_ for odd | ||
| 33 | - | ||
| 34 | -The _data_bits_ argument specifies the number of bits of data, the allowed | ||
| 35 | -values are 5, 6, 7 and 8. | ||
| 36 | - | ||
| 37 | -The _stop_bits_ argument specifies the bits of stop, the allowed values are 1 | ||
| 38 | -and 2. | ||
| 39 | - | ||
| 40 | -Once the _modbus_t_ structure is initialized, you must set the slave of your | ||
| 41 | -device with linkmb:modbus_set_slave[3] and connect to the serial bus with | ||
| 42 | -linkmb:modbus_connect[3]. | ||
| 43 | - | ||
| 44 | -RETURN VALUE | ||
| 45 | ------------- | ||
| 46 | -The function shall return a pointer to a _modbus_t_ structure if | ||
| 47 | -successful. Otherwise it shall return NULL and set errno to one of the values | ||
| 48 | -defined below. | ||
| 49 | - | ||
| 50 | - | ||
| 51 | -ERRORS | ||
| 52 | ------- | ||
| 53 | -*EINVAL*:: | ||
| 54 | -An invalid argument was given. | ||
| 55 | - | ||
| 56 | -*ENOMEM*:: | ||
| 57 | -Out of memory. Possibly, the application hits its memory limit and/or whole | ||
| 58 | -system is running out of memory. | ||
| 59 | - | ||
| 60 | - | ||
| 61 | -EXAMPLE | ||
| 62 | -------- | ||
| 63 | -[source,c] | ||
| 64 | -------------------- | ||
| 65 | -modbus_t *ctx; | ||
| 66 | - | ||
| 67 | -ctx = modbus_new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1); | ||
| 68 | -if (ctx == NULL) { | ||
| 69 | - fprintf(stderr, "Unable to create the libmodbus context\n"); | ||
| 70 | - return -1; | ||
| 71 | -} | ||
| 72 | - | ||
| 73 | -modbus_set_slave(ctx, YOUR_DEVICE_ID); | ||
| 74 | - | ||
| 75 | -if (modbus_connect(ctx) == -1) { | ||
| 76 | - fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); | ||
| 77 | - modbus_free(ctx); | ||
| 78 | - return -1; | ||
| 79 | -} | ||
| 80 | -------------------- | ||
| 81 | - | ||
| 82 | -SEE ALSO | ||
| 83 | --------- | ||
| 84 | -linkmb:modbus_new_tcp[3] | ||
| 85 | -linkmb:modbus_free[3] | ||
| 86 | - | ||
| 87 | - | ||
| 88 | -AUTHORS | ||
| 89 | -------- | ||
| 90 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 91 | -<stephane.raimbault@gmail.com> |
doc/modbus_new_tcp.txt deleted
| 1 | -modbus_new_tcp(3) | ||
| 2 | -================= | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_new_tcp - create a libmodbus context for TCP/IPv4 | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*modbus_t *modbus_new_tcp(const char *'ip', int 'port');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_new_tcp()* function shall allocate and initialize a modbus_t | ||
| 18 | -structure to communicate with a Modbus TCP IPv4 server. | ||
| 19 | - | ||
| 20 | -The _ip_ argument specifies the IP address of the server to which the client | ||
| 21 | -wants to establish a connection. A NULL value can be used to listen any addresses in | ||
| 22 | -server mode. | ||
| 23 | - | ||
| 24 | -The _port_ argument is the TCP port to use. Set the port to | ||
| 25 | -`MODBUS_TCP_DEFAULT_PORT` to use the default one (502). It’s convenient to use a | ||
| 26 | -port number greater than or equal to 1024 because it’s not necessary to have | ||
| 27 | -administrator privileges. | ||
| 28 | - | ||
| 29 | - | ||
| 30 | -RETURN VALUE | ||
| 31 | ------------- | ||
| 32 | -The function shall return a pointer to a *modbus_t* structure if | ||
| 33 | -successful. Otherwise it shall return NULL and set errno to one of the values | ||
| 34 | -defined below. | ||
| 35 | - | ||
| 36 | - | ||
| 37 | -ERRORS | ||
| 38 | ------- | ||
| 39 | -*EINVAL*:: | ||
| 40 | -An invalid IP address was given. | ||
| 41 | - | ||
| 42 | -*ENOMEM*:: | ||
| 43 | -Out of memory. Possibly, the application hits its memory limit and/or whole | ||
| 44 | -system is running out of memory. | ||
| 45 | - | ||
| 46 | - | ||
| 47 | -EXAMPLE | ||
| 48 | -------- | ||
| 49 | -[source,c] | ||
| 50 | -------------------- | ||
| 51 | -modbus_t *ctx; | ||
| 52 | - | ||
| 53 | -ctx = modbus_new_tcp("127.0.0.1", 1502); | ||
| 54 | -if (ctx == NULL) { | ||
| 55 | - fprintf(stderr, "Unable to allocate libmodbus context\n"); | ||
| 56 | - return -1; | ||
| 57 | -} | ||
| 58 | - | ||
| 59 | -if (modbus_connect(ctx) == -1) { | ||
| 60 | - fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); | ||
| 61 | - modbus_free(ctx); | ||
| 62 | - return -1; | ||
| 63 | -} | ||
| 64 | -------------------- | ||
| 65 | - | ||
| 66 | -SEE ALSO | ||
| 67 | --------- | ||
| 68 | -linkmb:modbus_tcp_listen[3] | ||
| 69 | -linkmb:modbus_free[3] | ||
| 70 | - | ||
| 71 | - | ||
| 72 | -AUTHORS | ||
| 73 | -------- | ||
| 74 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 75 | -<stephane.raimbault@gmail.com> |
doc/modbus_new_tcp_pi.txt deleted
| 1 | -modbus_new_tcp_pi(3) | ||
| 2 | -==================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_new_tcp_pi - create a libmodbus context for TCP Protocol Independent | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*modbus_t *modbus_new_tcp_pi(const char *'node', const char *'service');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_new_tcp_pi()* function shall allocate and initialize a modbus_t | ||
| 18 | -structure to communicate with a Modbus TCP IPv4 or IPv6 server. | ||
| 19 | - | ||
| 20 | -The _node_ argument specifies the host name or IP address of the host to connect | ||
| 21 | -to, eg. "192.168.0.5" , "::1" or "server.com". A NULL value can be used to | ||
| 22 | -listen any addresses in server mode. | ||
| 23 | - | ||
| 24 | -The _service_ argument is the service name/port number to connect to. To use the | ||
| 25 | -default Modbus port use the string "502". On many Unix systems, it’s | ||
| 26 | -convenient to use a port number greater than or equal to 1024 because it’s not | ||
| 27 | -necessary to have administrator privileges. | ||
| 28 | - | ||
| 29 | - | ||
| 30 | -RETURN VALUE | ||
| 31 | ------------- | ||
| 32 | -The function shall return a pointer to a *modbus_t* structure if | ||
| 33 | -successful. Otherwise it shall return NULL and set errno to one of the values | ||
| 34 | -defined below. | ||
| 35 | - | ||
| 36 | - | ||
| 37 | -ERRORS | ||
| 38 | ------- | ||
| 39 | -*EINVAL*:: | ||
| 40 | -The node string is empty or has been truncated. The service string is empty or | ||
| 41 | -has been truncated. | ||
| 42 | - | ||
| 43 | -*ENOMEM*:: | ||
| 44 | -Out of memory. Possibly, the application hits its memory limit and/or whole | ||
| 45 | -system is running out of memory. | ||
| 46 | - | ||
| 47 | - | ||
| 48 | -EXAMPLE | ||
| 49 | -------- | ||
| 50 | -[source,c] | ||
| 51 | -------------------- | ||
| 52 | -modbus_t *ctx; | ||
| 53 | - | ||
| 54 | -ctx = modbus_new_tcp_pi("::1", "1502"); | ||
| 55 | -if (ctx == NULL) { | ||
| 56 | - fprintf(stderr, "Unable to allocate libmodbus context\n"); | ||
| 57 | - return -1; | ||
| 58 | -} | ||
| 59 | - | ||
| 60 | -if (modbus_connect(ctx) == -1) { | ||
| 61 | - fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); | ||
| 62 | - modbus_free(ctx); | ||
| 63 | - return -1; | ||
| 64 | -} | ||
| 65 | -------------------- | ||
| 66 | - | ||
| 67 | -SEE ALSO | ||
| 68 | --------- | ||
| 69 | -linkmb:modbus_new_tcp[3] | ||
| 70 | -linkmb:modbus_tcp_pi_listen[3] | ||
| 71 | -linkmb:modbus_free[3] | ||
| 72 | - | ||
| 73 | - | ||
| 74 | -AUTHORS | ||
| 75 | -------- | ||
| 76 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 77 | -<stephane.raimbault@gmail.com> |
doc/modbus_read_bits.txt deleted
| 1 | -modbus_read_bits(3) | ||
| 2 | -=================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_read_bits - read many bits | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_read_bits(modbus_t *'ctx', int 'addr', int 'nb', uint8_t *'dest');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_read_bits()* function shall read the status of the _nb_ bits (coils) | ||
| 18 | -to the address _addr_ of the remote device. The result of reading is stored in | ||
| 19 | -_dest_ array as unsigned bytes (8 bits) set to `TRUE` or `FALSE`. | ||
| 20 | - | ||
| 21 | -You must take care to allocate enough memory to store the results in _dest_ | ||
| 22 | -(at least _nb_ * sizeof(uint8_t)). | ||
| 23 | - | ||
| 24 | -The function uses the Modbus function code 0x01 (read coil status). | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -RETURN VALUE | ||
| 28 | ------------- | ||
| 29 | -The function shall return the number of read bits if successful. Otherwise it | ||
| 30 | -shall return -1 and set errno. | ||
| 31 | - | ||
| 32 | - | ||
| 33 | -ERRORS | ||
| 34 | ------- | ||
| 35 | -*EMBMDATA*:: | ||
| 36 | -Too many bits requested | ||
| 37 | - | ||
| 38 | - | ||
| 39 | -SEE ALSO | ||
| 40 | --------- | ||
| 41 | -linkmb:modbus_write_bit[3] | ||
| 42 | -linkmb:modbus_write_bits[3] | ||
| 43 | - | ||
| 44 | - | ||
| 45 | -AUTHORS | ||
| 46 | -------- | ||
| 47 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 48 | -<stephane.raimbault@gmail.com> |
doc/modbus_read_input_bits.txt deleted
| 1 | -modbus_read_input_bits(3) | ||
| 2 | -========================= | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_read_input_bits - read many input bits | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_read_input_bits(modbus_t *'ctx', int 'addr', int 'nb', uint8_t *'dest');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_read_input_bits()* function shall read the content of the _nb_ input | ||
| 18 | -bits to the address _addr_ of the remote device. The result of reading is stored | ||
| 19 | -in _dest_ array as unsigned bytes (8 bits) set to _TRUE_ or _FALSE_. | ||
| 20 | - | ||
| 21 | -You must take care to allocate enough memory to store the results in _dest_ | ||
| 22 | -(at least _nb_ * sizeof(uint8_t)). | ||
| 23 | - | ||
| 24 | -The function uses the Modbus function code 0x02 (read input status). | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -RETURN VALUE | ||
| 28 | ------------- | ||
| 29 | -The function shall return the number of read input status if | ||
| 30 | -successful. Otherwise it shall return -1 and set errno. | ||
| 31 | - | ||
| 32 | - | ||
| 33 | -ERRORS | ||
| 34 | ------- | ||
| 35 | -*EMBMDATA*:: | ||
| 36 | -Too many discrete inputs requested | ||
| 37 | - | ||
| 38 | - | ||
| 39 | -SEE ALSO | ||
| 40 | --------- | ||
| 41 | -linkmb:modbus_read_input_registers[3] | ||
| 42 | - | ||
| 43 | - | ||
| 44 | -AUTHORS | ||
| 45 | -------- | ||
| 46 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 47 | -<stephane.raimbault@gmail.com> |
doc/modbus_read_input_registers.txt deleted
| 1 | -modbus_read_input_registers(3) | ||
| 2 | -============================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_read_input_registers - read many input registers | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_read_input_registers(modbus_t *'ctx', int 'addr', int 'nb', uint16_t *'dest');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_read_input_registers()* function shall read the content of the _nb_ | ||
| 18 | -input registers to address _addr_ of the remote device. The result of the | ||
| 19 | -reading is stored in _dest_ array as word values (16 bits). | ||
| 20 | - | ||
| 21 | -You must take care to allocate enough memory to store the results in _dest_ (at | ||
| 22 | -least _nb_ * sizeof(uint16_t)). | ||
| 23 | - | ||
| 24 | -The function uses the Modbus function code 0x04 (read input registers). The | ||
| 25 | -holding registers and input registers have different historical meaning, but | ||
| 26 | -nowadays it's more common to use holding registers only. | ||
| 27 | - | ||
| 28 | - | ||
| 29 | -RETURN VALUE | ||
| 30 | ------------- | ||
| 31 | -The function shall return the number of read input registers if | ||
| 32 | -successful. Otherwise it shall return -1 and set errno. | ||
| 33 | - | ||
| 34 | - | ||
| 35 | -ERRORS | ||
| 36 | ------- | ||
| 37 | -*EMBMDATA*:: | ||
| 38 | -Too many bits requested | ||
| 39 | - | ||
| 40 | - | ||
| 41 | -SEE ALSO | ||
| 42 | --------- | ||
| 43 | -linkmb:modbus_read_input_bits[3] | ||
| 44 | -linkmb:modbus_write_register[3] | ||
| 45 | -linkmb:modbus_write_registers[3] | ||
| 46 | - | ||
| 47 | - | ||
| 48 | -AUTHORS | ||
| 49 | -------- | ||
| 50 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 51 | -<stephane.raimbault@gmail.com> |
doc/modbus_read_registers.txt deleted
| 1 | -modbus_read_registers(3) | ||
| 2 | -======================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_read_registers - read many registers | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_read_registers(modbus_t *'ctx', int 'addr', int 'nb', uint16_t *'dest');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_read_registers()* function shall read the content of the _nb_ | ||
| 18 | -holding registers to the address _addr_ of the remote device. The result of | ||
| 19 | -reading is stored in _dest_ array as word values (16 bits). | ||
| 20 | - | ||
| 21 | -You must take care to allocate enough memory to store the results in _dest_ | ||
| 22 | -(at least _nb_ * sizeof(uint16_t)). | ||
| 23 | - | ||
| 24 | -The function uses the Modbus function code 0x03 (read holding registers). | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -RETURN VALUE | ||
| 28 | ------------- | ||
| 29 | -The function shall return the number of read registers | ||
| 30 | -if successful. Otherwise it shall return -1 and set errno. | ||
| 31 | - | ||
| 32 | - | ||
| 33 | -ERRORS | ||
| 34 | ------- | ||
| 35 | -*EMBMDATA*:: | ||
| 36 | -Too many registers requested | ||
| 37 | - | ||
| 38 | - | ||
| 39 | -EXAMPLE | ||
| 40 | -------- | ||
| 41 | -[source,c] | ||
| 42 | -------------------- | ||
| 43 | -modbus_t *ctx; | ||
| 44 | -uint16_t tab_reg[64]; | ||
| 45 | -int rc; | ||
| 46 | -int i; | ||
| 47 | - | ||
| 48 | -ctx = modbus_new_tcp("127.0.0.1", 1502); | ||
| 49 | -if (modbus_connect(ctx) == -1) { | ||
| 50 | - fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); | ||
| 51 | - modbus_free(ctx); | ||
| 52 | - return -1; | ||
| 53 | -} | ||
| 54 | - | ||
| 55 | -rc = modbus_read_registers(ctx, 0, 10, tab_reg); | ||
| 56 | -if (rc == -1) { | ||
| 57 | - fprintf(stderr, "%s\n", modbus_strerror(errno)); | ||
| 58 | - return -1; | ||
| 59 | -} | ||
| 60 | - | ||
| 61 | -for (i=0; i < rc; i++) { | ||
| 62 | - printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]); | ||
| 63 | -} | ||
| 64 | - | ||
| 65 | -modbus_close(ctx); | ||
| 66 | -modbus_free(ctx); | ||
| 67 | -------------------- | ||
| 68 | - | ||
| 69 | - | ||
| 70 | -SEE ALSO | ||
| 71 | --------- | ||
| 72 | -linkmb:modbus_write_register[3] | ||
| 73 | -linkmb:modbus_write_registers[3] | ||
| 74 | - | ||
| 75 | - | ||
| 76 | -AUTHORS | ||
| 77 | -------- | ||
| 78 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 79 | -<stephane.raimbault@gmail.com> |
doc/modbus_receive.txt deleted
| 1 | -modbus_receive(3) | ||
| 2 | -================= | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_receive - receive an indication request | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_receive(modbus_t *'ctx', uint8_t *'req');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_receive()* function shall receive an indication request from the | ||
| 18 | -socket of the context _ctx_. This function is used by Modbus slave/server to | ||
| 19 | -receive and analyze indication request sent by the masters/clients. | ||
| 20 | - | ||
| 21 | -If you need to use another socket or file descriptor than the one defined in the | ||
| 22 | -context _ctx_, see the function linkmb:modbus_set_socket[3]. | ||
| 23 | - | ||
| 24 | - | ||
| 25 | -RETURN VALUE | ||
| 26 | ------------- | ||
| 27 | -The function shall store the indication request in _req_ and return the request | ||
| 28 | -length if successful. The returned request length can be zero if the indication | ||
| 29 | -request is ignored (eg. a query for another slave in RTU mode). Otherwise it | ||
| 30 | -shall return -1 and set errno. | ||
| 31 | - | ||
| 32 | - | ||
| 33 | -SEE ALSO | ||
| 34 | --------- | ||
| 35 | -linkmb:modbus_set_socket[3] | ||
| 36 | -linkmb:modbus_reply[3] | ||
| 37 | - | ||
| 38 | - | ||
| 39 | -AUTHORS | ||
| 40 | -------- | ||
| 41 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 42 | -<stephane.raimbault@gmail.com> |
doc/modbus_receive_confirmation.txt deleted
| 1 | -modbus_receive_confirmation(3) | ||
| 2 | -============================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_receive_confirmation - receive a confirmation request | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_receive_confirmation(modbus_t *'ctx', uint8_t *'rsp');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_receive_confirmation()* function shall receive a request via the | ||
| 18 | -socket of the context _ctx_. This function must be used for debugging purposes | ||
| 19 | -because the received response isn't checked against the initial request. This | ||
| 20 | -function can be used to receive request not handled by the library. | ||
| 21 | - | ||
| 22 | -The maximum size of the response depends on the used backend, in RTU the _rsp_ | ||
| 23 | -array must be _MODBUS_RTU_MAX_ADU_LENGTH_ bytes and in TCP it must be | ||
| 24 | -_MODBUS_TCP_MAX_ADU_LENGTH_ bytes. If you want to write code compatible with | ||
| 25 | -both, you can use the constant _MODBUS_MAX_ADU_LENGTH_ (maximum value of all | ||
| 26 | -libmodbus backends). Take care to allocate enough memory to store responses to | ||
| 27 | -avoid crashes of your server. | ||
| 28 | - | ||
| 29 | - | ||
| 30 | -RETURN VALUE | ||
| 31 | ------------- | ||
| 32 | -The function shall store the confirmation request in _rsp_ and return the | ||
| 33 | -response length if successful. The returned request length can be zero if the | ||
| 34 | -indication request is ignored (eg. a query for another slave in RTU | ||
| 35 | -mode). Otherwise it shall return -1 and set errno. | ||
| 36 | - | ||
| 37 | -EXAMPLE | ||
| 38 | -------- | ||
| 39 | -[source,c] | ||
| 40 | -------------------- | ||
| 41 | -uint8_t rsp[MODBUS_MAX_ADU_LENGTH]; | ||
| 42 | -rc = modbus_receive_confirmation(ctx, rsp); | ||
| 43 | -------------------- | ||
| 44 | - | ||
| 45 | -SEE ALSO | ||
| 46 | --------- | ||
| 47 | -linkmb:modbus_send_raw_request[3] | ||
| 48 | - | ||
| 49 | - | ||
| 50 | -AUTHORS | ||
| 51 | -------- | ||
| 52 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 53 | -<stephane.raimbault@gmail.com> |
doc/modbus_reply.txt deleted
| 1 | -modbus_reply(3) | ||
| 2 | -=============== | ||
| 3 | - | ||
| 4 | -NAME | ||
| 5 | ----- | ||
| 6 | -modbus_reply - send a response to the received request | ||
| 7 | - | ||
| 8 | - | ||
| 9 | -SYNOPSIS | ||
| 10 | --------- | ||
| 11 | -*int modbus_reply(modbus_t *'ctx', const uint8_t *'req', int 'req_length', modbus_mapping_t *'mb_mapping'); | ||
| 12 | - | ||
| 13 | - | ||
| 14 | -DESCRIPTION | ||
| 15 | ------------ | ||
| 16 | -The *modbus_reply()* function shall send a response to received request. The | ||
| 17 | -request _req_ given in argument is analyzed, a response is then built and sent | ||
| 18 | -by using the information of the modbus context _ctx_. | ||
| 19 | - | ||
| 20 | -If the request indicates to read or write a value the operation will done in the | ||
| 21 | -modbus mapping _mb_mapping_ according to the type of the manipulated data. | ||
| 22 | - | ||
| 23 | -If an error occurs, an exception response will be sent. | ||
| 24 | - | ||
| 25 | -This function is designed for Modbus server. | ||
| 26 | - | ||
| 27 | - | ||
| 28 | -RETURN VALUE | ||
| 29 | ------------- | ||
| 30 | -The function shall return the length of the response sent if | ||
| 31 | -successful. Otherwise it shall return -1 and set errno. | ||
| 32 | - | ||
| 33 | - | ||
| 34 | -ERRORS | ||
| 35 | ------- | ||
| 36 | -*EMBMDATA*:: | ||
| 37 | -Sending has failed | ||
| 38 | - | ||
| 39 | -See also the errors returned by the syscall used to send the response (eg. send | ||
| 40 | -or write). | ||
| 41 | - | ||
| 42 | - | ||
| 43 | -SEE ALSO | ||
| 44 | --------- | ||
| 45 | -linkmb:modbus_reply_exception[3] | ||
| 46 | -linkmb:libmodbus[7] | ||
| 47 | - | ||
| 48 | - | ||
| 49 | -AUTHORS | ||
| 50 | -------- | ||
| 51 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 52 | -<stephane.raimbault@gmail.com> |
doc/modbus_reply_exception.txt deleted
| 1 | -modbus_reply_exception(3) | ||
| 2 | -========================= | ||
| 3 | - | ||
| 4 | -NAME | ||
| 5 | ----- | ||
| 6 | -modbus_reply_exception - send an exception response | ||
| 7 | - | ||
| 8 | - | ||
| 9 | -SYNOPSIS | ||
| 10 | --------- | ||
| 11 | -*int modbus_reply_exception(modbus_t *'ctx', const uint8_t *'req', unsigned int 'exception_code'); | ||
| 12 | - | ||
| 13 | - | ||
| 14 | -DESCRIPTION | ||
| 15 | ------------ | ||
| 16 | -The *modbus_reply_exception()* function shall send an exception response based | ||
| 17 | -on the 'exception_code' in argument. | ||
| 18 | - | ||
| 19 | -The libmodbus provides the following exception codes: | ||
| 20 | - | ||
| 21 | -* MODBUS_EXCEPTION_ILLEGAL_FUNCTION (1) | ||
| 22 | -* MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS (2) | ||
| 23 | -* MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE (3) | ||
| 24 | -* MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE (4) | ||
| 25 | -* MODBUS_EXCEPTION_ACKNOWLEDGE (5) | ||
| 26 | -* MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY (6) | ||
| 27 | -* MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE (7) | ||
| 28 | -* MODBUS_EXCEPTION_MEMORY_PARITY (8) | ||
| 29 | -* MODBUS_EXCEPTION_NOT_DEFINED (9) | ||
| 30 | -* MODBUS_EXCEPTION_GATEWAY_PATH (10) | ||
| 31 | -* MODBUS_EXCEPTION_GATEWAY_TARGET (11) | ||
| 32 | - | ||
| 33 | -The initial request _req_ is required to build a valid response. | ||
| 34 | - | ||
| 35 | - | ||
| 36 | -RETURN VALUE | ||
| 37 | ------------- | ||
| 38 | -The function shall return the length of the response sent if | ||
| 39 | -successful. Otherwise it shall return -1 and set errno. | ||
| 40 | - | ||
| 41 | - | ||
| 42 | -ERRORS | ||
| 43 | ------- | ||
| 44 | -*EINVAL*:: | ||
| 45 | -The exception code is invalid | ||
| 46 | - | ||
| 47 | - | ||
| 48 | -SEE ALSO | ||
| 49 | --------- | ||
| 50 | -linkmb:modbus_reply[3] | ||
| 51 | -linkmb:libmodbus[7] | ||
| 52 | - | ||
| 53 | - | ||
| 54 | -AUTHORS | ||
| 55 | -------- | ||
| 56 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 57 | -<stephane.raimbault@gmail.com> |
doc/modbus_report_slave_id.txt deleted
| 1 | -modbus_report_slave_id(3) | ||
| 2 | -========================= | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_report_slave_id - returns a description of the controller | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_report_slave_id(modbus_t *'ctx', int 'max_dest', uint8_t *'dest');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_report_slave_id()* function shall send a request to the controller | ||
| 18 | -to obtain a description of the controller. | ||
| 19 | - | ||
| 20 | -The response stored in _dest_ contains: | ||
| 21 | - | ||
| 22 | -* the slave ID, this unique ID is in reality not unique at all so it's not | ||
| 23 | - possible to depend on it to know how the information are packed in the | ||
| 24 | - response. | ||
| 25 | -* the run indicator status (0x00 = OFF, 0xFF = ON) | ||
| 26 | -* additional data specific to each controller. For example, libmodbus returns | ||
| 27 | - the version of the library as a string. | ||
| 28 | - | ||
| 29 | -The function writes at most _max_dest_ bytes from the response to _dest_ so | ||
| 30 | -you must ensure that _dest_ is large enough. | ||
| 31 | - | ||
| 32 | -RETURN VALUE | ||
| 33 | ------------- | ||
| 34 | -The function shall return the number of read data if successful. | ||
| 35 | - | ||
| 36 | -If the output was truncated due to the _max_dest_ limit then the return value is | ||
| 37 | -the number of bytes which would have been written to _dest_ if enough space had | ||
| 38 | -been available. Thus, a return value greater than _max_dest_ means that the | ||
| 39 | -response data was truncated. | ||
| 40 | - | ||
| 41 | -Otherwise it shall return -1 and set errno. | ||
| 42 | - | ||
| 43 | -EXAMPLE | ||
| 44 | -------- | ||
| 45 | -[source,c] | ||
| 46 | -------------------- | ||
| 47 | -uint8_t tab_bytes[MODBUS_MAX_PDU_LENGTH]; | ||
| 48 | - | ||
| 49 | -... | ||
| 50 | - | ||
| 51 | -rc = modbus_report_slave_id(ctx, MODBUS_MAX_PDU_LENGTH, tab_bytes); | ||
| 52 | -if (rc > 1) { | ||
| 53 | - printf("Run Status Indicator: %s\n", tab_bytes[1] ? "ON" : "OFF"); | ||
| 54 | -} | ||
| 55 | -------------------- | ||
| 56 | - | ||
| 57 | - | ||
| 58 | -AUTHORS | ||
| 59 | -------- | ||
| 60 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 61 | -<stephane.raimbault@gmail.com> |
doc/modbus_rtu_get_rts.txt deleted
| 1 | -modbus_rtu_get_rts(3) | ||
| 2 | -===================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_rtu_get_rts - get the current RTS mode in RTU | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_rtu_get_rts(modbus_t *'ctx');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_rtu_get_rts()* function shall get the current Request To Send mode | ||
| 18 | -of the libmodbus context _ctx_. The possible returned values are: | ||
| 19 | - | ||
| 20 | -* MODBUS_RTU_RTS_NONE | ||
| 21 | -* MODBUS_RTU_RTS_UP | ||
| 22 | -* MODBUS_RTU_RTS_DOWN | ||
| 23 | - | ||
| 24 | -This function can only be used with a context using a RTU backend. | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -RETURN VALUE | ||
| 28 | ------------- | ||
| 29 | -The function shall return the current RTS mode if successful. Otherwise it shall | ||
| 30 | -return -1 and set errno. | ||
| 31 | - | ||
| 32 | - | ||
| 33 | -ERRORS | ||
| 34 | ------- | ||
| 35 | -*EINVAL*:: | ||
| 36 | -The libmodbus backend is not RTU. | ||
| 37 | - | ||
| 38 | - | ||
| 39 | -SEE ALSO | ||
| 40 | --------- | ||
| 41 | -linkmb:modbus_rtu_set_rts[3] | ||
| 42 | - | ||
| 43 | - | ||
| 44 | -AUTHORS | ||
| 45 | -------- | ||
| 46 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 47 | -<stephane.raimbault@gmail.com> |
doc/modbus_rtu_get_rts_delay.txt deleted
| 1 | -modbus_rtu_get_rts_delay(3) | ||
| 2 | -=========================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_rtu_get_rts_delay - get the current RTS delay in RTU | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_rtu_get_rts_delay(modbus_t *'ctx');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | - | ||
| 18 | -The _modbus_rtu_get_rts_delay()_ function shall get the current Request To Send | ||
| 19 | -delay period of the libmodbus context 'ctx'. | ||
| 20 | - | ||
| 21 | -This function can only be used with a context using a RTU backend. | ||
| 22 | - | ||
| 23 | - | ||
| 24 | -RETURN VALUE | ||
| 25 | ------------- | ||
| 26 | -The _modbus_rtu_get_rts_delay()_ function shall return the current RTS delay in | ||
| 27 | -microseconds if successful. Otherwise it shall return -1 and set errno. | ||
| 28 | - | ||
| 29 | - | ||
| 30 | -ERRORS | ||
| 31 | ------- | ||
| 32 | -*EINVAL*:: | ||
| 33 | -The libmodbus backend is not RTU. | ||
| 34 | - | ||
| 35 | - | ||
| 36 | -SEE ALSO | ||
| 37 | --------- | ||
| 38 | -linkmb:modbus_rtu_set_rts_delay[3] | ||
| 39 | - | ||
| 40 | - | ||
| 41 | -AUTHORS | ||
| 42 | -------- | ||
| 43 | -Jimmy Bergström <jimmy@ekontroll.com> | ||
| 44 | - | ||
| 45 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 46 | -<stephane.raimbault@gmail.com> |
doc/modbus_rtu_get_serial_mode.txt deleted
| 1 | -modbus_rtu_get_serial_mode(3) | ||
| 2 | -============================= | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_rtu_get_serial_mode - get the current serial mode | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_rtu_get_serial_mode(modbus_t *'ctx');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_rtu_get_serial_mode()* function shall return the serial mode | ||
| 18 | -currently used by the libmodbus context: | ||
| 19 | - | ||
| 20 | -*MODBUS_RTU_RS232*:: the serial line is set for RS232 communication. RS-232 | ||
| 21 | - (Recommended Standard 232) is the traditional name for a series of standards | ||
| 22 | - for serial binary single-ended data and control signals connecting between a | ||
| 23 | - DTE (Data Terminal Equipment) and a DCE (Data Circuit-terminating | ||
| 24 | - Equipment). It is commonly used in computer serial ports | ||
| 25 | - | ||
| 26 | -*MODBUS_RTU_RS485*:: the serial line is set for RS485 communication. EIA-485, | ||
| 27 | - also known as TIA/EIA-485 or RS-485, is a standard defining the electrical | ||
| 28 | - characteristics of drivers and receivers for use in balanced digital multipoint | ||
| 29 | - systems. This standard is widely used for communications in industrial | ||
| 30 | - automation because it can be used effectively over long distances and in | ||
| 31 | - electrically noisy environments. | ||
| 32 | - | ||
| 33 | -This function is only available on Linux kernels 2.6.28 onwards and can only be | ||
| 34 | -used with a context using a RTU backend. | ||
| 35 | - | ||
| 36 | - | ||
| 37 | -RETURN VALUE | ||
| 38 | ------------- | ||
| 39 | -The function shall return `MODBUS_RTU_RS232` or `MODBUS_RTU_RS485` if | ||
| 40 | -successful. Otherwise it shall return -1 and set errno to one of the values | ||
| 41 | -defined below. | ||
| 42 | - | ||
| 43 | - | ||
| 44 | -ERRORS | ||
| 45 | ------- | ||
| 46 | -*EINVAL*:: | ||
| 47 | -The current libmodbus backend is not RTU. | ||
| 48 | - | ||
| 49 | - | ||
| 50 | -AUTHORS | ||
| 51 | -------- | ||
| 52 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 53 | -<stephane.raimbault@gmail.com> |
doc/modbus_rtu_set_custom_rts.txt deleted
| 1 | -modbus_rtu_set_custom_rts(3) | ||
| 2 | -============================ | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_rtu_set_custom_rts - set a function to be used for custom RTS implementation | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_rtu_set_custom_rts(modbus_t *'ctx', void (*'set_rts') (modbus_t *ctx, int on))* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The _modbus_rtu_set_custom_rts()_ function shall set a custom function to be | ||
| 18 | -called when the RTS pin is to be set before and after a transmission. By default | ||
| 19 | -this is set to an internal function that toggles the RTS pin using an ioctl | ||
| 20 | -call. | ||
| 21 | - | ||
| 22 | -Note that this function adheres to the RTS mode, the values MODBUS_RTU_RTS_UP or | ||
| 23 | -MODBUS_RTU_RTS_DOWN must be used for the function to be called. | ||
| 24 | - | ||
| 25 | -This function can only be used with a context using a RTU backend. | ||
| 26 | - | ||
| 27 | - | ||
| 28 | -RETURN VALUE | ||
| 29 | ------------- | ||
| 30 | -The _modbus_rtu_set_custom_rts()_ function shall return 0 if successful. | ||
| 31 | -Otherwise it shall return -1 and set errno to one of the values defined below. | ||
| 32 | - | ||
| 33 | - | ||
| 34 | -ERRORS | ||
| 35 | ------- | ||
| 36 | -*EINVAL*:: | ||
| 37 | -The libmodbus backend is not RTU. | ||
| 38 | - | ||
| 39 | - | ||
| 40 | -AUTHORS | ||
| 41 | -------- | ||
| 42 | -Jimmy Bergström <jimmy@ekontroll.com> | ||
| 43 | - | ||
| 44 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 45 | -<stephane.raimbault@gmail.com> |
doc/modbus_rtu_set_rts_delay.txt deleted
| 1 | -modbus_rtu_set_rts_delay(3) | ||
| 2 | -=========================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_rtu_set_rts_delay - set the RTS delay in RTU | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_rtu_set_rts_delay(modbus_t *'ctx', int 'us');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | - | ||
| 18 | -The _modbus_rtu_set_rts_delay()_ function shall set the Request To Send delay | ||
| 19 | -period of the libmodbus context 'ctx'. | ||
| 20 | - | ||
| 21 | -This function can only be used with a context using a RTU backend. | ||
| 22 | - | ||
| 23 | - | ||
| 24 | -RETURN VALUE | ||
| 25 | ------------- | ||
| 26 | -The _modbus_rtu_set_rts_delay()_ function shall return 0 if successful. | ||
| 27 | -Otherwise it shall return -1 and set errno. | ||
| 28 | - | ||
| 29 | - | ||
| 30 | -ERRORS | ||
| 31 | ------- | ||
| 32 | -*EINVAL*:: | ||
| 33 | -The libmodbus backend is not RTU or a negative delay was specified. | ||
| 34 | - | ||
| 35 | - | ||
| 36 | -SEE ALSO | ||
| 37 | --------- | ||
| 38 | -linkmb:modbus_rtu_get_rts_delay[3] | ||
| 39 | - | ||
| 40 | - | ||
| 41 | -AUTHORS | ||
| 42 | -------- | ||
| 43 | -Jimmy Bergström <jimmy@ekontroll.com> | ||
| 44 | - | ||
| 45 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 46 | -<stephane.raimbault@gmail.com> |
doc/modbus_rtu_set_serial_mode.txt deleted
| 1 | -modbus_rtu_set_serial_mode(3) | ||
| 2 | -============================= | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_rtu_set_serial_mode - set the serial mode | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_rtu_set_serial_mode(modbus_t *'ctx', int 'mode');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_rtu_set_serial_mode()* function shall set the selected serial | ||
| 18 | -mode: | ||
| 19 | - | ||
| 20 | -*MODBUS_RTU_RS232*:: the serial line is set for RS232 communication. RS-232 | ||
| 21 | - (Recommended Standard 232) is the traditional name for a series of standards | ||
| 22 | - for serial binary single-ended data and control signals connecting between a | ||
| 23 | - DTE (Data Terminal Equipment) and a DCE (Data Circuit-terminating | ||
| 24 | - Equipment). It is commonly used in computer serial ports | ||
| 25 | - | ||
| 26 | -*MODBUS_RTU_RS485*:: the serial line is set for RS485 communication. EIA-485, | ||
| 27 | - also known as TIA/EIA-485 or RS-485, is a standard defining the electrical | ||
| 28 | - characteristics of drivers and receivers for use in balanced digital multipoint | ||
| 29 | - systems. This standard is widely used for communications in industrial | ||
| 30 | - automation because it can be used effectively over long distances and in | ||
| 31 | - electrically noisy environments. | ||
| 32 | - | ||
| 33 | -This function is only supported on Linux kernels 2.6.28 onwards. | ||
| 34 | - | ||
| 35 | - | ||
| 36 | -RETURN VALUE | ||
| 37 | ------------- | ||
| 38 | -The function shall return 0 if successful. Otherwise it shall return -1 and set | ||
| 39 | -errno to one of the values defined below. | ||
| 40 | - | ||
| 41 | - | ||
| 42 | -ERRORS | ||
| 43 | ------- | ||
| 44 | -*EINVAL*:: | ||
| 45 | -The current libmodbus backend is not RTU. | ||
| 46 | - | ||
| 47 | -*ENOTSUP*:: | ||
| 48 | -The function is not supported on your platform. | ||
| 49 | - | ||
| 50 | -If the call to ioctl() fails, the error code of ioctl will be returned. | ||
| 51 | - | ||
| 52 | - | ||
| 53 | -AUTHORS | ||
| 54 | -------- | ||
| 55 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 56 | -<stephane.raimbault@gmail.com> |
doc/modbus_set_bits_from_byte.txt deleted
| 1 | -modbus_set_bits_from_byte(3) | ||
| 2 | -============================ | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_set_bits_from_byte - set many bits from a single byte value | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*void modbus_set_bits_from_byte(uint8_t *'dest', int 'index', const uint8_t 'value');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_set_bits_from_byte()* function shall set many bits from a single byte. | ||
| 18 | -All 8 bits from the byte _value_ will be written to _dest_ array starting at | ||
| 19 | -_index_ position. | ||
| 20 | - | ||
| 21 | - | ||
| 22 | -RETURN VALUE | ||
| 23 | ------------- | ||
| 24 | -There is no return values. | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -SEE ALSO | ||
| 28 | --------- | ||
| 29 | -linkmb:modbus_set_bits_from_byte[3] | ||
| 30 | -linkmb:modbus_set_bits_from_bytes[3] | ||
| 31 | - | ||
| 32 | - | ||
| 33 | -AUTHORS | ||
| 34 | -------- | ||
| 35 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 36 | -<stephane.raimbault@gmail.com> |
doc/modbus_set_bits_from_bytes.txt deleted
| 1 | -modbus_set_bits_from_bytes(3) | ||
| 2 | -============================ | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_set_bits_from_bytes - set many bits from an array of bytes | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*void modbus_set_bits_from_bytes(uint8_t *'dest', int 'index', unsigned int 'nb_bits', const uint8_t *'tab_byte');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_set_bits_from_bytes* function shall set bits by reading an array of | ||
| 18 | -bytes. All the bits of the bytes read from the first position of the array | ||
| 19 | -_tab_byte_ are written as bits in the _dest_ array starting at position _index_. | ||
| 20 | - | ||
| 21 | - | ||
| 22 | -RETURN VALUE | ||
| 23 | ------------- | ||
| 24 | -There is no return values. | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -SEE ALSO | ||
| 28 | --------- | ||
| 29 | -linkmb:modbus_set_bits_from_byte[3] | ||
| 30 | -linkmb:modbus_get_byte_from_bits[3] | ||
| 31 | - | ||
| 32 | - | ||
| 33 | -AUTHORS | ||
| 34 | -------- | ||
| 35 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 36 | -<stephane.raimbault@gmail.com> |
doc/modbus_set_byte_timeout.txt deleted
| 1 | -modbus_set_byte_timeout(3) | ||
| 2 | -========================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_set_byte_timeout - set timeout between bytes | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*void modbus_set_byte_timeout(modbus_t *'ctx', uint32_t 'to_sec', uint32_t 'to_usec');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_set_byte_timeout()* function shall set the timeout interval between | ||
| 18 | -two consecutive bytes of the same message. The timeout is an upper bound on the | ||
| 19 | -amount of time elapsed before *select()* returns, if the time elapsed is longer | ||
| 20 | -than the defined timeout, an `ETIMEDOUT` error will be raised by the | ||
| 21 | -function waiting for a response. | ||
| 22 | - | ||
| 23 | -The value of _to_usec_ argument must be in the range 0 to 999999. | ||
| 24 | - | ||
| 25 | -If both _to_sec_ and _to_usec_ are zero, this timeout will not be used at all. | ||
| 26 | -In this case, *modbus_set_response_timeout()* governs the entire handling of the | ||
| 27 | -response, the full confirmation response must be received before expiration of | ||
| 28 | -the response timeout. When a byte timeout is set, the response timeout is only | ||
| 29 | -used to wait for until the first byte of the response. | ||
| 30 | - | ||
| 31 | - | ||
| 32 | -RETURN VALUE | ||
| 33 | ------------- | ||
| 34 | -The function shall return 0 if successful. Otherwise it shall return -1 and set | ||
| 35 | -errno. | ||
| 36 | - | ||
| 37 | - | ||
| 38 | -ERRORS | ||
| 39 | ------- | ||
| 40 | -*EINVAL*:: | ||
| 41 | -The argument _ctx_ is NULL or _to_usec_ is larger than 999999. | ||
| 42 | - | ||
| 43 | - | ||
| 44 | -SEE ALSO | ||
| 45 | --------- | ||
| 46 | -linkmb:modbus_get_byte_timeout[3] | ||
| 47 | -linkmb:modbus_get_response_timeout[3] | ||
| 48 | -linkmb:modbus_set_response_timeout[3] | ||
| 49 | - | ||
| 50 | - | ||
| 51 | -AUTHORS | ||
| 52 | -------- | ||
| 53 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 54 | -<stephane.raimbault@gmail.com> |
doc/modbus_set_debug.txt deleted
| 1 | -modbus_set_debug(3) | ||
| 2 | -=================== | ||
| 3 | - | ||
| 4 | -NAME | ||
| 5 | ----- | ||
| 6 | -modbus_set_debug - set debug flag of the context | ||
| 7 | - | ||
| 8 | - | ||
| 9 | -SYNOPSIS | ||
| 10 | --------- | ||
| 11 | -*int modbus_set_debug(modbus_t *'ctx', int 'flag');* | ||
| 12 | - | ||
| 13 | - | ||
| 14 | -DESCRIPTION | ||
| 15 | ------------ | ||
| 16 | -The *modbus_set_debug()* function shall set the debug flag of the *modbus_t* | ||
| 17 | -context by using the argument _flag_. By default, the boolean flag is set to | ||
| 18 | -`FALSE`. When the _flag_ value is set to `TRUE`, many verbose messages are | ||
| 19 | -displayed on stdout and stderr. For example, this flag is useful to display the | ||
| 20 | -bytes of the Modbus messages. | ||
| 21 | - | ||
| 22 | -[verse] | ||
| 23 | -___________________ | ||
| 24 | -[00][14][00][00][00][06][12][03][00][6B][00][03] | ||
| 25 | -Waiting for a confirmation... | ||
| 26 | -<00><14><00><00><00><09><12><03><06><02><2B><00><00><00><00> | ||
| 27 | -___________________ | ||
| 28 | - | ||
| 29 | - | ||
| 30 | -RETURN VALUE | ||
| 31 | ------------- | ||
| 32 | -The function shall return 0 if successful. Otherwise it shall return -1 and set errno. | ||
| 33 | - | ||
| 34 | - | ||
| 35 | -AUTHORS | ||
| 36 | -------- | ||
| 37 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 38 | -<stephane.raimbault@gmail.com> |
doc/modbus_set_float.txt deleted
| 1 | -modbus_set_float(3) | ||
| 2 | -=================== | ||
| 3 | - | ||
| 4 | -NAME | ||
| 5 | ----- | ||
| 6 | -modbus_set_float - set a float value from 2 registers | ||
| 7 | - | ||
| 8 | - | ||
| 9 | -SYNOPSIS | ||
| 10 | --------- | ||
| 11 | -*void modbus_set_float(float 'f', uint16_t *'dest');* | ||
| 12 | - | ||
| 13 | -Warning, this function is *deprecated* since libmodbus v3.2.0 and has been | ||
| 14 | -replaced by *modbus_set_float_dcba()*. | ||
| 15 | - | ||
| 16 | -DESCRIPTION | ||
| 17 | ------------ | ||
| 18 | -The *modbus_set_float()* function shall set a float to 4 bytes in Modbus format | ||
| 19 | -(ABCD). The _dest_ array must be pointer on two 16 bits values to be able to | ||
| 20 | -store the full result of the conversion. | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -RETURN VALUE | ||
| 24 | ------------- | ||
| 25 | -There is no return values. | ||
| 26 | - | ||
| 27 | - | ||
| 28 | -SEE ALSO | ||
| 29 | --------- | ||
| 30 | -linkmb:modbus_get_float[3] | ||
| 31 | -linkmb:modbus_set_float_dcba[3] | ||
| 32 | - | ||
| 33 | -AUTHORS | ||
| 34 | -------- | ||
| 35 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 36 | -<stephane.raimbault@gmail.com> |
doc/modbus_set_float_abcd.txt deleted
| 1 | -modbus_set_float_abcd(3) | ||
| 2 | -======================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_set_float_abcd - set a float value in 2 registers using ABCD byte order | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*void modbus_set_float_abcd(float 'f', uint16_t *'dest');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_set_float_abcd()* function shall set a float to 4 bytes in usual | ||
| 18 | -Modbus format. The _dest_ array must be pointer on two 16 bits values to be able | ||
| 19 | -to store the full result of the conversion. | ||
| 20 | - | ||
| 21 | - | ||
| 22 | -RETURN VALUE | ||
| 23 | ------------- | ||
| 24 | -There is no return values. | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -SEE ALSO | ||
| 28 | --------- | ||
| 29 | -linkmb:modbus_get_float_abcd[3] | ||
| 30 | -linkmb:modbus_set_float_badc[3] | ||
| 31 | -linkmb:modbus_set_float_cdab[3] | ||
| 32 | -linkmb:modbus_set_float_dcba[3] | ||
| 33 | - | ||
| 34 | - | ||
| 35 | -AUTHORS | ||
| 36 | -------- | ||
| 37 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 38 | -<stephane.raimbault@gmail.com> |
doc/modbus_set_float_badc.txt deleted
| 1 | -modbus_set_float_badc(3) | ||
| 2 | -======================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_set_float_badc - set a float value in 2 registers using BADC byte order | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*void modbus_set_float_badc(float 'f', uint16_t *'dest');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_set_float_badc()* function shall set a float to 4 bytes in swapped | ||
| 18 | -bytes Modbus format (BADC instead of ABCD). The _dest_ array must be pointer on | ||
| 19 | -two 16 bits values to be able to store the full result of the conversion. | ||
| 20 | - | ||
| 21 | - | ||
| 22 | -RETURN VALUE | ||
| 23 | ------------- | ||
| 24 | -There is no return values. | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -SEE ALSO | ||
| 28 | --------- | ||
| 29 | -linkmb:modbus_get_float_badc[3] | ||
| 30 | -linkmb:modbus_set_float_abcd[3] | ||
| 31 | -linkmb:modbus_set_float_cdab[3] | ||
| 32 | -linkmb:modbus_set_float_dcba[3] | ||
| 33 | - | ||
| 34 | - | ||
| 35 | -AUTHORS | ||
| 36 | -------- | ||
| 37 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 38 | -<stephane.raimbault@gmail.com> |
doc/modbus_set_float_cdab.txt deleted
| 1 | -modbus_set_float_cdab(3) | ||
| 2 | -======================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_set_float_cdab - set a float value in 2 registers using CDAB byte order | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*void modbus_set_float_cdab(float 'f', uint16_t *'dest');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_set_float_cdab()* function shall set a float to 4 bytes in swapped | ||
| 18 | -words Modbus format (CDAB order instead of ABCD). The _dest_ array must be | ||
| 19 | -pointer on two 16 bits values to be able to store the full result of the | ||
| 20 | -conversion. | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -RETURN VALUE | ||
| 24 | ------------- | ||
| 25 | -There is no return values. | ||
| 26 | - | ||
| 27 | - | ||
| 28 | -SEE ALSO | ||
| 29 | --------- | ||
| 30 | -linkmb:modbus_get_float_cdab[3] | ||
| 31 | -linkmb:modbus_set_float_abcd[3] | ||
| 32 | -linkmb:modbus_set_float_badc[3] | ||
| 33 | -linkmb:modbus_set_float_dcba[3] | ||
| 34 | - | ||
| 35 | - | ||
| 36 | -AUTHORS | ||
| 37 | -------- | ||
| 38 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 39 | -<stephane.raimbault@gmail.com> |
doc/modbus_set_float_dcba.txt deleted
| 1 | -modbus_set_float_dcba(3) | ||
| 2 | -======================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_set_float_dcba - set a float value in 2 registers using DCBA byte order | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*void modbus_set_float_dcba(float 'f', uint16_t *'dest');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_set_float_dcba()* function shall set a float to 4 bytes in inverted | ||
| 18 | -Modbus format (DCBA order). The _dest_ array must be pointer on two 16 bits | ||
| 19 | -values to be able to store the full result of the conversion. | ||
| 20 | - | ||
| 21 | - | ||
| 22 | -RETURN VALUE | ||
| 23 | ------------- | ||
| 24 | -There is no return values. | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -SEE ALSO | ||
| 28 | --------- | ||
| 29 | -linkmb:modbus_get_float_dcba[3] | ||
| 30 | -linkmb:modbus_set_float[3] | ||
| 31 | -linkmb:modbus_get_float[3] | ||
| 32 | - | ||
| 33 | - | ||
| 34 | -AUTHORS | ||
| 35 | -------- | ||
| 36 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 37 | -<stephane.raimbault@gmail.com> |
doc/modbus_set_indication_timeout.txt deleted
| 1 | -modbus_set_indication_timeout(3) | ||
| 2 | -================================ | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_set_indication_timeout - set timeout between indications | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*void modbus_set_indication_timeout(modbus_t *'ctx', uint32_t 'to_sec', uint32_t 'to_usec');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_set_indication_timeout()* function shall set the timeout interval used by | ||
| 18 | -a server to wait for a request from a client. | ||
| 19 | - | ||
| 20 | -The value of _to_usec_ argument must be in the range 0 to 999999. | ||
| 21 | - | ||
| 22 | -If both _to_sec_ and _to_usec_ are zero, this timeout will not be used at all. | ||
| 23 | -In this case, the server will wait forever. | ||
| 24 | - | ||
| 25 | - | ||
| 26 | -RETURN VALUE | ||
| 27 | ------------- | ||
| 28 | -The function shall return 0 if successful. Otherwise it shall return -1 and set | ||
| 29 | -errno. | ||
| 30 | - | ||
| 31 | - | ||
| 32 | -ERRORS | ||
| 33 | ------- | ||
| 34 | -*EINVAL*:: | ||
| 35 | -The argument _ctx_ is NULL or _to_usec_ is larger than 1000000. | ||
| 36 | - | ||
| 37 | - | ||
| 38 | -SEE ALSO | ||
| 39 | --------- | ||
| 40 | -linkmb:modbus_get_indication_timeout[3] | ||
| 41 | -linkmb:modbus_get_response_timeout[3] | ||
| 42 | -linkmb:modbus_set_response_timeout[3] | ||
| 43 | - | ||
| 44 | - | ||
| 45 | -AUTHORS | ||
| 46 | -------- | ||
| 47 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 48 | -<stephane.raimbault@gmail.com> |
doc/modbus_set_response_timeout.txt deleted
| 1 | -modbus_set_response_timeout(3) | ||
| 2 | -============================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_set_response_timeout - set timeout for response | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_set_response_timeout(modbus_t *'ctx', uint32_t 'to_sec', uint32_t 'to_usec');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_set_response_timeout()* function shall set the timeout interval used | ||
| 18 | -to wait for a response. When a byte timeout is set, if elapsed time for the | ||
| 19 | -first byte of response is longer than the given timeout, an `ETIMEDOUT` error | ||
| 20 | -will be raised by the function waiting for a response. When byte timeout is | ||
| 21 | -disabled, the full confirmation response must be received before expiration of | ||
| 22 | -the response timeout. | ||
| 23 | - | ||
| 24 | -The value of _to_usec_ argument must be in the range 0 to 999999. | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -RETURN VALUE | ||
| 28 | ------------- | ||
| 29 | -The function shall return 0 if successful. Otherwise it shall return -1 and set | ||
| 30 | -errno. | ||
| 31 | - | ||
| 32 | - | ||
| 33 | -ERRORS | ||
| 34 | ------- | ||
| 35 | -*EINVAL*:: | ||
| 36 | -The argument _ctx_ is NULL, or both _to_sec_ and _to_usec_ are zero, or _to_usec_ | ||
| 37 | -is larger than 999999. | ||
| 38 | - | ||
| 39 | - | ||
| 40 | -EXAMPLE | ||
| 41 | -------- | ||
| 42 | -[source,c] | ||
| 43 | -------------------- | ||
| 44 | -uint32_t old_response_to_sec; | ||
| 45 | -uint32_t old_response_to_usec; | ||
| 46 | - | ||
| 47 | -/* Save original timeout */ | ||
| 48 | -modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); | ||
| 49 | - | ||
| 50 | -/* Define a new timeout of 200ms */ | ||
| 51 | -modbus_set_response_timeout(ctx, 0, 200000); | ||
| 52 | -------------------- | ||
| 53 | - | ||
| 54 | - | ||
| 55 | -SEE ALSO | ||
| 56 | --------- | ||
| 57 | -linkmb:modbus_get_response_timeout[3] | ||
| 58 | -linkmb:modbus_get_byte_timeout[3] | ||
| 59 | -linkmb:modbus_set_byte_timeout[3] | ||
| 60 | - | ||
| 61 | - | ||
| 62 | -AUTHORS | ||
| 63 | -------- | ||
| 64 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 65 | -<stephane.raimbault@gmail.com> |
doc/modbus_strerror.txt deleted
| 1 | -modbus_strerror(3) | ||
| 2 | -================= | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_strerror - return the error message | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*const char *modbus_strerror(int 'errnum');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_strerror()* function shall return a pointer to an error message | ||
| 18 | -string corresponding to the error number specified by the _errnum_ argument. As | ||
| 19 | -libmodbus defines additional error numbers over and above those defined by the | ||
| 20 | -operating system, applications should use *modbus_strerror()* in preference to | ||
| 21 | -the standard *strerror()* function. | ||
| 22 | - | ||
| 23 | - | ||
| 24 | -RETURN VALUE | ||
| 25 | ------------- | ||
| 26 | -The *modbus_strerror()* function shall return a pointer to an error message | ||
| 27 | -string. | ||
| 28 | - | ||
| 29 | - | ||
| 30 | -ERRORS | ||
| 31 | ------- | ||
| 32 | -No errors are defined. | ||
| 33 | - | ||
| 34 | - | ||
| 35 | -EXAMPLE | ||
| 36 | -------- | ||
| 37 | -.Display an error message when a Modbus connection cannot be established | ||
| 38 | -[source,c] | ||
| 39 | -------------------- | ||
| 40 | -if (modbus_connect(ctx) == -1) { | ||
| 41 | - fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); | ||
| 42 | - abort(); | ||
| 43 | -} | ||
| 44 | -------------------- | ||
| 45 | - | ||
| 46 | -SEE ALSO | ||
| 47 | --------- | ||
| 48 | -linkmb:libmodbus | ||
| 49 | - | ||
| 50 | - | ||
| 51 | -AUTHORS | ||
| 52 | -------- | ||
| 53 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 54 | -<stephane.raimbault@gmail.com> |
doc/modbus_tcp_accept.txt deleted
| 1 | -modbus_tcp_accept(3) | ||
| 2 | -==================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_tcp_accept - accept a new connection on a TCP Modbus socket (IPv4) | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_tcp_accept(modbus_t *'ctx', int *'s);* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_tcp_accept()* function shall extract the first connection on the | ||
| 18 | -queue of pending connections, create a new socket and store it in libmodbus | ||
| 19 | -context given in argument. If available, _accept4()_ with `SOCK_CLOEXEC` will be | ||
| 20 | -called instead of *accept()*. | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -RETURN VALUE | ||
| 24 | ------------- | ||
| 25 | -The function shall return a new socket if successful. | ||
| 26 | -Otherwise it shall return -1 and set errno. | ||
| 27 | - | ||
| 28 | - | ||
| 29 | -EXAMPLE | ||
| 30 | -------- | ||
| 31 | -For detailed example, see unit-test-server.c source file in tests directory. | ||
| 32 | - | ||
| 33 | -[source,c] | ||
| 34 | -------------------- | ||
| 35 | -... | ||
| 36 | - | ||
| 37 | -ctx = modbus_new_tcp("127.0.0.1", 502); | ||
| 38 | -s = modbus_tcp_listen(ctx, 1); | ||
| 39 | -modbus_tcp_accept(ctx, &s); | ||
| 40 | - | ||
| 41 | -... | ||
| 42 | - | ||
| 43 | -close(s) | ||
| 44 | -modbus_free(ctx); | ||
| 45 | -------------------- | ||
| 46 | - | ||
| 47 | -SEE ALSO | ||
| 48 | --------- | ||
| 49 | -linkmb:modbus_tcp_pi_accept[3] | ||
| 50 | -linkmb:modbus_tcp_listen[3] | ||
| 51 | -linkmb:modbus_tcp_pi_listen[3] | ||
| 52 | - | ||
| 53 | -AUTHORS | ||
| 54 | -------- | ||
| 55 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 56 | -<stephane.raimbault@gmail.com> |
doc/modbus_tcp_pi_accept.txt deleted
| 1 | -modbus_tcp_pi_accept(3) | ||
| 2 | -======================= | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_tcp_pi_accept - accept a new connection on a TCP PI Modbus socket (IPv6) | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_tcp_pi_accept(modbus_t *'ctx', int *'s);* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_tcp_pi_accept()* function shall extract the first connection on the | ||
| 18 | -queue of pending connections, create a new socket and store it in libmodbus | ||
| 19 | -context given in argument. If available, _accept4()_ with `SOCK_CLOEXEC` will be | ||
| 20 | -called instead of *accept()*. | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -RETURN VALUE | ||
| 24 | ------------- | ||
| 25 | -The function shall return a new socket if successful. | ||
| 26 | -Otherwise it shall return -1 and set errno. | ||
| 27 | - | ||
| 28 | - | ||
| 29 | -EXAMPLE | ||
| 30 | -------- | ||
| 31 | -For detailed example, see unit-test-server.c source file in tests directory. | ||
| 32 | - | ||
| 33 | -[source,c] | ||
| 34 | -------------------- | ||
| 35 | -... | ||
| 36 | - | ||
| 37 | -ctx = modbus_new_tcp_pi("::0", 502); | ||
| 38 | -s = modbus_tcp_pi_listen(ctx, 1); | ||
| 39 | -modbus_tcp_pi_accept(ctx, &s); | ||
| 40 | - | ||
| 41 | -... | ||
| 42 | - | ||
| 43 | -close(s) | ||
| 44 | -modbus_free(ctx); | ||
| 45 | -------------------- | ||
| 46 | - | ||
| 47 | -SEE ALSO | ||
| 48 | --------- | ||
| 49 | -linkmb:modbus_tcp_pi_accept[3] | ||
| 50 | -linkmb:modbus_tcp_listen[3] | ||
| 51 | -linkmb:modbus_tcp_pi_listen[3] | ||
| 52 | - | ||
| 53 | -AUTHORS | ||
| 54 | -------- | ||
| 55 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 56 | -<stephane.raimbault@gmail.com> |
doc/modbus_tcp_pi_listen.txt deleted
| 1 | -modbus_tcp_pi_listen(3) | ||
| 2 | -======================= | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_tcp_pi_listen - create and listen a TCP PI Modbus socket (IPv6) | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_tcp_pi_listen(modbus_t *'ctx', int 'nb_connection');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_tcp_pi_listen()* function shall create a socket and listen to | ||
| 18 | -maximum _nb_connection_ incoming connections on the specified nodes. The | ||
| 19 | -context *ctx* must be allocated and initialized with linkmb:modbus_new_tcp_pi[3] | ||
| 20 | -before to set the node to listen, if node is set to NULL or '0.0.0.0', any addresses will be | ||
| 21 | -listen. | ||
| 22 | - | ||
| 23 | - | ||
| 24 | -RETURN VALUE | ||
| 25 | ------------- | ||
| 26 | -The function shall return a new socket if successful. Otherwise it shall return | ||
| 27 | --1 and set errno. | ||
| 28 | - | ||
| 29 | - | ||
| 30 | -EXAMPLE | ||
| 31 | -------- | ||
| 32 | - | ||
| 33 | -For detailed examples, see source files in tests directory: | ||
| 34 | - | ||
| 35 | -- unit-test-server.c, simple but handle only one connection | ||
| 36 | - | ||
| 37 | -[source,c] | ||
| 38 | -------------------- | ||
| 39 | -... | ||
| 40 | - | ||
| 41 | -ctx = modbus_new_tcp_pi("::0", "502"); | ||
| 42 | -s = modbus_tcp_pi_listen(ctx, 1); | ||
| 43 | -modbus_tcp_pi_accept(ctx, &s); | ||
| 44 | - | ||
| 45 | -for (;;) { | ||
| 46 | - rc = modbus_receive(ctx, query); | ||
| 47 | - modbus_replay(ctx, query, rc, mb_mapping); | ||
| 48 | -} | ||
| 49 | -... | ||
| 50 | - | ||
| 51 | -mclose(s); | ||
| 52 | -modbus_free(ctx); | ||
| 53 | -------------------- | ||
| 54 | - | ||
| 55 | -- bandwidth-server-many-up.c, handles several connections at once | ||
| 56 | - | ||
| 57 | - | ||
| 58 | -SEE ALSO | ||
| 59 | --------- | ||
| 60 | -linkmb:modbus_new_tcp_pi[3] | ||
| 61 | -linkmb:modbus_tcp_pi_accept[3] | ||
| 62 | -linkmb:modbus_tcp_listen[3] | ||
| 63 | - | ||
| 64 | -AUTHORS | ||
| 65 | -------- | ||
| 66 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 67 | -<stephane.raimbault@gmail.com> |
doc/modbus_write_and_read_registers.txt deleted
| 1 | -modbus_write_and_read_registers(3) | ||
| 2 | -================================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_write_and_read_registers - write and read many registers in a single transaction | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_write_and_read_registers(modbus_t *'ctx', int 'write_addr', int 'write_nb', const uint16_t *'src', int 'read_addr', int 'read_nb', const uint16_t *'dest');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_write_and_read_registers()* function shall write the content of the | ||
| 18 | -_write_nb_ holding registers from the array 'src' to the address _write_addr_ of | ||
| 19 | -the remote device then shall read the content of the _read_nb_ holding registers | ||
| 20 | -to the address _read_addr_ of the remote device. The result of reading is stored | ||
| 21 | -in _dest_ array as word values (16 bits). | ||
| 22 | - | ||
| 23 | -You must take care to allocate enough memory to store the results in _dest_ | ||
| 24 | -(at least _nb_ * sizeof(uint16_t)). | ||
| 25 | - | ||
| 26 | -The function uses the Modbus function code 0x17 (write/read registers). | ||
| 27 | - | ||
| 28 | - | ||
| 29 | -RETURN VALUE | ||
| 30 | ------------- | ||
| 31 | -The function shall return the number of read registers if successful. Otherwise | ||
| 32 | -it shall return -1 and set errno. | ||
| 33 | - | ||
| 34 | - | ||
| 35 | -ERRORS | ||
| 36 | ------- | ||
| 37 | -*EMBMDATA*:: | ||
| 38 | -Too many registers requested, Too many registers to write | ||
| 39 | - | ||
| 40 | - | ||
| 41 | -SEE ALSO | ||
| 42 | --------- | ||
| 43 | -linkmb:modbus_read_registers[3] | ||
| 44 | -linkmb:modbus_write_register[3] | ||
| 45 | -linkmb:modbus_write_registers[3] | ||
| 46 | - | ||
| 47 | - | ||
| 48 | -AUTHORS | ||
| 49 | -------- | ||
| 50 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 51 | -<stephane.raimbault@gmail.com> |
doc/modbus_write_bit.txt deleted
| 1 | -modbus_write_bit(3) | ||
| 2 | -=================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_write_bit - write a single bit | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_write_bit(modbus_t *'ctx', int 'addr', int 'status');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_write_bit()* function shall write the status of _status_ at the | ||
| 18 | -address _addr_ of the remote device. The value must be set to `TRUE` or `FALSE`. | ||
| 19 | - | ||
| 20 | -The function uses the Modbus function code 0x05 (force single coil). | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -RETURN VALUE | ||
| 24 | ------------- | ||
| 25 | -The function shall return 1 if successful. Otherwise it shall return -1 and set | ||
| 26 | -errno. | ||
| 27 | - | ||
| 28 | - | ||
| 29 | -SEE ALSO | ||
| 30 | --------- | ||
| 31 | -linkmb:modbus_read_bits[3] | ||
| 32 | -linkmb:modbus_write_bits[3] | ||
| 33 | - | ||
| 34 | - | ||
| 35 | -AUTHORS | ||
| 36 | -------- | ||
| 37 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 38 | -<stephane.raimbault@gmail.com> |
doc/modbus_write_bits.txt deleted
| 1 | -modbus_write_bits(3) | ||
| 2 | -==================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_write_bits - write many bits | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_write_bits(modbus_t *'ctx', int 'addr', int 'nb', const uint8_t *'src');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_write_bits()* function shall write the status of the _nb_ bits | ||
| 18 | -(coils) from _src_ at the address _addr_ of the remote device. The | ||
| 19 | -_src_ array must contains bytes set to `TRUE` or `FALSE`. | ||
| 20 | - | ||
| 21 | -The function uses the Modbus function code 0x0F (force multiple coils). | ||
| 22 | - | ||
| 23 | - | ||
| 24 | -RETURN VALUE | ||
| 25 | ------------- | ||
| 26 | -The function shall return the number of written bits if successful. Otherwise it | ||
| 27 | -shall return -1 and set errno. | ||
| 28 | - | ||
| 29 | - | ||
| 30 | -ERRORS | ||
| 31 | ------- | ||
| 32 | -*EMBMDATA*:: | ||
| 33 | -Writing too many bits | ||
| 34 | - | ||
| 35 | - | ||
| 36 | -SEE ALSO | ||
| 37 | --------- | ||
| 38 | -linkmb:modbus_read_bits[3] | ||
| 39 | -linkmb:modbus_write_bit[3] | ||
| 40 | - | ||
| 41 | - | ||
| 42 | -AUTHORS | ||
| 43 | -------- | ||
| 44 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 45 | -<stephane.raimbault@gmail.com> |
doc/modbus_write_register.txt deleted
| 1 | -modbus_write_register(3) | ||
| 2 | -======================== | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_write_register - write a single register | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_write_register(modbus_t *'ctx', int 'addr', const uint16_t 'value');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_write_register()* function shall write the value of _value_ | ||
| 18 | -holding registers at the address _addr_ of the remote device. | ||
| 19 | - | ||
| 20 | -The function uses the Modbus function code 0x06 (preset single register). | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -RETURN VALUE | ||
| 24 | ------------- | ||
| 25 | -The function shall return 1 if successful. Otherwise it shall return -1 and set | ||
| 26 | -errno. | ||
| 27 | - | ||
| 28 | - | ||
| 29 | -SEE ALSO | ||
| 30 | --------- | ||
| 31 | -linkmb:modbus_read_registers[3] | ||
| 32 | -linkmb:modbus_write_registers[3] | ||
| 33 | - | ||
| 34 | - | ||
| 35 | -AUTHORS | ||
| 36 | -------- | ||
| 37 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 38 | -<stephane.raimbault@gmail.com> |
doc/modbus_write_registers.txt deleted
| 1 | -modbus_write_registers(3) | ||
| 2 | -========================= | ||
| 3 | - | ||
| 4 | - | ||
| 5 | -NAME | ||
| 6 | ----- | ||
| 7 | -modbus_write_registers - write many registers | ||
| 8 | - | ||
| 9 | - | ||
| 10 | -SYNOPSIS | ||
| 11 | --------- | ||
| 12 | -*int modbus_write_registers(modbus_t *'ctx', int 'addr', int 'nb', const uint16_t *'src');* | ||
| 13 | - | ||
| 14 | - | ||
| 15 | -DESCRIPTION | ||
| 16 | ------------ | ||
| 17 | -The *modbus_write_registers()* function shall write the content of the _nb_ | ||
| 18 | -holding registers from the array _src_ at address _addr_ of the remote device. | ||
| 19 | - | ||
| 20 | -The function uses the Modbus function code 0x10 (preset multiple registers). | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -RETURN VALUE | ||
| 24 | ------------- | ||
| 25 | -The function shall return the number of written registers if | ||
| 26 | -successful. Otherwise it shall return -1 and set errno. | ||
| 27 | - | ||
| 28 | - | ||
| 29 | -SEE ALSO | ||
| 30 | --------- | ||
| 31 | -linkmb:modbus_write_register[3] | ||
| 32 | -linkmb:modbus_read_registers[3] | ||
| 33 | - | ||
| 34 | - | ||
| 35 | -AUTHORS | ||
| 36 | -------- | ||
| 37 | -The libmodbus documentation was written by Stéphane Raimbault | ||
| 38 | -<stephane.raimbault@gmail.com> |
docs/assets/client-sensors.excalidraw
0 → 100644
| 1 | +{ | ||
| 2 | + "type": "excalidraw", | ||
| 3 | + "version": 2, | ||
| 4 | + "source": "https://excalidraw.com", | ||
| 5 | + "elements": [ | ||
| 6 | + { | ||
| 7 | + "type": "rectangle", | ||
| 8 | + "version": 473, | ||
| 9 | + "versionNonce": 1256506895, | ||
| 10 | + "isDeleted": false, | ||
| 11 | + "id": "ox1Blt2bzl0onmQfB7ZAN", | ||
| 12 | + "fillStyle": "hachure", | ||
| 13 | + "strokeWidth": 1, | ||
| 14 | + "strokeStyle": "solid", | ||
| 15 | + "roughness": 1, | ||
| 16 | + "opacity": 100, | ||
| 17 | + "angle": 0, | ||
| 18 | + "x": 827.69921875, | ||
| 19 | + "y": 210.68359375, | ||
| 20 | + "strokeColor": "#000000", | ||
| 21 | + "backgroundColor": "transparent", | ||
| 22 | + "width": 251.7109375, | ||
| 23 | + "height": 259.47265625, | ||
| 24 | + "seed": 1508024704, | ||
| 25 | + "groupIds": [], | ||
| 26 | + "strokeSharpness": "sharp", | ||
| 27 | + "boundElements": [ | ||
| 28 | + { | ||
| 29 | + "id": "sE5xq9Fz5VDTWcJGhJizg", | ||
| 30 | + "type": "arrow" | ||
| 31 | + }, | ||
| 32 | + { | ||
| 33 | + "id": "HZoAI_wR8CyRR9fVaFwSl", | ||
| 34 | + "type": "arrow" | ||
| 35 | + } | ||
| 36 | + ], | ||
| 37 | + "updated": 1660298248381, | ||
| 38 | + "link": null, | ||
| 39 | + "locked": false | ||
| 40 | + }, | ||
| 41 | + { | ||
| 42 | + "type": "text", | ||
| 43 | + "version": 585, | ||
| 44 | + "versionNonce": 720617423, | ||
| 45 | + "isDeleted": false, | ||
| 46 | + "id": "rjHz2X8U0ZDEyckj_tTSw", | ||
| 47 | + "fillStyle": "hachure", | ||
| 48 | + "strokeWidth": 1, | ||
| 49 | + "strokeStyle": "solid", | ||
| 50 | + "roughness": 1, | ||
| 51 | + "opacity": 100, | ||
| 52 | + "angle": 0, | ||
| 53 | + "x": 854.0546875, | ||
| 54 | + "y": 287.16015625, | ||
| 55 | + "strokeColor": "#000000", | ||
| 56 | + "backgroundColor": "transparent", | ||
| 57 | + "width": 199, | ||
| 58 | + "height": 160, | ||
| 59 | + "seed": 2100367744, | ||
| 60 | + "groupIds": [], | ||
| 61 | + "strokeSharpness": "sharp", | ||
| 62 | + "boundElements": [ | ||
| 63 | + { | ||
| 64 | + "id": "vJNRjoY0dZcqOBw5RzuHn", | ||
| 65 | + "type": "arrow" | ||
| 66 | + } | ||
| 67 | + ], | ||
| 68 | + "updated": 1660298281789, | ||
| 69 | + "link": null, | ||
| 70 | + "locked": false, | ||
| 71 | + "fontSize": 16, | ||
| 72 | + "fontFamily": 1, | ||
| 73 | + "text": "Reads temperatures\nfrom various\nModbus sensors (servers)\n\nS1: read index 0 -> 28\nS2: read index 0 -> 26\n...\n", | ||
| 74 | + "baseline": 154, | ||
| 75 | + "textAlign": "left", | ||
| 76 | + "verticalAlign": "top", | ||
| 77 | + "containerId": null, | ||
| 78 | + "originalText": "Reads temperatures\nfrom various\nModbus sensors (servers)\n\nS1: read index 0 -> 28\nS2: read index 0 -> 26\n...\n" | ||
| 79 | + }, | ||
| 80 | + { | ||
| 81 | + "type": "rectangle", | ||
| 82 | + "version": 534, | ||
| 83 | + "versionNonce": 2127380463, | ||
| 84 | + "isDeleted": false, | ||
| 85 | + "id": "mDgu1gSg34HbU-NAHPB30", | ||
| 86 | + "fillStyle": "hachure", | ||
| 87 | + "strokeWidth": 1, | ||
| 88 | + "strokeStyle": "solid", | ||
| 89 | + "roughness": 1, | ||
| 90 | + "opacity": 100, | ||
| 91 | + "angle": 0, | ||
| 92 | + "x": 420.2109375, | ||
| 93 | + "y": 212.580078125, | ||
| 94 | + "strokeColor": "#000000", | ||
| 95 | + "backgroundColor": "transparent", | ||
| 96 | + "width": 216.16406250000006, | ||
| 97 | + "height": 172.06640624999997, | ||
| 98 | + "seed": 1336837760, | ||
| 99 | + "groupIds": [], | ||
| 100 | + "strokeSharpness": "sharp", | ||
| 101 | + "boundElements": [ | ||
| 102 | + { | ||
| 103 | + "id": "sE5xq9Fz5VDTWcJGhJizg", | ||
| 104 | + "type": "arrow" | ||
| 105 | + } | ||
| 106 | + ], | ||
| 107 | + "updated": 1660298020282, | ||
| 108 | + "link": null, | ||
| 109 | + "locked": false | ||
| 110 | + }, | ||
| 111 | + { | ||
| 112 | + "type": "text", | ||
| 113 | + "version": 653, | ||
| 114 | + "versionNonce": 2127484513, | ||
| 115 | + "isDeleted": false, | ||
| 116 | + "id": "UxvTnld8qh188IzV4uJ2q", | ||
| 117 | + "fillStyle": "hachure", | ||
| 118 | + "strokeWidth": 1, | ||
| 119 | + "strokeStyle": "solid", | ||
| 120 | + "roughness": 1, | ||
| 121 | + "opacity": 100, | ||
| 122 | + "angle": 0, | ||
| 123 | + "x": 443.79296875, | ||
| 124 | + "y": 286.3515625, | ||
| 125 | + "strokeColor": "#000000", | ||
| 126 | + "backgroundColor": "transparent", | ||
| 127 | + "width": 178, | ||
| 128 | + "height": 80, | ||
| 129 | + "seed": 759374208, | ||
| 130 | + "groupIds": [], | ||
| 131 | + "strokeSharpness": "sharp", | ||
| 132 | + "boundElements": [], | ||
| 133 | + "updated": 1660298185311, | ||
| 134 | + "link": null, | ||
| 135 | + "locked": false, | ||
| 136 | + "fontSize": 16, | ||
| 137 | + "fontFamily": 1, | ||
| 138 | + "text": "Measures temperature\nand hygrometry:\n0: 28°C\n1: 32% ", | ||
| 139 | + "baseline": 74, | ||
| 140 | + "textAlign": "left", | ||
| 141 | + "verticalAlign": "top", | ||
| 142 | + "containerId": null, | ||
| 143 | + "originalText": "Measures temperature\nand hygrometry:\n0: 28°C\n1: 32% " | ||
| 144 | + }, | ||
| 145 | + { | ||
| 146 | + "type": "text", | ||
| 147 | + "version": 349, | ||
| 148 | + "versionNonce": 1469666511, | ||
| 149 | + "isDeleted": false, | ||
| 150 | + "id": "F6UUk6_B6uALmjxcHLYw4", | ||
| 151 | + "fillStyle": "hachure", | ||
| 152 | + "strokeWidth": 1, | ||
| 153 | + "strokeStyle": "solid", | ||
| 154 | + "roughness": 1, | ||
| 155 | + "opacity": 100, | ||
| 156 | + "angle": 0, | ||
| 157 | + "x": 488.19921875, | ||
| 158 | + "y": 237.921875, | ||
| 159 | + "strokeColor": "#000000", | ||
| 160 | + "backgroundColor": "transparent", | ||
| 161 | + "width": 79, | ||
| 162 | + "height": 25, | ||
| 163 | + "seed": 354006656, | ||
| 164 | + "groupIds": [], | ||
| 165 | + "strokeSharpness": "sharp", | ||
| 166 | + "boundElements": [], | ||
| 167 | + "updated": 1660298032950, | ||
| 168 | + "link": null, | ||
| 169 | + "locked": false, | ||
| 170 | + "fontSize": 20, | ||
| 171 | + "fontFamily": 1, | ||
| 172 | + "text": "Sensor 1", | ||
| 173 | + "baseline": 18, | ||
| 174 | + "textAlign": "left", | ||
| 175 | + "verticalAlign": "top", | ||
| 176 | + "containerId": null, | ||
| 177 | + "originalText": "Sensor 1" | ||
| 178 | + }, | ||
| 179 | + { | ||
| 180 | + "type": "text", | ||
| 181 | + "version": 224, | ||
| 182 | + "versionNonce": 864770191, | ||
| 183 | + "isDeleted": false, | ||
| 184 | + "id": "v7q2uvVFHZBvjr-y_ZJKl", | ||
| 185 | + "fillStyle": "hachure", | ||
| 186 | + "strokeWidth": 1, | ||
| 187 | + "strokeStyle": "solid", | ||
| 188 | + "roughness": 1, | ||
| 189 | + "opacity": 100, | ||
| 190 | + "angle": 0, | ||
| 191 | + "x": 884.5546875, | ||
| 192 | + "y": 238.328125, | ||
| 193 | + "strokeColor": "#000000", | ||
| 194 | + "backgroundColor": "transparent", | ||
| 195 | + "width": 150, | ||
| 196 | + "height": 25, | ||
| 197 | + "seed": 2108436864, | ||
| 198 | + "groupIds": [], | ||
| 199 | + "strokeSharpness": "sharp", | ||
| 200 | + "boundElements": [], | ||
| 201 | + "updated": 1660299132232, | ||
| 202 | + "link": null, | ||
| 203 | + "locked": false, | ||
| 204 | + "fontSize": 20, | ||
| 205 | + "fontFamily": 1, | ||
| 206 | + "text": "libmodbus client", | ||
| 207 | + "baseline": 18, | ||
| 208 | + "textAlign": "left", | ||
| 209 | + "verticalAlign": "top", | ||
| 210 | + "containerId": null, | ||
| 211 | + "originalText": "libmodbus client" | ||
| 212 | + }, | ||
| 213 | + { | ||
| 214 | + "type": "arrow", | ||
| 215 | + "version": 925, | ||
| 216 | + "versionNonce": 27208751, | ||
| 217 | + "isDeleted": false, | ||
| 218 | + "id": "sE5xq9Fz5VDTWcJGhJizg", | ||
| 219 | + "fillStyle": "hachure", | ||
| 220 | + "strokeWidth": 1, | ||
| 221 | + "strokeStyle": "solid", | ||
| 222 | + "roughness": 1, | ||
| 223 | + "opacity": 100, | ||
| 224 | + "angle": 0, | ||
| 225 | + "x": 656.03125, | ||
| 226 | + "y": 313.29799967005374, | ||
| 227 | + "strokeColor": "#000000", | ||
| 228 | + "backgroundColor": "transparent", | ||
| 229 | + "width": 154.05078125, | ||
| 230 | + "height": 8.294130761394001, | ||
| 231 | + "seed": 455209344, | ||
| 232 | + "groupIds": [], | ||
| 233 | + "strokeSharpness": "round", | ||
| 234 | + "boundElements": [], | ||
| 235 | + "updated": 1660298248381, | ||
| 236 | + "link": null, | ||
| 237 | + "locked": false, | ||
| 238 | + "startBinding": { | ||
| 239 | + "elementId": "mDgu1gSg34HbU-NAHPB30", | ||
| 240 | + "focus": 0.08648410639065775, | ||
| 241 | + "gap": 19.65625 | ||
| 242 | + }, | ||
| 243 | + "endBinding": { | ||
| 244 | + "elementId": "ox1Blt2bzl0onmQfB7ZAN", | ||
| 245 | + "focus": 0.08133464876815498, | ||
| 246 | + "gap": 17.6171875 | ||
| 247 | + }, | ||
| 248 | + "lastCommittedPoint": null, | ||
| 249 | + "startArrowhead": null, | ||
| 250 | + "endArrowhead": "arrow", | ||
| 251 | + "points": [ | ||
| 252 | + [ | ||
| 253 | + 0, | ||
| 254 | + 0 | ||
| 255 | + ], | ||
| 256 | + [ | ||
| 257 | + 154.05078125, | ||
| 258 | + 8.294130761394001 | ||
| 259 | + ] | ||
| 260 | + ] | ||
| 261 | + }, | ||
| 262 | + { | ||
| 263 | + "type": "text", | ||
| 264 | + "version": 709, | ||
| 265 | + "versionNonce": 650449167, | ||
| 266 | + "isDeleted": false, | ||
| 267 | + "id": "Q6P32mRyop5JlKGPB3tei", | ||
| 268 | + "fillStyle": "hachure", | ||
| 269 | + "strokeWidth": 1, | ||
| 270 | + "strokeStyle": "solid", | ||
| 271 | + "roughness": 1, | ||
| 272 | + "opacity": 100, | ||
| 273 | + "angle": 5.552321937284518, | ||
| 274 | + "x": 679.345703125, | ||
| 275 | + "y": 433.1444738051471, | ||
| 276 | + "strokeColor": "#000000", | ||
| 277 | + "backgroundColor": "transparent", | ||
| 278 | + "width": 79, | ||
| 279 | + "height": 15, | ||
| 280 | + "seed": 1091054019, | ||
| 281 | + "groupIds": [], | ||
| 282 | + "strokeSharpness": "sharp", | ||
| 283 | + "boundElements": [], | ||
| 284 | + "updated": 1660298261423, | ||
| 285 | + "link": null, | ||
| 286 | + "locked": false, | ||
| 287 | + "fontSize": 11.542968749999993, | ||
| 288 | + "fontFamily": 1, | ||
| 289 | + "text": "TCP or serial", | ||
| 290 | + "baseline": 10, | ||
| 291 | + "textAlign": "left", | ||
| 292 | + "verticalAlign": "top", | ||
| 293 | + "containerId": null, | ||
| 294 | + "originalText": "TCP or serial" | ||
| 295 | + }, | ||
| 296 | + { | ||
| 297 | + "type": "text", | ||
| 298 | + "version": 707, | ||
| 299 | + "versionNonce": 1999616833, | ||
| 300 | + "isDeleted": false, | ||
| 301 | + "id": "vETmEnYJoC4MKv7ysqjAv", | ||
| 302 | + "fillStyle": "hachure", | ||
| 303 | + "strokeWidth": 1, | ||
| 304 | + "strokeStyle": "solid", | ||
| 305 | + "roughness": 1, | ||
| 306 | + "opacity": 100, | ||
| 307 | + "angle": 0.06779103263247777, | ||
| 308 | + "x": 683.3417968749999, | ||
| 309 | + "y": 281.21582031250006, | ||
| 310 | + "strokeColor": "#000000", | ||
| 311 | + "backgroundColor": "transparent", | ||
| 312 | + "width": 79, | ||
| 313 | + "height": 15, | ||
| 314 | + "seed": 1043479501, | ||
| 315 | + "groupIds": [], | ||
| 316 | + "strokeSharpness": "sharp", | ||
| 317 | + "boundElements": [], | ||
| 318 | + "updated": 1660298255264, | ||
| 319 | + "link": null, | ||
| 320 | + "locked": false, | ||
| 321 | + "fontSize": 11.542968749999993, | ||
| 322 | + "fontFamily": 1, | ||
| 323 | + "text": "TCP or serial", | ||
| 324 | + "baseline": 10, | ||
| 325 | + "textAlign": "left", | ||
| 326 | + "verticalAlign": "top", | ||
| 327 | + "containerId": null, | ||
| 328 | + "originalText": "TCP or serial" | ||
| 329 | + }, | ||
| 330 | + { | ||
| 331 | + "type": "rectangle", | ||
| 332 | + "version": 587, | ||
| 333 | + "versionNonce": 85990017, | ||
| 334 | + "isDeleted": false, | ||
| 335 | + "id": "pHhCP3DIU5fE4v3yi3obG", | ||
| 336 | + "fillStyle": "hachure", | ||
| 337 | + "strokeWidth": 1, | ||
| 338 | + "strokeStyle": "solid", | ||
| 339 | + "roughness": 1, | ||
| 340 | + "opacity": 100, | ||
| 341 | + "angle": 0, | ||
| 342 | + "x": 426.513671875, | ||
| 343 | + "y": 424.2646484375, | ||
| 344 | + "strokeColor": "#000000", | ||
| 345 | + "backgroundColor": "transparent", | ||
| 346 | + "width": 216.16406250000006, | ||
| 347 | + "height": 172.06640624999997, | ||
| 348 | + "seed": 1733016847, | ||
| 349 | + "groupIds": [], | ||
| 350 | + "strokeSharpness": "sharp", | ||
| 351 | + "boundElements": [ | ||
| 352 | + { | ||
| 353 | + "id": "sE5xq9Fz5VDTWcJGhJizg", | ||
| 354 | + "type": "arrow" | ||
| 355 | + }, | ||
| 356 | + { | ||
| 357 | + "id": "HZoAI_wR8CyRR9fVaFwSl", | ||
| 358 | + "type": "arrow" | ||
| 359 | + } | ||
| 360 | + ], | ||
| 361 | + "updated": 1660298157321, | ||
| 362 | + "link": null, | ||
| 363 | + "locked": false | ||
| 364 | + }, | ||
| 365 | + { | ||
| 366 | + "type": "text", | ||
| 367 | + "version": 708, | ||
| 368 | + "versionNonce": 1824105825, | ||
| 369 | + "isDeleted": false, | ||
| 370 | + "id": "3oXICnKHoOzNPyb-PxNbt", | ||
| 371 | + "fillStyle": "hachure", | ||
| 372 | + "strokeWidth": 1, | ||
| 373 | + "strokeStyle": "solid", | ||
| 374 | + "roughness": 1, | ||
| 375 | + "opacity": 100, | ||
| 376 | + "angle": 0, | ||
| 377 | + "x": 450.095703125, | ||
| 378 | + "y": 498.0361328125, | ||
| 379 | + "strokeColor": "#000000", | ||
| 380 | + "backgroundColor": "transparent", | ||
| 381 | + "width": 178, | ||
| 382 | + "height": 80, | ||
| 383 | + "seed": 1378197345, | ||
| 384 | + "groupIds": [], | ||
| 385 | + "strokeSharpness": "sharp", | ||
| 386 | + "boundElements": [], | ||
| 387 | + "updated": 1660298208836, | ||
| 388 | + "link": null, | ||
| 389 | + "locked": false, | ||
| 390 | + "fontSize": 16, | ||
| 391 | + "fontFamily": 1, | ||
| 392 | + "text": "Measures temperature\nand hygrometry:\n0: 26°C\n1: 40% ", | ||
| 393 | + "baseline": 74, | ||
| 394 | + "textAlign": "left", | ||
| 395 | + "verticalAlign": "top", | ||
| 396 | + "containerId": null, | ||
| 397 | + "originalText": "Measures temperature\nand hygrometry:\n0: 26°C\n1: 40% " | ||
| 398 | + }, | ||
| 399 | + { | ||
| 400 | + "type": "text", | ||
| 401 | + "version": 400, | ||
| 402 | + "versionNonce": 747588289, | ||
| 403 | + "isDeleted": false, | ||
| 404 | + "id": "rD_cbOE0Mwz-sfB0YqcaJ", | ||
| 405 | + "fillStyle": "hachure", | ||
| 406 | + "strokeWidth": 1, | ||
| 407 | + "strokeStyle": "solid", | ||
| 408 | + "roughness": 1, | ||
| 409 | + "opacity": 100, | ||
| 410 | + "angle": 0, | ||
| 411 | + "x": 494.501953125, | ||
| 412 | + "y": 449.6064453125, | ||
| 413 | + "strokeColor": "#000000", | ||
| 414 | + "backgroundColor": "transparent", | ||
| 415 | + "width": 88, | ||
| 416 | + "height": 25, | ||
| 417 | + "seed": 68109103, | ||
| 418 | + "groupIds": [], | ||
| 419 | + "strokeSharpness": "sharp", | ||
| 420 | + "boundElements": [], | ||
| 421 | + "updated": 1660298172011, | ||
| 422 | + "link": null, | ||
| 423 | + "locked": false, | ||
| 424 | + "fontSize": 20, | ||
| 425 | + "fontFamily": 1, | ||
| 426 | + "text": "Sensor 2", | ||
| 427 | + "baseline": 18, | ||
| 428 | + "textAlign": "left", | ||
| 429 | + "verticalAlign": "top", | ||
| 430 | + "containerId": null, | ||
| 431 | + "originalText": "Sensor 2" | ||
| 432 | + }, | ||
| 433 | + { | ||
| 434 | + "type": "arrow", | ||
| 435 | + "version": 1150, | ||
| 436 | + "versionNonce": 1550306895, | ||
| 437 | + "isDeleted": false, | ||
| 438 | + "id": "HZoAI_wR8CyRR9fVaFwSl", | ||
| 439 | + "fillStyle": "hachure", | ||
| 440 | + "strokeWidth": 1, | ||
| 441 | + "strokeStyle": "solid", | ||
| 442 | + "roughness": 1, | ||
| 443 | + "opacity": 100, | ||
| 444 | + "angle": 0, | ||
| 445 | + "x": 666.49609375, | ||
| 446 | + "y": 532.2655116636315, | ||
| 447 | + "strokeColor": "#000000", | ||
| 448 | + "backgroundColor": "transparent", | ||
| 449 | + "width": 145.8515625, | ||
| 450 | + "height": 133.46442554799017, | ||
| 451 | + "seed": 1409289601, | ||
| 452 | + "groupIds": [], | ||
| 453 | + "strokeSharpness": "round", | ||
| 454 | + "boundElements": [], | ||
| 455 | + "updated": 1660298248381, | ||
| 456 | + "link": null, | ||
| 457 | + "locked": false, | ||
| 458 | + "startBinding": { | ||
| 459 | + "elementId": "pHhCP3DIU5fE4v3yi3obG", | ||
| 460 | + "focus": 0.7718436212944663, | ||
| 461 | + "gap": 23.818359375 | ||
| 462 | + }, | ||
| 463 | + "endBinding": { | ||
| 464 | + "elementId": "ox1Blt2bzl0onmQfB7ZAN", | ||
| 465 | + "focus": 0.28922965891088237, | ||
| 466 | + "gap": 15.3515625 | ||
| 467 | + }, | ||
| 468 | + "lastCommittedPoint": null, | ||
| 469 | + "startArrowhead": null, | ||
| 470 | + "endArrowhead": "arrow", | ||
| 471 | + "points": [ | ||
| 472 | + [ | ||
| 473 | + 0, | ||
| 474 | + 0 | ||
| 475 | + ], | ||
| 476 | + [ | ||
| 477 | + 145.8515625, | ||
| 478 | + -133.46442554799017 | ||
| 479 | + ] | ||
| 480 | + ] | ||
| 481 | + }, | ||
| 482 | + { | ||
| 483 | + "id": "feq5Rn2_gEHIfIzRPvNu6", | ||
| 484 | + "type": "rectangle", | ||
| 485 | + "x": 832.283203125, | ||
| 486 | + "y": 515.0556640625, | ||
| 487 | + "width": 255, | ||
| 488 | + "height": 76.1171875, | ||
| 489 | + "angle": 0, | ||
| 490 | + "strokeColor": "#000000", | ||
| 491 | + "backgroundColor": "transparent", | ||
| 492 | + "fillStyle": "hachure", | ||
| 493 | + "strokeWidth": 1, | ||
| 494 | + "strokeStyle": "solid", | ||
| 495 | + "roughness": 1, | ||
| 496 | + "opacity": 100, | ||
| 497 | + "groupIds": [], | ||
| 498 | + "strokeSharpness": "sharp", | ||
| 499 | + "seed": 826152751, | ||
| 500 | + "version": 65, | ||
| 501 | + "versionNonce": 19459567, | ||
| 502 | + "isDeleted": false, | ||
| 503 | + "boundElements": [ | ||
| 504 | + { | ||
| 505 | + "type": "text", | ||
| 506 | + "id": "n4_rv3VhjyMXLSFrP52Vw" | ||
| 507 | + }, | ||
| 508 | + { | ||
| 509 | + "id": "vJNRjoY0dZcqOBw5RzuHn", | ||
| 510 | + "type": "arrow" | ||
| 511 | + } | ||
| 512 | + ], | ||
| 513 | + "updated": 1660298281790, | ||
| 514 | + "link": null, | ||
| 515 | + "locked": false | ||
| 516 | + }, | ||
| 517 | + { | ||
| 518 | + "id": "n4_rv3VhjyMXLSFrP52Vw", | ||
| 519 | + "type": "text", | ||
| 520 | + "x": 837.283203125, | ||
| 521 | + "y": 540.6142578125, | ||
| 522 | + "width": 245, | ||
| 523 | + "height": 25, | ||
| 524 | + "angle": 0, | ||
| 525 | + "strokeColor": "#000000", | ||
| 526 | + "backgroundColor": "transparent", | ||
| 527 | + "fillStyle": "hachure", | ||
| 528 | + "strokeWidth": 1, | ||
| 529 | + "strokeStyle": "solid", | ||
| 530 | + "roughness": 1, | ||
| 531 | + "opacity": 100, | ||
| 532 | + "groupIds": [], | ||
| 533 | + "strokeSharpness": "sharp", | ||
| 534 | + "seed": 555916079, | ||
| 535 | + "version": 20, | ||
| 536 | + "versionNonce": 1538604143, | ||
| 537 | + "isDeleted": false, | ||
| 538 | + "boundElements": null, | ||
| 539 | + "updated": 1660298276528, | ||
| 540 | + "link": null, | ||
| 541 | + "locked": false, | ||
| 542 | + "text": "Database or logs", | ||
| 543 | + "fontSize": 20, | ||
| 544 | + "fontFamily": 1, | ||
| 545 | + "textAlign": "center", | ||
| 546 | + "verticalAlign": "middle", | ||
| 547 | + "baseline": 18, | ||
| 548 | + "containerId": "feq5Rn2_gEHIfIzRPvNu6", | ||
| 549 | + "originalText": "Database or logs" | ||
| 550 | + }, | ||
| 551 | + { | ||
| 552 | + "id": "vJNRjoY0dZcqOBw5RzuHn", | ||
| 553 | + "type": "arrow", | ||
| 554 | + "x": 958.509765625, | ||
| 555 | + "y": 472.4150390625, | ||
| 556 | + "width": 0, | ||
| 557 | + "height": 39.33984375, | ||
| 558 | + "angle": 0, | ||
| 559 | + "strokeColor": "#000000", | ||
| 560 | + "backgroundColor": "transparent", | ||
| 561 | + "fillStyle": "hachure", | ||
| 562 | + "strokeWidth": 1, | ||
| 563 | + "strokeStyle": "solid", | ||
| 564 | + "roughness": 1, | ||
| 565 | + "opacity": 100, | ||
| 566 | + "groupIds": [], | ||
| 567 | + "strokeSharpness": "round", | ||
| 568 | + "seed": 1036508641, | ||
| 569 | + "version": 20, | ||
| 570 | + "versionNonce": 2130978977, | ||
| 571 | + "isDeleted": false, | ||
| 572 | + "boundElements": null, | ||
| 573 | + "updated": 1660298281790, | ||
| 574 | + "link": null, | ||
| 575 | + "locked": false, | ||
| 576 | + "points": [ | ||
| 577 | + [ | ||
| 578 | + 0, | ||
| 579 | + 0 | ||
| 580 | + ], | ||
| 581 | + [ | ||
| 582 | + 0, | ||
| 583 | + 39.33984375 | ||
| 584 | + ] | ||
| 585 | + ], | ||
| 586 | + "lastCommittedPoint": null, | ||
| 587 | + "startBinding": { | ||
| 588 | + "elementId": "rjHz2X8U0ZDEyckj_tTSw", | ||
| 589 | + "focus": -0.04979978015075378, | ||
| 590 | + "gap": 25.2548828125 | ||
| 591 | + }, | ||
| 592 | + "endBinding": { | ||
| 593 | + "elementId": "feq5Rn2_gEHIfIzRPvNu6", | ||
| 594 | + "focus": -0.009987745098039217, | ||
| 595 | + "gap": 3.30078125 | ||
| 596 | + }, | ||
| 597 | + "startArrowhead": null, | ||
| 598 | + "endArrowhead": "arrow" | ||
| 599 | + } | ||
| 600 | + ], | ||
| 601 | + "appState": { | ||
| 602 | + "gridSize": null, | ||
| 603 | + "viewBackgroundColor": "#ffffff" | ||
| 604 | + }, | ||
| 605 | + "files": {} | ||
| 606 | +} | ||
| 0 | \ No newline at end of file | 607 | \ No newline at end of file |
docs/assets/client-sensors.webp
0 → 100644
No preview for this file type
docs/assets/server-grafana.excalidraw
0 → 100644
| 1 | +{ | ||
| 2 | + "type": "excalidraw", | ||
| 3 | + "version": 2, | ||
| 4 | + "source": "https://excalidraw.com", | ||
| 5 | + "elements": [ | ||
| 6 | + { | ||
| 7 | + "type": "rectangle", | ||
| 8 | + "version": 938, | ||
| 9 | + "versionNonce": 1589965569, | ||
| 10 | + "isDeleted": false, | ||
| 11 | + "id": "ox1Blt2bzl0onmQfB7ZAN", | ||
| 12 | + "fillStyle": "hachure", | ||
| 13 | + "strokeWidth": 1, | ||
| 14 | + "strokeStyle": "solid", | ||
| 15 | + "roughness": 1, | ||
| 16 | + "opacity": 100, | ||
| 17 | + "angle": 0, | ||
| 18 | + "x": 471.66796875, | ||
| 19 | + "y": 61.640625, | ||
| 20 | + "strokeColor": "#000000", | ||
| 21 | + "backgroundColor": "transparent", | ||
| 22 | + "width": 251.7109375, | ||
| 23 | + "height": 346.86328125, | ||
| 24 | + "seed": 1508024704, | ||
| 25 | + "groupIds": [], | ||
| 26 | + "strokeSharpness": "sharp", | ||
| 27 | + "boundElements": [ | ||
| 28 | + { | ||
| 29 | + "id": "sE5xq9Fz5VDTWcJGhJizg", | ||
| 30 | + "type": "arrow" | ||
| 31 | + }, | ||
| 32 | + { | ||
| 33 | + "id": "RdDFVItfRo8k8NarDHSp-", | ||
| 34 | + "type": "arrow" | ||
| 35 | + } | ||
| 36 | + ], | ||
| 37 | + "updated": 1660300922199, | ||
| 38 | + "link": null, | ||
| 39 | + "locked": false | ||
| 40 | + }, | ||
| 41 | + { | ||
| 42 | + "type": "text", | ||
| 43 | + "version": 1153, | ||
| 44 | + "versionNonce": 977576399, | ||
| 45 | + "isDeleted": false, | ||
| 46 | + "id": "rjHz2X8U0ZDEyckj_tTSw", | ||
| 47 | + "fillStyle": "hachure", | ||
| 48 | + "strokeWidth": 1, | ||
| 49 | + "strokeStyle": "solid", | ||
| 50 | + "roughness": 1, | ||
| 51 | + "opacity": 100, | ||
| 52 | + "angle": 0, | ||
| 53 | + "x": 498.0234375, | ||
| 54 | + "y": 138.1171875, | ||
| 55 | + "strokeColor": "#000000", | ||
| 56 | + "backgroundColor": "transparent", | ||
| 57 | + "width": 187, | ||
| 58 | + "height": 240, | ||
| 59 | + "seed": 2100367744, | ||
| 60 | + "groupIds": [], | ||
| 61 | + "strokeSharpness": "sharp", | ||
| 62 | + "boundElements": [], | ||
| 63 | + "updated": 1660300922199, | ||
| 64 | + "link": null, | ||
| 65 | + "locked": false, | ||
| 66 | + "fontSize": 16, | ||
| 67 | + "fontFamily": 1, | ||
| 68 | + "text": "Collect data from CPU,\nIO and memory with\ntimestamp\n\n0: 0.1 %\n1: 1456 b/s\n2: 4567 b\n3: 1660190233 (time)\n...\n\n100: false (alert)\n", | ||
| 69 | + "baseline": 234, | ||
| 70 | + "textAlign": "left", | ||
| 71 | + "verticalAlign": "top", | ||
| 72 | + "containerId": null, | ||
| 73 | + "originalText": "Collect data from CPU,\nIO and memory with\ntimestamp\n\n0: 0.1 %\n1: 1456 b/s\n2: 4567 b\n3: 1660190233 (time)\n...\n\n100: false (alert)\n" | ||
| 74 | + }, | ||
| 75 | + { | ||
| 76 | + "type": "rectangle", | ||
| 77 | + "version": 772, | ||
| 78 | + "versionNonce": 1558709263, | ||
| 79 | + "isDeleted": false, | ||
| 80 | + "id": "mDgu1gSg34HbU-NAHPB30", | ||
| 81 | + "fillStyle": "hachure", | ||
| 82 | + "strokeWidth": 1, | ||
| 83 | + "strokeStyle": "solid", | ||
| 84 | + "roughness": 1, | ||
| 85 | + "opacity": 100, | ||
| 86 | + "angle": 0, | ||
| 87 | + "x": 896.8984375, | ||
| 88 | + "y": 44.853515625, | ||
| 89 | + "strokeColor": "#000000", | ||
| 90 | + "backgroundColor": "transparent", | ||
| 91 | + "width": 216.16406250000006, | ||
| 92 | + "height": 172.06640624999997, | ||
| 93 | + "seed": 1336837760, | ||
| 94 | + "groupIds": [], | ||
| 95 | + "strokeSharpness": "sharp", | ||
| 96 | + "boundElements": [ | ||
| 97 | + { | ||
| 98 | + "id": "sE5xq9Fz5VDTWcJGhJizg", | ||
| 99 | + "type": "arrow" | ||
| 100 | + } | ||
| 101 | + ], | ||
| 102 | + "updated": 1660300917063, | ||
| 103 | + "link": null, | ||
| 104 | + "locked": false | ||
| 105 | + }, | ||
| 106 | + { | ||
| 107 | + "type": "text", | ||
| 108 | + "version": 607, | ||
| 109 | + "versionNonce": 747285039, | ||
| 110 | + "isDeleted": false, | ||
| 111 | + "id": "F6UUk6_B6uALmjxcHLYw4", | ||
| 112 | + "fillStyle": "hachure", | ||
| 113 | + "strokeWidth": 1, | ||
| 114 | + "strokeStyle": "solid", | ||
| 115 | + "roughness": 1, | ||
| 116 | + "opacity": 100, | ||
| 117 | + "angle": 0, | ||
| 118 | + "x": 964.88671875, | ||
| 119 | + "y": 70.1953125, | ||
| 120 | + "strokeColor": "#000000", | ||
| 121 | + "backgroundColor": "transparent", | ||
| 122 | + "width": 84, | ||
| 123 | + "height": 25, | ||
| 124 | + "seed": 354006656, | ||
| 125 | + "groupIds": [], | ||
| 126 | + "strokeSharpness": "sharp", | ||
| 127 | + "boundElements": [], | ||
| 128 | + "updated": 1660300917063, | ||
| 129 | + "link": null, | ||
| 130 | + "locked": false, | ||
| 131 | + "fontSize": 20, | ||
| 132 | + "fontFamily": 1, | ||
| 133 | + "text": "Grafana", | ||
| 134 | + "baseline": 18, | ||
| 135 | + "textAlign": "left", | ||
| 136 | + "verticalAlign": "top", | ||
| 137 | + "containerId": null, | ||
| 138 | + "originalText": "Grafana" | ||
| 139 | + }, | ||
| 140 | + { | ||
| 141 | + "type": "text", | ||
| 142 | + "version": 556, | ||
| 143 | + "versionNonce": 1932158625, | ||
| 144 | + "isDeleted": false, | ||
| 145 | + "id": "v7q2uvVFHZBvjr-y_ZJKl", | ||
| 146 | + "fillStyle": "hachure", | ||
| 147 | + "strokeWidth": 1, | ||
| 148 | + "strokeStyle": "solid", | ||
| 149 | + "roughness": 1, | ||
| 150 | + "opacity": 100, | ||
| 151 | + "angle": 0, | ||
| 152 | + "x": 528.5234375, | ||
| 153 | + "y": 89.28515625, | ||
| 154 | + "strokeColor": "#000000", | ||
| 155 | + "backgroundColor": "transparent", | ||
| 156 | + "width": 159, | ||
| 157 | + "height": 25, | ||
| 158 | + "seed": 2108436864, | ||
| 159 | + "groupIds": [], | ||
| 160 | + "strokeSharpness": "sharp", | ||
| 161 | + "boundElements": [], | ||
| 162 | + "updated": 1660300922199, | ||
| 163 | + "link": null, | ||
| 164 | + "locked": false, | ||
| 165 | + "fontSize": 20, | ||
| 166 | + "fontFamily": 1, | ||
| 167 | + "text": "libmodbus server", | ||
| 168 | + "baseline": 18, | ||
| 169 | + "textAlign": "left", | ||
| 170 | + "verticalAlign": "top", | ||
| 171 | + "containerId": null, | ||
| 172 | + "originalText": "libmodbus server" | ||
| 173 | + }, | ||
| 174 | + { | ||
| 175 | + "type": "arrow", | ||
| 176 | + "version": 2401, | ||
| 177 | + "versionNonce": 1251011297, | ||
| 178 | + "isDeleted": false, | ||
| 179 | + "id": "sE5xq9Fz5VDTWcJGhJizg", | ||
| 180 | + "fillStyle": "hachure", | ||
| 181 | + "strokeWidth": 1, | ||
| 182 | + "strokeStyle": "solid", | ||
| 183 | + "roughness": 1, | ||
| 184 | + "opacity": 100, | ||
| 185 | + "angle": 0, | ||
| 186 | + "x": 748.0898437500001, | ||
| 187 | + "y": 161.19331310212854, | ||
| 188 | + "strokeColor": "#000000", | ||
| 189 | + "backgroundColor": "transparent", | ||
| 190 | + "width": 134.5039062499999, | ||
| 191 | + "height": 30.970574872077407, | ||
| 192 | + "seed": 455209344, | ||
| 193 | + "groupIds": [], | ||
| 194 | + "strokeSharpness": "round", | ||
| 195 | + "boundElements": [], | ||
| 196 | + "updated": 1660300922199, | ||
| 197 | + "link": null, | ||
| 198 | + "locked": false, | ||
| 199 | + "startBinding": { | ||
| 200 | + "elementId": "ox1Blt2bzl0onmQfB7ZAN", | ||
| 201 | + "gap": 24.710937500000114, | ||
| 202 | + "focus": -0.19349510698149744 | ||
| 203 | + }, | ||
| 204 | + "endBinding": { | ||
| 205 | + "elementId": "mDgu1gSg34HbU-NAHPB30", | ||
| 206 | + "gap": 14.3046875, | ||
| 207 | + "focus": 0.2600477394392373 | ||
| 208 | + }, | ||
| 209 | + "lastCommittedPoint": null, | ||
| 210 | + "startArrowhead": null, | ||
| 211 | + "endArrowhead": "arrow", | ||
| 212 | + "points": [ | ||
| 213 | + [ | ||
| 214 | + 0, | ||
| 215 | + 0 | ||
| 216 | + ], | ||
| 217 | + [ | ||
| 218 | + 134.5039062499999, | ||
| 219 | + -30.970574872077407 | ||
| 220 | + ] | ||
| 221 | + ] | ||
| 222 | + }, | ||
| 223 | + { | ||
| 224 | + "type": "text", | ||
| 225 | + "version": 1184, | ||
| 226 | + "versionNonce": 1589324399, | ||
| 227 | + "isDeleted": false, | ||
| 228 | + "id": "Q6P32mRyop5JlKGPB3tei", | ||
| 229 | + "fillStyle": "hachure", | ||
| 230 | + "strokeWidth": 1, | ||
| 231 | + "strokeStyle": "solid", | ||
| 232 | + "roughness": 1, | ||
| 233 | + "opacity": 100, | ||
| 234 | + "angle": 6.077759617018872, | ||
| 235 | + "x": 746.0369822154072, | ||
| 236 | + "y": 102.90361683493032, | ||
| 237 | + "strokeColor": "#000000", | ||
| 238 | + "backgroundColor": "transparent", | ||
| 239 | + "width": 111, | ||
| 240 | + "height": 29, | ||
| 241 | + "seed": 1091054019, | ||
| 242 | + "groupIds": [], | ||
| 243 | + "strokeSharpness": "sharp", | ||
| 244 | + "boundElements": [], | ||
| 245 | + "updated": 1660300917063, | ||
| 246 | + "link": null, | ||
| 247 | + "locked": false, | ||
| 248 | + "fontSize": 11.542968749999993, | ||
| 249 | + "fontFamily": 1, | ||
| 250 | + "text": "TCP read requests\n(polling)", | ||
| 251 | + "baseline": 25, | ||
| 252 | + "textAlign": "left", | ||
| 253 | + "verticalAlign": "top", | ||
| 254 | + "containerId": null, | ||
| 255 | + "originalText": "TCP read requests\n(polling)" | ||
| 256 | + }, | ||
| 257 | + { | ||
| 258 | + "id": "ViVqW_nxoEJO1DpluuMzF", | ||
| 259 | + "type": "image", | ||
| 260 | + "x": 923.3162172379032, | ||
| 261 | + "y": 116.828369140625, | ||
| 262 | + "width": 163.32850302419354, | ||
| 263 | + "height": 63.289794921875, | ||
| 264 | + "angle": 0, | ||
| 265 | + "strokeColor": "transparent", | ||
| 266 | + "backgroundColor": "transparent", | ||
| 267 | + "fillStyle": "hachure", | ||
| 268 | + "strokeWidth": 1, | ||
| 269 | + "strokeStyle": "solid", | ||
| 270 | + "roughness": 1, | ||
| 271 | + "opacity": 100, | ||
| 272 | + "groupIds": [], | ||
| 273 | + "strokeSharpness": "round", | ||
| 274 | + "seed": 953641007, | ||
| 275 | + "version": 332, | ||
| 276 | + "versionNonce": 1122873217, | ||
| 277 | + "isDeleted": false, | ||
| 278 | + "boundElements": null, | ||
| 279 | + "updated": 1660300917064, | ||
| 280 | + "link": null, | ||
| 281 | + "locked": false, | ||
| 282 | + "status": "saved", | ||
| 283 | + "fileId": "fe56123c11422301d020f581b74d4397ab49e99c", | ||
| 284 | + "scale": [ | ||
| 285 | + 1, | ||
| 286 | + 1 | ||
| 287 | + ] | ||
| 288 | + }, | ||
| 289 | + { | ||
| 290 | + "id": "RdDFVItfRo8k8NarDHSp-", | ||
| 291 | + "type": "arrow", | ||
| 292 | + "x": 898.5878906250001, | ||
| 293 | + "y": 340.31123325850484, | ||
| 294 | + "width": 158.6875000000001, | ||
| 295 | + "height": 28.44727928318008, | ||
| 296 | + "angle": 0, | ||
| 297 | + "strokeColor": "#000000", | ||
| 298 | + "backgroundColor": "transparent", | ||
| 299 | + "fillStyle": "hachure", | ||
| 300 | + "strokeWidth": 1, | ||
| 301 | + "strokeStyle": "solid", | ||
| 302 | + "roughness": 1, | ||
| 303 | + "opacity": 100, | ||
| 304 | + "groupIds": [], | ||
| 305 | + "strokeSharpness": "round", | ||
| 306 | + "seed": 595270337, | ||
| 307 | + "version": 1096, | ||
| 308 | + "versionNonce": 1842538177, | ||
| 309 | + "isDeleted": false, | ||
| 310 | + "boundElements": null, | ||
| 311 | + "updated": 1660300922199, | ||
| 312 | + "link": null, | ||
| 313 | + "locked": false, | ||
| 314 | + "points": [ | ||
| 315 | + [ | ||
| 316 | + 0, | ||
| 317 | + 0 | ||
| 318 | + ], | ||
| 319 | + [ | ||
| 320 | + -158.6875000000001, | ||
| 321 | + -28.44727928318008 | ||
| 322 | + ] | ||
| 323 | + ], | ||
| 324 | + "lastCommittedPoint": null, | ||
| 325 | + "startBinding": { | ||
| 326 | + "elementId": "ro1CNQcmtpkib2r-uhEJo", | ||
| 327 | + "gap": 10.179687499999886, | ||
| 328 | + "focus": -0.37043558235421187 | ||
| 329 | + }, | ||
| 330 | + "endBinding": { | ||
| 331 | + "elementId": "ox1Blt2bzl0onmQfB7ZAN", | ||
| 332 | + "gap": 16.521484375, | ||
| 333 | + "focus": 0.2615821499314503 | ||
| 334 | + }, | ||
| 335 | + "startArrowhead": null, | ||
| 336 | + "endArrowhead": "arrow" | ||
| 337 | + }, | ||
| 338 | + { | ||
| 339 | + "id": "ro1CNQcmtpkib2r-uhEJo", | ||
| 340 | + "type": "rectangle", | ||
| 341 | + "x": 908.767578125, | ||
| 342 | + "y": 248.8369140625, | ||
| 343 | + "width": 216.01953125, | ||
| 344 | + "height": 154, | ||
| 345 | + "angle": 0, | ||
| 346 | + "strokeColor": "#000000", | ||
| 347 | + "backgroundColor": "transparent", | ||
| 348 | + "fillStyle": "hachure", | ||
| 349 | + "strokeWidth": 1, | ||
| 350 | + "strokeStyle": "solid", | ||
| 351 | + "roughness": 1, | ||
| 352 | + "opacity": 100, | ||
| 353 | + "groupIds": [], | ||
| 354 | + "strokeSharpness": "sharp", | ||
| 355 | + "seed": 1261656367, | ||
| 356 | + "version": 298, | ||
| 357 | + "versionNonce": 866798383, | ||
| 358 | + "isDeleted": false, | ||
| 359 | + "boundElements": [ | ||
| 360 | + { | ||
| 361 | + "id": "RdDFVItfRo8k8NarDHSp-", | ||
| 362 | + "type": "arrow" | ||
| 363 | + }, | ||
| 364 | + { | ||
| 365 | + "type": "text", | ||
| 366 | + "id": "zWdPKja_yF9g4yVY1kvXH" | ||
| 367 | + } | ||
| 368 | + ], | ||
| 369 | + "updated": 1660300917064, | ||
| 370 | + "link": null, | ||
| 371 | + "locked": false | ||
| 372 | + }, | ||
| 373 | + { | ||
| 374 | + "id": "zWdPKja_yF9g4yVY1kvXH", | ||
| 375 | + "type": "text", | ||
| 376 | + "x": 913.767578125, | ||
| 377 | + "y": 253.8369140625, | ||
| 378 | + "width": 206, | ||
| 379 | + "height": 75, | ||
| 380 | + "angle": 0, | ||
| 381 | + "strokeColor": "#000000", | ||
| 382 | + "backgroundColor": "transparent", | ||
| 383 | + "fillStyle": "hachure", | ||
| 384 | + "strokeWidth": 1, | ||
| 385 | + "strokeStyle": "solid", | ||
| 386 | + "roughness": 1, | ||
| 387 | + "opacity": 100, | ||
| 388 | + "groupIds": [], | ||
| 389 | + "strokeSharpness": "sharp", | ||
| 390 | + "seed": 76196961, | ||
| 391 | + "version": 380, | ||
| 392 | + "versionNonce": 1800831809, | ||
| 393 | + "isDeleted": false, | ||
| 394 | + "boundElements": null, | ||
| 395 | + "updated": 1660300917064, | ||
| 396 | + "link": null, | ||
| 397 | + "locked": false, | ||
| 398 | + "text": "\nTriggers alert when\nservice is down", | ||
| 399 | + "fontSize": 20, | ||
| 400 | + "fontFamily": 1, | ||
| 401 | + "textAlign": "center", | ||
| 402 | + "verticalAlign": "top", | ||
| 403 | + "baseline": 68, | ||
| 404 | + "containerId": "ro1CNQcmtpkib2r-uhEJo", | ||
| 405 | + "originalText": "\nTriggers alert when\nservice is down" | ||
| 406 | + }, | ||
| 407 | + { | ||
| 408 | + "type": "text", | ||
| 409 | + "version": 1386, | ||
| 410 | + "versionNonce": 2109148495, | ||
| 411 | + "isDeleted": false, | ||
| 412 | + "id": "DZ2rUAdMymO7ajB4Xr_Kf", | ||
| 413 | + "fillStyle": "hachure", | ||
| 414 | + "strokeWidth": 1, | ||
| 415 | + "strokeStyle": "solid", | ||
| 416 | + "roughness": 1, | ||
| 417 | + "opacity": 100, | ||
| 418 | + "angle": 0.17070993938211565, | ||
| 419 | + "x": 774.3998831194928, | ||
| 420 | + "y": 298.59613347989244, | ||
| 421 | + "strokeColor": "#000000", | ||
| 422 | + "backgroundColor": "transparent", | ||
| 423 | + "width": 107, | ||
| 424 | + "height": 15, | ||
| 425 | + "seed": 109244929, | ||
| 426 | + "groupIds": [], | ||
| 427 | + "strokeSharpness": "sharp", | ||
| 428 | + "boundElements": [], | ||
| 429 | + "updated": 1660300917064, | ||
| 430 | + "link": null, | ||
| 431 | + "locked": false, | ||
| 432 | + "fontSize": 11.542968749999993, | ||
| 433 | + "fontFamily": 1, | ||
| 434 | + "text": "TCP write request", | ||
| 435 | + "baseline": 10, | ||
| 436 | + "textAlign": "left", | ||
| 437 | + "verticalAlign": "top", | ||
| 438 | + "containerId": null, | ||
| 439 | + "originalText": "TCP write request" | ||
| 440 | + }, | ||
| 441 | + { | ||
| 442 | + "id": "Os6j9M5Ipt4Ay74nFj29L", | ||
| 443 | + "type": "text", | ||
| 444 | + "x": 937.599609375, | ||
| 445 | + "y": 348.8330078125, | ||
| 446 | + "width": 163, | ||
| 447 | + "height": 30, | ||
| 448 | + "angle": 0, | ||
| 449 | + "strokeColor": "#000000", | ||
| 450 | + "backgroundColor": "transparent", | ||
| 451 | + "fillStyle": "hachure", | ||
| 452 | + "strokeWidth": 1, | ||
| 453 | + "strokeStyle": "solid", | ||
| 454 | + "roughness": 1, | ||
| 455 | + "opacity": 100, | ||
| 456 | + "groupIds": [], | ||
| 457 | + "strokeSharpness": "sharp", | ||
| 458 | + "seed": 577132609, | ||
| 459 | + "version": 307, | ||
| 460 | + "versionNonce": 654734113, | ||
| 461 | + "isDeleted": false, | ||
| 462 | + "boundElements": null, | ||
| 463 | + "updated": 1660300917064, | ||
| 464 | + "link": null, | ||
| 465 | + "locked": false, | ||
| 466 | + "text": "Write True to address 100\non issue", | ||
| 467 | + "fontSize": 12.1, | ||
| 468 | + "fontFamily": 1, | ||
| 469 | + "textAlign": "left", | ||
| 470 | + "verticalAlign": "top", | ||
| 471 | + "baseline": 26, | ||
| 472 | + "containerId": null, | ||
| 473 | + "originalText": "Write True to address 100\non issue" | ||
| 474 | + } | ||
| 475 | + ], | ||
| 476 | + "appState": { | ||
| 477 | + "gridSize": null, | ||
| 478 | + "viewBackgroundColor": "#ffffff" | ||
| 479 | + }, | ||
| 480 | + "files": { | ||
| 481 | + "fe56123c11422301d020f581b74d4397ab49e99c": { | ||
| 482 | + "mimeType": "image/jpeg", | ||
| 483 | + "id": "fe56123c11422301d020f581b74d4397ab49e99c", | ||
| 484 | + "dataURL": "data:image/jpeg;base64,/9j/4QDoRXhpZgAATU0AKgAAAAgABgESAAMAAAABAAEAAAEaAAUAAAABAAAAVgEbAAUAAAABAAAAXgEoAAMAAAABAAIAAAITAAMAAAABAAEAAIdpAAQAAAABAAAAZgAAAAAAAACQAAAAAQAAAJAAAAABAAiQAAAHAAAABDAyMjGRAQAHAAAABAECAwCShgAHAAAAEgAAAMygAAAHAAAABDAxMDCgAQADAAAAAQABAACgAgAEAAAAAQAAAoCgAwAEAAAAAQAAAPikBgADAAAAAQAAAAAAAAAAQVNDSUkAAABTY3JlZW5zaG90AAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAAAChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAAABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANv/bAEMAAwICAgICAwICAgMDAwMEBgQEBAQECAYGBQYJCAoKCQgJCQoMDwwKCw4LCQkNEQ0ODxAQERAKDBITEhATDxAQEP/bAEMBAwMDBAMECAQECBALCQsQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEP/AABEIAPgCgAMBIgACEQEDEQH/xAAdAAABBQEBAQEAAAAAAAAAAAAAAQIDBAYHBQgJ/8QAShAAAQIEAwMHBgoKAwADAAMAAQIDAAQFEQYSITFBUQcTFCJhktEyUlNxgbEVJDM0QnKRoeHwI0NUYmNzk6KywRaC0gg1RBfC8f/EABoBAQACAwEAAAAAAAAAAAAAAAABAgMEBQb/xAA1EQACAQMCBQIGAAUEAwEAAAAAAQIDBBEFIRITMUFRFGEGFSIycYEjJDORoRZCsfBScqLR/9oADAMBAAIRAxEAPwD86+jy40Uhw+pQH+oeiVk1DrJeH/cf+Yfa4F4UDcIz5IyN6LJea93x4QdEkeD39Qf+YdBEZGRvRJHzXv6g8IOhyP8AG748IdBDIyN6LJea93x4QdEkeD39Qf8AmHQQyMjeiSPmvf1B4QdDkf43fHhDoIZGRvRZLzXu+PCDokjwe/qD/wAw6CGRkb0SR817+oPCDocj/G748IdBDIyN6LJea93x4QdEkeD39Qf+YdBDIyN6JI+a9/UHhB0OR/jd8eEOghkZG9FkvNe748IOiSPB7+oP/MOghkZG9EkfNe/qDwg6HI/xu+PCHQQyMjeiyXmvd8eEHRJHg9/UH/mHQQyMjeiSPmvf1B4QdDkf43fHhDoIZGRvRZLzXu+PCDokjwe/qD/zDoIZGRvRJHzXv6g8IOhyP8bvjwh0EMjI3osl5r3fHhB0SR4Pf1B/5h0EMjI3okj5r39QeEHQ5H+N3x4Q6BCFOKDaALqIA3dkWJG9DktmV7vjwg6HJ+a93x4R0LF/IZyg4GxdQME1qRll1TE7Eq/TEy7xWh4TBAQM1hY3IBB2R4vKNgHEPJXjCoYGxYiWRU6YWw/0d3O112kujKqwv1Vp9txuh0Bl+hyPmv8AfH/mF6JJ+a93x4QpcbFgVpBte1xsgDrROUOJJG4EaeEAN6HJWtle748IOhyfmvd8eEP5xvzh9sAUg3AUNO2AGdDkfNf74/8AML0ST817vjwi1IyU3U52Wp1PZL0zNuoZZbG1a1EJSkdpJAj3muTrFc3j9zk0pck1Ua63Orp/NSjgWhTqCQvrkAZUkG6jYWBMB0Mt0OStbK93x4QdDk/Ne748I6pO/wDxx5SJWq0Cly7lAqSMRVJNHlp2nVRL8szOkA8w8tKf0ara2sRYHU2iaof/ABp5R5N+Rbp07hqstztVaoq36ZVQ+3KTjhsht/qgt3Nxe1tCIA5L0OR81/vj/wAwvRJPzXu+PCNajkzxUuRxhUA3Kc1gZxlurWeNwXH+YTzYy9YZ/VprujKwBH0SS2ZXu+PCDokjwe/qD/zDjtggBvRJHzXv6g8IOhyP8bvjwh0ERkjI3osl5r3fHhB0SR4Pf1B/5h0ERkZG9EkfNe/qDwg6HI/xu+PCHQQyMjeiyXmvd8eEHRJHg9/UH/mHQQyMkKpWUvYNvn1LT4QdElfQTHeT4RNBEFSDosrs5qY7yfCDosr6KY76fCJ4IAg6LK+imO+nwheiSvoJjvJ8ImggCDosrs5qY7yfCDosr6KY76fCJ4IAg6LK+imO+nwheiSvoJjvJ8ImggCDosrs5qY7yfCDosr6KY76fCJ4IAg6LK+imO+nwheiSvoJjvJ8ImggCDosrs5qY7yfCDosr6KY76fCJ4IAg6LK+imO+nwheiSvoJjvJ8ImggCDosrs5qY7yfCDosr6KY76fCJ4IAg6LKeimO+nwg6LK+imO+nwiXxhU7AIAiblWL5QlwAecR4RWmW0tO5RsOsXfCK1Rtzjf1BAFuCCCBLCCCCBAQQQQAQQQQAQQQQAQQQQAQQQQAQQQQAQQQQAQQQQAQQQQAQQQQAQQQQAQQQQAQQQQAQQQQAWNiq2giRgETLAIsVrASPO12DjEe8AH1i+ntg2qtoQN18w+zdF12J6rB9740xPg6enKhjqq1aTXVuSKQl5ukt50kzZnJJtEuga681MErI3AbrQ5ufoX/8AKHKdU6PLLqOMy3h9UiJSflGZpyU6E0JgMuTDbjZGYIKwBmI3ixj4EU2nMSSkXtoQT74MgCs4WkK42izfE8lWs/o+1pDHaMONmo4Xp9KoC6tysS0lOyLbktNoRLONNh9sLCcpQo5ictk+q0PdxBhLF1RmZPlFNDVRML8qiKXTGzLMtNSshkfSluyEi7WZDVwdNI+JwMpBSdQd2kISSrNvOpNoLqSfd2FJuqs40wM/yyP0BeLRiCsGmFpUsrLRfg53KF831SjnsuQK3XttjF8iHKFJY+wviXGfKNNSz9Y5OJ1WMJdZYQ2JpLkuZdLJSkBISHAyQkDcY+RFWURoNNnZGnkuUPEFNwLPcnkgJNimVOYRMzjiJZImXsliltTm0tggHLx14WnsyUjVci0wgYyqvKhWm2lt4SkZivqS4QAudJCJVPA/GXGjbgk6Ra/+NWJKbSuV1mbxHUmpRVXkKjTkz0w5lS1NzLCm23FKOwZyOt2xylDrrba223VoQ6AHEpUQFAG4BA2i9jbjaGEA7rxjSw0ykk28n0xyU8meLOSrHuAncd4vlJIzeM5RTVBbn0vB9CUm86rIrIlP0ElWpCju2pTOWvk3wfjcYXwdhufpkhUMcS1TxBVKrPomVKEvMKADSUISlCLkqJ109UfNObQneBp2REFKAtF1LhZbqfU+MMMzfJrgnlrnsSTlORK44m5BGHVMTzTxn0pnS+paEoUSEhuxubbRHy/e8QZjoMotuFoeFm9iLRVbF+2Bx2wQQQCCCCCKFWEEEECAggggAggggAggggAggggAggggAggggAggggAggggAggggAggggAggggAggggBvjDh5PthvjDgLJEAN8IrVH5RsfuCLKeEV6lotv6ggC1BCQsAEEEEAEEEEAEEEEAB0F9wgtpeEUMyCnjC34QAQQgGp7TCwAW0vBrt4QHyR7YDoCO3/UAHbBqB90KPIJ7fGAgBA+tACQQo8IBvgBIDokmF3H2QirBpXqMAG4eqCAjQeoe4QQAQQQQAQqRcgQh2fbDmBd9A7YAbBArd6/GAbYADptggcGgPaPeIEjT88IAILdUngQIUabYW36JX1k+4wA3h2ez3QfT12abdkB2wROQBtfSCCCGQENKSDa1tm2HHZ7IkdF1j6if8REp4BCQQQDCDgIkIFwLbv9wxNswHYf8AUTxEp4FGkL69kJayvafcIcfJt2RQgSEDYtpDki5A7R7xCjRI9X+otkEeVPCFyiFO2CIyWyINNIWCCCeBkLaXg4eu0OA/RE8FD3GI9yPrCIKjoALwot7vdALXt2QAkB0HqtCnfbjCOaINuz3iAAgA27BBbS8OcFnLdg/1CfRgBIW2toSH261uyAGWubQDXZCjyx7YRoXIHFQgAghBshYAIIIIAIIXYBDgLi8AMggggAggggAg27IN1oRItAC7IIDqYIAIIIIATxhQLJAgggBvhFao+W3bzBFrwitUbZ2x+4IAtQQQQAQQQQAQQRYp9PnapNtU+nSy35h42Q2m1yfbEpOTSS3DaisyeEivBGyp/JDjyoTz1PTSA06w0HlFxwZSNwBF7nTZGZmKNVJRLrj9PmEtMuFlbvNnIFg2tmAtfSE1y5cue0jNSt6takq9OOYPuio0MzyUAXvpYQwX3RNJi060DtziIbWVaJwYRxtpbgIIIIqAvpaA6jTf4QbdIUjVI7IAcB+hJ/eA+4wxR6oH7w/1EqB8XJ/iJ9xiBZtb2QA6+loL6WghDtAgBddkCvIIHAwE6geqE+lbsMAPdTZYFtiU+4Q2JpsWft+6n/ERDABBBBACHd7fdEsv84b+sIiVtHqMSyw+MN8c4/1AEZ3XgB1FoL2A/PCE3fZ7hAAv/f8AuHJ0Nvzshqhu4EQuxcAKdNPzshwvzKvrp9xhqhoPzuEOT83Uf3k+4wAw6wQQQAQQQQARI8OsPqJ/xERDU2iZ8WOvmI/xEARKOoPZCC4WPUf9QbT7IVQsq57YAQ+UPVCk6W7IFiykdqYTd7IAe0MziRxUn3iAeSPVCymsy0nitPvENvZMAJBBBABBBBADx8ir6yfcYjO624iJU/Nl/XT7jEahZXqt7hACm4tCA2MF9QIanbADuPbCK8iFhDcpP53QBK9ou/YPcIjvdIiZ8dcD91P+AiAbIAWFG32Qm2E3awAoPXFu2Hy6f0iBxIiIeV9sWJYAzLQ4kQBDa2kEBHWUO0wQAQQQQAq/IEPbT+gKgNAbE7oYfJHridv/AOvdv6RP+4ArwQHboI22DOS+oYwo8xWWp9qXaaUpCEqSSVqSAT6hbSM9vb1LqfLpLLMFxcU7WHHUe3QxMEOeaUy64ysWU2opUO0GLFPpNUqylpplPmJotC6wy2V5R22GgiOVLi4EsvwZXOKjxN4RV3gWhy0lOhGsKhh5T4lkNKLpUEJQBrmvoLcb6Wj2qzg/FUhOMy03QZtLz7KVttpbKlKFhcgDWMM2oPEtmbFChUuE5U02vKPBGu6FhVsPMKLbzSm1g2UlQIIPaDDm3AjQstr+skGBRwcXwvqhgF431O5N6VV8GTNeplfmnalJSyZqYZ6CRJousIDJmM1ue1ByhJFt+kYRxxC0n9GlJtsSLe6OiUXlIw7QsETlEpVHqSKnUJUMPpVOgyClhYUJjmSm4dFgMwVbsgUlsRYy5MKXhmjT87IYidn5uhTjFPq7CpTmkNOupUUlpeY84m6FC5CTcbI9iR5FKXPYJkq+mtVluoTtFcrQKqSPg5tCV5ebVMBy4WQNmW148zHPKZRMR0apydJoU1KT9fnWJ+qvPTAW0FsoUEpZSAClN1qNiVHtj2qfy20Wn4LpdF+D8RPztNortIEuuppFMdzknnVsc3mKhe41tcCATyceNrnLqBsPGKlR+UbH7gi0TmJNgL62GgitUtFt/UEAWRshYVjmS+2JhakNFYDhSLlKbi5A42jtkjyfcnOKv+Oqp1Hn6Iip1JbLAdm1LdqMg22pS5gpUSGzmCU9WyesbA2vAHEoI7VS8J8klTNCrs1T3qZKYilHUy8gZl90JfQ4EEoWnMsqy6hKurfgI5xjXCa8I1YU1SJstloFMw8wUIfX9MtkiykAnLmF7kbdRAGcjScnLky1jSlKlFtIcL6Ugu6JsdoPsjO5NYVClNOJUkqSUqGo0I1HDZF6UnCaaK1EnFqW67nXuVjGWKsL4v6PSKqmWb6LlHM2JIO3NwP+o8CU5VZ6fwe1yfVCTYSxMPgOT6zdaQVXJIPr28I83lSBdxMibIV8ZkWHEk7+oB/qMaAoHyT9kZ9Wo8+5c6nXYz6PqlWzoKnbPEPH/Jv+UHBuGsIVWmNYdrqaiiYQFu2UlWQ6W1ToAQdm3SMDbrabN0a/kuxBQ8O4oam8SUnp8qWylKcoORdtFWO3Za0XJ7BlWxn8NY3wvR25aisuqUlpSwFAAC9k29vtjl05ul9FT+52a1tDUY+ot0k//BdtuphbHhBY8IEqKrEJNjs0h22NnKOJKLg8NYGJ0VrDlbUdghCNdkFjppsiShMj5orsdR7jFc7fUBFpA+JL0/Wo9yor26xHYPdACWt90Lw7IUJ7Dt4QmW24/ZACHyh7IUC7nsMKU8QfsMLl640/NoAlntJlX1Uf4iIIsTqCZg9U+SjYP3BEGRWzIqAEghcivNVBkV5ivz7IAQ20HZEkrrMt/XH+ojKDcdQxNJNq6S11T5afeIAhuOqD+dkINg3bPcIeUG6RkVsEIpB0GRWwe6AEJFz64Do56jBlOY9VW/3QKQc6rIV+fZACrtbT86CHoB6Mv6yfcqGZSb9RX59kTIQejLGQ/KI9yoAggh2X9w/ZBkPmL/PsgBsEOyn0aoMu7IqAGp0JiZ/RQ+oj/FMRZVAiyDsO7siaZQcx6ivk2/8ABMAVt/qAhytTp2wJQbHqK2fndDsu7Ifz7IAaq3U7E/7MJ4CFKVXHUP59kLkPmK3fnZAEkjrNs389HviK+gET09KumsdRXygiAINx1DvgAghcp9GYXIfMX+fZADYIdlPo1QZd2RUAPT80X9dHuVEa/K9g9wiZCVdDc6h+URu7FREtBuboVs/0OyAGk+T2CGgak/nbDik5dEK2eHZChB8xX5EANPkn874B5JH52Q7KfRmEyKzDqHf7oAnmLBQB81H+AituA2Ram0EOJ6ivk2/8BEBTs6it8AINPVaG/RAh6kHKOor7IbkVYdRX2QA0aGLcprNsjhb/AHFbIofQVe3CLUihXTmuqdo3QBWVtP1j74IcUKueqrbw/CEyK2ZFQAkELkV5qoMivMV+fZABcBI9cTt//WuW9Kn/AHEJQco6itvCJ20H4OcGQ/KJ3euAKx2x1/k3VMS3JnWAzMOtOza3ej5TaxQ2CSOGy0ciU2rzFW9UdmwUOiUXC0iU6T5fS4LefdIJ9kdvQXwXPH4RxNeebdRXlHGFEklSttzmvrrHYuR95GG6MJ2ooFq1NBqXBTY2A1N+F9OEc4kcLzFbxb/xhhaW1OzK2itQ0SkXufsGwR3JUhhHD0+3T8TJzSctKIbpwAOhA6xsNhuBrG1YUZUJ1LtrKi8fsreShexp2XFw8azn8HOcR8nWMKe1O8oj6ZVhqXnS6Gk6KQM/VNtm22kWWOXfFUrieWr9Qk5ScMvKhgN5cgsRcm/G9tkaTlAodbxBhQ1+VrjrEkmWDjsiVEoXa1jobA24xxGcGV0An9WndbSwjiarptSnWc7j/duvwz0uma9ChSjR06TXDhS8OSOlsPcnGJcN13EeJJro+I5pxbsuyhZCUqJ6oSBpa0cxcl32AlTrK0JWMySpJAUOI4j1RGkJCkqO4g7OEb3H/KW3jWhUqkN0BiSNOAHONkXVpa1raD83jlqM6MlGO6f+Dq1LqlqFFyq4jOP/ANGCghCnXWEt6o2jhNZHQQg0hYBLAh3+qKtR8tu3mCLcVKj5bY/cEAW2l826h1TaVhCgrKrYqx2Hs/1HQ61y01KqVeQxBIYPoFKqVNLYYmJRMwcraBYNhC3VICLaaJHrEc8ggDWVvlKrlVqMhP0+TkKM3S2VsyUrIM2aYCyc5TnKjmJN7k6G1rWiDGOPqrjSWp0pUJOUZTIJ2sJUC6vIhOdWZRAOVCRYWHZGahIAmTNTCEhKHVBI2AGHIm5ok/p17OMQQqDZYMSuqEt1g3XKWtYbw7MoWpPPUxKFWJscpjD8+/p+mWP+xjdY7AmMHYWnAOsjnmVH2ggRgtm2OlqP9RfhGhpv9Fx8NlqVfeM0z+lXtH0jxj0abjXFFJpT9Ep9aeYkZr5VpNiFaai9rjZbSPKk/nDf1h74hOwdkc2UIyWJI6dK4q0JcVJ4Z12axNTOVgYfwXSpVFDmGwQ7MXABITawttva+sYfHVAncE4heoSqwua5oD9KhdgSRsIvoeyMy2440sONKKFJN0qSbEHsjVYVwLizHUvPVGkNJeRJDM8t1RuTa9hx0HZGooch5z9J2J3L1WHL5eavleF7GbM5O7elPd8+MIJyd/anu+YY4FJcUhYspJKSOBvaEjaWOxxXHDwy4idnehL+NPfKI+meCu2K/TZ3MfjT2wfTPCJEfMl/zUe5UVh5Z9Q90CpKJyct85dP/cwvTJz9qd75iMbT64TW0AS9MnLfOXR/3MHTZwKT8Ze754REdghfpgn86QBbnJyaD/zl7yEfSPmjtiATs1+0O/aYdOg9INjbqo0t+6Ihykb/ALoAl6ZNftDvePjB0ya/aHe8fGIbHj90Fjx+6AJDOzV/nDvePjE0jPTXSWvjLvlp+keIioQbjrfdE0iD0prW/XT7xAC9Om7p+Mu7B9I+MIZ6auLTLveMRkG6ddwhFBWl1cPdAEnTprMfjDu/6RgM7NZj8Yd7x8YhIOZWvGFI66ut934QBMJ2aA+cO94+MTtz010Zfxh35RP0jwVFKx11/P2ROgWll39In3KgA6bNftDvePjB02a/aHe8fGIrHj90Jbt+6AJunTX7Q73jB02a/aHe8fGIteMHrV+fsgCTps1p8Yd2H6R4euJ5qdms/wA4d+TR9I+YIp2uR6j7ommQQo62/Rt/4J7IAamdmv2h3vGHdNmtB0h3vGIBv13Q7/t+fsgB5nZq/wA4d7x8YXps0RpMO94+MQnyhr9x8IAD53Dd+EAXJCemumsfGHflB9I+MQJnZq4+MO94+MOp4vOsfzB/qIANRrbbAE/TZr9od7x8YOmzX7Q73j4xD+dhgt2/dAE3Tpr9od7xg6bNftDvePjEWvGD1q/P2QBbROzXQnfjDvyiPpHgqIVz0zr8Yd2D6R4euBAJk3f5qPcqInBqRfd/odkASdOmgPnDuzzj4wCemrAdId7x8YhN8u3d4QtjvVw93qgCbps1+0O94+MIZ2azD4w7v+keERfnYYQjrD2+6ALs3OzXOJ+MO/Jo+kfMEQGemtPjDvePjDpwHnE62/Rt/wCCYrkbLq4/nZAEyp2by6vu94+MNE7NafGHftPjDFBVtp+yG2VYa7uEATdNmx+vc7x8YsyE5NdOaHSHdvnGKBCrbfui1IpPTmtd4gBpnZrMfjDu07zCCdmv2h37TERHWVfiYIAm6ZNftDvePjB0ya/aHe8fGIYIAkVOThHzlz7TEyJyc+DnPjLnyqd54GKhF9InGkg5b0ifcYAj6ZNlYSZlZG8Zo7PMylZZ+BDIS76002Rly8Ug9U2Cj9xjjtJp79UqjEjLsrcW84lAShJJAJAvbhaO41TG1ToNRqlGk2WlNPhLWZQF0gICdPsjtaU3ThOceuxy76NKVWnCvlRwz3Z6dwfKJfn5KnqbqlHSJhTuSwUp0WSL79CTaOcVzEc/iGb6TOqylAyhKdAPYI3OMafMtYTZmUJbzK5pU0obVWQEpPaBoI5qU2Mdu4t/Rw5cX931P9nGV58xkpNYUFwr9HrYgqtQHJupLM44lLc6GVhKrZkFF7HsuI51OTk0l1CUzDgHNo0Cj5ojfzCUv4ArbJ/UOsPjs1yxzibtziD/AAke4RxdYbny232Ojo8FDjS8idNm/wBqd7xhqn3HDdx1Sj2m8RZbnyvZDktr+jlMcQ7q2AnWCBV0nrWEaNHJ5jBzDRxcKOfgxLfOlfPtB0tXtzgZzc5kvpny5e2BBnII0lf5OsY4XpbNYrlH6NKvEN355ta21kZglxCVFTara5VAG26LLHJTjuZw23iyXpDDlOdljOIyz8sX1MA2Lglwvnctxa+S0AZKKlR+UbH7gi1oRFapaLb+oIAsjZCwkLABBBBABD2Rd1I3XEMh7Plj1iJXUiXQ3+JG+f5NZNYGspUMvqBTHPTtjpcynpHJ3WGSL8w9LPDsubGOaHd2iOrqSwqcvKOZpk8upHwyaU+cN/WHviEbExNKfOG/rCICNnsjmHUG2PCPZoOLMQ4bamWKPUnZZubFnUptZQtbfs04R5A2CFjHOKksSRlo1p0JcdN4ZrajyaYhp+DpbHkw9LuyM2R5CwSm5sCeOuluMZIgA24R7lFq0xPu0/DVbrUwzQ+kpLrec5G0k6kDcY9rlJoGFKTWmpfA8/06VLQKyleeyvX/AKjDBy4+W92zoXFvSuKHqqP0qOOLL6v2Mi38yX/NT7jFfefUPdFm1pN0W2OpFvYYq/TI7BGzw42Zytuw4bwIQGwhBfNsgF9loqBSdBC364P52Q03ygWgHlC/50gCzOH4wdPoI/xEQX7PuiWduH9n0Ef4CINeEAOzDZb7oLjhDbnhBc8IAWwNomkQOktfXT7xEF9htwieR+ctfXT7xAERtdI7BAQNPUPdCnanTcIRXq3D3QAhFlK04wHy1dWF+lfthctzYDXgIJB7Ibx0iw3rKr0/WI9yojcYW0oIdbWhRFwkgg29USNi0ssfxEe5UWcXF4awRGSksxeUVztggO2CKkhBBBACbx6j7onmNV2/ht/4JiE7fYfdE0wOvb+G3/gmAIRYAwp2aQkEAEEEEAWKePjrGn6we+K/DTZFin26ax/MEVhtIgB17bvdBpwEJBE4a6hNPoEEEEQCdHzJz+aj3KiJY6x0+iPcIkRcSSx/FR7lREbkn1DZ6oAQgWt2Q6wt9nuhpvYaboUXsNNoHugBbCEsMwFuPug60JZWYe2ALE4Bzidf1bf+CYgsNPbE85fnE/y2/wDBMVzfT2wApsE2AhLeTcQpvYXEN4aboADs2botSHz5q3nCKpi1IfPmhb6QgCuryjCQqvKMJABF+g0wVqsydJMwlgTbqWucVsTfS8UI9nBkuZnFdJYG1c039lx4RmoRU6sYvdZRirycKUmnjCPa5SOT5vAjknzNRVMomknykAEEEX37IyjaVOyam0C6luoCRxOto3fLeVv4kYnAtRYel0hpJOictwbDdqI9HAXJVTsUYQ+HziBLE0zMhRYTbqhJsc3DQX9UburUo0LrlUY4zgwaHCpeW3MqSTaTf6DAOCseYLxlSahNUJPMzTKlXUQQluwuTwOzSLGMjPKxJNuz7AacWu6QNhR9E8NkbvFWPWpGWk00aptTDqbNKT5QyAAWJ3bI5nVqpOVieXPTqwXFgABOgSncBHWo2SsKPDOWZvfY5F7qPrrj+Xi1Sjtv5CarVWm5ZMhMVB5cumwDec202RRtbQffAbXvBEynKf3PJgjCMftWD1qS2JuiYikDrnp/OAfUUDHMZkWWgfw0e4R1LCiednZuUOyZkX2v7TaOYTycj+TzUJH3ARo6nHipQkb2mPFacfwQAJO2FAYvqVCGwW7I4uDuCuBvKQg3Ft8dco0qiicmq6zI4wos5VqowGpmWmKgQ7JySFhXR0NlOqlkA2BtaORQQwDtPKXWsNKw3iubp2IpKfVi6ryU9IsMKJcYaZQ4F86CBkN3Ei37saahYmwqzyb0J2amcLoVLYUfp0xNdIc+F2Xys5WkN/JhJ0BNr2j5u8YcRrFQJvURqL6eqK1SFlt/UEWwBY/ndFWpW51H8oQBZghAOGp2Wj0F4frjLkqy7R5xtc/80SplQL2thkH0tdNIAoQR7b+BsZy0+5S38KVZE401z7kuZNznEN+eUgXCe0x4qkqRopNj26QAkOa8seuGw9nyx9YRaPVBvCOt4Zoc5iLD1dpEq2M78u3zZJAGcHQRyick5qnTbsjOt82+wotrTwI0jp+GcUVLDaXBIlBRMBOZLibi/ER69Z5L6XjCRXiiSmOiz86kK5ouJDPObNbC4vYaR6qrZfMLaEaX3x6nlad69PuZut9kn1RxymSszOTjbMpLOPrzA5W0FRt6hFd5h6XWWJhlbTiCApC0kFPYQdkdvwjhlrkr5uo1pPS52oK5i7NsjKNpIJFybxhOVKnTjuIl1tiX5yTn20utOtpJGgsQojQHQDdGnX0Z29tzJP6/Bu2+tQubnlQX0Y+73MQNkLCJ1OUa9kKeqLnQRwXF5xg7nEgjrf8A8fW2Vz1YK20KKGEEEpBKdd19n4RyO44x1zkXAp9LnajsM1NMygPEEEx1NEj/ADsW+xy9Zl/Jyj5wYfGb7EziCsvSraENqniEhBBSRY6gjTW1/bGc2KPqEdPm+TmjjA9XxK7iFLc7KTTiRKnKBdCikJI23I2W7I5fcZj7I0K9XmV5/lnZjZytralJ9JRWO4C4PkXhdfM+6FFr74NOJ+2MBjGm+XyIASCnT82hdCnf9sLpmSfzsgCadzc+Tk+gj/ERDdXmfdE89bpB2+Sj/ERBpxP2wAnW8yDreZC6cT9sGnE/bADVZrjqcIlkc3SW9Ldce8RGRqLExNI6TLY/fT7xAEJzZh1b6CAlWnU3D3Q76SduwQitxudg90ANBIUbptHv4FUP+X0i7CXgZpsFBtYgm2+PBO0xquTCW6Tjml3TcMuF8i2wIBVf1aRs2e9xD8mvdvFCbfg0nL3U5R2vylIYllIdkmrrd0GcK2DT1Rzhknoy/wCYj3KjZ8ry1z0/Sq4Rc1CTuo8SlZHutGLbv0ZYSnMS4gAAbTZQAjo65mV5J/8ABz9ESp2USE7YIuT9FrVLShVTpj8sHRdCnGygK9VxrFOxva0ciUJQ2kjqwqRmsp5CFyqzWCTcC9hwjbYE5O5mtVBmcxBLrkqQOsp1481zp+ihObbu1jqUg1ya4MqrshLSzaXJpIKnNXgATbLfXLHasdEqXUOZUfCvc419rtG1ny4JyfsfO28epXuiaZ8v1tt/4Jj2MbUZ+lYjqDYkCxLl0raKUnIULsUlJ2G4I2b4bR8LVnFU6qTospz7zTDa1gkJCRkFtTpHPqWdSNXkxWX2N+ne050lVk9sZ/B4cAO7fwjslB5EacikGdxNPvMzbYKnWZdxBDaRci9xrsELj/DOFanhZL2DKewubkVBShLpAcU1bUkDb9kdNfD1yqLq1Gl7HP8A9QWzqqlTTaffscaAvBCuNusuc26yts7cqwQbbj6ocww7MvIl2EFbrqglCRtKjoAI4kqcovhxv4O3GcXHizsS0/56x/MT74rbCd3H1b/ujRVLB2IsKTkiqu04ywmVAtnMFC4tcG2w6jTw08amSZn6lKyIFzMPttW9agP9xbkzhUUZrDMfOp1ablTeVg63yuS2EqfhGmy8pSWJWefKHWC20E9QJAVc21GuwxxyOtctSROUuQmG02TTZ5+QNvqJI/xMcljq67j1CSSSwjl6E27dvOXlhBBBHDO0ToPxJwW/WI9yoiuSTpuHuiVBHQnP5qPcqIjcEgcB7oAapRsNBshQo2HqHuhCdPYN8OvoPUN/ZACZuyG5usPb7ode+33wbFjTj7oAmnFnnE6D5NH+CYgzHTZFicJ5xP8ALb/xTEH52wAFRy3sIbc5Rp90POzh7fwhNQBx9f4QA0k22CLcifjzW7rRW1t+MWZH5+1fjAFZR6x9ZhIFAFZNjt7YTKOCvtMALGs5LpcTGMpVa9Ey7Tr5PDKgkffGTA4J+2N/yOU9ycq1VyqQhXwepttSjYBaiEi52AWJjbsV/MQNO/z6eSXV7f3PareEq5j+hUd2gygfmmXJhpxOYABAOYEk+vZGhwqml4S5PlylUlxK1GYD6Xk5eutQWpIBPCw07IvP0zE2AKLMSdEqCTP86w42tABGRw5CCNm0j7IzOOJ1yYqTkupecygaYKjtKgk5ifbePSJz9Q7xJOPDhfk41WhRoWisZNqqpZeHtgzZ12bLaeqEgSrTZC5jGu5N9SscRSSEgggiSx7GD3A3iWRJ2LcyH1FJEc5rjRl6rMy5Fi2spI9WkbqiuczWJJ3zJhtX9wjy8RYTrOIse1in0OS55bbxWoZgAlJ3knQCMV1RlXoKMN3kta1o29xKU3hYMTcQsdcp3Ii2zh2YqGIZ7mJ5pC1ltpaVIbAGmY290ckUACQLHbsjm3enV7KMZVV1Ora6jQvJONF5wJBBBGib6QQqtsM8YcRYxQgUbDFWpfKt/wAoRaG+KtS+Vb/lCALKVKbUlVyk3uk7NQdLR3Kj4skn6/yYVHEdeaedYl5lD70y+FFlechBWSeru27o4YMv0klXDs9ULYHywpfC+6AO8N4pmcGDB9Eq1fpK5xEtMGrPKfTNpaQHs6LLQSlS9LgA21APCMRywUqlStQkqvTK4xNtz7dkS7a2yJdsIQUJASSQOsodaysyVG2sc+sn6QWvhfd6oOrsWFL4X3eqAJksM5QVzAQd6cp0h7bLGYWmgdR9ExW9t/XD2dVj1iLQ6kSWUbtvIGkXeINhpbZpFmXnX5ZSVS9QcSEqCgLm1xFRPyaPUPdCx6alJwScdjzdamptpo9mpYin6++wiqT3OJZ8hIFgDx0jRYcxdQZPD4w/Upd1ebMk2SCCFaaX2RiJdLZdSpQ1BENIukOo8pI0jap3dSE+N758mlOyhKKgtsdDZS3I5hGkTEvWarWlTEk4TlZWAEKJOguNbDZHuU+mcmEjUHqXKU6TCplIRmPXbOhAAJ2RzR+oz862huZmHFtt+QgqNh6t0RhRSoKSSk6WI3Rs0rq3ov8Ah0l7mGpa3FVfXVe3TBlK9TGadW52RWVSqkPrCWFIN0i5t6xa2sdEw6pFKwbQ8r/zioqfuU+UEkAafbHrY2l8M1vAD9ZRLtvVCUabS48lv9KlVxqo2uPXsjyKu0adTcPU9SrmWkEqVpbVaiq/2WjXjYq1uJVYvZrP9zPK+d1bxpSTTTxv3x3MxjaRlJfFlVbmppQaXUEOrQEnyFXV6t/CPQ5R5Lkubapv/BZtYcLV5q6VEE24bjeIeVlnm6w3NBI+OS8s8SOGQp94jy+TnC0hjLE7FDqdTEgw6hSlOaAkgaAE6X9ceV1mlwXUqmeh7P4fuJ17VWyim5YSb7GfS2x+1W7MkHNMD/8AX/YY9HGFElcO4mnqLJTyZxiUcCEvC3WFh7OzThHjRqxkpJNdGZK1J0ZunLqictM2+d/2GANMXSOk/wBp4RD9AQo8pP53RJjwXp1pjpHzv6CPonzREHNM/tf9hhZ35f8A6I/wEQQIJuaZ/a/7DCc0z+1/2mIoIEEvMsaXm+H0YnkWZfpLXxv6afoHiIpbx7InkR8ZaH76feIAcWWLj43sA+hCKZl9LTe4fR7IhNvuHuhIAmLTFz8b/sjZ8lbDbdaqFRQ/cyVMmHb5SNSAj/8AtGGje8nSDLUDEtRy2zNsSiT/ADFm4/tEdHS1m6jk0NTeLaRZxtLNTWCqFNl/rScw9LHTYmwt9948vk/wwiqTJqs2XEU2nqEy+6UEJUEA2SCdCb22bI9epNKn+TmpMgXXJzbMwn6puk/eRGrk65LYUwJJ4amJIOTrkqFLCbZUlwlXWG29iNvuj0HpIXN1zajxFL/J5z1dS3tHTpLMm8fo9NGJsMY5WzSq7SW+jIu4hTpICVgC2o2C3sinLcnHJi9PzM/KzCHEtKuGC/ZpKkpB0vqRf2X0EYEJOQFBKb6qsCB6tIUL5pOVoqTfbt1jZV5CX9WmpY7mBWk4b0qjjnsbLEmOJetUA0BuSSyErFlAGwSnYBvjIltlQ6zuvG0Q9U3tpCxp17ideWZdjaoWkKEfpXU6HJ4jwzW6BK4Tq7ayXUiVWo2sBuXc7N0PfXROTVqVbwy3LnpAyPqVZa3EpFk3I2RzpKgkgp0IINx7IfPKUt9CluqWAlOh+qI2o6g1H7VxLozW+XLP3Ph8HoVOrzdYmnpyYnSA+oEtpJCbcLeyHUCel6NWZapOLKm2Sc6UbVJsQRbhc7I8pRST1RbshO2Nb1FRzU5PLNv0sODlpbex0GuYew1ytzCJiUm3pFynICVKDYGdJva47NRDKNyc4XwfT5mttzbdRqMmlSm1v2yJUNgCNt/tjDy05NySyuUmXGSRYlCiNPZCKmH3EqQp5Zz3vc7bxuK6t2+bOknPyabtbhLlQqPg8exocbVCaxfhqQqy1JQqlToE4gDcvRC7bhpb2xheTeSl5nGtL/T3Qy/z6tNyAT4RuuTuZpcrVpiUqq0iWnGeZKHBdCySLX3bL7YhlKVTaTyoYgepkqhiTkaY64lKU2QlS0AAjgNRs0jWurd3koXT65xg2La4VlCpaxW2OpBidYrGBqy6tz5tVG5wm19V3Rsjl2WW/af7DHT6ajpmGsUU2170/pIHa2sKjlLfki8czWo8fBUOnomIqcCfJLftH9hgyy37T/YYigjgHeLaW2OhOETGnOo+ieCohLLG+YGwfQPCFSPiLn85v3KiFQvYfnZADy0xl+XGzzD4w4NMWHxgbB9E8IgVDhsT7PdAEvMsD9eO4YOaYuP04sP3TEfhAfKH53QBbnGmOcF5gfJt/QPmJ7Yr80xpaYG/6Bh078sPqI/xTEMASlmXt84HcPjDeZYsPjA0/cPjDIIAdzLA/XjuHxi3ItMiea/TjyvNMUVbIsyPz5r68AIGZck3mrG50yHjC8xLgfOv7DFfXOobRfZeBYFvJtAE3NSw2zYtxyGOv4awc1h3k4msUM1ht1yrtNBKUgAtgLvYb72I07I5dh7B+I8UtzS6FS3ZtEoMzxRoEi1/bpuja0FTktyb9HdUsrfqZABJslCEAWA2DXhG/piU7nEX06mLUU7e046kNpdH7m25NVvz9Rm35mcXNZWEApWCokhV027AReMriKUMjUp+WdnQ4pMxcqKDre51jzJeYmpNQclJhxpRABKFEX+yBxSnGnFuLKlqWCVE3JNjHpnWgrZUUt/J5F0pyuXXcuq6DU5bfLDuQt0+nT3YiGyFjSwbZIMtvlh3INPTJ7kRwW0ECy6FqndGNTlRNPZWOdRzigPJTcX0jo2IcUUjD00mdw8qSdmJuypmyBdQAFrkH7o5eLe+JJi3O+we6Nu3u5W8XGK3Zp3FlG5knJ9DRMYocmq6ZyedvLzxLUyym+VSCLW4RgMZ4JqWE51znmFmSW6RLvZeqpJ2C+423aR7IORYc22INosY85QajiSQRh/4LS02yoKU6m5Kja1gNwjDd1qdxQl6iW66GSzp1ba4iqEVwvqc6seEETKaWgXU2oesWjfyMvQqryPTDow9JS1Rka0xKrqKMxedQ4m5CipRAA4JA2R5RvB66L2Oc2P2H/8AyFKhxEdo5UKLh5ugYrlZHDNPpysJVaRkpN+XYDbrzTqHMwdUOs6btpN1X8r1Ro6LhfCM7yeUaQek8KOzM5hJ+oCSFOtV3plKz+lTMc2LJCQTYubBbLFQfOid8V6j8oj+UIsgAZgBYA6CKtR+VR/LEAWR2qI7BBe/0vsgvbZBqNIADrtV6rQXJ2qI4WguRBqIADrthzPlD1iGw5ry/bErZoPobpvyE+oe6FhEeQntA/1Cx6SD+lHnp/cPbAzpsNbiIW85Tt0AtaJ2R+kQO0RGgaERcxYC+y4tpBCnbCRKIwe/hBwKqgpjzfOy1SSZZ9s7FJOw24xc5R6K/TKpLul1K2Fy6GWrCxSEC1j7LRmZeYelXkPsOFt1tQUlSdCDFqqVio1laV1KaW+pAsCrdG/TuIRt3Tktzn1becq6qReF3RT5T2y5RMOz/lF6WLZP1FH/AEY5+2sp2XFthBsY7PVsFzOJeTSVmmnwl2QU6+2m18ydhTps2XjiySBodDsjiavbzhONRrZo7uiXUeF04veLNlhfksreL8PVDE0i+w3LyFwoOKN1EC/s03xi7Wv98elJYgrdMk5inSFTfl5ea0daQshKt2o3xp8WclU5hLCtNxS/VZZ9ufA/RIOqSRca31FhHnON058M+nY9i7eN5Q5ltHeK+ptmI+jDh5SfzugA4QmxQ9cZjllie+cf9Ef4iIInnvnH/RH+IiCBVhBBBAgOHsiaR+ct/XT7xEMTSPzlofvp94gCE7fYIIDu9UITYXOkALHR8LtGX5NZh4pt0uqpQO0Nt395jnktKzE6+iWlGFuuuGyEITcqPACO8VLDtFpHJ5L0pcyhE7IJDikJcBJeOirgfZ2R3dEtZVJyqPZJbHD1u7jSpxp9W32KHJ3S2q0ajSppouSrzLXOAbilwKSPtEeRiZyZdq1QXOM827z2UpGxIAIAHZYCIsP4mqWG3nHactILyQlQULgjaIrz06/UC/OzS87rqwpSjvNjHanXg7aNNdcnFhQqO4dR9MFIFRsNwAtAtKlLF7Qo2D1QRoZ7G7hIVQynLppwhIIIq3kyx6BbqkgbolmsxWAUAdVH+Ihm4i26JJv5f/oj/ERYrtkiV5RhIIIDsF7QQmQq+la5h+W2btGgvACsA8+gDRWYWjotKp7mJcHP1JhKWqg/JmScdP6xtpQUCeBsLeyOeM2Ew3bzh74u03EVVpUi7ISc242y4TmSlVhwNuHDSN6zrQpN8e6ZpXtvKvD+G8PJbwcgLqq6cRbpsrMS6gdnyZNvtEcjCSgFKgQQSLGOtYKUx/yeTcm30tIQSq5UEi+U6EndujxOV7C9Nw9XWHqMytMrPNc6VAlSM99Qk7O2140r+1lXtebHszasLhULrlS/3IwUEJmTxELHmXA9QpJ9CdHzF3+c37lRAr8/ZEyPmLn85HuVEKto/O6KEiK2QqdifzuhFbIUfR/O6ADf/wBYU+UPzuhN/wD1hT5Q/O6AJp35UfUR/imIImnflh9RH+KY9el4DxXWaUqt0ykOPygJCSki6rGxypvc66Rlo0Z15cNNZZirVqdCPFUeEeFBHt13BWJMNyjU7WaaqXZdOVJJB14EX0PrjxImrQnRlw1Fh+5NGtCvHiptNCKB4RZkfnrXrivE8iQmcaJ0GbfGNIyECkkXcVktc7tdsTSMhO1V5ErTZRT7qzlShO1R4ADb7IgVfMU21KrWjt2DeSiZwhV6PiqZxBLoba/SOJsAUrIslIvu1jLRta1zLgorLMdS4oW6467xH/vQweG8S8oXJxPzFBpsuqTmZ/K2thbd1EkWFu2xjptXmMO0vCAw+4WTUWEALShOqXzqskj1n3R781IYUn8aOYonqi27UWmwkFTicjQtYKSN5+32RyapKQ5UH1tv88guEhfnC+2PS2Wmy0inKrVw5z2/R57UtXjrM1a0JS5MN1nYiSbJF4VQPR1abVj3GIxsiU/In6w90UcjGlhYIk7NkLBBEF8BCnYISC2kCQESPj9KB2D3RGIkf+V/6j3QBGdsZKv/AP2blvNT7hGtO2MniH/7Rz6qfcI077ansbdmv4n6PN0+yLzVZqjFHeoLU2pNPmX0zDrAAAU4kZQb7RpppFKCOMdpPB71f5QsZYopctSK7VzMy0soFKebSkqIFgVkC6yBpdWsXJblUx7L4ebwuxWG26czLmUaAlWw6hgklTYdy5wk32XtGVggXF0ANt8Vaif0jf8AKEWBv9cVal8o3/LERgo3uW0W1vAmxBudkMgioHoIN7nZsgTqDc7IZBADgbxKyOt9kQjbErIuu3aIeCJbI3KPIHqHuhYRFubSOwQselp/Yjz839THs/Ko+sIakWvcb4cwP0zd/OEIPJVFzGIdsJBBABDhb7IjVthw3Qe5Q9ekYhqFKSlDU26lhLgUpsC4KbG4t/qNfNL5Ka5PyiZyQlgQCoKLWRKTwVbQ3jnunRj9ce4xEPo+yN2jeukuGSUl7mrWslVeYS4X7GwqPI3hiuCbquHKsWGhcJabAUhKwLnbraOY4dq7dNxFT0YrS/O0unPkOSyiVJAF03CTs11tGqlalPSC0qlJp1lKVhZCDYXHZG0rlAwTjuUYkJF6WlKo+Uuh9DAC1KA64NrXvYxhvNPoarHNCKjNf5/Bn07V7nQ6q5snOH/epjK9QUcp2Jp+ocmVCSzTpZlHOpUAjrW2hOwaC1hwjm62nWHCy8koWhRCgdx1uI6PVKbjfkgn3JbD1SddYqLF1uNMXzAaEEa2Ou3hHqKoeHq3yZyjdMwvOf8AI5l9CTMlk2uV9YlW5Nr6R5Kpp15Y1eVKDfjB72nfadrFH1UaihPdvOy/Ryqctz+z6CP8REFjwjqchyHV+eqPNVOdYlGEtI/So6+ZQASUgaHaNvCPYleQ7D0tJPu1TELi1tk9dspQlAB3g3MdehoN9XXFwY/J5a412xt58DnlrwcTuL2hY6tyl4EwpRcLy1Uw22VuIdShxxLpczJIOqtw+4Ryg6bY1b2wqWNTlT3ZtWN/Tv6fNp7L3FieRHxlr66feItIw5XXKb8MN0qZVJbOeDZKOG37o9TCGBsRYkqqZaVk1S6Ghzi3n0FCUgWsBxPYIwwtK9RqMYN59jLVu6FKLlKa267mdQ0t1aW0JKlLICQBqTuAEddoPI7IUVyWq+MKg05LWBVL5SE3IsAo8LkHThHpYT5KJHDZcqtZnmJmflkqLbadWmjYkEg7TpfWwjPVHE1ZrCDL1CoLeaSokJOy4v8An3R6Gx0yFiuZeRy30R5q81Sd/Pk2csR7v/8ADc017kwwzUZlymy7bL4QDzzYzp36JvqD6o5vOu8/NPvNBYQ66VhKlE6RHYk3tFtmkVSYSytqnv5X1BDa8nVWTsAPrjZub1VYqCSikUtNOnCXFvJ+5QGy0WBfoivWPcY0Uhyc4mnagulqkeYfQ3zhDigBa9hr69Iuy9EwpL4VnBVZotVdh8trbSbkEEgADeI5ruYLZHcp6bWntNcK8sxegAvwEJcXAuNdkdCXK8mNHrFMdS65MyzrJ6QnUhKrCxP36QxiocnHNVtJp6ruH4lmTchOUAW4da5tGNXDb2izP8oSWZ1ImKap0+8plLcm8TMHK11DZfqNtfZHu0Pk/rtampmULaZRyTSFOJf0NiDaw9luEXZzlHmlU6kyUrT2GnqW4HEuBN83VsBbcLR5FXxhXatU3as5NKYedQGzzV0jKBsteJlKtJfTsQqWn0X9UnLB67fJ82cPtVhVYZS4uYQ0po26oKwgnbuj0hye4ek8Sy9Mq2I2+ivSxdDiVJGosLE3sOPaBHPFTD3MgKecIBKsuY2JuP8AcSTLrjkwC4c5CAEkqN09UaQdKpJbyIje2UOlHJsE4cwYqiVOdFazTUq4sS7eYArAOgtvvbdEGIsAGkIpiZCptzr9RUGwhAA1tfTXZYRkE5kpCdEi26JmJ6blphmaZmFh1hQU0q/kkbLcIRpzi/uEru1qrhdJL3PVnMCYmlKmaUuQdU/k52zeoCdxJGzZ90eeqi1lmSXUF06ZEtm5tThQQEkaWva0aGn8peJ5GovVRcyh999sNKLqRaw2Wtshn/Pqs9SPgGbS2uTdf5xwhNlkFeZQFtm+Jc6q7IpKjpz3UmjNtZkvtJWLEEcDpEI2K+tHRXJDAOJ65ISlDcEg2hsrdJTlzKFrJF9L2ueEVWsOYIkqdWW56rc5Oyq1NypBtmAAsQNh109kWjdR7rcPS5y3hJOP5MKQRbS0bbBtfoEtTH5HE7SZltKs7KHUZwkW1CRuMR1HkyqbKKWZWcamHKmQENg2CTlzG54abo8apYVrtKnpinPSKnVyyQtxTIK0gG1tg7Y2Le+VKWVv7M0bvSK0oYmv2j25/BPJ3iCguSmHWZZiozJvKhaiFhe9J10FtI5ZirBVewc+wxW2209IQVNKbVmTodl+PZGqlHpuRfanpUqQ40oKQsDQH3RsafO0jH5ckcZtSp6L+klrEtkE6HrX+6NyrSttTjjCjP26HLhO60mSbblDvnqcNQPiLg/jI9yogVu9nujp9d5HZ9iVqVRoU5KvyCCZhhAWorUgXum9tbEkbdgjmbbLjq0tNtqUtWxKRqfUAI81dadXtpYnE9Ja6jb3Ucwl+iNWyFGgA/OyHraW2strQpK0eUkixT6xuj28D4XVi+vtUouLalxdUw6keQm2mu4k2Gsa8LepUmoRW7Nmrc06VN1JPZHheEBtmHs90dxTyGYSM8tBr81zSW02aCkZ0q3km2zTdaPOY5B5OXIqFRxLmlEOBRCWgAUX0Ga+htwjrP4cvdnhYfuciPxHZNbto5exSp+t1Vmm0yXW8+6lpICUkhN0jU2Gg7dkdfViVzBUk3g+itJAkmg0t5V7h06rI3WuTGnpVJw9hqopl8H0ZE9NPtArLLmZaUJFk6q0HC0eDUcJz2I5erYxfdZk1sOqSqUNs/U0Nzfsjo06FPRoP61zWauK/wAQzUYU3yvL2yebWqjNcomHJihO5GagwRMSwAsJgpGqTwMcxp+B8WVGZXKSeH5znGwCpK2ygDhqrbHaFYdpGGanQZ6VrDcwX3E86LiybjXZsEbB/EFHkcSGnTlVlUsCWS4FC3la6adlorVlaaklUuptSX+TNHT9Q0xujawTi/focnkOQlxygpnapWhJz2YBbdgptsX2KPG3btjT4d5MMM4Sqcu7MGYqUzMpKG0rbBQm2pOW0PqbmFahQp2oP1h9U25NKXzAcICk5tBl2eTbWG1nG1JkavTZ/CiVl1iX5p4PAlNtLAbt26LRubCi0rajlruy/wAqvakeO7uUovql1PUXgDAU2KhVX6LmmQsLSjVASUC5GXcTaMjiPHM9W5EUtyWbYabWOqka2GwE+zdEasfYhdE4M7aROKKyMougkAEJMZs3Uq6lZidp4xl5tOinKisSn1NOpGdaSpVd4Q+33/JCc5UVKUok8eELa260PO2CNVybMijgQbIlPyJ+uPdEcSfqD9Ye6K4JwR7YIIIE5xsEHiIIIABt+2Hv/Kj6o90MFr+yJJgDnQOwe6AI4ymIf/s3Pqp9wjVxkq/rU3PUPcI071Zp/s3bL+p+jz4IINscXO510EEEESZEIN4irUvLb/liLPGKlS+Ub/liBRotR72BMLnGeKpDDnSejibcyqdtfKkAkkDjYR4J2x7uCMTv4MxRIYjlpZL6pNy5aUbBSbWIvu0igOh07khwVWX5OekcUzLFKqsot2S6Uppt4OJcDasxNkkAEKsnW2m2Oa4iw+5huqro8xNtvPspSXQ2kgIWRqi53gWB9o3Rp6rykSQnKMrDuHRJ0/DzbqZGWm3ufWHFnNnUoBIUQbWFhoBtiLlC5QZfHMvSkppKpZ+RbKXXFuheYlKE2ToMqboKra6qJvAGKy9kSNIVmBA3iHBxxIACWtPOQCfvEPTOPI0yM9weESVlvsbJohTSFJFxlGo2bIflNtkZFNbqCEhDbiAkbAEiw+6F+H6l6ZPdHhHWhfQUUmc52M2/Y2DIPPI0+kPfCCwCr74y8lXKkubaSXU2KgPJHhEPw7U/SDujwifmMfBT0Ml4NXY8IWw4GMn8O1L0g7o8IPh6p+lHdHhD5hDwSrCT8GqKVX8kw7KbWyxkvhyp+lHdHhB8O1P0qe6IfMIeB8umbG3xY288e4xCAdNOH+ozaa5UjJLUXRcOoA6o4GIDXqpvdT9giPmEPBX0E/Jr7HZD2X35V5L8s6ppxB6qkmxG7SMb8O1P0o7o8IPh2p+lT3RFlqUVjBV6bOXXB2TDGP0yLcwmuB6dcULtlRBA02a7oe7ypTJkjLy1Mbadz3SoHqgX00HZHGPh2p+eO6IjNdqecfpR3R4Rux+IakY8KNP/AE7SlPil/bsd1oWIV4oriZat1j4KaYYKkqbVkzneCfvtHgzuGa/NNT9Wpbrs1Tm3VJDpXq4N57R2xzGZr1T5z5UeSn6I80dkX5TlCxfJ0t2jsVZTco7e7YSLWNr7t5jRr6zXqT4uJnZtNIso0lSqU0vddTp9HwvXKROylJr8s2abWQph1tSswIy3GzYRaPZp/JBgeSqL8uaYudWWkqLbqioNgnaLfZHHZnlLxnOmTXNVhS1yNlMHIkZTx9cTDlZx8moOVNFeWmYdb5taghIBSNgtbtjNb63yo4q01N+Wa9zoVtVq/wAKtKEcdEdrE5V6fSFppuHGTS25jo7OtkhAVYkp9d49GuSmInqxS6dRlsSjj6FvKUSMqkgWtbhHzy9ykYxdpho66uvoy3C4U5Re5NzY7tddIYzjfFbtQlXV1qZ5xuzYXm1COA9kZJfEV3NNQwkZYfDukwxxpyx136nWncH1CflqzU6tiLmpqUWtC0BYCVZU6Ai/DQRC5hLBDaqQBX9ZtdpjK4LNixsTwF9NdxjjS8U1+YWtx6pLKnFEq0HWPbDPhypkdaZv60iObUvqlTepJtm9StrS2+mlSWDt7M1gHClRq8g4k1JtxAEu4LLAXbUX2e2PHd5Q6oujS1EYaZaak3ErbcSnrgpIIBv6gI5R8N1HZzw7ohfhuo+mT3RFI3FNbyy2TVrXEvppYivY6bP4+xPP1IVZVTU2+GuauiwGX1R4i3lvhbrisy1OhRJ2k2OsY34bqPph3RE7daqIk3Fh8XDiAOqNlleAjNG9pQ+2Jo1aNzX/AKs8mkcvnveFSRYcYyhrtTO15J/6iD4dqXpU9wRkWoQ8GD0M+mTWaXvArVMZP4dqXpU9wQnw5UvSo7gg9Qh4J9BL2NXtCbKsE7Rp90OmDmWpI0IQnQ2F+qIyKq5Ubj9Knf8AQEWJyt1Hn786m/No+gPNHZEevh4I+Xy8o0qlozaGwAhAtA3iMr8N1H0qe4IT4bqHno7gifXQ8BWE14NXmTxhMyOIjK/DdR2c6nuCD4bqPpE9wQ9dAj0E2+xrpfKp5Cc1rqAuIapST9PbtjNSNaqCp1hBdTYuIHkDZcRAa1UdvOp7g8Ih3kH2LKxnHZM3EtXKnKusPs1B0LlyC0c5OXdoDHu0blJq9JcnnXAmbcnkgOLc2ggEaRyr4bqOznUdwQfDVQ9InuDwjG7qk+qM9ON1Ra4JHYUY3pE1QZLDs1S2UIQ+2Zh5IsShJFyLb49L4I5NKviPmpOppk5JMslRJXlC18LnZxjhnw3UPSJ/piD4bqPpEdweEQ68MfQ2jfp1aklivBS/R36iyT8hhmanZDEjbslLTCktS+hKkZ7Ea8dtu2NQqk02Vq0giVokml6aS4pC8gBQkAHZbtAj5eRX6siUdSmaIHOINgABsVu9kWFY+xet1p9VbmCtgENKvqgcBwEbtDXbmguFYkvdZNG50bTruSlKHB/6vB9FOUelzr1cfnMOMqclAEPqCEkqTkB28Y8eq4TkadhKXlcMSHQ3Kk62Wgg2K9NhVwy6xxWW5S8ayctNSrFZcCJy/PXSCVbtSRwhy+VHHK2JSXNbWG5FWZkBCeqbWHr001jLL4hrSi1KEc+cGs/hzT1jFSSXjOxv2sB40dqUxItpWZhhsKdPOaZDsF9+zZFRFOxaunNyg6QKet4M3VfIFXt9l4ybfK9j1qddn26ypL77YbcIbTYgAjQW02xM5yv4sfwwnCy3GeYQsOc7zdnLg3GuzbwjnLVrmOyOm9G0uSS3WDc1GTxByY1RicYm2w7NM6FOtwNLEbtRGYm6zU515556bcvMKKnADYKPq2RlariuvT76FztRdfUltISXLHKCBoIofDdRvfpBPsETG7i/qqLfyatehJPgt3iC7GvsSLKJ+3ZAAASbkk7zGPNeqYNue9lhB8PVP0/3CMivqa7Gr6Op5NjeJJc/p0W4pjFfD9U9OfsETS1fqfPt/pt43RKv4eB6KWOpqiDeEseEZNVbqZUf0/8AaPCD4aqfpx3R4Rb5hDwR6OZrLXgjJfDdT/af7R4QfDVTvfpH9o8Ij18PA9DLBrrDgYk05g/XHuMY34bqf7T/AG/hEya1VDLOfGdApP0RvB8Ievh4J9DP2NPY8ILHhGS+G6l+0DuiD4aqf7T/AGCI9fDwVdhLya32QRkvhqp7Ok/2wvw1Uxtmf7RE+vh4J9FL2NaBcw+YBDvsHujIJrVTsQZnd5o8IdM12pJcHxgeQn6I4CJV9Bk+hlg1JOuyMnXwPhFZG9I90N+H6l6f+0eEQO1F6YXzjwQpXEoF4wXF3GrHhijNQtnSllsri19fsEdNY5LKK7hQTCqrOoxCuimvpl8iOjiWCwkoJ8rPqDcadkc1U6HARlQLjSyALfdHQmeVmSThX4Pcw84quN0g0NFQMzZrohWFG7YFyvQC9wNNkc9m+j0+S3kho+OsLM1qcbxK9MTVZXSkmlyyXGJRKWm1h58lJsm67XuPJ2xzCpyIptTm6cH0PiWfWyHUbFBJIuOzSN/ye8qVEwlhlqhVWi1SZek6wqryzklUhLoUottoyOJ5tRUm7YOhG0iMJW6mutVidrDrTbS519b6m2xZKcxvYDhAuihbbFWpfKN29GItjyVRUqXyqP5QgMFmHJ01ghYoVFVqNYROmkEEAP5wjSwMMJJ+in8+yCCAwETrkZ1uTRUFyb6ZRxfNIfLZDal2uUhWwm2thrEA01G0bI6vTq6mqclVAksSVQzMtIYxlkJZdcvzUtzDpUAnaE3O7S8XQzg5pMUyq0tMtMz9Nm5VuZTzkut5lSA6jzkkiyh2jSHPUKuy9OZq79Gnm5CYVlZmly6wy4dlkrIsT2CO38scmioVNvEbNCk2qo/PTErKMLnBNNTVPSyCl4IWopQANAE23aaR7RnJOUll1uszzAwtNU+hNSAU6lSC62pAdCUA9VQUFlWm+LYKnztU6JWqIppNZpE7IGYQHWhNS6mucRuUkKAuO0RRuY7LyyCflsKdHxFNh2fmMTTk1JBTwcUZItpAUkg6IJy2Gmw6aRxmKtYLxHtoW6sNtIUtaiAkAXJO4ACPQl8OYinKkuiylBqL9QaF1yrcq4p5AsDcoAzAWIMQUipVGkVKWqVJm3JabYcCmnWjZSTcag7jH0RIzctP8pvKAp0P1MzdOpahLSM0hiZmDzEupSm3ToAkglQ22vs3QiW8HzsxI1F+ZFKl5KYcm1OBtMuholwr1GUJGt76WteLbeFsUPVRdCZw5VF1JpOZckmTcL6Ra9ygDMBbsjtUtOvr5ZK+60qmhubmag3ITzQQkmeXLKDSAu9wAogX2Zt8XlM1J3DZw3JzSTjNFBkG30pmEh/ImYUpSCu+qgkpJF72iSp86ONusOKZebUhaFFKkqFikg2II3HS1obffGx5YH5GZ5S6+/TnWnWTNWLjRBQpYSkLIOwjOFG4jHRGCU8F+m0Cv1hp9+kUWfnmpQZphctLLdSyniopFkjTbpDRQq0aV8Pijzppmfm+miXXzGbzectlv2bY6tyKyWNDRpnENM5+ZpVCmg+1TpVxKHJ2dU2oJSoEglAAuSbjdvjSTC5pWE3aq++03Qxgx2SfaDiAhNT6QCWubv5fOWOm5MMEcRwmTotbq7D85TKPPTjMokF9xiXW4hkW0KiBZIsN9oQUKtqpIrwo06aYVZBO9HXzBVwz2y37I7xgQ1RyQoJSZWQVScRTMxiBppxDLTcsqWbDalpGhRYOjS4urdeI6g8yvCEzU5aZZRhZeC1yTSQ8kI6d0gZWwjbnzDNs2awwTxY6Hz7BuiK5Um/ZD9NAokGxuBwA1hgoeg7QK63TGq45RJ9NNdWG0TipZYYUq9rBdspOlrCFqdDrtAclnK1Rp6n8+kOMGalltc4jzk5gLjtEdkRI8odE5NWayuXcqL1fYlpeRShbZlqfKNPBSFLTe3OKcFrW2XJ2iGco1Ox3RJSlYbqlMNVmkzU3UZufnC26w5NvMjOy1ckFCEIvfTr6jYIkscYdoVbl6a1W36POt059WVqbXLrDCzsslZGUnQ6CHVOhVqiFkVmjzsgZhHOMial1tc4jzk5gLjtFxH0Oidp8rLGt1ecZGEpql4eYkkF1KkKfbcb54BAOikqS6VaDQ9sZDlgRUJXCb0tiCa52dmcWTk3TwqYS6ehKZQM6cp0Qo5LbBdJ00irRKkcaiSXl35t9EtKsLeddIShttJUpROwAAXJ7BEdjtjccij8vLcptFcmX22CVuoZdcICUvlpQaJJ0HXKdYrggzgwnilVWOH04aqpqiU84ZESbnPhFtpby5gLa3taKjUlUXZn4KZkphc2p0NCXS2S4Vi4y5Rre+lvZH0EZatuYH/4kzMXx0jD7SXEdJSJjmxOlXN577cmVVr7IqNT7T3LVV3pRVP5mYfnZeUqCSgFVUMhlSA55vOgm+zMq8WSI4jijeFcUrrCsPIw1VVVRCSpUimTcL6Ra9y3bMBbW9tkec807LurYeaU242SlaFpIKVA6gjcb6Wj6EmpWqTGE14YlJrPjhvDFNQ62mYSJgJRMrUprPe2ZKCgkXJsOyOW8tEzJznKliKYkX2nkLmhndaIKVuhCQ6oEaEFYUbjTfE4LoxUXqbQq3WW5h2kUednUSiOcfVLy6nAyjiopHVGm02EUY7byOJmn8M0hVEn22V0/GDE3WEF4N5ZLmCA4u+1CeuLbOsNNYYD2OQfAFdVShXxRZ40wK5szol1cxm2Ac5bLfsvD5Oi1ytMTE7S6PPTrEmgKmHZeXW4hlNtCspFkiw2m2yOzVFnGEpye1vErLD1VpldlX6dSJRhaOjyVKRNB0vrTfRd0BKRa9ipXCLnJ+at0KgKb6DTjRsTTL+JWGFoZaalFSbaWlKSLAosHk216yrW1imCqZwoUOtGk/Dwo88aZn5vpvR18xn2Zc9st9LWijH0C8/LvYUfrUlNt/wDE14Bcp6G+eSG/hHpCcrYbvfnOcCVjS9kk33R8/RJZdQi+uhVpukorrlHnU01a+bROKl1BhS/NC7ZSewaxQj6CRzE1hVydqNUblsJTeCpCmNuKcC0MzvSbOAMg3LiFBxezYRtvEoh7HBOh1CWYlKo5IvolZhZEu+poht0oICglWxVrgEC9rjZEq6HXJemNVmYo081T5hWRqbVLrDLh4JXaxOmwcI7xypvUSpYFwY1gOt0StylOqNWlKdS0y6gUynMsErWlwAZhkUok7VLuNht6ImKfLU//AJBWZtlWEX6VhhiWSXklBfada59CUX0Ukh8qGm3ti2CqPnip0OtUUMGsUeekBMoDjHSZdbXOo3KTmAuO0aRRjtHLE1UJTCT7GI5tL87NYtnJ2mkvpdJklsthS0kbEKUGwNl8p00ji8RgkkYYfmnm5aWZW666oIbbbSSpRJ0AA1JvpYReew1iOXqyKA/QKk1U3LBEkqVWH1XFxZu2Y6dmyNHyNTUpJ8pFHdm3m2bqdbZccISlD6mlJaJOwdcp1jseH5h+iUSUpdVprVTxyxhRbCJJ2dyPKQudzFBcSoHNzWXQKvbfuMhs+cESE8ub+CkST6pxTgaEuGyXSu5GTIBfNfS3si4nCWKFVZVARhuqmpoTmVJCTc59IsNS3lzAWI3R1yjU2n4d5V52m0ToiaaHZ6XkJtbqCtFQcklZGQ8TchDigAdhKY9iaarL+GF4TYmQcaIwvTUOpE2kPkImXFLbK76qCS0Sm+wdkBnB88PMOy7y5eYaW262opWhaSCkjaCDqDutDMojbctr8nNcqNfeknm3kmYAcdaN0LdCQHFA7CCsKN/bGH02QKt5L9NoFbrSX1UejT0+JVPOPmWl1OhpHnKyjqjtMKnD9bVSVV5NFnjTEL5tU6JZfMJXsyldsoN9LR1/kYVPP4apLdEmksrkMWMTlX/TBq0kGSM6rnrIFljeOsBbURq6o/SXeTWouSC1FheHZppmoiZSJIBU8laZYsbS/oAF7Num+BKPnWSolbq7ExN0qjz06xJJCph2Xl1OIZTbasgWSLA6mGig1xVLNdTRp401KubM4JdXMBXDPbLe+lo7xyeCrv0+jloSlMXSsRvzWIGGltsIbljKoCFKSDYoIzjS4urthVutO4Udq0lNsnC3/CXZFSQ8kN9P59OVvm73z5xn0GwXicbE4PncjfCQ82KbQ1Kcp2RRjCJlyE83JJqTkm+JRS+bEwWyGiu2qQrZe27baLc9Q61Q+jOVmjz0gmZSHGFTMutoOp4pzAZh2i8dDw3WmnOSykylanudkaZjeTUJdxVw1LlAW7ZO4aqJ7Y0/KF8PMUSbZqDcrU56cxTOTdIl33m3krkzLpCnEpJ0QeqRe2qdmkERg4s5Qq4zS2q49Rp5FOfVlam1S6gws8ErIyk6bBBUqDW6MlhVYo09ICZRzjBmZdbQdTxTmAzDtGkfQKZmUlZQVmrTkv8A8Tdp1Bblmy4koL7byOfCWwbgpAczab+2MzywN1KRwlNs4hnEPzM7imZm6aC8HSZQtIutFjcIUcoGwdU6aRYnBxaHIQpakoQm6lEJATqSdgAH+oaFZosSFSn6PNtVOmTTktNyys7TrZspCtxBGwxQjBal8NYinKoaHKUCov1FAuqUblVqfSLXuUAZgLWOzZFdEjUDMmlpknzNlwN9HDZ5zPcjLl23vpbbHcqjTcUYy5ZsSylDq60ST0jITVXmZdxHPuNJZbJQ2onValG1gbX1OgitR5yrzvKxUKrXqHLUhU+/OJllPlsPMza5Y8ygrGzak32XO2MkRg5CjCmKF1Y0BGG6oamlOYyQk3OfA4lvLmAt2R5z7D0s8uXmWVtOtkpW2tJSpJ3gjceyPodbVUcw09hZmbBxsnDsm2pHSE8+oJmFFbee9swSWza97J7I5Vy0zMnMcpVZXKTLL5DiUPONEFK3ggBwgjQ9YK2ROCTExYlafPTyXVSUk/MBhBcdLTRWEIG1SrbB27BFeOi8j+IJ+SViWi/CZYkJzDs+pxgrCUPOpbGS43nhFMEYMFLyU9NMzEzLSb7rMokKmHG2ypLKSbAqIHVF9Nd+kSytCr1ZbmJml0WenWpNAMw5Ly63EspttWUjqj12juGChgprkQxPRaVjSmtTs5RUTlTYdZdD65oTDeRpJy5SlIGUAHapR0F4dydrrTlOpCwqTknJCvvTNcZaUhhCJUywCFKANlJtmFhfUxZDBwlFBri6UquIo08achXNqmxLqLCVcCu2UHsijH0cubYfw67VpKba/wCKowi/KON8+kI6bzqbIDd7584zbNgvsj5xg3ggNd0OGyAaCFjGWSwJlEGyFgi5ZCDYoRUqPyjf8oRb0sbRUqPyqP5YgSXIIIIoUCCCCJAQQQRACEKlCwBNhqBw9ULcC3boIIugBcfUQS6slIsm6joOA4Qis6kpSVqKRsSToPUN0LBE5GAJWu3OLUqwsLkmw4C8EEEG8kp4DQajSHJdeSvOhxYUdMwJB4WvDYIgZyOClgghZFjmFidvH1w4OOBZc51QWraoKNz7YjggQGp1gtugggB6H32tGnnEDbZKiBCc44pJbUtRQTmylRtfjbZeGwQGCTnnBms4oZxZVlHrDt4wy6ubDQUoIBvlvpf1QkEAKEpyEgpvbZwhDcLSALjNqRtAtugggRgm5x1ADXPrKLAhIWSB2AQOuPvW5yZeIGwFZIGm6IYNRpAkC2opCOdVlT5KSbgeobBAtTyyOddUuwsm5JsOAvBBABCglJuNCNnZCQQA/n3Uuc6HV57WzZje2zbDUrWCLKI1zCxOh4+uEggMEhcWXefzq5w/SBN+G2EJzbTc9sMggSngde0KhSm782opziyrG1xwNoZBANkvPvhrmkzDoRa2ULNrcLcIjzOkKCnFnPtGY9b18YSCBA4KUGw1mIRfNlvpfjbZBDYIEp4HQ4qUWuazqyA3y3Nr+rZEcEBnI4KdTbK6U2vYA2tpY2tCKzrbDK3CUA3CSTYHsEJBAgdmWoDnHFLyjKm5JsOA4QQ2CAH5ikgg2tqLQ7nnOd58OK5zZnzHNs47dkRQQGByhmSNTcKzDXfx9cIHHgvnOdXm11zG/wBu2EggAJJNzBBBAYBKlovkUpOYWNiRcdsOzuc1zGdXN3vkubX9UNggMDucdsRzi7K29Y6jt4w5K1Brmc6gi98tza/HheI4IcWAB29kKQBCQRQCBawnJc5b3y7r7L2hynHVFKitZKRYEk6DgOENsOELEgb18obzqCRsFzYeyBSluEc4ta7DKMyibDgOAh0EWAJ0teFVe2htCQQA9px1tZcbfcQpQAJSsg23bIFlbhzLcWo3zXKiTfj64ZBBbAkDzqXOeS6sL84KN/t2xERqTe5Ot4WCD3AQqVKQsKSSCElOmnrhIANbRCWAKB1SkEgHaAdoiRC1ISUpcUAraATr64igiyA4rXbKFkI82+n2Q2CE324C8S1kCwQbtkJvtFNicCwQb7b+EJElhNxitUtHW/5SYtCxvpFWoj9I2f4YgVcty0NkLCZE7rQZE9kUIOj8mlL5JZ6mTC8f1ZyVnA7ZpIUsAosPNHHjGucw9/8AGkNryYldzBJy5XHtttLXTHCsohco2aRo1LOU58aqNex6Sy12ja0FRlbQk13ZYfblfhBbUu4TLc8QhR25M1gT7I+hpPAlDcxXRKE5yaU52gl+SElVTYGoFbIUtKjf9NdRULDycu60fOGg9Ue3hnFtVwxWZGsyzpfXIKzMtPLJQk23C+m3daOhFYSR56pJTk5Yxl9PB3Cq8mdMquH5vncBy9NxW7S5lyWpErL5FgNzbaUPIaGoUWysabQI5Ryv4flML47mqHJSKZNEvKyRUwABlcVKtKXcbjmKj7YzL1XqL04uoKnn+fWokLDqrpBJ0BvoNdkVHn3Jh0vPOKWtVsylKJJ0sLk67IMoNgghIhPAFghLjjBccYZAsEEJDIFghLjjBccYZAsEEJDIFghLjjBccYZAsEEJDIFghLjjBccYZAsEEJDIFghLjjBccYZAsEEJDIFghLjjBccYZAsEEJDIFghLjjBccYZAsEEJDIFghLjjBccYZAsEEJDIFghLjjBccYZAsEEJDIFghLjjBccYZAsEEJDIFghLjjBccYZAsEEJDIFghLjjBfdEAWCCC2toAIIIIALEwtv3fvhLHcRBlVxETkBYmCxgyq7IMquIicgIISxvuhLHsiMgdBCWPAQW3aROQOAPCOg4Qo3JLN0Fh/FlUcYqSlL5xCVuAAZiE6JFtlo54SBBlQeP59kbFrcK3nxyipLwzWu7eVzT4FLh90dTqlB5D2qZNOU2svOTaWVFhOd03Xbqi1uMYbBcnTpvFtFlashsyD08wiZDpARzRWMwUTsFr68I8YISLWvDgFDZGa8vY3bXDBRx4MVjZStE1KblnyfR9PlMAVaYpUujk+w221V8QT1DU4yzYJlm0JUhaCDYL63l7bARNK8nfJnL4PoiHKKqfbm+iK6c3TbjpKpkJW25NFywGUlPN5d3tj5r6RMoyhDziQhWZICiMp3nsOkPbnp9LQl0zb4bSoKDYcOUHbe2y/bGombx9Iy9O5Ppmek5FfJxhxAmsWP4fUUy9imUS22oLGui7rPX22Ajz3OTzCqKQqXawnJroopgmkV86Ome54JLHOb9Mwyfu7I4CJuYBCi85cKzghR8rj69NsOM9M8z0YTDvNXzc3nOW/G17Xirwwm08H0NLYTwBivHmKcJO4ZpFKZwypFQaMu2El6Ul78+2ok9YqSUnj1Y+eKq/KTVTm5iQl0MSzjy1NNJFghF9ABwtaPTouMJ2gSVXl5SWZVM1dgSzk4u5dbauMyUHYM1gCTrYR4Wqtv3RLxguJbcYq1LRbd9LtiLelx6tkVKnYrYAOxsCIKNbk/TJL0i+7+MHTJH0i+5BBFAL0uR9Ivu/jB0uR9Ivu/jBBACdLkfSL7n4wdLkPPX3IIIsgHS5DZzi+7+MHS5Dz19yCCJJ7B0yR9IvufjB0yR9IvuQQRQgXpcj6Rfd/GDpcj6Rfd/GCCADpcj6Rfd/GE6ZI+kX3IIIAXpcj6Rfd/GDpcj6Rfd/GCCADpcj6Rfd/GE6ZI+kX3IIIAXpcj6Rfd/GDpcj6Rfd/GCCADpcj6Rfd/GE6ZI+kX3IIIAXpcj6Rfd/GDpcj6Rfd/GCCADpcj6Rfd/GE6ZI+kX3IIIAXpcj6Rfd/GDpcj6Rfd/GCCADpcj6Rfd/GE6ZI+kX3IIIAXpcj6Rfd/GDpcj6Rfd/GCCADpcj6Rfd/GE6ZI+kX3IIIAXpcj6Rfd/GDpcj6Rfd/GCCADpcj6Rfd/GE6ZI+kX3IIIAXpcj6Rfd/GDpcj6Rfd/GCCADpcj6Rfd/GE6ZI+kX3IIIAXpcj6Rfd/GDpcj6Rfd/GCCADpcj6Rfd/GE6ZI+kX3IIIAXpcj6Rfd/GDpcj6Rfd/GCCADpcj6Rfd/GE6ZI+kX3IIIAXpcj6Rfd/GDpcj6Rfd/GCCADpcj6Rfd/GE6ZI+kX3IIIAXpcj6Rfd/GDpcj6Rfd/GCCADpcn56+5+MHSpO1s6+5+MEEAHS5Tz19z8YOlynnr7n4wQQAdJkz+sX3IOkSVvlF9z8YIIAXpMn6Rfdg6TJj9Yvu/jBBACGZkx9Nfc/GDpMn56+5+MEEAHSpPz192DpUp56+7BBADTOSPplj/p+MKmZkVfr1dz8YIIAdz8oNekL7n4whnJQf8A6Fdz8YIIAb0qUOvOr7n4wCZlB+tX3PxggjIiRwnJS3yiu5B0yU9IvufjBBGN9SBqpmUOvOq7n4wCakwLc6rufjBBF0XQompbMbajtFoqTsy0paClJICQNIIIENH/2Q==", | ||
| 485 | + "created": 1660300358240 | ||
| 486 | + } | ||
| 487 | + } | ||
| 488 | +} | ||
| 0 | \ No newline at end of file | 489 | \ No newline at end of file |
docs/assets/server-grafana.webp
0 → 100644
No preview for this file type
docs/index.md
0 → 100644
| 1 | +# libmodbus | ||
| 2 | + | ||
| 3 | +A featureful and portable Open Source Modbus library. | ||
| 4 | + | ||
| 5 | +## Description | ||
| 6 | + | ||
| 7 | +libmodbus is a library to send/receive data with a device which respects the | ||
| 8 | +Modbus protocol. This library contains various backends to communicate over | ||
| 9 | +different networks (eg. serial in RTU mode or Ethernet in TCP IPv4/IPv6). The | ||
| 10 | +<http://www.modbus.org> site provides documentation about the [Modbus | ||
| 11 | +Specifications and Implementation Guides](http://www.modbus.org/specs.php). | ||
| 12 | + | ||
| 13 | +libmodbus provides an abstraction of the lower communication layers and offers | ||
| 14 | +the same API on all supported platforms. | ||
| 15 | + | ||
| 16 | +This documentation presents an overview of libmodbus concepts, describes how | ||
| 17 | +libmodbus abstracts Modbus communication with different hardware and platforms | ||
| 18 | +and provides a reference manual for the functions provided by the libmodbus | ||
| 19 | +library. | ||
| 20 | + | ||
| 21 | +## Use cases | ||
| 22 | + | ||
| 23 | +The library can be used to write a: | ||
| 24 | + | ||
| 25 | +- **client**, the application reads/writes data from various devices. | ||
| 26 | +- **server**, the application provides data to several clients. | ||
| 27 | + | ||
| 28 | +<figure markdown> | ||
| 29 | + <img src="assets/client-sensors.webp" width="512"> | ||
| 30 | + <figcaption>A libmodbus client that reads only the temperatures from sensors.</figcaption> | ||
| 31 | +</figure> | ||
| 32 | + | ||
| 33 | +<figure markdown> | ||
| 34 | + <img src="assets/server-grafana.webp" width="512"> | ||
| 35 | + <figcaption>A libmodbus server that exposes data to a Grafana service.</figcaption> | ||
| 36 | +</figure> | ||
| 37 | + | ||
| 38 | +## Contexts | ||
| 39 | + | ||
| 40 | +The Modbus protocol supports several transport protocols (eg. serial RTU, | ||
| 41 | +Ethernet TCP) called backends in *libmodbus*. | ||
| 42 | + | ||
| 43 | +The first step is to allocate and set a `modbus_t` context according to the | ||
| 44 | +required backend (RTU or TCP) with a dedicated function, such as | ||
| 45 | +[modbus_new_rtu](modbus_new_rtu). | ||
| 46 | +The function will return an opaque structure called `modbus_t` containing all | ||
| 47 | +necessary information to establish a connection with other Modbus devices | ||
| 48 | +according to the selected backend. | ||
| 49 | + | ||
| 50 | +Once this context has been created, you can use use the common API provided by | ||
| 51 | +*libmodbus* to read/write or set the various timeouts. With this common API, | ||
| 52 | +it's easy to switch the backend of your application from RTU to TCP IPv6 for | ||
| 53 | +example. | ||
| 54 | + | ||
| 55 | +### RTU Context | ||
| 56 | + | ||
| 57 | +The RTU backend (Remote Terminal Unit) is used in serial communication and makes | ||
| 58 | +use of a compact, binary representation of the data for protocol communication. | ||
| 59 | +The RTU format follows the commands/data with a cyclic redundancy check checksum | ||
| 60 | +as an error check mechanism to ensure the reliability of data. Modbus RTU is the | ||
| 61 | +most common implementation available for Modbus. A Modbus RTU message must be | ||
| 62 | +transmitted continuously without inter-character hesitations (extract from | ||
| 63 | +Wikipedia, [Modbus](http://en.wikipedia.org/wiki/Modbus) as of Mar. 13, 2011, | ||
| 64 | +20:51 GMT). | ||
| 65 | + | ||
| 66 | +The Modbus RTU framing calls a slave, a device/service which handle Modbus | ||
| 67 | +requests, and a master, a client which send requests. The communication is | ||
| 68 | +always initiated by the master. | ||
| 69 | + | ||
| 70 | +Many Modbus devices can be connected together on the same physical link so | ||
| 71 | +before sending a message, you must set the slave (receiver) with | ||
| 72 | +[modbus_set_slave](mobus_set_slave). If you're running a slave, its slave number | ||
| 73 | +will be used to filter received messages. | ||
| 74 | + | ||
| 75 | +The libmodbus implementation of RTU isn't time based as stated in original | ||
| 76 | +Modbus specification, instead all bytes are sent as fast as possible and a | ||
| 77 | +response or an indication is considered complete when all expected characters | ||
| 78 | +have been received. This implementation offers very fast communication but you | ||
| 79 | +must take care to set a response timeout of slaves less than response timeout of | ||
| 80 | +master (ortherwise other slaves may ignore master requests when one of the slave | ||
| 81 | +is not responding). | ||
| 82 | + | ||
| 83 | +To create a Modbus RTU context, you should use [modbus_new_rtu](modbus_new_rtu). | ||
| 84 | + | ||
| 85 | +You can tweak the serial mode with the following functions: | ||
| 86 | + | ||
| 87 | +- [modbus_rtu_get_serial_mode](modbus_rtu_get_serial_mode) | ||
| 88 | +- [modbus_rtu_set_serial_mode](modbus_rtu_set_serial_mode) | ||
| 89 | +- [modbus_rtu_get_rts](modbus_rtu_get_rts) | ||
| 90 | +- [modbus_rtu_set_rts](modbus_rtu_set_rts) | ||
| 91 | +- [modbus_rtu_set_custom_rts](modbus_rtu_set_custom_rts) | ||
| 92 | +- [modbus_rtu_get_rts_delay](modbus_rtu_get_rts_delay) | ||
| 93 | +- [modbus_rtu_set_rts_delay](modbus_rtu_set_rts_delay) | ||
| 94 | + | ||
| 95 | +### TCP (IPv4) Context | ||
| 96 | + | ||
| 97 | +The TCP backend implements a Modbus variant used for communications over | ||
| 98 | +TCP/IPv4 networks. It does not require a checksum calculation as lower layer | ||
| 99 | +takes care of the same. | ||
| 100 | + | ||
| 101 | +To create a Modbus TCP context, you should use [modbus_new_tcp](modbus_new_tcp). | ||
| 102 | + | ||
| 103 | +### TCP PI (IPv4 and IPv6) Context | ||
| 104 | + | ||
| 105 | +The TCP PI (Protocol Independent) backend implements a Modbus variant used for | ||
| 106 | +communications over TCP IPv4 and IPv6 networks. It does not require a checksum | ||
| 107 | +calculation as lower layer takes care of the same. | ||
| 108 | + | ||
| 109 | +Contrary to the TCP IPv4 only backend, the TCP PI backend offers hostname | ||
| 110 | +resolution but it consumes about 1Kb of additional memory. | ||
| 111 | + | ||
| 112 | +Create a Modbus TCP PI context, you should use [modbus_new_tcp_pi](modbus_new_tcp_pi). | ||
| 113 | + | ||
| 114 | +## Connection | ||
| 115 | + | ||
| 116 | +The following functions are provided to establish and close a connection with | ||
| 117 | +Modbus devices: | ||
| 118 | + | ||
| 119 | +- [modbus_connect](modbus_connect) establishes a connection. | ||
| 120 | +- [modbus_close](modbus_close) closes a connection. | ||
| 121 | +- [modbus_flush](modbus_flush) flushed a connection. | ||
| 122 | + | ||
| 123 | +In RTU, you should define the slave ID of your client with | ||
| 124 | +[modbus_set_slave](modbus_set_slave). | ||
| 125 | + | ||
| 126 | +To analyse the exchanged data, you can enable the debug mode with | ||
| 127 | +[modbus_set_debug](modbus_set_debug). | ||
| 128 | + | ||
| 129 | +Once you have completed the communication or at the end of your program, you | ||
| 130 | +should free the resources with the common function, [modbus_free](modbus_free) | ||
| 131 | + | ||
| 132 | +## Reads and writes from the client | ||
| 133 | + | ||
| 134 | +The Modbus protocol defines different data types and functions to read and write | ||
| 135 | +them from/to remote devices. The following functions are used by the clients to | ||
| 136 | +send Modbus requests: | ||
| 137 | + | ||
| 138 | +To read data: | ||
| 139 | + | ||
| 140 | +- [modbus_read_bits](modbus_read_bits) | ||
| 141 | +- [modbus_read_input_bits](modbus_read_input_bits) | ||
| 142 | +- [modbus_read_registers](modbus_read_registers) | ||
| 143 | +- [modbus_read_input_registers](modbus_read_input_registers) | ||
| 144 | +- [modbus_report_slave_id](modbus_report_slave_id) | ||
| 145 | + | ||
| 146 | +To write data: | ||
| 147 | + | ||
| 148 | +- [modbus_write_bit](modbus_write_bit) | ||
| 149 | +- [modbus_write_register](modbus_write_register) | ||
| 150 | +- [modbus_write_bits](modbus_write_bits) | ||
| 151 | +- [modbus_write_registers](modbus_write_registers) | ||
| 152 | + | ||
| 153 | +To write and read data in a single operation: | ||
| 154 | + | ||
| 155 | +- [modbus_write_and_read_registers](modbus_write_and_read_registers) | ||
| 156 | + | ||
| 157 | +To send and receive low-level requests: | ||
| 158 | + | ||
| 159 | +- [modbus_send_raw_request](modbus_send_raw_request) | ||
| 160 | +- [modbus_receive_confirmation](modbus_receive_confirmation) | ||
| 161 | + | ||
| 162 | +To reply to an exception: | ||
| 163 | + | ||
| 164 | +- [modbus_reply_exception](modbus_reply_exception) | ||
| 165 | + | ||
| 166 | +## Handling requests from server | ||
| 167 | + | ||
| 168 | +The server is waiting for request from clients and must answer when it is | ||
| 169 | +concerned by the request. The libmodbus offers the following functions to | ||
| 170 | +handle requests: | ||
| 171 | + | ||
| 172 | +Data mapping: | ||
| 173 | + | ||
| 174 | +- [modbus_mapping_new](modbus_mapping_new) | ||
| 175 | +- [modbus_mapping_free](modbus_mapping_free) | ||
| 176 | + | ||
| 177 | +Receive: | ||
| 178 | + | ||
| 179 | +- [modbus_receive](modbus_receive) | ||
| 180 | + | ||
| 181 | +Reply: | ||
| 182 | + | ||
| 183 | +- [modbus_reply](modbus_reply) | ||
| 184 | +- [modbus_reply_exception](modbus_reply_exception) | ||
| 185 | + | ||
| 186 | +## Advanced functions | ||
| 187 | + | ||
| 188 | +Timeout settings: | ||
| 189 | + | ||
| 190 | +- [modbus_get_byte_timeout](modbus_get_byte_timeout) | ||
| 191 | +- [modbus_set_byte_timeout](modbus_set_byte_timeout) | ||
| 192 | +- [modbus_get_response_timeout](modbus_get_response_timeout) | ||
| 193 | +- [modbus_set_response_timeout](modbus_set_response_timeout) | ||
| 194 | + | ||
| 195 | +Error recovery mode: | ||
| 196 | + | ||
| 197 | +- [modbus_set_error_recovery](modbus_set_error_recovery) | ||
| 198 | + | ||
| 199 | +Setter/getter of internal socket: | ||
| 200 | + | ||
| 201 | +- [modbus_set_socket](modbus_set_socket) | ||
| 202 | +- [modbus_get_socket](modbus_get_socket) | ||
| 203 | + | ||
| 204 | +Information about header: | ||
| 205 | + | ||
| 206 | +- [modbus_get_header_length](modbus_get_header_length) | ||
| 207 | + | ||
| 208 | +## Data handling | ||
| 209 | + | ||
| 210 | +Macros for data manipulation: | ||
| 211 | + | ||
| 212 | +- `MODBUS_GET_HIGH_BYTE(data)`, extracts the high byte from a byte | ||
| 213 | +- `MODBUS_GET_LOW_BYTE(data)`, extracts the low byte from a byte | ||
| 214 | +- `MODBUS_GET_INT64_FROM_INT16(tab_int16, index)`, builds an int64 from the four first int16 starting at tab_int16[index] | ||
| 215 | +- `MODBUS_GET_INT32_FROM_INT16(tab_int16, index)`, builds an int32 from the two first int16 starting at tab_int16[index] | ||
| 216 | +- `MODBUS_GET_INT16_FROM_INT8(tab_int8, index)`, builds an int16 from the two first int8 starting at tab_int8[index] | ||
| 217 | +- `MODBUS_SET_INT16_TO_INT8(tab_int8, index, value)`, set an int16 value into the two first bytes starting at tab_int8[index] | ||
| 218 | +- `MODBUS_SET_INT32_TO_INT16(tab_int16, index, value)`, set an int32 value into the two first int16 starting at tab_int16[index] | ||
| 219 | +- `MODBUS_SET_INT64_TO_INT16(tab_int16, index, value)`, set an int64 value into the four first int16 starting at tab_int16[index] | ||
| 220 | + | ||
| 221 | +Handling of bits and bytes: | ||
| 222 | + | ||
| 223 | +- [modbus_set_bits_from_byte](modbus_set_bits_from_byte) | ||
| 224 | +- [modbus_set_bits_from_bytes](modbus_set_bits_from_bytes) | ||
| 225 | +- [modbus_get_byte_from_bits](modbus_get_byte_from_bits) | ||
| 226 | + | ||
| 227 | +Set or get float numbers: | ||
| 228 | + | ||
| 229 | +- [modbus_get_float_abcd](modbus_get_float_abcd) | ||
| 230 | +- [modbus_set_float_abcd](modbus_set_float_abcd) | ||
| 231 | +- [modbus_get_float_badc](modbus_get_float_badc) | ||
| 232 | +- [modbus_set_float_badc](modbus_set_float_badc) | ||
| 233 | +- [modbus_get_float_cdab](modbus_get_float_cdab) | ||
| 234 | +- [modbus_set_float_cdab](modbus_set_float_cdab) | ||
| 235 | +- [modbus_get_float_dcba](modbus_get_float_dcba) | ||
| 236 | +- [modbus_set_float_dcba](modbus_set_float_dcba) | ||
| 237 | +- [modbus_get_float](modbus_get_float) **deprecated** | ||
| 238 | +- [modbus_set_float](modbus_set_float) **deprecated** | ||
| 239 | + | ||
| 240 | +## Error handling | ||
| 241 | + | ||
| 242 | +The libmodbus functions handle errors using the standard conventions found on | ||
| 243 | +POSIX systems. Generally, this means that upon failure a libmodbus function | ||
| 244 | +shall return either a NULL value (if returning a pointer) or a negative value | ||
| 245 | +(if returning an integer), and the actual error code shall be stored in the | ||
| 246 | +`errno` variable. | ||
| 247 | + | ||
| 248 | +The *modbus_strerror()* function is provided to translate libmodbus-specific | ||
| 249 | +error codes into error message strings; for details refer to | ||
| 250 | +[modbus_strerror](modbus_strerror). | ||
| 251 | + | ||
| 252 | +## Miscellaneous | ||
| 253 | + | ||
| 254 | +The `_LIBMODBUS_VERSION_STRING_` constant indicates the libmodbus version the | ||
| 255 | +program has been compiled against. The variables 'libmodbus_version_major', | ||
| 256 | +'libmodbus_version_minor', 'libmodbus_version_micro' give the version the | ||
| 257 | +program is linked against. | ||
| 258 | + | ||
| 259 | +## Copying | ||
| 260 | + | ||
| 261 | +Free use of this software is granted under the terms of the GNU Lesser General | ||
| 262 | +Public License (LGPL v2.1+). For details see the file `COPYING.LESSER` included | ||
| 263 | +with the libmodbus distribution. |
docs/modbus_close.md
0 → 100644
| 1 | +# modbus_close | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_close - close a Modbus connection | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +void modbus_close(modbus_t *ctx); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_close()* function shall close the connection established with the | ||
| 16 | +backend set in the context. | ||
| 17 | + | ||
| 18 | +## Return value | ||
| 19 | + | ||
| 20 | +There is no return value. | ||
| 21 | + | ||
| 22 | +## Example | ||
| 23 | + | ||
| 24 | +```c | ||
| 25 | +modbus_t *ctx; | ||
| 26 | + | ||
| 27 | +ctx = modbus_new_tcp("127.0.0.1", 502); | ||
| 28 | +if (modbus_connect(ctx) == -1) { | ||
| 29 | + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); | ||
| 30 | + modbus_free(ctx); | ||
| 31 | + return -1; | ||
| 32 | +} | ||
| 33 | + | ||
| 34 | +modbus_close(ctx); | ||
| 35 | +modbus_free(ctx); | ||
| 36 | +``` | ||
| 37 | + | ||
| 38 | +## See also | ||
| 39 | + | ||
| 40 | +- [modbus_connect](modbus_connect) |
docs/modbus_connect.md
0 → 100644
| 1 | +# modbus_connect | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_connect - establish a Modbus connection | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +int modbus_connect(modbus_t *ctx); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_connect()* function shall establish a connection to a Modbus server, | ||
| 16 | +a network or a bus using the context information of libmodbus context given in | ||
| 17 | +argument. | ||
| 18 | + | ||
| 19 | +## Return value | ||
| 20 | + | ||
| 21 | +The function shall return 0 if successful. Otherwise it shall return -1 and set | ||
| 22 | +errno to one of the values defined by the system calls of the underlying | ||
| 23 | +platform. | ||
| 24 | + | ||
| 25 | +## Example | ||
| 26 | + | ||
| 27 | +```c | ||
| 28 | +modbus_t *ctx; | ||
| 29 | + | ||
| 30 | +ctx = modbus_new_tcp("127.0.0.1", 502); | ||
| 31 | +if (modbus_connect(ctx) == -1) { | ||
| 32 | + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); | ||
| 33 | + modbus_free(ctx); | ||
| 34 | + return -1; | ||
| 35 | +} | ||
| 36 | +``` | ||
| 37 | + | ||
| 38 | +## See also | ||
| 39 | + | ||
| 40 | +- [modbus_close](modbus_close) |
docs/modbus_flush.md
0 → 100644
| 1 | +# modbus_flush | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_flush - flush non-transmitted data | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +int modbus_flush(modbus_t *ctx); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_flush()* function shall discard data received but not read to the | ||
| 16 | +socket or file descriptor associated to the context 'ctx'. | ||
| 17 | + | ||
| 18 | +## Return value | ||
| 19 | + | ||
| 20 | +The function shall return 0 or the number of flushed bytes if | ||
| 21 | +successful. Otherwise it shall return -1 and set errno. |
docs/modbus_free.md
0 → 100644
| 1 | +# modbus_free | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_free - free a libmodbus context | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +void modbus_free(modbus_t *ctx); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_free()* function shall free an allocated modbus_t structure. | ||
| 16 | + | ||
| 17 | +## Return value | ||
| 18 | + | ||
| 19 | +There is no return values. |
docs/modbus_get_byte_from_bits.md
0 → 100644
| 1 | +# modbus_get_byte_from_bits | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_get_byte_from_bits - get the value from many bits | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +uint8_t modbus_get_byte_from_bits(const uint8_t *src, int index, unsigned int nb_bits); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_get_byte_from_bits()* function shall extract a value from many | ||
| 16 | +bits. All `nb_bits` bits from `src` at position `index` will be read as a | ||
| 17 | +single value. To obtain a full byte, set nb_bits to 8. | ||
| 18 | + | ||
| 19 | +## Return value | ||
| 20 | + | ||
| 21 | +The function shall return a byte containing the bits read. | ||
| 22 | + | ||
| 23 | +## See also | ||
| 24 | + | ||
| 25 | +- [modbus_set_bits_from_byte](modbus_set_bits_from_byte) | ||
| 26 | +- [modbus_set_bits_from_bytes](modbus_set_bits_from_bytes) |
docs/modbus_get_byte_timeout.md
0 → 100644
| 1 | +# modbus_get_byte_timeout | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_get_byte_timeout - get timeout between bytes | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_get_byte_timeout()* function shall store the timeout interval | ||
| 16 | +between two consecutive bytes of the same message in the `to_sec` and `to_usec` | ||
| 17 | +arguments. | ||
| 18 | + | ||
| 19 | +## Return value | ||
| 20 | + | ||
| 21 | +The function shall return 0 if successful. Otherwise it shall return -1 and set | ||
| 22 | +errno. | ||
| 23 | + | ||
| 24 | +## Example | ||
| 25 | + | ||
| 26 | +```c | ||
| 27 | +uint32_t to_sec; | ||
| 28 | +uint32_t to_usec; | ||
| 29 | + | ||
| 30 | +/* Save original timeout */ | ||
| 31 | +modbus_get_byte_timeout(ctx, &to_sec, &to_usec); | ||
| 32 | +``` | ||
| 33 | + | ||
| 34 | +## See also | ||
| 35 | + | ||
| 36 | +- [modbus_set_byte_timeout](modbus_set_byte_timeout) | ||
| 37 | +- [modbus_get_response_timeout](modbus_get_response_timeout) | ||
| 38 | +- [modbus_set_response_timeout](modbus_set_response_timeout) |
docs/modbus_get_float.md
0 → 100644
| 1 | +# modbus_get_float | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_get_float - get a float value from 2 registers | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +float modbus_get_float(const uint16_t *src); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +Warning, this function is *deprecated* since libmodbus v3.2.0 and has been | ||
| 14 | +replaced by *modbus_get_float_dcba()*. | ||
| 15 | + | ||
| 16 | +## Description | ||
| 17 | + | ||
| 18 | +The *modbus_get_float()* function shall get a float from 4 bytes in Modbus | ||
| 19 | +format (DCBA byte order). The `src` array must be a pointer on two 16 bits | ||
| 20 | +values, for example, if the first word is set to 0x4465 and the second to | ||
| 21 | +0x229a, the float value will be 916.540649. | ||
| 22 | + | ||
| 23 | +## Return value | ||
| 24 | + | ||
| 25 | +The function shall return a float. | ||
| 26 | + | ||
| 27 | +## See also | ||
| 28 | + | ||
| 29 | +- [modbus_set_float](modbus_set_float) | ||
| 30 | +- [modbus_set_float_dcba](modbus_set_float_dcba) | ||
| 31 | +- [modbus_get_float_dcba](modbus_get_float_dcba) |
docs/modbus_get_float_abcd.md
0 → 100644
| 1 | +# modbus_get_float_abcd | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_get_float_abcd - get a float value from 2 registers in ABCD byte order | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +float modbus_get_float_abcd(const uint16_t *src); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_get_float_abcd()* function shall get a float from 4 bytes in usual | ||
| 16 | +Modbus format. The `src` array must be a pointer on two 16 bits values, for | ||
| 17 | +example, if the first word is set to 0x0020 and the second to 0xF147, the float | ||
| 18 | +value will be read as 123456.0. | ||
| 19 | + | ||
| 20 | +## Return value | ||
| 21 | + | ||
| 22 | +The function shall return a float. | ||
| 23 | + | ||
| 24 | +## See also | ||
| 25 | + | ||
| 26 | +- [modbus_set_float_abcd](modbus_set_float_abcd) | ||
| 27 | +- [modbus_get_float_badc](modbus_get_float_badc) | ||
| 28 | +- [modbus_get_float_cdab](modbus_get_float_cdab) | ||
| 29 | +- [modbus_get_float_dcba](modbus_get_float_dcba) |
docs/modbus_get_float_badc.md
0 → 100644
| 1 | +# modbus_get_float_badc | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_get_float_badc - get a float value from 2 registers in BADC byte order | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +float modbus_get_float_badc(const uint16_t *src); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_get_float_badc()* function shall get a float from 4 bytes with | ||
| 16 | +swapped bytes (BADC instead of ABCD). The `src` array must be a pointer on two | ||
| 17 | +16 bits values, for example, if the first word is set to 0x2000 and the second | ||
| 18 | +to 0x47F1, the float value will be read as 123456.0. | ||
| 19 | + | ||
| 20 | +## Return value | ||
| 21 | + | ||
| 22 | +The function shall return a float. | ||
| 23 | + | ||
| 24 | +## See also | ||
| 25 | + | ||
| 26 | +- [modbus_set_float_badc](modbus_set_float_badc) | ||
| 27 | +- [modbus_get_float_abcd](modbus_get_float_abcd) | ||
| 28 | +- [modbus_get_float_cdab](modbus_get_float_cdab) | ||
| 29 | +- [modbus_get_float_dcba](modbus_get_float_dcba) |
docs/modbus_get_float_cdab.md
0 → 100644
| 1 | +# modbus_get_float_cdab | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_get_float_cdab - get a float value from 2 registers in CDAB byte order | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +float modbus_get_float_cdab(const uint16_t *src); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_get_float_cdab()* function shall get a float from 4 bytes with | ||
| 16 | +swapped words (CDAB order instead of ABCD). The `src` array must be a pointer on | ||
| 17 | +two 16 bits values, for example, if the first word is set to F147 and the second | ||
| 18 | +to 0x0020, the float value will be read as 123456.0. | ||
| 19 | + | ||
| 20 | +## Return value | ||
| 21 | + | ||
| 22 | +The function shall return a float. | ||
| 23 | + | ||
| 24 | +## See also | ||
| 25 | + | ||
| 26 | +- [modbus_set_float_cdab](modbus_set_float_cdab) | ||
| 27 | +- [modbus_get_float_abcd](modbus_get_float_abcd) | ||
| 28 | +- [modbus_get_float_badc](modbus_get_float_badc) | ||
| 29 | +- [modbus_get_float_dcba](modbus_get_float_dcba) |
docs/modbus_get_float_dcba.md
0 → 100644
| 1 | +# modbus_get_float_dcba | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_get_float_dcba - get a float value from 2 registers in DCBA byte order | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +float modbus_get_float_dcba(const uint16_t *src); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_get_float_dcba()* function shall get a float from 4 bytes in | ||
| 16 | +inverted Modbus format (DCBA order instead of ABCD). The `src` array must be a | ||
| 17 | +pointer on two 16 bits values, for example, if the first word is set to 0x47F1 | ||
| 18 | +and the second to 0x2000, the float value will be read as 123456.0. | ||
| 19 | + | ||
| 20 | +## Return value | ||
| 21 | + | ||
| 22 | +The function shall return a float. | ||
| 23 | + | ||
| 24 | +## See also | ||
| 25 | + | ||
| 26 | +- [modbus_set_float_dcba](modbus_set_float_dcba) | ||
| 27 | +- [modbus_get_float_abcd](modbus_get_float_abcd) | ||
| 28 | +- [modbus_get_float_badc](modbus_get_float_badc) | ||
| 29 | +- [modbus_get_float_cdab](modbus_get_float_cdab) |
docs/modbus_get_header_length.md
0 → 100644
| 1 | +# modbus_get_header_length | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_get_header_length - retrieve the current header length | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +int modbus_get_header_length(modbus_t *ctx); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_get_header_length()* function shall retrieve the current header | ||
| 16 | +length from the backend. This function is convenient to manipulate a message and | ||
| 17 | +so its limited to low-level operations. | ||
| 18 | + | ||
| 19 | +## Return value | ||
| 20 | + | ||
| 21 | +The header length as integer value. |
docs/modbus_get_indication_timeout.md
0 → 100644
| 1 | +# modbus_get_indication_timeout | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_get_indication_timeout - get timeout used to wait for an indication (request received by a server). | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +int modbus_get_indication_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_get_indication_timeout()* function shall store the timeout interval | ||
| 16 | +used to wait for an indication in the `to_sec` and `to_usec` arguments. | ||
| 17 | +Indication is the term used by the Modbus protocol to designate a request | ||
| 18 | +received by the server. | ||
| 19 | + | ||
| 20 | +The default value is zero, it means the server will wait forever. | ||
| 21 | + | ||
| 22 | +## Return value | ||
| 23 | + | ||
| 24 | +The function shall return 0 if successful. Otherwise it shall return -1 and set | ||
| 25 | +errno. | ||
| 26 | + | ||
| 27 | +```c | ||
| 28 | +uint32_t to_sec; | ||
| 29 | +uint32_t to_usec; | ||
| 30 | + | ||
| 31 | +/* Save original timeout */ | ||
| 32 | +modbus_get_indication_timeout(ctx, &to_sec, &to_usec); | ||
| 33 | +``` | ||
| 34 | + | ||
| 35 | +## See also | ||
| 36 | + | ||
| 37 | +- [modbus_set_indication_timeout](modbus_set_indication_timeout) | ||
| 38 | +- [modbus_get_response_timeout](modbus_get_response_timeout) | ||
| 39 | +- [modbus_set_response_timeout](modbus_set_response_timeout) |
docs/modbus_get_response_timeout.md
0 → 100644
| 1 | +# modbus_get_response_timeout | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_get_response_timeout - get timeout for response | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +int modbus_get_response_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_get_response_timeout()* function shall return the timeout interval | ||
| 16 | +used to wait for a response in the `to_sec` and `to_usec` arguments. | ||
| 17 | + | ||
| 18 | +## Return value | ||
| 19 | + | ||
| 20 | +The function shall return 0 if successful. Otherwise it shall return -1 and set | ||
| 21 | +errno. | ||
| 22 | + | ||
| 23 | +Example: | ||
| 24 | + | ||
| 25 | +```c | ||
| 26 | +uint32_t old_response_to_sec; | ||
| 27 | +uint32_t old_response_to_usec; | ||
| 28 | + | ||
| 29 | +/* Save original timeout */ | ||
| 30 | +modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); | ||
| 31 | + | ||
| 32 | +/* Define a new and too short timeout! */ | ||
| 33 | +modbus_set_response_timeout(ctx, 0, 0); | ||
| 34 | +``` | ||
| 35 | + | ||
| 36 | +## See also | ||
| 37 | + | ||
| 38 | +- [modbus_set_response_timeout](modbus_set_response_timeout) | ||
| 39 | +- [modbus_get_byte_timeout](modbus_get_byte_timeout) | ||
| 40 | +- [modbus_set_byte_timeout](modbus_set_byte_timeout) |
docs/modbus_get_slave.md
0 → 100644
| 1 | +# modbus_get_slave | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_get_slave - get slave number in the context | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +int modbus_get_slave(modbus_t *ctx); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_get_slave()* function shall get the slave number in the libmodbus | ||
| 16 | +context. | ||
| 17 | + | ||
| 18 | +## Return value | ||
| 19 | + | ||
| 20 | +The function shall return the slave number if successful. Otherwise it shall | ||
| 21 | +return -1 and set errno to one of the values defined below. | ||
| 22 | + | ||
| 23 | +## Errors | ||
| 24 | + | ||
| 25 | +- *EINVAL*, the libmodbus context is undefined. | ||
| 26 | + | ||
| 27 | +## See also | ||
| 28 | + | ||
| 29 | +- [modbus_set_slave](modbus_set_slave) |
docs/modbus_get_socket.md
0 → 100644
| 1 | +# modbus_get_socket | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_get_socket - get the current socket of the context | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +int modbus_get_socket(modbus_t *'ctx'); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_get_socket()* function shall return the current socket or file | ||
| 16 | +descriptor of the libmodbus context. | ||
| 17 | + | ||
| 18 | +## Return value | ||
| 19 | + | ||
| 20 | +The function returns the current socket or file descriptor of the context if | ||
| 21 | +successful. Otherwise it shall return -1 and set errno. | ||
| 22 | + | ||
| 23 | +## See also | ||
| 24 | + | ||
| 25 | +- [modbus_set_socket](modbus_set_socket) |
docs/modbus_mapping_free.md
0 → 100644
| 1 | +# modbus_mapping_free | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_mapping_free - free a modbus_mapping_t structure | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +void modbus_mapping_free(modbus_mapping_t *mb_mapping); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The function shall free the four arrays of mb_mapping_t structure and finally | ||
| 16 | +the mb_mapping_t referenced by `mb_mapping`. | ||
| 17 | + | ||
| 18 | +## Return value | ||
| 19 | + | ||
| 20 | +There is no return values. | ||
| 21 | + | ||
| 22 | +## See also | ||
| 23 | + | ||
| 24 | +- [modbus_mapping_new](modbus_mapping_new) |
docs/modbus_mapping_new.md
0 → 100644
| 1 | +# modbus_mapping_new | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_mapping_new - allocate four arrays of bits and registers | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits, int nb_registers, int nb_input_registers); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_mapping_new()* function shall allocate four arrays to store bits, | ||
| 16 | +input bits, registers and inputs registers. The pointers are stored in | ||
| 17 | +modbus_mapping_t structure. All values of the arrays are initialized to zero. | ||
| 18 | + | ||
| 19 | +This function is equivalent to a call of the | ||
| 20 | +[modbus_mapping_new_start_address](modbus_mapping_new_start_address) function | ||
| 21 | +with all start addresses to `0`. | ||
| 22 | + | ||
| 23 | +If it isn't necessary to allocate an array for a specific type of data, you can | ||
| 24 | +pass the zero value in argument, the associated pointer will be NULL. | ||
| 25 | + | ||
| 26 | +This function is convenient to handle requests in a Modbus server/slave. | ||
| 27 | + | ||
| 28 | +## Return value | ||
| 29 | + | ||
| 30 | +The function shall return the new allocated structure if successful. Otherwise | ||
| 31 | +it shall return NULL and set errno. | ||
| 32 | + | ||
| 33 | +## Errors | ||
| 34 | + | ||
| 35 | +- *ENOMEM*, not enough memory. | ||
| 36 | + | ||
| 37 | +## Example | ||
| 38 | + | ||
| 39 | +```c | ||
| 40 | +/* The first value of each array is accessible from the 0 address. */ | ||
| 41 | +mb_mapping = modbus_mapping_new( | ||
| 42 | + BITS_ADDRESS + BITS_NB, | ||
| 43 | + INPUT_BITS_ADDRESS + INPUT_BITS_NB, | ||
| 44 | + REGISTERS_ADDRESS + REGISTERS_NB, | ||
| 45 | + INPUT_REGISTERS_ADDRESS + INPUT_REGISTERS_NB | ||
| 46 | +); | ||
| 47 | +if (mb_mapping == NULL) { | ||
| 48 | + fprintf( | ||
| 49 | + stderr, "Failed to allocate the mapping: %s\n", | ||
| 50 | + modbus_strerror(errno) | ||
| 51 | + ); | ||
| 52 | + modbus_free(ctx); | ||
| 53 | + return -1; | ||
| 54 | +} | ||
| 55 | +``` | ||
| 56 | + | ||
| 57 | +## See also | ||
| 58 | + | ||
| 59 | +- [modbus_mapping_free](modbus_mapping_free) | ||
| 60 | +- [modbus_mapping_new_start_address](modbus_mapping_new_start_address) |
docs/modbus_mapping_new_start_address.md
0 → 100644
| 1 | +# modbus_mapping_new_start_address | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_mapping_new_start_address - allocate four arrays of bits and registers accessible from their starting addresses | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +modbus_mapping_t* modbus_mapping_new_start_address( | ||
| 11 | + int start_bits, int nb_bits, | ||
| 12 | + int start_input_bits, int nb_input_bits, | ||
| 13 | + int start_registers, int nb_registers, | ||
| 14 | + int start_input_registers, int nb_input_registers); | ||
| 15 | +``` | ||
| 16 | + | ||
| 17 | +## Description | ||
| 18 | + | ||
| 19 | +The `modbus_mapping_new_start_address()` function shall allocate four arrays to | ||
| 20 | +store bits, input bits, registers and inputs registers. The pointers are stored | ||
| 21 | +in modbus_mapping_t structure. All values of the arrays are initialized to zero. | ||
| 22 | + | ||
| 23 | +The different starting addresses make it possible to place the mapping at any | ||
| 24 | +address in each address space. This way, you can give access to the clients at | ||
| 25 | +values stored at high addresses without allocating memory from the address zero, | ||
| 26 | +for eg. to make available registers from 340 to 349, you can use: | ||
| 27 | + | ||
| 28 | +```c | ||
| 29 | +mb_mapping = modbus_mapping_new_start_address(0, 0, 0, 0, 340, 10, 0, 0); | ||
| 30 | +``` | ||
| 31 | + | ||
| 32 | +The newly created `mb_mapping` will have the following arrays: | ||
| 33 | + | ||
| 34 | +- `tab_bits` set to NULL | ||
| 35 | +- `tab_input_bits` set to NULL | ||
| 36 | +- `tab_input_registers` allocated to store 10 registers (`uint16_t`) | ||
| 37 | +- `tab_registers` set to NULL. | ||
| 38 | + | ||
| 39 | +The clients can read the first register by using the address 340 in its request. | ||
| 40 | +On the server side, you should use the first index of the array to set the value | ||
| 41 | +at this client address: | ||
| 42 | + | ||
| 43 | +```c | ||
| 44 | +mb_mapping->tab_registers[0] = 42; | ||
| 45 | +``` | ||
| 46 | + | ||
| 47 | +If it isn't necessary to allocate an array for a specific type of data, you can | ||
| 48 | +pass the zero value in argument, the associated pointer will be NULL. | ||
| 49 | + | ||
| 50 | +This function is convenient to handle requests in a Modbus server/slave. | ||
| 51 | + | ||
| 52 | +## Return value | ||
| 53 | + | ||
| 54 | +The `modbus_mapping_new_start_address()` function shall return the new allocated structure if | ||
| 55 | +successful. Otherwise it shall return NULL and set errno. | ||
| 56 | + | ||
| 57 | +## Errors | ||
| 58 | + | ||
| 59 | +- *ENOMEM*, not enough memory. | ||
| 60 | + | ||
| 61 | +## Example | ||
| 62 | + | ||
| 63 | +```c | ||
| 64 | +/* The first value of each array is accessible at the defined address. | ||
| 65 | +The end address is ADDRESS + NB - 1. */ | ||
| 66 | +mb_mapping = modbus_mapping_new_start_address( | ||
| 67 | + BITS_ADDRESS, BITS_NB, | ||
| 68 | + INPUT_BITS_ADDRESS, INPUT_BITS_NB, | ||
| 69 | + REGISTERS_ADDRESS, REGISTERS_NB, | ||
| 70 | + INPUT_REGISTERS_ADDRESS, INPUT_REGISTERS_NB | ||
| 71 | +); | ||
| 72 | +if (mb_mapping == NULL) { | ||
| 73 | + fprintf( | ||
| 74 | + stderr, "Failed to allocate the mapping: %s\n", | ||
| 75 | + modbus_strerror(errno) | ||
| 76 | + ); | ||
| 77 | + modbus_free(ctx); | ||
| 78 | + return -1; | ||
| 79 | +} | ||
| 80 | +``` | ||
| 81 | + | ||
| 82 | +## See also | ||
| 83 | + | ||
| 84 | +- [modbus_mapping_new](modbus_mapping_new) | ||
| 85 | +- [modbus_mapping_free](modbus_mapping_free) |
docs/modbus_mask_write_register.md
0 → 100644
| 1 | +# modbus_mask_write_register | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_mask_write_register - mask a single register | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +int modbus_mask_write_register(modbus_t *ctx, int addr, uint16_t and, uint16_t or); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_mask_write_register()* function shall modify the value of the | ||
| 16 | +holding register at the address 'addr' of the remote device using the algorithm: | ||
| 17 | + | ||
| 18 | + new value = (current value AND 'and') OR ('or' AND (NOT 'and')) | ||
| 19 | + | ||
| 20 | +The function uses the Modbus function code 0x16 (mask single register). | ||
| 21 | + | ||
| 22 | +## Return value | ||
| 23 | + | ||
| 24 | +The function shall return 1 if successful. Otherwise it shall return -1 and set | ||
| 25 | +errno. | ||
| 26 | + | ||
| 27 | +## See also | ||
| 28 | + | ||
| 29 | +- [modbus_read_registers](modbus_read_registers) | ||
| 30 | +- [modbus_write_registers](modbus_write_registers) |
docs/modbus_new_rtu.md
0 → 100644
| 1 | +# modbus_new_rtu | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_new_rtu - create a libmodbus context for RTU | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +modbus_t *modbus_new_rtu(const char *device, int baud, char parity, int data_bit, int stop_bit); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_new_rtu()* function shall allocate and initialize a `modbus_t` | ||
| 16 | +structure to communicate in RTU mode on a serial line. | ||
| 17 | + | ||
| 18 | +The `device` argument specifies the name of the serial port handled by the OS, | ||
| 19 | +eg. "/dev/ttyS0" or "/dev/ttyUSB0". On Windows, it's necessary to prepend COM | ||
| 20 | +name with "\\.\" for COM number greater than 9, eg. "\\\\.\\COM10". See | ||
| 21 | +http://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx for details | ||
| 22 | + | ||
| 23 | +The `baud` argument specifies the baud rate of the communication, eg. 9600, | ||
| 24 | +19200, 57600, 115200, etc. | ||
| 25 | + | ||
| 26 | +The `parity` argument can have one of the following values: | ||
| 27 | + | ||
| 28 | +- `N` for none | ||
| 29 | +- `E` for even | ||
| 30 | +- `O` for odd | ||
| 31 | + | ||
| 32 | +The `data_bits` argument specifies the number of bits of data, the allowed | ||
| 33 | +values are 5, 6, 7 and 8. | ||
| 34 | + | ||
| 35 | +The `stop_bits` argument specifies the bits of stop, the allowed values are 1 | ||
| 36 | +and 2. | ||
| 37 | + | ||
| 38 | +Once the `modbus_t` structure is initialized, you must set the slave of your | ||
| 39 | +device with [modbus_set_slave](modbus_set_slave) and connect to the serial bus with | ||
| 40 | +[modbus_connect](modbus_connect). | ||
| 41 | + | ||
| 42 | +## Return value | ||
| 43 | + | ||
| 44 | +The function shall return a pointer to a `modbus_t` structure if | ||
| 45 | +successful. Otherwise it shall return NULL and set errno to one of the values | ||
| 46 | +defined below. | ||
| 47 | + | ||
| 48 | +## Errors | ||
| 49 | + | ||
| 50 | +- *EINVAL*, an invalid argument was given. | ||
| 51 | +- *ENOMEM*, out of memory. Possibly, the application hits its memory limit | ||
| 52 | + and/or whole system is running out of memory. | ||
| 53 | + | ||
| 54 | +## Example | ||
| 55 | + | ||
| 56 | +```c | ||
| 57 | +modbus_t *ctx; | ||
| 58 | + | ||
| 59 | +ctx = modbus_new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1); | ||
| 60 | +if (ctx == NULL) { | ||
| 61 | + fprintf(stderr, "Unable to create the libmodbus context\n"); | ||
| 62 | + return -1; | ||
| 63 | +} | ||
| 64 | + | ||
| 65 | +modbus_set_slave(ctx, YOUR_DEVICE_ID); | ||
| 66 | + | ||
| 67 | +if (modbus_connect(ctx) == -1) { | ||
| 68 | + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); | ||
| 69 | + modbus_free(ctx); | ||
| 70 | + return -1; | ||
| 71 | +} | ||
| 72 | +``` | ||
| 73 | + | ||
| 74 | +## See also | ||
| 75 | + | ||
| 76 | +- [modbus_new_tcp](modbus_new_tcp) | ||
| 77 | +- [modbus_free](modbus_free) |
docs/modbus_new_tcp.md
0 → 100644
| 1 | +# modbus_new_tcp | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_new_tcp - create a libmodbus context for TCP/IPv4 | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +modbus_t *modbus_new_tcp(const char *ip, int port); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_new_tcp()* function shall allocate and initialize a modbus_t | ||
| 16 | +structure to communicate with a Modbus TCP IPv4 server. | ||
| 17 | + | ||
| 18 | +The `ip` argument specifies the IP address of the server to which the client | ||
| 19 | +wants to establish a connection. A NULL value can be used to listen any addresses in | ||
| 20 | +server mode. | ||
| 21 | + | ||
| 22 | +The `port` argument is the TCP port to use. Set the port to | ||
| 23 | +`MODBUS_TCP_DEFAULT_PORT` to use the default one (502). It’s convenient to use a | ||
| 24 | +port number greater than or equal to 1024 because it’s not necessary to have | ||
| 25 | +administrator privileges. | ||
| 26 | + | ||
| 27 | +## Return value | ||
| 28 | + | ||
| 29 | +The function shall return a pointer to a *modbus_t* structure if | ||
| 30 | +successful. Otherwise it shall return NULL and set errno to one of the values | ||
| 31 | +defined below. | ||
| 32 | + | ||
| 33 | +## Errors | ||
| 34 | + | ||
| 35 | +- *EINVAL*, an invalid IP address was given. | ||
| 36 | +- *ENOMEM*, out of memory. Possibly, the application hits its memory limit | ||
| 37 | + and/or whole system is running out of memory. | ||
| 38 | + | ||
| 39 | +## Example | ||
| 40 | + | ||
| 41 | +```c | ||
| 42 | +modbus_t *ctx; | ||
| 43 | + | ||
| 44 | +ctx = modbus_new_tcp("127.0.0.1", 1502); | ||
| 45 | +if (ctx == NULL) { | ||
| 46 | + fprintf(stderr, "Unable to allocate libmodbus context\n"); | ||
| 47 | + return -1; | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +if (modbus_connect(ctx) == -1) { | ||
| 51 | + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); | ||
| 52 | + modbus_free(ctx); | ||
| 53 | + return -1; | ||
| 54 | +} | ||
| 55 | +``` | ||
| 56 | + | ||
| 57 | +## See also | ||
| 58 | + | ||
| 59 | +- [modbus_tcp_listen](modbus_tcp_listen) | ||
| 60 | +- [modbus_free](modbus_free) |
docs/modbus_new_tcp_pi.md
0 → 100644
| 1 | +# modbus_new_tcp_pi | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_new_tcp_pi - create a libmodbus context for TCP Protocol Independent | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +*modbus_t *modbus_new_tcp_pi(const char *node, const char *service); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_new_tcp_pi()* function shall allocate and initialize a modbus_t | ||
| 16 | +structure to communicate with a Modbus TCP IPv4 or IPv6 server. | ||
| 17 | + | ||
| 18 | +The `node` argument specifies the host name or IP address of the host to connect | ||
| 19 | +to, eg. "192.168.0.5" , "::1" or "server.com". A NULL value can be used to | ||
| 20 | +listen any addresses in server mode. | ||
| 21 | + | ||
| 22 | +The `service` argument is the service name/port number to connect to. To use the | ||
| 23 | +default Modbus port, you can provide an NULL value or the string "502". On many | ||
| 24 | +Unix systems, it’s convenient to use a port number greater than or equal to 1024 | ||
| 25 | +because it’s not necessary to have administrator privileges. | ||
| 26 | + | ||
| 27 | +:octicons-tag-24: v3.1.8 handles NULL value for `service` (no *EINVAL* error). | ||
| 28 | + | ||
| 29 | +## Return value | ||
| 30 | + | ||
| 31 | +The function shall return a pointer to a *modbus_t* structure if | ||
| 32 | +successful. Otherwise it shall return NULL and set errno to one of the values | ||
| 33 | +defined below. | ||
| 34 | + | ||
| 35 | +## Errors | ||
| 36 | + | ||
| 37 | +- *ENOMEM*, out of memory. Possibly, the application hits its memory limit | ||
| 38 | + and/or whole system is running out of memory. | ||
| 39 | + | ||
| 40 | +## Example | ||
| 41 | + | ||
| 42 | +```c | ||
| 43 | +modbus_t *ctx; | ||
| 44 | + | ||
| 45 | +ctx = modbus_new_tcp_pi("::1", "1502"); | ||
| 46 | +if (ctx == NULL) { | ||
| 47 | + fprintf(stderr, "Unable to allocate libmodbus context\n"); | ||
| 48 | + return -1; | ||
| 49 | +} | ||
| 50 | + | ||
| 51 | +if (modbus_connect(ctx) == -1) { | ||
| 52 | + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); | ||
| 53 | + modbus_free(ctx); | ||
| 54 | + return -1; | ||
| 55 | +} | ||
| 56 | +``` | ||
| 57 | + | ||
| 58 | +## See also | ||
| 59 | + | ||
| 60 | +- [modbus_new_tcp](modbus_new_tcp) | ||
| 61 | +- [modbus_tcp_pi_listen](modbus_tcp_pi_listen) | ||
| 62 | +- [modbus_free](modbus_free) |
docs/modbus_read_bits.md
0 → 100644
| 1 | +# modbus_read_bits | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_read_bits - read many bits | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_read_bits()* function shall read the status of the `nb` bits (coils) | ||
| 16 | +to the address `addr` of the remote device. The result of reading is stored in | ||
| 17 | +`dest` array as unsigned bytes (8 bits) set to `TRUE` or `FALSE`. | ||
| 18 | + | ||
| 19 | +You must take care to allocate enough memory to store the results in `dest` | ||
| 20 | +(at least `nb` * sizeof(uint8_t)). | ||
| 21 | + | ||
| 22 | +The function uses the Modbus function code 0x01 (read coil status). | ||
| 23 | + | ||
| 24 | +## Return value | ||
| 25 | + | ||
| 26 | +The function shall return the number of read bits if successful. Otherwise it | ||
| 27 | +shall return -1 and set errno. | ||
| 28 | + | ||
| 29 | +## Errors | ||
| 30 | + | ||
| 31 | +- *EMBMDATA*, too many bits requested | ||
| 32 | + | ||
| 33 | +## See also | ||
| 34 | + | ||
| 35 | +- [modbus_write_bit](modbus_write_bit) | ||
| 36 | +- [modbus_write_bits](modbus_write_bits) |
docs/modbus_read_input_bits.md
0 → 100644
| 1 | +# modbus_read_input_bits | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_read_input_bits - read many input bits | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_read_input_bits()* function shall read the content of the `nb` input | ||
| 16 | +bits to the address `addr` of the remote device. The result of reading is stored | ||
| 17 | +in `dest` array as unsigned bytes (8 bits) set to `TRUE` or `FALSE`. | ||
| 18 | + | ||
| 19 | +You must take care to allocate enough memory to store the results in `dest` | ||
| 20 | +(at least `nb` * sizeof(uint8_t)). | ||
| 21 | + | ||
| 22 | +The function uses the Modbus function code 0x02 (read input status). | ||
| 23 | + | ||
| 24 | +## Return value | ||
| 25 | + | ||
| 26 | +The function shall return the number of read input status if | ||
| 27 | +successful. Otherwise it shall return -1 and set errno. | ||
| 28 | + | ||
| 29 | +## Errors | ||
| 30 | + | ||
| 31 | +- *EMBMDATA*, too many discrete inputs requested | ||
| 32 | + | ||
| 33 | +## See also | ||
| 34 | + | ||
| 35 | +- [modbus_read_input_registers](modbus_read_input_registers) |
docs/modbus_read_input_registers.md
0 → 100644
| 1 | +# modbus_read_input_registers | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_read_input_registers - read many input registers | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_read_input_registers()* function shall read the content of the `nb` | ||
| 16 | +input registers to address `addr` of the remote device. The result of the | ||
| 17 | +reading is stored in `dest` array as word values (16 bits). | ||
| 18 | + | ||
| 19 | +You must take care to allocate enough memory to store the results in `dest` (at | ||
| 20 | +least `nb` * sizeof(uint16_t)). | ||
| 21 | + | ||
| 22 | +The function uses the Modbus function code 0x04 (read input registers). The | ||
| 23 | +holding registers and input registers have different historical meaning, but | ||
| 24 | +nowadays it's more common to use holding registers only. | ||
| 25 | + | ||
| 26 | +## Return value | ||
| 27 | + | ||
| 28 | +The function shall return the number of read input registers if | ||
| 29 | +successful. Otherwise it shall return -1 and set errno. | ||
| 30 | + | ||
| 31 | +## Errors | ||
| 32 | + | ||
| 33 | +- *EMBMDATA*, too many bits requested. | ||
| 34 | + | ||
| 35 | +## See also | ||
| 36 | + | ||
| 37 | +- [modbus_read_input_bits](modbus_read_input_bits) | ||
| 38 | +- [modbus_write_register](modbus_write_register) | ||
| 39 | +- [modbus_write_registers](modbus_write_registers) |
docs/modbus_read_registers.md
0 → 100644
| 1 | +# modbus_read_registers | ||
| 2 | + | ||
| 3 | +## Name | ||
| 4 | + | ||
| 5 | +modbus_read_registers - read many registers | ||
| 6 | + | ||
| 7 | +## Synopsis | ||
| 8 | + | ||
| 9 | +```c | ||
| 10 | +int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest); | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Description | ||
| 14 | + | ||
| 15 | +The *modbus_read_registers()* function shall read the content of the `nb` | ||
| 16 | +holding registers to the address `addr` of the remote device. The result of | ||
| 17 | +reading is stored in `dest` array as word values (16 bits). | ||
| 18 | + | ||
| 19 | +You must take care to allocate enough memory to store the results in `dest` | ||
| 20 | +(at least `nb` * sizeof(uint16_t)). | ||
| 21 | + | ||
| 22 | +The function uses the Modbus function code 0x03 (read holding registers). | ||
| 23 | + | ||
| 24 | +## Return value | ||
| 25 | + | ||
| 26 | +The function shall return the number of read registers | ||
| 27 | +if successful. Otherwise it shall return -1 and set errno. | ||
| 28 | + | ||
| 29 | +## Errors | ||
| 30 | + | ||
| 31 | +- *EMBMDATA*, too many registers requested. | ||
| 32 | + | ||
| 33 | +## Example | ||
| 34 | + | ||
| 35 | +```c | ||
| 36 | +modbus_t *ctx; | ||
| 37 | +uint16_t tab_reg[64]; | ||
| 38 | +int rc; | ||
| 39 | +int i; | ||
| 40 | + | ||
| 41 | +ctx = modbus_new_tcp("127.0.0.1", 1502); | ||
| 42 | +if (modbus_connect(ctx) == -1) { | ||
| 43 | + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); | ||
| 44 | + modbus_free(ctx); | ||
| 45 | + return -1; | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +rc = modbus_read_registers(ctx, 0, 10, tab_reg); | ||
| 49 | +if (rc == -1) { | ||
| 50 | + fprintf(stderr, "%s\n", modbus_strerror(errno)); | ||
| 51 | + return -1; | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | +for (i=0; i < rc; i++) { | ||
| 55 | + printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]); | ||
| 56 | +} | ||
| 57 | + | ||
| 58 | +modbus_close(ctx); | ||
| 59 | +modbus_free(ctx); | ||
| 60 | +``` | ||
| 61 | + | ||
| 62 | +## See also | ||
| 63 | + | ||
| 64 | +- [modbus_write_register](modbus_write_register) | ||
| 65 | +- [modbus_write_registers](modbus_write_registers) |