diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/Doxyfile b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/Doxyfile new file mode 100644 index 0000000..8715223 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/Doxyfile @@ -0,0 +1,1921 @@ +# Doxyfile 1.8.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = ModbusRtu + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.20 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Another Arduino library for communicating with Modbus devices over RS232/USB/485 via RTU protocol" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = /home/samuel/Escriptori/libmodbus/documentation + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, +# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, +# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields or simple typedef fields will be shown +# inline in the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO (the default), structs, classes, and unions are shown on a separate +# page (for HTML and Man pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can +# be an expensive process and often the same symbol appear multiple times in +# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too +# small doxygen will become slower. If the cache is too large, memory is wasted. +# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid +# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 +# symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if section-label ... \endif +# and \cond section-label ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. Do not use +# file names with spaces, bibtex cannot handle them. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = /home/samuel/Escriptori/libmodbus + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be ignored. +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If left blank doxygen will +# generate a default style sheet. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is included after the standard +# style sheets created by doxygen. Using this option one can overrule +# certain style aspects. This is preferred over using HTML_STYLESHEET +# since it does not replace the standard style sheet and is therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely +# identify the documentation publisher. This should be a reverse domain-name +# style string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and +# SVG. The default value is HTML-CSS, which is slower, but has the best +# compatibility. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript +# pieces of code that will be used on startup of the MathJax code. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. +# There are two flavours of web server based search depending on the +# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +# searching and an index file used by the script. When EXTERNAL_SEARCH is +# enabled the indexing and searching needs to be provided by external tools. +# See the manual for details. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain +# the search results. Doxygen ships with an example indexer (doxyindexer) and +# search engine (doxysearch.cgi) which are based on the open source search +# engine library Xapian. See the manual for configuration details. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will returned the search results when EXTERNAL_SEARCH is enabled. +# Doxygen ships with an example search engine (doxysearch) which is based on +# the open source search engine library Xapian. See the manual for configuration +# details. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id +# of to a relative location where the documentation can be found. +# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4 will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images +# or other source files which should be copied to the LaTeX output directory. +# Note that the files will be copied as-is; there are no commands or markers +# available. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = YES + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files +# that can be used to generate PDF. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. If left blank docbook will be used as the default path. + +DOCBOOK_OUTPUT = docbook + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed +# in the related pages index. If set to NO, only the current project's +# pages will be listed. + +EXTERNAL_PAGES = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# manageable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/LICENSE.md b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/LICENSE.md new file mode 100644 index 0000000..941668d --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/LICENSE.md @@ -0,0 +1,458 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/ModbusRtu.cpp b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/ModbusRtu.cpp new file mode 100644 index 0000000..f33abaf --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/ModbusRtu.cpp @@ -0,0 +1,1145 @@ +/** + * @file ModbusRtu.h + * @version 1.21 + * @date 2016.02.21 + * @author Samuel Marco i Armengol + * @contact sammarcoarmengol@gmail.com + * @contribution Helium6072 + * @contribution gabrielsan + * + * @description + * Arduino library for communicating with Modbus devices + * over RS232/USB/485 via RTU protocol. + * + * Further information: + * http://modbus.org/ + * http://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf + * + * @license + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version + * 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * @defgroup setup Modbus Object Instantiation/Initialization + * @defgroup loop Modbus Object Management + * @defgroup buffer Modbus Buffer Management + * @defgroup discrete Modbus Function Codes for Discrete Coils/Inputs + * @defgroup register Modbus Function Codes for Holding/Input Registers + * + */ + +#include + +/* _____PUBLIC FUNCTIONS_____________________________________________________ */ + +/** + * @brief + * Constructor for a Master/Slave. + * + * For hardware serial through USB/RS232C/RS485 set port to Serial, Serial1, + * Serial2, or Serial3. (Numbered hardware serial ports are only available on + * some boards.) + * + * For software serial through RS232C/RS485 set port to a SoftwareSerial object + * that you have already constructed. + * + * ModbusRtu needs a pin for flow control only for RS485 mode. Pins 0 and 1 + * cannot be used. + * + * First call begin() on your serial port, and then start up ModbusRtu by + * calling start(). You can choose the line speed and other port parameters + * by passing the appropriate values to the port's begin() function. + * + * @param u8id node address 0=master, 1..247=slave + * @param port serial port used + * @param u8txenpin pin for txen RS-485 (=0 means USB/RS232C mode) + * @ingroup setup + */ +Modbus::Modbus(uint8_t u8id, Stream& port, uint8_t u8txenpin) +{ + this->port = &port; + this->u8id = u8id; + this->u8txenpin = u8txenpin; + this->u16timeOut = 1000; + this->u32overTime = 0; +} + + +/** + * @brief + * DEPRECATED constructor for a Master/Slave. + * + * THIS CONSTRUCTOR IS ONLY PROVIDED FOR BACKWARDS COMPATIBILITY. + * USE Modbus(uint8_t, T_Stream&, uint8_t) INSTEAD. + * + * @param u8id node address 0=master, 1..247=slave + * @param u8serno serial port used 0..3 (ignored for software serial) + * @param u8txenpin pin for txen RS-485 (=0 means USB/RS232C mode) + * @ingroup setup + * @overload Modbus::Modbus(uint8_t u8id, T_Stream& port, uint8_t u8txenpin) + */ +Modbus::Modbus(uint8_t u8id, uint8_t u8serno, uint8_t u8txenpin) +{ + this->u8id = u8id; + this->u8txenpin = u8txenpin; + this->u16timeOut = 1000; + this->u32overTime = 0; + + switch( u8serno ) + { +#if defined(UBRR1H) + case 1: + port = &Serial1; + break; +#endif + +#if defined(UBRR2H) + case 2: + port = &Serial2; + break; +#endif + +#if defined(UBRR3H) + case 3: + port = &Serial3; + break; +#endif + case 0: + default: + port = &Serial; + break; + } +} + + +/** + * @brief + * Start-up class object. + * + * Call this AFTER calling begin() on the serial port, typically within setup(). + * + * (If you call this function, then you should NOT call any of + * ModbusRtu's own begin() functions.) + * + * @ingroup setup + */ +void Modbus::start() +{ + if (u8txenpin > 1) // pin 0 & pin 1 are reserved for RX/TX + { + // return RS485 transceiver to transmit mode + pinMode(u8txenpin, OUTPUT); + digitalWrite(u8txenpin, LOW); + } + + while(port->read() >= 0); + u8lastRec = u8BufferSize = 0; + u16InCnt = u16OutCnt = u16errCnt = 0; +} + + +/** + * @brief + * DEPRECATED Install a serial port, begin() it, and start ModbusRtu. + * + * ONLY PROVIDED FOR BACKWARDS COMPATIBILITY. + * USE Serial.begin(); FOLLOWED BY Modbus.start() INSTEAD. + * + * @param install_port pointer to SoftwareSerial or HardwareSerial class object + * @param u32speed baud rate, in standard increments (300..115200) + * @ingroup setup + */ +template +void Modbus::begin(T_Stream* install_port, long u32speed) +{ + port = install_port; + install_port->begin(u32speed); + start(); +} + + +/** + * @brief + * DEPRECATED. Install a serial port, begin() it, and start ModbusRtu. + * + * ONLY PROVIDED FOR BACKWARDS COMPATIBILITY. + * USE Serial.begin(); FOLLOWED BY Modbus.start() INSTEAD. + * + * @param install_port pointer to SoftwareSerial or HardwareSerial class object + * @param u32speed baud rate, in standard increments (300..115200) + * @param u8txenpin pin for txen RS-485 (=0 means USB/RS232C mode) + * @ingroup setup + */ +template +void Modbus::begin(T_Stream* install_port, long u32speed, uint8_t u8txenpin) +{ + this->u8txenpin = u8txenpin; + this->port = install_port; + install_port->begin(u32speed); + start(); +} + + +/** + * @brief + * DEPRECATED. begin() hardware serial port and start ModbusRtu. + * + * ONLY PROVIDED FOR BACKWARDS COMPATIBILITY. + * USE Serial.begin(); FOLLOWED BY Modbus.start() INSTEAD. + * + * @see http://arduino.cc/en/Serial/Begin#.Uy4CJ6aKlHY + * @param speed baud rate, in standard increments (300..115200). Default=19200 + * @ingroup setup + */ +void Modbus::begin(long u32speed) +{ + // !!Can ONLY do this if port ACTUALLY IS a HardwareSerial object!! + static_cast(port)->begin(u32speed); + start(); +} + + +/** + * @brief + * Method to write a new slave ID address + * + * @param u8id new slave address between 1 and 247 + * @ingroup setup + */ +void Modbus::setID( uint8_t u8id) +{ + if (( u8id != 0) && (u8id <= 247)) + { + this->u8id = u8id; + } +} + +/** + * @brief + * Method to write the overtime count for txend pin. + * It waits until count reaches 0 after the transfer is done. + * With this, you can extend the time between txempty and + * the falling edge if needed. + * + * @param uint32_t overtime count for txend pin + * @ingroup setup + */ +void Modbus::setTxendPinOverTime( uint32_t u32overTime ) +{ + this->u32overTime = u32overTime; +} + +/** + * @brief + * Method to read current slave ID address + * + * @return u8id current slave address between 1 and 247 + * @ingroup setup + */ +uint8_t Modbus::getID() +{ + return this->u8id; +} + +/** + * @brief + * Initialize time-out parameter + * + * Call once class has been instantiated, typically within setup(). + * The time-out timer is reset each time that there is a successful communication + * between Master and Slave. It works for both. + * + * @param time-out value (ms) + * @ingroup setup + */ +void Modbus::setTimeOut( uint16_t u16timeOut) +{ + this->u16timeOut = u16timeOut; +} + +/** + * @brief + * Return communication Watchdog state. + * It could be usefull to reset outputs if the watchdog is fired. + * + * @return TRUE if millis() > u32timeOut + * @ingroup loop + */ +boolean Modbus::getTimeOutState() +{ + return ((unsigned long)(millis() -u32timeOut) > (unsigned long)u16timeOut); +} + +/** + * @brief + * Get input messages counter value + * This can be useful to diagnose communication + * + * @return input messages counter + * @ingroup buffer + */ +uint16_t Modbus::getInCnt() +{ + return u16InCnt; +} + +/** + * @brief + * Get transmitted messages counter value + * This can be useful to diagnose communication + * + * @return transmitted messages counter + * @ingroup buffer + */ +uint16_t Modbus::getOutCnt() +{ + return u16OutCnt; +} + +/** + * @brief + * Get errors counter value + * This can be useful to diagnose communication + * + * @return errors counter + * @ingroup buffer + */ +uint16_t Modbus::getErrCnt() +{ + return u16errCnt; +} + +/** + * Get modbus master state + * + * @return = 0 IDLE, = 1 WAITING FOR ANSWER + * @ingroup buffer + */ +uint8_t Modbus::getState() +{ + return u8state; +} + +/** + * Get the last error in the protocol processor + * + * @returnreturn NO_REPLY = 255 Time-out + * @return EXC_FUNC_CODE = 1 Function code not available + * @return EXC_ADDR_RANGE = 2 Address beyond available space for Modbus registers + * @return EXC_REGS_QUANT = 3 Coils or registers number beyond the available space + * @ingroup buffer + */ +uint8_t Modbus::getLastError() +{ + return u8lastError; +} + +/** + * @brief + * *** Only Modbus Master *** + * Generate a query to an slave with a modbus_t telegram structure + * The Master must be in COM_IDLE mode. After it, its state would be COM_WAITING. + * This method has to be called only in loop() section. + * + * @see modbus_t + * @param modbus_t modbus telegram structure (id, fct, ...) + * @ingroup loop + * @todo finish function 15 + */ +int8_t Modbus::query( modbus_t telegram ) +{ + uint8_t u8regsno, u8bytesno; + if (u8id!=0) return -2; + if (u8state != COM_IDLE) return -1; + + if ((telegram.u8id==0) || (telegram.u8id>247)) return -3; + + au16regs = telegram.au16reg; + + // telegram header + au8Buffer[ ID ] = telegram.u8id; + au8Buffer[ FUNC ] = telegram.u8fct; + au8Buffer[ ADD_HI ] = highByte(telegram.u16RegAdd ); + au8Buffer[ ADD_LO ] = lowByte( telegram.u16RegAdd ); + + switch( telegram.u8fct ) + { + case MB_FC_READ_COILS: + case MB_FC_READ_DISCRETE_INPUT: + case MB_FC_READ_REGISTERS: + case MB_FC_READ_INPUT_REGISTER: + au8Buffer[ NB_HI ] = highByte(telegram.u16CoilsNo ); + au8Buffer[ NB_LO ] = lowByte( telegram.u16CoilsNo ); + u8BufferSize = 6; + break; + case MB_FC_WRITE_COIL: + au8Buffer[ NB_HI ] = ((au16regs[0] > 0) ? 0xff : 0); + au8Buffer[ NB_LO ] = 0; + u8BufferSize = 6; + break; + case MB_FC_WRITE_REGISTER: + au8Buffer[ NB_HI ] = highByte(au16regs[0]); + au8Buffer[ NB_LO ] = lowByte(au16regs[0]); + u8BufferSize = 6; + break; + case MB_FC_WRITE_MULTIPLE_COILS: // TODO: implement "sending coils" + u8regsno = telegram.u16CoilsNo / 16; + u8bytesno = u8regsno * 2; + if ((telegram.u16CoilsNo % 16) != 0) + { + u8bytesno++; + u8regsno++; + } + + au8Buffer[ NB_HI ] = highByte(telegram.u16CoilsNo ); + au8Buffer[ NB_LO ] = lowByte( telegram.u16CoilsNo ); + au8Buffer[ BYTE_CNT ] = u8bytesno; + u8BufferSize = 7; + + for (uint16_t i = 0; i < u8bytesno; i++) + { + if(i%2) + { + au8Buffer[ u8BufferSize ] = lowByte( au16regs[ i/2 ] ); + } + else + { + au8Buffer[ u8BufferSize ] = highByte( au16regs[ i/2] ); + } + u8BufferSize++; + } + break; + + case MB_FC_WRITE_MULTIPLE_REGISTERS: + au8Buffer[ NB_HI ] = highByte(telegram.u16CoilsNo ); + au8Buffer[ NB_LO ] = lowByte( telegram.u16CoilsNo ); + au8Buffer[ BYTE_CNT ] = (uint8_t) ( telegram.u16CoilsNo * 2 ); + u8BufferSize = 7; + + for (uint16_t i=0; i< telegram.u16CoilsNo; i++) + { + au8Buffer[ u8BufferSize ] = highByte( au16regs[ i ] ); + u8BufferSize++; + au8Buffer[ u8BufferSize ] = lowByte( au16regs[ i ] ); + u8BufferSize++; + } + break; + } + + sendTxBuffer(); + u8state = COM_WAITING; + u8lastError = 0; + return 0; +} + +/** + * @brief *** Only for Modbus Master *** + * This method checks if there is any incoming answer if pending. + * If there is no answer, it would change Master state to COM_IDLE. + * This method must be called only at loop section. + * Avoid any delay() function. + * + * Any incoming data would be redirected to au16regs pointer, + * as defined in its modbus_t query telegram. + * + * @params nothing + * @return errors counter + * @ingroup loop + */ +int8_t Modbus::poll() +{ + // check if there is any incoming frame + uint8_t u8current; + u8current = port->available(); + + if ((unsigned long)(millis() -u32timeOut) > (unsigned long)u16timeOut) + { + u8state = COM_IDLE; + u8lastError = NO_REPLY; + u16errCnt++; + return 0; + } + + if (u8current == 0) return 0; + + // check T35 after frame end or still no frame end + if (u8current != u8lastRec) + { + u8lastRec = u8current; + u32time = millis(); + return 0; + } + if ((unsigned long)(millis() -u32time) < (unsigned long)T35) return 0; + + // transfer Serial buffer frame to auBuffer + u8lastRec = 0; + int8_t i8state = getRxBuffer(); + if (i8state < 6) //7 was incorrect for functions 1 and 2 the smallest frame could be 6 bytes long + { + u8state = COM_IDLE; + u16errCnt++; + return i8state; + } + + // validate message: id, CRC, FCT, exception + uint8_t u8exception = validateAnswer(); + if (u8exception != 0) + { + u8state = COM_IDLE; + return u8exception; + } + + // process answer + switch( au8Buffer[ FUNC ] ) + { + case MB_FC_READ_COILS: + case MB_FC_READ_DISCRETE_INPUT: + // call get_FC1 to transfer the incoming message to au16regs buffer + get_FC1( ); + break; + case MB_FC_READ_INPUT_REGISTER: + case MB_FC_READ_REGISTERS : + // call get_FC3 to transfer the incoming message to au16regs buffer + get_FC3( ); + break; + case MB_FC_WRITE_COIL: + case MB_FC_WRITE_REGISTER : + case MB_FC_WRITE_MULTIPLE_COILS: + case MB_FC_WRITE_MULTIPLE_REGISTERS : + // nothing to do + break; + default: + break; + } + u8state = COM_IDLE; + return u8BufferSize; +} + +/** + * @brief + * *** Only for Modbus Slave *** + * This method checks if there is any incoming query + * Afterwards, it would shoot a validation routine plus a register query + * Avoid any delay() function !!!! + * After a successful frame between the Master and the Slave, the time-out timer is reset. + * + * @param *regs register table for communication exchange + * @param u8size size of the register table + * @return 0 if no query, 1..4 if communication error, >4 if correct query processed + * @ingroup loop + */ +int8_t Modbus::poll( uint16_t *regs, uint8_t u8size ) +{ + + au16regs = regs; + u8regsize = u8size; + uint8_t u8current; + + + // check if there is any incoming frame + u8current = port->available(); + + if (u8current == 0) return 0; + + // check T35 after frame end or still no frame end + if (u8current != u8lastRec) + { + u8lastRec = u8current; + u32time = millis(); + return 0; + } + if ((unsigned long)(millis() -u32time) < (unsigned long)T35) return 0; + + u8lastRec = 0; + int8_t i8state = getRxBuffer(); + u8lastError = i8state; + if (i8state < 7) return i8state; + + // check slave id + if (au8Buffer[ ID ] != u8id) return 0; + + // validate message: CRC, FCT, address and size + uint8_t u8exception = validateRequest(); + if (u8exception > 0) + { + if (u8exception != NO_REPLY) + { + buildException( u8exception ); + sendTxBuffer(); + } + u8lastError = u8exception; + return u8exception; + } + + u32timeOut = millis(); + u8lastError = 0; + + // process message + switch( au8Buffer[ FUNC ] ) + { + case MB_FC_READ_COILS: + case MB_FC_READ_DISCRETE_INPUT: + return process_FC1( regs, u8size ); + break; + case MB_FC_READ_INPUT_REGISTER: + case MB_FC_READ_REGISTERS : + return process_FC3( regs, u8size ); + break; + case MB_FC_WRITE_COIL: + return process_FC5( regs, u8size ); + break; + case MB_FC_WRITE_REGISTER : + return process_FC6( regs, u8size ); + break; + case MB_FC_WRITE_MULTIPLE_COILS: + return process_FC15( regs, u8size ); + break; + case MB_FC_WRITE_MULTIPLE_REGISTERS : + return process_FC16( regs, u8size ); + break; + default: + break; + } + return i8state; +} + +/* _____PRIVATE FUNCTIONS_____________________________________________________ */ + +/** + * @brief + * This method moves Serial buffer data to the Modbus au8Buffer. + * + * @return buffer size if OK, ERR_BUFF_OVERFLOW if u8BufferSize >= MAX_BUFFER + * @ingroup buffer + */ +int8_t Modbus::getRxBuffer() +{ + boolean bBuffOverflow = false; + + if (u8txenpin > 1) digitalWrite( u8txenpin, LOW ); + + u8BufferSize = 0; + while ( port->available() ) + { + au8Buffer[ u8BufferSize ] = port->read(); + u8BufferSize ++; + + if (u8BufferSize >= MAX_BUFFER) bBuffOverflow = true; + } + u16InCnt++; + + if (bBuffOverflow) + { + u16errCnt++; + return ERR_BUFF_OVERFLOW; + } + return u8BufferSize; +} + +/** + * @brief + * This method transmits au8Buffer to Serial line. + * Only if u8txenpin != 0, there is a flow handling in order to keep + * the RS485 transceiver in output state as long as the message is being sent. + * This is done with UCSRxA register. + * The CRC is appended to the buffer before starting to send it. + * + * @param nothing + * @return nothing + * @ingroup buffer + */ +void Modbus::sendTxBuffer() +{ + // append CRC to message + uint16_t u16crc = calcCRC( u8BufferSize ); + au8Buffer[ u8BufferSize ] = u16crc >> 8; + u8BufferSize++; + au8Buffer[ u8BufferSize ] = u16crc & 0x00ff; + u8BufferSize++; + + if (u8txenpin > 1) + { + // set RS485 transceiver to transmit mode + digitalWrite( u8txenpin, HIGH ); + } + + // transfer buffer to serial line + port->write( au8Buffer, u8BufferSize ); + + if (u8txenpin > 1) + { + // must wait transmission end before changing pin state + // soft serial does not need it since it is blocking + // ...but the implementation in SoftwareSerial does nothing + // anyway, so no harm in calling it. + port->flush(); + // return RS485 transceiver to receive mode + volatile uint32_t u32overTimeCountDown = u32overTime; + while ( u32overTimeCountDown-- > 0); + digitalWrite( u8txenpin, LOW ); + } + while(port->read() >= 0); + + u8BufferSize = 0; + + // set time-out for master + u32timeOut = millis(); + + // increase message counter + u16OutCnt++; +} + +/** + * @brief + * This method calculates CRC + * + * @return uint16_t calculated CRC value for the message + * @ingroup buffer + */ +uint16_t Modbus::calcCRC(uint8_t u8length) +{ + unsigned int temp, temp2, flag; + temp = 0xFFFF; + for (unsigned char i = 0; i < u8length; i++) + { + temp = temp ^ au8Buffer[i]; + for (unsigned char j = 1; j <= 8; j++) + { + flag = temp & 0x0001; + temp >>=1; + if (flag) + temp ^= 0xA001; + } + } + // Reverse byte order. + temp2 = temp >> 8; + temp = (temp << 8) | temp2; + temp &= 0xFFFF; + // the returned value is already swapped + // crcLo byte is first & crcHi byte is last + return temp; +} + +/** + * @brief + * This method validates slave incoming messages + * + * @return 0 if OK, EXCEPTION if anything fails + * @ingroup buffer + */ +uint8_t Modbus::validateRequest() +{ + // check message crc vs calculated crc + uint16_t u16MsgCRC = + ((au8Buffer[u8BufferSize - 2] << 8) + | au8Buffer[u8BufferSize - 1]); // combine the crc Low & High bytes + if ( calcCRC( u8BufferSize-2 ) != u16MsgCRC ) + { + u16errCnt ++; + return NO_REPLY; + } + + // check fct code + boolean isSupported = false; + for (uint8_t i = 0; i< sizeof( fctsupported ); i++) + { + if (fctsupported[i] == au8Buffer[FUNC]) + { + isSupported = 1; + break; + } + } + if (!isSupported) + { + u16errCnt ++; + return EXC_FUNC_CODE; + } + + // check start address & nb range + uint16_t u16regs = 0; + uint8_t u8regs; + switch ( au8Buffer[ FUNC ] ) + { + case MB_FC_READ_COILS: + case MB_FC_READ_DISCRETE_INPUT: + case MB_FC_WRITE_MULTIPLE_COILS: + u16regs = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ]) / 16; + u16regs += word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ]) /16; + u8regs = (uint8_t) u16regs; + if (u8regs > u8regsize) return EXC_ADDR_RANGE; + break; + case MB_FC_WRITE_COIL: + u16regs = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ]) / 16; + u8regs = (uint8_t) u16regs; + if (u8regs > u8regsize) return EXC_ADDR_RANGE; + break; + case MB_FC_WRITE_REGISTER : + u16regs = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ]); + u8regs = (uint8_t) u16regs; + if (u8regs > u8regsize) return EXC_ADDR_RANGE; + break; + case MB_FC_READ_REGISTERS : + case MB_FC_READ_INPUT_REGISTER : + case MB_FC_WRITE_MULTIPLE_REGISTERS : + u16regs = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ]); + u16regs += word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ]); + u8regs = (uint8_t) u16regs; + if (u8regs > u8regsize) return EXC_ADDR_RANGE; + break; + } + return 0; // OK, no exception code thrown +} + +/** + * @brief + * This method validates master incoming messages + * + * @return 0 if OK, EXCEPTION if anything fails + * @ingroup buffer + */ +uint8_t Modbus::validateAnswer() +{ + // check message crc vs calculated crc + uint16_t u16MsgCRC = + ((au8Buffer[u8BufferSize - 2] << 8) + | au8Buffer[u8BufferSize - 1]); // combine the crc Low & High bytes + if ( calcCRC( u8BufferSize-2 ) != u16MsgCRC ) + { + u16errCnt ++; + return NO_REPLY; + } + + // check exception + if ((au8Buffer[ FUNC ] & 0x80) != 0) + { + u16errCnt ++; + return ERR_EXCEPTION; + } + + // check fct code + boolean isSupported = false; + for (uint8_t i = 0; i< sizeof( fctsupported ); i++) + { + if (fctsupported[i] == au8Buffer[FUNC]) + { + isSupported = 1; + break; + } + } + if (!isSupported) + { + u16errCnt ++; + return EXC_FUNC_CODE; + } + + return 0; // OK, no exception code thrown +} + +/** + * @brief + * This method builds an exception message + * + * @ingroup buffer + */ +void Modbus::buildException( uint8_t u8exception ) +{ + uint8_t u8func = au8Buffer[ FUNC ]; // get the original FUNC code + + au8Buffer[ ID ] = u8id; + au8Buffer[ FUNC ] = u8func + 0x80; + au8Buffer[ 2 ] = u8exception; + u8BufferSize = EXCEPTION_SIZE; +} + +/** + * This method processes functions 1 & 2 (for master) + * This method puts the slave answer into master data buffer + * + * @ingroup register + * TODO: finish its implementation + */ +void Modbus::get_FC1() +{ + uint8_t u8byte, i; + u8byte = 3; + for (i=0; i< au8Buffer[2]; i++) { + + if(i%2) + { + au16regs[i/2]= word(au8Buffer[i+u8byte], lowByte(au16regs[i/2])); + } + else + { + + au16regs[i/2]= word(highByte(au16regs[i/2]), au8Buffer[i+u8byte]); + } + + } +} + +/** + * This method processes functions 3 & 4 (for master) + * This method puts the slave answer into master data buffer + * + * @ingroup register + */ +void Modbus::get_FC3() +{ + uint8_t u8byte, i; + u8byte = 3; + + for (i=0; i< au8Buffer[ 2 ] /2; i++) + { + au16regs[ i ] = word( + au8Buffer[ u8byte ], + au8Buffer[ u8byte +1 ]); + u8byte += 2; + } +} + +/** + * @brief + * This method processes functions 1 & 2 + * This method reads a bit array and transfers it to the master + * + * @return u8BufferSize Response to master length + * @ingroup discrete + */ +int8_t Modbus::process_FC1( uint16_t *regs, uint8_t /*u8size*/ ) +{ + uint8_t u8currentRegister, u8currentBit, u8bytesno, u8bitsno; + uint8_t u8CopyBufferSize; + uint16_t u16currentCoil, u16coil; + + // get the first and last coil from the message + uint16_t u16StartCoil = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ] ); + uint16_t u16Coilno = word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ] ); + + // put the number of bytes in the outcoming message + u8bytesno = (uint8_t) (u16Coilno / 8); + if (u16Coilno % 8 != 0) u8bytesno ++; + au8Buffer[ ADD_HI ] = u8bytesno; + u8BufferSize = ADD_LO; + au8Buffer[ u8BufferSize + u8bytesno - 1 ] = 0; + + // read each coil from the register map and put its value inside the outcoming message + u8bitsno = 0; + + for (u16currentCoil = 0; u16currentCoil < u16Coilno; u16currentCoil++) + { + u16coil = u16StartCoil + u16currentCoil; + u8currentRegister = (uint8_t) (u16coil / 16); + u8currentBit = (uint8_t) (u16coil % 16); + + bitWrite( + au8Buffer[ u8BufferSize ], + u8bitsno, + bitRead( regs[ u8currentRegister ], u8currentBit ) ); + u8bitsno ++; + + if (u8bitsno > 7) + { + u8bitsno = 0; + u8BufferSize++; + } + } + + // send outcoming message + if (u16Coilno % 8 != 0) u8BufferSize ++; + u8CopyBufferSize = u8BufferSize +2; + sendTxBuffer(); + return u8CopyBufferSize; +} + +/** + * @brief + * This method processes functions 3 & 4 + * This method reads a word array and transfers it to the master + * + * @return u8BufferSize Response to master length + * @ingroup register + */ +int8_t Modbus::process_FC3( uint16_t *regs, uint8_t /*u8size*/ ) +{ + + uint8_t u8StartAdd = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ] ); + uint8_t u8regsno = word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ] ); + uint8_t u8CopyBufferSize; + uint8_t i; + + au8Buffer[ 2 ] = u8regsno * 2; + u8BufferSize = 3; + + for (i = u8StartAdd; i < u8StartAdd + u8regsno; i++) + { + au8Buffer[ u8BufferSize ] = highByte(regs[i]); + u8BufferSize++; + au8Buffer[ u8BufferSize ] = lowByte(regs[i]); + u8BufferSize++; + } + u8CopyBufferSize = u8BufferSize +2; + sendTxBuffer(); + + return u8CopyBufferSize; +} + +/** + * @brief + * This method processes function 5 + * This method writes a value assigned by the master to a single bit + * + * @return u8BufferSize Response to master length + * @ingroup discrete + */ +int8_t Modbus::process_FC5( uint16_t *regs, uint8_t /*u8size*/ ) +{ + uint8_t u8currentRegister, u8currentBit; + uint8_t u8CopyBufferSize; + uint16_t u16coil = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ] ); + + // point to the register and its bit + u8currentRegister = (uint8_t) (u16coil / 16); + u8currentBit = (uint8_t) (u16coil % 16); + + // write to coil + bitWrite( + regs[ u8currentRegister ], + u8currentBit, + au8Buffer[ NB_HI ] == 0xff ); + + + // send answer to master + u8BufferSize = 6; + u8CopyBufferSize = u8BufferSize +2; + sendTxBuffer(); + + return u8CopyBufferSize; +} + +/** + * @brief + * This method processes function 6 + * This method writes a value assigned by the master to a single word + * + * @return u8BufferSize Response to master length + * @ingroup register + */ +int8_t Modbus::process_FC6( uint16_t *regs, uint8_t /*u8size*/ ) +{ + + uint8_t u8add = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ] ); + uint8_t u8CopyBufferSize; + uint16_t u16val = word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ] ); + + regs[ u8add ] = u16val; + + // keep the same header + u8BufferSize = RESPONSE_SIZE; + + u8CopyBufferSize = u8BufferSize +2; + sendTxBuffer(); + + return u8CopyBufferSize; +} + +/** + * @brief + * This method processes function 15 + * This method writes a bit array assigned by the master + * + * @return u8BufferSize Response to master length + * @ingroup discrete + */ +int8_t Modbus::process_FC15( uint16_t *regs, uint8_t /*u8size*/ ) +{ + uint8_t u8currentRegister, u8currentBit, u8frameByte, u8bitsno; + uint8_t u8CopyBufferSize; + uint16_t u16currentCoil, u16coil; + boolean bTemp; + + // get the first and last coil from the message + uint16_t u16StartCoil = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ] ); + uint16_t u16Coilno = word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ] ); + + + // read each coil from the register map and put its value inside the outcoming message + u8bitsno = 0; + u8frameByte = 7; + for (u16currentCoil = 0; u16currentCoil < u16Coilno; u16currentCoil++) + { + + u16coil = u16StartCoil + u16currentCoil; + u8currentRegister = (uint8_t) (u16coil / 16); + u8currentBit = (uint8_t) (u16coil % 16); + + bTemp = bitRead( + au8Buffer[ u8frameByte ], + u8bitsno ); + + bitWrite( + regs[ u8currentRegister ], + u8currentBit, + bTemp ); + + u8bitsno ++; + + if (u8bitsno > 7) + { + u8bitsno = 0; + u8frameByte++; + } + } + + // send outcoming message + // it's just a copy of the incomping frame until 6th byte + u8BufferSize = 6; + u8CopyBufferSize = u8BufferSize +2; + sendTxBuffer(); + return u8CopyBufferSize; +} + +/** + * @brief + * This method processes function 16 + * This method writes a word array assigned by the master + * + * @return u8BufferSize Response to master length + * @ingroup register + */ +int8_t Modbus::process_FC16( uint16_t *regs, uint8_t /*u8size*/ ) +{ + uint8_t u8StartAdd = au8Buffer[ ADD_HI ] << 8 | au8Buffer[ ADD_LO ]; + uint8_t u8regsno = au8Buffer[ NB_HI ] << 8 | au8Buffer[ NB_LO ]; + uint8_t u8CopyBufferSize; + uint8_t i; + uint16_t temp; + + // build header + au8Buffer[ NB_HI ] = 0; + au8Buffer[ NB_LO ] = u8regsno; + u8BufferSize = RESPONSE_SIZE; + + // write registers + for (i = 0; i < u8regsno; i++) + { + temp = word( + au8Buffer[ (BYTE_CNT + 1) + i * 2 ], + au8Buffer[ (BYTE_CNT + 2) + i * 2 ]); + + regs[ u8StartAdd + i ] = temp; + } + u8CopyBufferSize = u8BufferSize +2; + sendTxBuffer(); + + return u8CopyBufferSize; +} diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/ModbusRtu.h b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/ModbusRtu.h new file mode 100644 index 0000000..48887b2 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/ModbusRtu.h @@ -0,0 +1,228 @@ +/** + * @file ModbusRtu.h + * @version 1.21 + * @date 2016.02.21 + * @author Samuel Marco i Armengol + * @contact sammarcoarmengol@gmail.com + * @contribution Helium6072 + * @contribution gabrielsan + * + * @description + * Arduino library for communicating with Modbus devices + * over RS232/USB/485 via RTU protocol. + * + * Further information: + * http://modbus.org/ + * http://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf + * + * @license + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version + * 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * @defgroup setup Modbus Object Instantiation/Initialization + * @defgroup loop Modbus Object Management + * @defgroup buffer Modbus Buffer Management + * @defgroup discrete Modbus Function Codes for Discrete Coils/Inputs + * @defgroup register Modbus Function Codes for Holding/Input Registers + * + */ + +#ifndef MODBUS_RTU_H +#define MODBUS_RTU_H + +#include +#include "Arduino.h" + + +/** + * @struct modbus_t + * @brief + * Master query structure: + * This includes all the necessary fields to make the Master generate a Modbus query. + * A Master may keep several of these structures and send them cyclically or + * use them according to program needs. + */ +typedef struct +{ + uint8_t u8id; /*!< Slave address between 1 and 247. 0 means broadcast */ + uint8_t u8fct; /*!< Function code: 1, 2, 3, 4, 5, 6, 15 or 16 */ + uint16_t u16RegAdd; /*!< Address of the first register to access at slave/s */ + uint16_t u16CoilsNo; /*!< Number of coils or registers to access */ + uint16_t *au16reg; /*!< Pointer to memory image in master */ +} +modbus_t; + +enum +{ + RESPONSE_SIZE = 6, + EXCEPTION_SIZE = 3, + CHECKSUM_SIZE = 2 +}; + +/** + * @enum MESSAGE + * @brief + * Indexes to telegram frame positions + */ +enum MESSAGE +{ + ID = 0, //!< ID field + FUNC, //!< Function code position + ADD_HI, //!< Address high byte + ADD_LO, //!< Address low byte + NB_HI, //!< Number of coils or registers high byte + NB_LO, //!< Number of coils or registers low byte + BYTE_CNT //!< byte counter +}; + +/** + * @enum MB_FC + * @brief + * Modbus function codes summary. + * These are the implement function codes either for Master or for Slave. + * + * @see also fctsupported + * @see also modbus_t + */ +enum MB_FC +{ + MB_FC_NONE = 0, /*!< null operator */ + MB_FC_READ_COILS = 1, /*!< FCT=1 -> read coils or digital outputs */ + MB_FC_READ_DISCRETE_INPUT = 2, /*!< FCT=2 -> read digital inputs */ + MB_FC_READ_REGISTERS = 3, /*!< FCT=3 -> read registers or analog outputs */ + MB_FC_READ_INPUT_REGISTER = 4, /*!< FCT=4 -> read analog inputs */ + MB_FC_WRITE_COIL = 5, /*!< FCT=5 -> write single coil or output */ + MB_FC_WRITE_REGISTER = 6, /*!< FCT=6 -> write single register */ + MB_FC_WRITE_MULTIPLE_COILS = 15, /*!< FCT=15 -> write multiple coils or outputs */ + MB_FC_WRITE_MULTIPLE_REGISTERS = 16 /*!< FCT=16 -> write multiple registers */ +}; + +enum COM_STATES +{ + COM_IDLE = 0, + COM_WAITING = 1 + +}; + +enum ERR_LIST +{ + ERR_NOT_MASTER = -1, + ERR_POLLING = -2, + ERR_BUFF_OVERFLOW = -3, + ERR_BAD_CRC = -4, + ERR_EXCEPTION = -5 +}; + +enum +{ + NO_REPLY = 255, + EXC_FUNC_CODE = 1, + EXC_ADDR_RANGE = 2, + EXC_REGS_QUANT = 3, + EXC_EXECUTE = 4 +}; + +const unsigned char fctsupported[] = +{ + MB_FC_READ_COILS, + MB_FC_READ_DISCRETE_INPUT, + MB_FC_READ_REGISTERS, + MB_FC_READ_INPUT_REGISTER, + MB_FC_WRITE_COIL, + MB_FC_WRITE_REGISTER, + MB_FC_WRITE_MULTIPLE_COILS, + MB_FC_WRITE_MULTIPLE_REGISTERS +}; + +#define T35 5 +#define MAX_BUFFER 64 //!< maximum size for the communication buffer in bytes + +/** + * @class Modbus + * @brief + * Arduino class library for communicating with Modbus devices over + * USB/RS232/485 (via RTU protocol). + */ +class Modbus +{ +private: + Stream *port; //!< Pointer to Stream class object (Either HardwareSerial or SoftwareSerial) + uint8_t u8id; //!< 0=master, 1..247=slave number + uint8_t u8txenpin; //!< flow control pin: 0=USB or RS-232 mode, >1=RS-485 mode + uint8_t u8state; + uint8_t u8lastError; + uint8_t au8Buffer[MAX_BUFFER]; + uint8_t u8BufferSize; + uint8_t u8lastRec; + uint16_t *au16regs; + uint16_t u16InCnt, u16OutCnt, u16errCnt; + uint16_t u16timeOut; + uint32_t u32time, u32timeOut, u32overTime; + uint8_t u8regsize; + + void sendTxBuffer(); + int8_t getRxBuffer(); + uint16_t calcCRC(uint8_t u8length); + uint8_t validateAnswer(); + uint8_t validateRequest(); + void get_FC1(); + void get_FC3(); + int8_t process_FC1( uint16_t *regs, uint8_t u8size ); + int8_t process_FC3( uint16_t *regs, uint8_t u8size ); + int8_t process_FC5( uint16_t *regs, uint8_t u8size ); + int8_t process_FC6( uint16_t *regs, uint8_t u8size ); + int8_t process_FC15( uint16_t *regs, uint8_t u8size ); + int8_t process_FC16( uint16_t *regs, uint8_t u8size ); + void buildException( uint8_t u8exception ); // build exception message + +public: + Modbus(uint8_t u8id, Stream& port, uint8_t u8txenpin =0); + + void start(); + void setTimeOut( uint16_t u16timeOut); //! + void begin(T_Stream* port_, long u32speed_) __attribute__((deprecated)); + + // Deprecated: Use "start()" instead. + template + void begin(T_Stream* port_, long u32speed_, uint8_t u8txenpin_) __attribute__((deprecated)); + + // Deprecated: Use "start()" instead. + void begin(long u32speed = 19200) __attribute__((deprecated)); +}; + +#endif // MODBUS_RTU_H + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/README.md b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/README.md new file mode 100644 index 0000000..990819e --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/README.md @@ -0,0 +1,80 @@ +README.txt + +libmodbus is a library that provides a Serial Modbus implementation for Arduino. + +A primary goal was to enable industrial communication for the Arduino in order to link it to industrial devices such as HMIs, CNCs, PLCs, temperature regulators or speed drives. + +now you can use software serial with the update from Helium6072! + +LIBRARY CONTENTS +================================================================= +LICENSE.txt GNU Licence file +keywords.txt Arduino IDE colouring syntax + +/documentation +Library documentation generated with Doxygen. + +/examples +Sample sketches to implement miscellaneous settings: + +/examples/advanced_slave Modbus slave node, which links Arduino pins to the Modbus port. +/examples/RS485_slave Modbus slave adapted to the RS485 port +/examples/simple_master Modbus master node with a single query +/examples/simple_slave Modbus slave node with a link array +/examples/software_serial_simple_master Modbus master node that works via software serial + +INSTALLATION PROCEDURE +================================================================= +Refer to this documentation to Install this library: + +http://arduino.cc/en/Guide/Libraries + +Starting with version 1.0.5, you can install 3rd party libraries in the IDE. + +Do not unzip the downloaded library, leave it as is. + +In the Arduino IDE, navigate to Sketch > Import Library. At the top of the drop down list, select the option to "Add Library". + +You will be prompted to select this zipped library. + +Return to the Sketch > Import Library menu. You should now see the library at the bottom of the drop-down menu. It is ready to be used in your sketch. + +The zip file will have been expanded in the libraries folder in your Arduino sketches directory. + +NB : the library will be available to use in sketches, but examples for the library will not be exposed in the File > Examples until after the IDE has restarted. + + +KNOWN ISSUES +================================================================= +It is not compatible with ARDUINO LEONARDO and not tested under ARDUINO DUE and newer boards. + +TODO List +================================================================= +Common to Master and Slave: + +1) Implement other Serial settings: parity, stop bits, ... + +2) End frame delay, also known as T35 + +3) Test it with several Arduino boards: UNO, Mega, etc.. + +4) Extend it to Leonardo + +Master: + +1) Function code 1 and 2 still not implemented + +2) Function code 15 still not implement + +3) Other codes under development + +New features by Helium6072 29 July 2016 +================================================================= +1) "port->flush();" changed into "while(port->read() >= 0);" + +Since Serial.flush() (port->flush(); in ModbusRtu.h line 287, 337, & 827) no longer empties incoming buffer on 1.6 (Arduino.cc : flush() "Waits for the transmission of outgoing serial data to complete. Prior to Arduino 1.0, this instead removed any buffered incoming serial data.), use "while(port->read() >= 0);" instead. + +2) software serial compatible + +New constructor Modbus::Modbus(uint8_t u8id) and method void Modbus::begin(SoftwareSerial *sPort, long u32speed) that makes using software serial possible. +Check out sexample "software_serial_simple_master" and learn more! \ No newline at end of file diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/config b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/config new file mode 100644 index 0000000..dc27219 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/config @@ -0,0 +1,1890 @@ +# Doxyfile 1.8.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed +# in front of the TAG it is preceding . +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = "My Project" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, +# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, +# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields or simple typedef fields will be shown +# inline in the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO (the default), structs, classes, and unions are shown on a separate +# page (for HTML and Man pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can +# be an expensive process and often the same symbol appear multiple times in +# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too +# small doxygen will become slower. If the cache is too large, memory is wasted. +# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid +# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 +# symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if section-label ... \endif +# and \cond section-label ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. Do not use +# file names with spaces, bibtex cannot handle them. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be ignored. +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If left blank doxygen will +# generate a default style sheet. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is included after the standard +# style sheets created by doxygen. Using this option one can overrule +# certain style aspects. This is preferred over using HTML_STYLESHEET +# since it does not replace the standard style sheet and is therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely +# identify the documentation publisher. This should be a reverse domain-name +# style string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and +# SVG. The default value is HTML-CSS, which is slower, but has the best +# compatibility. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript +# pieces of code that will be used on startup of the MathJax code. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. +# There are two flavours of web server based search depending on the +# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +# searching and an index file used by the script. When EXTERNAL_SEARCH is +# enabled the indexing and searching needs to be provided by external tools. +# See the manual for details. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain +# the search results. Doxygen ships with an example indexer (doxyindexer) and +# search engine (doxysearch.cgi) which are based on the open source search +# engine library Xapian. See the manual for configuration details. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will returned the search results when EXTERNAL_SEARCH is enabled. +# Doxygen ships with an example search engine (doxysearch) which is based on +# the open source search engine library Xapian. See the manual for configuration +# details. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id +# of to a relative location where the documentation can be found. +# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4 will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images +# or other source files which should be copied to the LaTeX output directory. +# Note that the files will be copied as-is; there are no commands or markers +# available. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files +# that can be used to generate PDF. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. If left blank docbook will be used as the default path. + +DOCBOOK_OUTPUT = docbook + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed +# in the related pages index. If set to NO, only the current project's +# pages will be listed. + +EXTERNAL_PAGES = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# manageable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/_modbus_rtu_8h.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/_modbus_rtu_8h.html new file mode 100644 index 0000000..ff65d96 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/_modbus_rtu_8h.html @@ -0,0 +1,400 @@ + + + + + + +Modbus Master and Slave for Arduino: ModbusRtu.h File Reference + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + +
+
+ +
+
ModbusRtu.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + + + + +

+Classes

struct  modbus_t
 Master query structure: This includes all the necessary fields to make the Master generate a Modbus query. A Master may keep several of these structures and send them cyclically or use them according to program needs. More...
 
class  Modbus
 Arduino class library for communicating with Modbus devices over USB/RS232/485 (via RTU protocol). More...
 
+ + + + + + +

+Macros

#define T35   5
 
#define MAX_BUFFER   64
 maximum size for the communication buffer in bytes More...
 
+ + + + + + + + + + + + + + + +

+Enumerations

enum  { RESPONSE_SIZE = 6, +EXCEPTION_SIZE = 3, +CHECKSUM_SIZE = 2 + }
 
enum  MESSAGE {
+  ID = 0, +FUNC, +ADD_HI, +ADD_LO, +
+  NB_HI, +NB_LO, +BYTE_CNT +
+ }
 Indexes to telegram frame positions. More...
 
enum  MB_FC {
+  MB_FC_NONE = 0, +MB_FC_READ_COILS = 1, +MB_FC_READ_DISCRETE_INPUT = 2, +MB_FC_READ_REGISTERS = 3, +
+  MB_FC_READ_INPUT_REGISTER = 4, +MB_FC_WRITE_COIL = 5, +MB_FC_WRITE_REGISTER = 6, +MB_FC_WRITE_MULTIPLE_COILS = 15, +
+  MB_FC_WRITE_MULTIPLE_REGISTERS = 16 +
+ }
 Modbus function codes summary. These are the implement function codes either for Master or for Slave. More...
 
enum  COM_STATES { COM_IDLE = 0, +COM_WAITING = 1 + }
 
enum  ERR_LIST {
+  ERR_NOT_MASTER = -1, +ERR_POLLING = -2, +ERR_BUFF_OVERFLOW = -3, +ERR_BAD_CRC = -4, +
+  ERR_EXCEPTION = -5 +
+ }
 
enum  {
+  NO_REPLY = 255, +EXC_FUNC_CODE = 1, +EXC_ADDR_RANGE = 2, +EXC_REGS_QUANT = 3, +
+  EXC_EXECUTE = 4 +
+ }
 
+ + + +

+Variables

const unsigned char fctsupported []
 
+

Detailed Description

+
Version
1.2
+
Date
2014.09.09
+
Author
Samuel Marco i Armengol samma.nosp@m.rcoa.nosp@m.rmeng.nosp@m.ol@g.nosp@m.mail..nosp@m.com
+

Arduino library for communicating with Modbus devices over RS232/USB/485 via RTU protocol.

+

Further information: http://modbus.org/ http://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf

+

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; version 2.1 of the License.

+

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

+

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

+ +

Definition in file ModbusRtu.h.

+

Macro Definition Documentation

+ +
+
+ + + + +
#define MAX_BUFFER   64
+
+ +

maximum size for the communication buffer in bytes

+ +

Definition at line 133 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + +
#define T35   5
+
+ +

Definition at line 132 of file ModbusRtu.h.

+ +
+
+

Enumeration Type Documentation

+ +
+
+ + + + +
anonymous enum
+
+ + + + +
Enumerator
RESPONSE_SIZE  +
EXCEPTION_SIZE  +
CHECKSUM_SIZE  +
+ +

Definition at line 57 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + +
anonymous enum
+
+ + + + + + +
Enumerator
NO_REPLY  +
EXC_FUNC_CODE  +
EXC_ADDR_RANGE  +
EXC_REGS_QUANT  +
EXC_EXECUTE  +
+ +

Definition at line 113 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + +
enum COM_STATES
+
+ + + +
Enumerator
COM_IDLE  +
COM_WAITING  +
+ +

Definition at line 99 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + +
enum ERR_LIST
+
+ + + + + + +
Enumerator
ERR_NOT_MASTER  +
ERR_POLLING  +
ERR_BUFF_OVERFLOW  +
ERR_BAD_CRC  +
ERR_EXCEPTION  +
+ +

Definition at line 105 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + +
enum MB_FC
+
+ +

Modbus function codes summary. These are the implement function codes either for Master or for Slave.

+
See Also
also fctsupported
+
+also modbus_t
+ + + + + + + + + + +
Enumerator
MB_FC_NONE  +

null operator

+
MB_FC_READ_COILS  +

FCT=1 -> read coils or digital outputs

+
MB_FC_READ_DISCRETE_INPUT  +

FCT=2 -> read digital inputs

+
MB_FC_READ_REGISTERS  +

FCT=3 -> read registers or analog outputs

+
MB_FC_READ_INPUT_REGISTER  +

FCT=4 -> read analog inputs

+
MB_FC_WRITE_COIL  +

FCT=5 -> write single coil or output

+
MB_FC_WRITE_REGISTER  +

FCT=6 -> write single register

+
MB_FC_WRITE_MULTIPLE_COILS  +

FCT=15 -> write multiple coils or outputs

+
MB_FC_WRITE_MULTIPLE_REGISTERS  +

FCT=16 -> write multiple registers

+
+ +

Definition at line 87 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + +
enum MESSAGE
+
+ +

Indexes to telegram frame positions.

+ + + + + + + + +
Enumerator
ID  +

ID field.

+
FUNC  +

Function code position.

+
ADD_HI  +

Address high byte.

+
ADD_LO  +

Address low byte.

+
NB_HI  +

Number of coils or registers high byte.

+
NB_LO  +

Number of coils or registers low byte.

+
BYTE_CNT  +

byte counter

+
+ +

Definition at line 68 of file ModbusRtu.h.

+ +
+
+

Variable Documentation

+ +
+
+ + + + +
const unsigned char fctsupported[]
+
+
+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/_modbus_rtu_8h_source.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/_modbus_rtu_8h_source.html new file mode 100644 index 0000000..d83da36 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/_modbus_rtu_8h_source.html @@ -0,0 +1,917 @@ + + + + + + +Modbus Master and Slave for Arduino: ModbusRtu.h Source File + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + +
+
+
+
ModbusRtu.h
+
+
+Go to the documentation of this file.
1 
+
48 typedef struct {
+
49  uint8_t u8id;
+
50  uint8_t u8fct;
+
51  uint16_t u16RegAdd;
+
52  uint16_t u16CoilsNo;
+
53  uint16_t *au16reg;
+
54 }
+
55 modbus_t;
+
56 
+
57 enum {
+ + + +
61 };
+
62 
+
68 enum MESSAGE {
+
69  ID = 0,
+
70  FUNC,
+ + + + + +
76 };
+
77 
+
87 enum MB_FC {
+
88  MB_FC_NONE = 0,
+ + + + + + + + +
97 };
+
98 
+
99 enum COM_STATES {
+
100  COM_IDLE = 0,
+ +
102 
+
103 };
+
104 
+
105 enum ERR_LIST {
+ + + + + +
111 };
+
112 
+
113 enum {
+
114  NO_REPLY = 255,
+ + + + +
119 };
+
120 
+
121 const unsigned char fctsupported[] = {
+ + + + + + + + +
130 };
+
131 
+
132 #define T35 5
+
133 #define MAX_BUFFER 64
+
134 
+
135 
+
141 class Modbus {
+
142 private:
+
143  HardwareSerial *port;
+
144  uint8_t u8id;
+
145  uint8_t u8serno;
+
146  uint8_t u8txenpin;
+
147  uint8_t u8state;
+
148  uint8_t u8lastError;
+
149  uint8_t au8Buffer[MAX_BUFFER];
+
150  uint8_t u8BufferSize;
+
151  uint8_t u8lastRec;
+
152  uint16_t *au16regs;
+
153  uint16_t u16InCnt, u16OutCnt, u16errCnt;
+
154  uint16_t u16timeOut;
+
155  uint32_t u32time, u32timeOut;
+
156  uint8_t u8regsize;
+
157 
+
158  void init(uint8_t u8id, uint8_t u8serno, uint8_t u8txenpin);
+
159  void sendTxBuffer();
+
160  int8_t getRxBuffer();
+
161  uint16_t calcCRC(uint8_t u8length);
+
162  uint8_t validateAnswer();
+
163  uint8_t validateRequest();
+
164  void get_FC1();
+
165  void get_FC3();
+
166  int8_t process_FC1( uint16_t *regs, uint8_t u8size );
+
167  int8_t process_FC3( uint16_t *regs, uint8_t u8size );
+
168  int8_t process_FC5( uint16_t *regs, uint8_t u8size );
+
169  int8_t process_FC6( uint16_t *regs, uint8_t u8size );
+
170  int8_t process_FC15( uint16_t *regs, uint8_t u8size );
+
171  int8_t process_FC16( uint16_t *regs, uint8_t u8size );
+
172  void buildException( uint8_t u8exception ); // build exception message
+
173 
+
174 public:
+
175  Modbus();
+
176  Modbus(uint8_t u8id, uint8_t u8serno);
+
177  Modbus(uint8_t u8id, uint8_t u8serno, uint8_t u8txenpin);
+
178  void begin(long u32speed);
+
179  void begin();
+
180  void setTimeOut( uint16_t u16timeout);
+
181  uint16_t getTimeOut();
+
182  boolean getTimeOutState();
+
183  int8_t query( modbus_t telegram );
+
184  int8_t poll();
+
185  int8_t poll( uint16_t *regs, uint8_t u8size );
+
186  uint16_t getInCnt();
+
187  uint16_t getOutCnt();
+
188  uint16_t getErrCnt();
+
189  uint8_t getID();
+
190  uint8_t getState();
+
191  uint8_t getLastError();
+
192  void setID( uint8_t u8id );
+
193  void end();
+
194 };
+
195 
+
196 /* _____PUBLIC FUNCTIONS_____________________________________________________ */
+
197 
+ +
205  init(0, 0, 0);
+
206 }
+
207 
+
218 Modbus::Modbus(uint8_t u8id, uint8_t u8serno) {
+
219  init(u8id, u8serno, 0);
+
220 }
+
221 
+
234 Modbus::Modbus(uint8_t u8id, uint8_t u8serno, uint8_t u8txenpin) {
+
235  init(u8id, u8serno, u8txenpin);
+
236 }
+
237 
+
250 void Modbus::begin(long u32speed) {
+
251 
+
252  switch( u8serno ) {
+
253 #if defined(UBRR1H)
+
254  case 1:
+
255  port = &Serial1;
+
256  break;
+
257 #endif
+
258 
+
259 #if defined(UBRR2H)
+
260  case 2:
+
261  port = &Serial2;
+
262  break;
+
263 #endif
+
264 
+
265 #if defined(UBRR3H)
+
266  case 3:
+
267  port = &Serial3;
+
268  break;
+
269 #endif
+
270  case 0:
+
271  default:
+
272  port = &Serial;
+
273  break;
+
274  }
+
275 
+
276  // port->begin(u32speed, u8config);
+
277  port->begin(u32speed);
+
278  if (u8txenpin > 1) { // pin 0 & pin 1 are reserved for RX/TX
+
279  // return RS485 transceiver to transmit mode
+
280  pinMode(u8txenpin, OUTPUT);
+
281  digitalWrite(u8txenpin, LOW);
+
282  }
+
283 
+
284  port->flush();
+
285  u8lastRec = u8BufferSize = 0;
+
286  u16InCnt = u16OutCnt = u16errCnt = 0;
+
287 }
+
288 
+ +
300  begin(19200);
+
301 }
+
302 
+
310 void Modbus::setID( uint8_t u8id) {
+
311  if (( u8id != 0) && (u8id <= 247)) {
+
312  this->u8id = u8id;
+
313  }
+
314 }
+
315 
+
323 uint8_t Modbus::getID() {
+
324  return this->u8id;
+
325 }
+
326 
+
338 void Modbus::setTimeOut( uint16_t u16timeOut) {
+
339  this->u16timeOut = u16timeOut;
+
340 }
+
341 
+ +
351  return (millis() > u32timeOut);
+
352 }
+
353 
+
362 uint16_t Modbus::getInCnt() {
+
363  return u16InCnt;
+
364 }
+
365 
+
374 uint16_t Modbus::getOutCnt() {
+
375  return u16OutCnt;
+
376 }
+
377 
+
386 uint16_t Modbus::getErrCnt() {
+
387  return u16errCnt;
+
388 }
+
389 
+
396 uint8_t Modbus::getState() {
+
397  return u8state;
+
398 }
+
399 
+ +
410  return u8lastError;
+
411 }
+
412 
+
425 int8_t Modbus::query( modbus_t telegram ) {
+
426  uint8_t u8regsno, u8bytesno;
+
427  if (u8id!=0) return -2;
+
428  if (u8state != COM_IDLE) return -1;
+
429 
+
430  if ((telegram.u8id==0) || (telegram.u8id>247)) return -3;
+
431 
+
432  au16regs = telegram.au16reg;
+
433 
+
434  // telegram header
+
435  au8Buffer[ ID ] = telegram.u8id;
+
436  au8Buffer[ FUNC ] = telegram.u8fct;
+
437  au8Buffer[ ADD_HI ] = highByte(telegram.u16RegAdd );
+
438  au8Buffer[ ADD_LO ] = lowByte( telegram.u16RegAdd );
+
439 
+
440  switch( telegram.u8fct ) {
+
441  case MB_FC_READ_COILS:
+ + + +
445  au8Buffer[ NB_HI ] = highByte(telegram.u16CoilsNo );
+
446  au8Buffer[ NB_LO ] = lowByte( telegram.u16CoilsNo );
+
447  u8BufferSize = 6;
+
448  break;
+
449  case MB_FC_WRITE_COIL:
+
450  au8Buffer[ NB_HI ] = ((au16regs[0] > 0) ? 0xff : 0);
+
451  au8Buffer[ NB_LO ] = 0;
+
452  u8BufferSize = 6;
+
453  break;
+ +
455  au8Buffer[ NB_HI ] = highByte(au16regs[0]);
+
456  au8Buffer[ NB_LO ] = lowByte(au16regs[0]);
+
457  u8BufferSize = 6;
+
458  break;
+
459  case MB_FC_WRITE_MULTIPLE_COILS: // TODO: implement "sending coils"
+
460  u8regsno = telegram.u16CoilsNo / 16;
+
461  u8bytesno = u8regsno * 2;
+
462  if ((telegram.u16CoilsNo % 16) != 0) {
+
463  u8bytesno++;
+
464  u8regsno++;
+
465  }
+
466 
+
467  au8Buffer[ NB_HI ] = highByte(telegram.u16CoilsNo );
+
468  au8Buffer[ NB_LO ] = lowByte( telegram.u16CoilsNo );
+
469  au8Buffer[ NB_LO+1 ] = u8bytesno;
+
470  u8BufferSize = 7;
+
471 
+
472  u8regsno = u8bytesno = 0; // now auxiliary registers
+
473  for (uint16_t i = 0; i < telegram.u16CoilsNo; i++) {
+
474 
+
475 
+
476  }
+
477  break;
+
478 
+ +
480  au8Buffer[ NB_HI ] = highByte(telegram.u16CoilsNo );
+
481  au8Buffer[ NB_LO ] = lowByte( telegram.u16CoilsNo );
+
482  au8Buffer[ NB_LO+1 ] = (uint8_t) ( telegram.u16CoilsNo * 2 );
+
483  u8BufferSize = 7;
+
484 
+
485  for (uint16_t i=0; i< telegram.u16CoilsNo; i++) {
+
486  au8Buffer[ u8BufferSize ] = highByte( au16regs[ i ] );
+
487  u8BufferSize++;
+
488  au8Buffer[ u8BufferSize ] = lowByte( au16regs[ i ] );
+
489  u8BufferSize++;
+
490  }
+
491  break;
+
492  }
+
493 
+
494  sendTxBuffer();
+
495  u8state = COM_WAITING;
+
496  return 0;
+
497 }
+
498 
+
513 int8_t Modbus::poll() {
+
514  // check if there is any incoming frame
+
515  uint8_t u8current = port->available();
+
516 
+
517  if (millis() > u32timeOut) {
+
518  u8state = COM_IDLE;
+
519  u8lastError = NO_REPLY;
+
520  u16errCnt++;
+
521  return 0;
+
522  }
+
523 
+
524  if (u8current == 0) return 0;
+
525 
+
526  // check T35 after frame end or still no frame end
+
527  if (u8current != u8lastRec) {
+
528  u8lastRec = u8current;
+
529  u32time = millis() + T35;
+
530  return 0;
+
531  }
+
532  if (millis() < u32time) return 0;
+
533 
+
534  // transfer Serial buffer frame to auBuffer
+
535  u8lastRec = 0;
+
536  int8_t i8state = getRxBuffer();
+
537  if (i8state < 7) {
+
538  u8state = COM_IDLE;
+
539  u16errCnt++;
+
540  return i8state;
+
541  }
+
542 
+
543  // validate message: id, CRC, FCT, exception
+
544  uint8_t u8exception = validateAnswer();
+
545  if (u8exception != 0) {
+
546  u8state = COM_IDLE;
+
547  return u8exception;
+
548  }
+
549 
+
550  // process answer
+
551  switch( au8Buffer[ FUNC ] ) {
+
552  case MB_FC_READ_COILS:
+ +
554  // call get_FC1 to transfer the incoming message to au16regs buffer
+
555  get_FC1( );
+
556  break;
+ +
558  case MB_FC_READ_REGISTERS :
+
559  // call get_FC3 to transfer the incoming message to au16regs buffer
+
560  get_FC3( );
+
561  break;
+
562  case MB_FC_WRITE_COIL:
+
563  case MB_FC_WRITE_REGISTER :
+ + +
566  // nothing to do
+
567  break;
+
568  default:
+
569  break;
+
570  }
+
571  u8state = COM_IDLE;
+
572  return u8BufferSize;
+
573 }
+
574 
+
588 int8_t Modbus::poll( uint16_t *regs, uint8_t u8size ) {
+
589 
+
590  au16regs = regs;
+
591  u8regsize = u8size;
+
592 
+
593  // check if there is any incoming frame
+
594  uint8_t u8current = port->available();
+
595  if (u8current == 0) return 0;
+
596 
+
597  // check T35 after frame end or still no frame end
+
598  if (u8current != u8lastRec) {
+
599  u8lastRec = u8current;
+
600  u32time = millis() + T35;
+
601  return 0;
+
602  }
+
603  if (millis() < u32time) return 0;
+
604 
+
605  u8lastRec = 0;
+
606  int8_t i8state = getRxBuffer();
+
607  u8lastError = i8state;
+
608  if (i8state < 7) return i8state;
+
609 
+
610  // check slave id
+
611  if (au8Buffer[ ID ] != u8id) return 0;
+
612 
+
613  // validate message: CRC, FCT, address and size
+
614  uint8_t u8exception = validateRequest();
+
615  if (u8exception > 0) {
+
616  if (u8exception != NO_REPLY) {
+
617  buildException( u8exception );
+
618  sendTxBuffer();
+
619  }
+
620  u8lastError = u8exception;
+
621  return u8exception;
+
622  }
+
623 
+
624  u32timeOut = millis() + long(u16timeOut);
+
625  u8lastError = 0;
+
626 
+
627  // process message
+
628  switch( au8Buffer[ FUNC ] ) {
+
629  case MB_FC_READ_COILS:
+ +
631  return process_FC1( regs, u8size );
+
632  break;
+ +
634  case MB_FC_READ_REGISTERS :
+
635  return process_FC3( regs, u8size );
+
636  break;
+
637  case MB_FC_WRITE_COIL:
+
638  return process_FC5( regs, u8size );
+
639  break;
+
640  case MB_FC_WRITE_REGISTER :
+
641  return process_FC6( regs, u8size );
+
642  break;
+ +
644  return process_FC15( regs, u8size );
+
645  break;
+ +
647  return process_FC16( regs, u8size );
+
648  break;
+
649  default:
+
650  break;
+
651  }
+
652  return i8state;
+
653 }
+
654 
+
655 /* _____PRIVATE FUNCTIONS_____________________________________________________ */
+
656 
+
657 void Modbus::init(uint8_t u8id, uint8_t u8serno, uint8_t u8txenpin) {
+
658  this->u8id = u8id;
+
659  this->u8serno = (u8serno > 3) ? 0 : u8serno;
+
660  this->u8txenpin = u8txenpin;
+
661  this->u16timeOut = 1000;
+
662 }
+
663 
+
671 int8_t Modbus::getRxBuffer() {
+
672  boolean bBuffOverflow = false;
+
673 
+
674  if (u8txenpin > 1) digitalWrite( u8txenpin, LOW );
+
675 
+
676  u8BufferSize = 0;
+
677  while ( port->available() ) {
+
678  au8Buffer[ u8BufferSize ] = port->read();
+
679  u8BufferSize ++;
+
680 
+
681  if (u8BufferSize >= MAX_BUFFER) bBuffOverflow = true;
+
682  }
+
683  u16InCnt++;
+
684 
+
685  if (bBuffOverflow) {
+
686  u16errCnt++;
+
687  return ERR_BUFF_OVERFLOW;
+
688  }
+
689  return u8BufferSize;
+
690 }
+
691 
+
704 void Modbus::sendTxBuffer() {
+
705  uint8_t i = 0;
+
706 
+
707  // append CRC to message
+
708  uint16_t u16crc = calcCRC( u8BufferSize );
+
709  au8Buffer[ u8BufferSize ] = u16crc >> 8;
+
710  u8BufferSize++;
+
711  au8Buffer[ u8BufferSize ] = u16crc & 0x00ff;
+
712  u8BufferSize++;
+
713 
+
714  // set RS485 transceiver to transmit mode
+
715  if (u8txenpin > 1) {
+
716  switch( u8serno ) {
+
717 #if defined(UBRR1H)
+
718  case 1:
+
719  UCSR1A=UCSR1A |(1 << TXC1);
+
720  break;
+
721 #endif
+
722 
+
723 #if defined(UBRR2H)
+
724  case 2:
+
725  UCSR2A=UCSR2A |(1 << TXC2);
+
726  break;
+
727 #endif
+
728 
+
729 #if defined(UBRR3H)
+
730  case 3:
+
731  UCSR3A=UCSR3A |(1 << TXC3);
+
732  break;
+
733 #endif
+
734  case 0:
+
735  default:
+
736  UCSR0A=UCSR0A |(1 << TXC0);
+
737  break;
+
738  }
+
739  digitalWrite( u8txenpin, HIGH );
+
740  }
+
741 
+
742  // transfer buffer to serial line
+
743  port->write( au8Buffer, u8BufferSize );
+
744 
+
745  // keep RS485 transceiver in transmit mode as long as sending
+
746  if (u8txenpin > 1) {
+
747  switch( u8serno ) {
+
748 #if defined(UBRR1H)
+
749  case 1:
+
750  while (!(UCSR1A & (1 << TXC1)));
+
751  break;
+
752 #endif
+
753 
+
754 #if defined(UBRR2H)
+
755  case 2:
+
756  while (!(UCSR2A & (1 << TXC2)));
+
757  break;
+
758 #endif
+
759 
+
760 #if defined(UBRR3H)
+
761  case 3:
+
762  while (!(UCSR3A & (1 << TXC3)));
+
763  break;
+
764 #endif
+
765  case 0:
+
766  default:
+
767  while (!(UCSR0A & (1 << TXC0)));
+
768  break;
+
769  }
+
770 
+
771  // return RS485 transceiver to receive mode
+
772  digitalWrite( u8txenpin, LOW );
+
773  }
+
774  port->flush();
+
775  u8BufferSize = 0;
+
776 
+
777  // set time-out for master
+
778  u32timeOut = millis() + (unsigned long) u16timeOut;
+
779 
+
780  // increase message counter
+
781  u16OutCnt++;
+
782 }
+
783 
+
791 uint16_t Modbus::calcCRC(uint8_t u8length) {
+
792  unsigned int temp, temp2, flag;
+
793  temp = 0xFFFF;
+
794  for (unsigned char i = 0; i < u8length; i++) {
+
795  temp = temp ^ au8Buffer[i];
+
796  for (unsigned char j = 1; j <= 8; j++) {
+
797  flag = temp & 0x0001;
+
798  temp >>=1;
+
799  if (flag)
+
800  temp ^= 0xA001;
+
801  }
+
802  }
+
803  // Reverse byte order.
+
804  temp2 = temp >> 8;
+
805  temp = (temp << 8) | temp2;
+
806  temp &= 0xFFFF;
+
807  // the returned value is already swapped
+
808  // crcLo byte is first & crcHi byte is last
+
809  return temp;
+
810 }
+
811 
+
819 uint8_t Modbus::validateRequest() {
+
820  // check message crc vs calculated crc
+
821  uint16_t u16MsgCRC =
+
822  ((au8Buffer[u8BufferSize - 2] << 8)
+
823  | au8Buffer[u8BufferSize - 1]); // combine the crc Low & High bytes
+
824  if ( calcCRC( u8BufferSize-2 ) != u16MsgCRC ) {
+
825  u16errCnt ++;
+
826  return NO_REPLY;
+
827  }
+
828 
+
829  // check fct code
+
830  boolean isSupported = false;
+
831  for (uint8_t i = 0; i< sizeof( fctsupported ); i++) {
+
832  if (fctsupported[i] == au8Buffer[FUNC]) {
+
833  isSupported = 1;
+
834  break;
+
835  }
+
836  }
+
837  if (!isSupported) {
+
838  u16errCnt ++;
+
839  return EXC_FUNC_CODE;
+
840  }
+
841 
+
842  // check start address & nb range
+
843  uint16_t u16regs = 0;
+
844  uint8_t u8regs;
+
845  switch ( au8Buffer[ FUNC ] ) {
+
846  case MB_FC_READ_COILS:
+ + +
849  u16regs = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ]) / 16;
+
850  u16regs += word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ]) /16;
+
851  u8regs = (uint8_t) u16regs;
+
852  if (u8regs > u8regsize) return EXC_ADDR_RANGE;
+
853  break;
+
854  case MB_FC_WRITE_COIL:
+
855  u16regs = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ]) / 16;
+
856  u8regs = (uint8_t) u16regs;
+
857  if (u8regs > u8regsize) return EXC_ADDR_RANGE;
+
858  break;
+
859  case MB_FC_WRITE_REGISTER :
+
860  u16regs = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ]);
+
861  u8regs = (uint8_t) u16regs;
+
862  if (u8regs > u8regsize) return EXC_ADDR_RANGE;
+
863  break;
+
864  case MB_FC_READ_REGISTERS :
+ + +
867  u16regs = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ]);
+
868  u16regs += word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ]);
+
869  u8regs = (uint8_t) u16regs;
+
870  if (u8regs > u8regsize) return EXC_ADDR_RANGE;
+
871  break;
+
872  }
+
873  return 0; // OK, no exception code thrown
+
874 }
+
875 
+
883 uint8_t Modbus::validateAnswer() {
+
884  // check message crc vs calculated crc
+
885  uint16_t u16MsgCRC =
+
886  ((au8Buffer[u8BufferSize - 2] << 8)
+
887  | au8Buffer[u8BufferSize - 1]); // combine the crc Low & High bytes
+
888  if ( calcCRC( u8BufferSize-2 ) != u16MsgCRC ) {
+
889  u16errCnt ++;
+
890  return NO_REPLY;
+
891  }
+
892 
+
893  // check exception
+
894  if ((au8Buffer[ FUNC ] & 0x80) != 0) {
+
895  u16errCnt ++;
+
896  return ERR_EXCEPTION;
+
897  }
+
898 
+
899  // check fct code
+
900  boolean isSupported = false;
+
901  for (uint8_t i = 0; i< sizeof( fctsupported ); i++) {
+
902  if (fctsupported[i] == au8Buffer[FUNC]) {
+
903  isSupported = 1;
+
904  break;
+
905  }
+
906  }
+
907  if (!isSupported) {
+
908  u16errCnt ++;
+
909  return EXC_FUNC_CODE;
+
910  }
+
911 
+
912  return 0; // OK, no exception code thrown
+
913 }
+
914 
+
921 void Modbus::buildException( uint8_t u8exception ) {
+
922  uint8_t u8func = au8Buffer[ FUNC ]; // get the original FUNC code
+
923 
+
924  au8Buffer[ ID ] = u8id;
+
925  au8Buffer[ FUNC ] = u8func + 0x80;
+
926  au8Buffer[ 2 ] = u8exception;
+
927  u8BufferSize = EXCEPTION_SIZE;
+
928 }
+
929 
+
936 void Modbus::get_FC1() {
+
937  uint8_t u8byte, i;
+
938  u8byte = 0;
+
939 
+
940  // for (i=0; i< au8Buffer[ 2 ] /2; i++) {
+
941  // au16regs[ i ] = word(
+
942  // au8Buffer[ u8byte ],
+
943  // au8Buffer[ u8byte +1 ]);
+
944  // u8byte += 2;
+
945  // }
+
946 }
+
947 
+
954 void Modbus::get_FC3() {
+
955  uint8_t u8byte, i;
+
956  u8byte = 3;
+
957 
+
958  for (i=0; i< au8Buffer[ 2 ] /2; i++) {
+
959  au16regs[ i ] = word(
+
960  au8Buffer[ u8byte ],
+
961  au8Buffer[ u8byte +1 ]);
+
962  u8byte += 2;
+
963  }
+
964 }
+
965 
+
974 int8_t Modbus::process_FC1( uint16_t *regs, uint8_t u8size ) {
+
975  uint8_t u8currentRegister, u8currentBit, u8bytesno, u8bitsno;
+
976  uint8_t u8CopyBufferSize;
+
977  uint16_t u16currentCoil, u16coil;
+
978 
+
979  // get the first and last coil from the message
+
980  uint16_t u16StartCoil = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ] );
+
981  uint16_t u16Coilno = word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ] );
+
982 
+
983  // put the number of bytes in the outcoming message
+
984  u8bytesno = (uint8_t) (u16Coilno / 8);
+
985  if (u16Coilno % 8 != 0) u8bytesno ++;
+
986  au8Buffer[ ADD_HI ] = u8bytesno;
+
987  u8BufferSize = ADD_LO;
+
988 
+
989  // read each coil from the register map and put its value inside the outcoming message
+
990  u8bitsno = 0;
+
991 
+
992  for (u16currentCoil = 0; u16currentCoil < u16Coilno; u16currentCoil++) {
+
993  u16coil = u16StartCoil + u16currentCoil;
+
994  u8currentRegister = (uint8_t) (u16coil / 16);
+
995  u8currentBit = (uint8_t) (u16coil % 16);
+
996 
+
997  bitWrite(
+
998  au8Buffer[ u8BufferSize ],
+
999  u8bitsno,
+
1000  bitRead( regs[ u8currentRegister ], u8currentBit ) );
+
1001  u8bitsno ++;
+
1002 
+
1003  if (u8bitsno > 7) {
+
1004  u8bitsno = 0;
+
1005  u8BufferSize++;
+
1006  }
+
1007  }
+
1008 
+
1009  // send outcoming message
+
1010  if (u16Coilno % 8 != 0) u8BufferSize ++;
+
1011  u8CopyBufferSize = u8BufferSize +2;
+
1012  sendTxBuffer();
+
1013  return u8CopyBufferSize;
+
1014 }
+
1015 
+
1024 int8_t Modbus::process_FC3( uint16_t *regs, uint8_t u8size ) {
+
1025 
+
1026  uint8_t u8StartAdd = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ] );
+
1027  uint8_t u8regsno = word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ] );
+
1028  uint8_t u8CopyBufferSize;
+
1029  uint8_t i;
+
1030 
+
1031  au8Buffer[ 2 ] = u8regsno * 2;
+
1032  u8BufferSize = 3;
+
1033 
+
1034  for (i = u8StartAdd; i < u8StartAdd + u8regsno; i++) {
+
1035  au8Buffer[ u8BufferSize ] = highByte(regs[i]);
+
1036  u8BufferSize++;
+
1037  au8Buffer[ u8BufferSize ] = lowByte(regs[i]);
+
1038  u8BufferSize++;
+
1039  }
+
1040  u8CopyBufferSize = u8BufferSize +2;
+
1041  sendTxBuffer();
+
1042 
+
1043  return u8CopyBufferSize;
+
1044 }
+
1045 
+
1054 int8_t Modbus::process_FC5( uint16_t *regs, uint8_t u8size ) {
+
1055  uint8_t u8currentRegister, u8currentBit;
+
1056  uint8_t u8CopyBufferSize;
+
1057  uint16_t u16coil = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ] );
+
1058 
+
1059  // point to the register and its bit
+
1060  u8currentRegister = (uint8_t) (u16coil / 16);
+
1061  u8currentBit = (uint8_t) (u16coil % 16);
+
1062 
+
1063  // write to coil
+
1064  bitWrite(
+
1065  regs[ u8currentRegister ],
+
1066  u8currentBit,
+
1067  au8Buffer[ NB_HI ] == 0xff );
+
1068 
+
1069 
+
1070  // send answer to master
+
1071  u8BufferSize = 6;
+
1072  u8CopyBufferSize = u8BufferSize +2;
+
1073  sendTxBuffer();
+
1074 
+
1075  return u8CopyBufferSize;
+
1076 }
+
1077 
+
1086 int8_t Modbus::process_FC6( uint16_t *regs, uint8_t u8size ) {
+
1087 
+
1088  uint8_t u8add = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ] );
+
1089  uint8_t u8CopyBufferSize;
+
1090  uint16_t u16val = word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ] );
+
1091 
+
1092  regs[ u8add ] = u16val;
+
1093 
+
1094  // keep the same header
+
1095  u8BufferSize = RESPONSE_SIZE;
+
1096 
+
1097  u8CopyBufferSize = u8BufferSize +2;
+
1098  sendTxBuffer();
+
1099 
+
1100  return u8CopyBufferSize;
+
1101 }
+
1102 
+
1111 int8_t Modbus::process_FC15( uint16_t *regs, uint8_t u8size ) {
+
1112  uint8_t u8currentRegister, u8currentBit, u8frameByte, u8bitsno;
+
1113  uint8_t u8CopyBufferSize;
+
1114  uint16_t u16currentCoil, u16coil;
+
1115  boolean bTemp;
+
1116 
+
1117  // get the first and last coil from the message
+
1118  uint16_t u16StartCoil = word( au8Buffer[ ADD_HI ], au8Buffer[ ADD_LO ] );
+
1119  uint16_t u16Coilno = word( au8Buffer[ NB_HI ], au8Buffer[ NB_LO ] );
+
1120 
+
1121 
+
1122  // read each coil from the register map and put its value inside the outcoming message
+
1123  u8bitsno = 0;
+
1124  u8frameByte = 7;
+
1125  for (u16currentCoil = 0; u16currentCoil < u16Coilno; u16currentCoil++) {
+
1126 
+
1127  u16coil = u16StartCoil + u16currentCoil;
+
1128  u8currentRegister = (uint8_t) (u16coil / 16);
+
1129  u8currentBit = (uint8_t) (u16coil % 16);
+
1130 
+
1131  bTemp = bitRead(
+
1132  au8Buffer[ u8frameByte ],
+
1133  u8bitsno );
+
1134 
+
1135  bitWrite(
+
1136  regs[ u8currentRegister ],
+
1137  u8currentBit,
+
1138  bTemp );
+
1139 
+
1140  u8bitsno ++;
+
1141 
+
1142  if (u8bitsno > 7) {
+
1143  u8bitsno = 0;
+
1144  u8frameByte++;
+
1145  }
+
1146  }
+
1147 
+
1148  // send outcoming message
+
1149  // it's just a copy of the incomping frame until 6th byte
+
1150  u8BufferSize = 6;
+
1151  u8CopyBufferSize = u8BufferSize +2;
+
1152  sendTxBuffer();
+
1153  return u8CopyBufferSize;
+
1154 }
+
1155 
+
1164 int8_t Modbus::process_FC16( uint16_t *regs, uint8_t u8size ) {
+
1165  uint8_t u8func = au8Buffer[ FUNC ]; // get the original FUNC code
+
1166  uint8_t u8StartAdd = au8Buffer[ ADD_HI ] << 8 | au8Buffer[ ADD_LO ];
+
1167  uint8_t u8regsno = au8Buffer[ NB_HI ] << 8 | au8Buffer[ NB_LO ];
+
1168  uint8_t u8CopyBufferSize;
+
1169  uint8_t i;
+
1170  uint16_t temp;
+
1171 
+
1172  // build header
+
1173  au8Buffer[ NB_HI ] = 0;
+
1174  au8Buffer[ NB_LO ] = u8regsno;
+
1175  u8BufferSize = RESPONSE_SIZE;
+
1176 
+
1177  // write registers
+
1178  for (i = 0; i < u8regsno; i++) {
+
1179  temp = word(
+
1180  au8Buffer[ (BYTE_CNT + 1) + i * 2 ],
+
1181  au8Buffer[ (BYTE_CNT + 2) + i * 2 ]);
+
1182 
+
1183  regs[ u8StartAdd + i ] = temp;
+
1184  }
+
1185  u8CopyBufferSize = u8BufferSize +2;
+
1186  sendTxBuffer();
+
1187 
+
1188  return u8CopyBufferSize;
+
1189 }
+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/annotated.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/annotated.html new file mode 100644 index 0000000..c3eefd7 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/annotated.html @@ -0,0 +1,67 @@ + + + + + + +Modbus Master and Slave for Arduino: Class List + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + +
+
+
+
Class List
+
+
+
Here are the classes, structs, unions and interfaces with brief descriptions:
+ + + +
oCModbusArduino class library for communicating with Modbus devices over USB/RS232/485 (via RTU protocol)
\Cmodbus_tMaster query structure: This includes all the necessary fields to make the Master generate a Modbus query. A Master may keep several of these structures and send them cyclically or use them according to program needs
+
+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/bc_s.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/bc_s.png new file mode 100644 index 0000000..224b29a Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/bc_s.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/bdwn.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/bdwn.png new file mode 100644 index 0000000..940a0b9 Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/bdwn.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/class_modbus-members.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/class_modbus-members.html new file mode 100644 index 0000000..9a8519b --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/class_modbus-members.html @@ -0,0 +1,83 @@ + + + + + + +Modbus Master and Slave for Arduino: Member List + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + +
+
+
+
Modbus Member List
+
+
+ +

This is the complete list of members for Modbus, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + +
begin(long u32speed)Modbus
begin()Modbus
end()Modbus
getErrCnt()Modbus
getID()Modbus
getInCnt()Modbus
getLastError()Modbus
getOutCnt()Modbus
getState()Modbus
getTimeOut()Modbus
getTimeOutState()Modbus
Modbus()Modbus
Modbus(uint8_t u8id, uint8_t u8serno)Modbus
Modbus(uint8_t u8id, uint8_t u8serno, uint8_t u8txenpin)Modbus
poll()Modbus
poll(uint16_t *regs, uint8_t u8size)Modbus
query(modbus_t telegram)Modbus
setID(uint8_t u8id)Modbus
setTimeOut(uint16_t u16timeout)Modbus
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/class_modbus.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/class_modbus.html new file mode 100644 index 0000000..3ec771f --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/class_modbus.html @@ -0,0 +1,248 @@ + + + + + + +Modbus Master and Slave for Arduino: Modbus Class Reference + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + +
+
+ +
+
Modbus Class Reference
+
+
+ +

Arduino class library for communicating with Modbus devices over USB/RS232/485 (via RTU protocol). + More...

+ +

#include <ModbusRtu.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 Modbus ()
 Default Constructor for Master through Serial. More...
 
 Modbus (uint8_t u8id, uint8_t u8serno)
 
 Modbus (uint8_t u8id, uint8_t u8serno, uint8_t u8txenpin)
 
void begin (long u32speed)
 Initialize class object. More...
 
void begin ()
 
void setTimeOut (uint16_t u16timeout)
 write communication watch-dog timer More...
 
uint16_t getTimeOut ()
 get communication watch-dog timer value More...
 
boolean getTimeOutState ()
 get communication watch-dog timer state More...
 
int8_t query (modbus_t telegram)
 only for master More...
 
int8_t poll ()
 cyclic poll for master More...
 
int8_t poll (uint16_t *regs, uint8_t u8size)
 cyclic poll for slave More...
 
uint16_t getInCnt ()
 number of incoming messages More...
 
uint16_t getOutCnt ()
 number of outcoming messages More...
 
uint16_t getErrCnt ()
 error counter More...
 
uint8_t getID ()
 get slave ID between 1 and 247 More...
 
uint8_t getState ()
 
uint8_t getLastError ()
 get last error message More...
 
void setID (uint8_t u8id)
 write new ID for the slave More...
 
void end ()
 finish any communication and release serial communication port More...
 
+

Detailed Description

+

Arduino class library for communicating with Modbus devices over USB/RS232/485 (via RTU protocol).

+ +

Definition at line 141 of file ModbusRtu.h.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + +
Modbus::Modbus (uint8_t u8id,
uint8_t u8serno 
)
+
+ +

Definition at line 218 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
Modbus::Modbus (uint8_t u8id,
uint8_t u8serno,
uint8_t u8txenpin 
)
+
+ +

Definition at line 234 of file ModbusRtu.h.

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
void Modbus::begin ()
+
+ +

Definition at line 299 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + + + + +
void Modbus::end ()
+
+ +

finish any communication and release serial communication port

+ +
+
+ +
+
+ + + + + + + +
uint16_t Modbus::getTimeOut ()
+
+ +

get communication watch-dog timer value

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/classes.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/classes.html new file mode 100644 index 0000000..65da245 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/classes.html @@ -0,0 +1,70 @@ + + + + + + +Modbus Master and Slave for Arduino: Class Index + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + +
+
+
+
Class Index
+
+
+ + + + + + +
  M  
+
modbus_t   
Modbus   
+ +
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/closed.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/closed.png new file mode 100644 index 0000000..98cc2c9 Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/closed.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/doxygen.css b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/doxygen.css new file mode 100644 index 0000000..3ac2851 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/doxygen.css @@ -0,0 +1,1186 @@ +/* The standard CSS for doxygen 1.8.4 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd, p.starttd { + margin-top: 2px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 0px; + margin: 0px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +div.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: bold; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + border-top-left-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view when not used as main index */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +dl +{ + padding: 0 0 0 10px; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ +dl.section +{ + margin-left: 0px; + padding-left: 0px; +} + +dl.note +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00D000; +} + +dl.deprecated +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #505050; +} + +dl.todo +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00C0E0; +} + +dl.test +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #3030E0; +} + +dl.bug +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 20px 10px 10px; + width: 200px; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/doxygen.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/doxygen.png new file mode 100644 index 0000000..3ff17d8 Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/doxygen.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/dynsections.js b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/dynsections.js new file mode 100644 index 0000000..ed092c7 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/dynsections.js @@ -0,0 +1,97 @@ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); +} +function toggleLevel(level) +{ + $('table.directory tr').each(function(){ + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + +Modbus Master and Slave for Arduino: File List + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + +
+
+
+
File List
+
+
+
Here is a list of all files with brief descriptions:
+ + +
\*ModbusRtu.h
+
+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2blank.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2blank.png new file mode 100644 index 0000000..63c605b Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2blank.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2cl.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2cl.png new file mode 100644 index 0000000..132f657 Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2cl.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2doc.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2doc.png new file mode 100644 index 0000000..17edabf Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2doc.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2folderclosed.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2folderclosed.png new file mode 100644 index 0000000..bb8ab35 Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2folderclosed.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2folderopen.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2folderopen.png new file mode 100644 index 0000000..d6c7f67 Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2folderopen.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2lastnode.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2lastnode.png new file mode 100644 index 0000000..63c605b Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2lastnode.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2link.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2link.png new file mode 100644 index 0000000..17edabf Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2link.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2mlastnode.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2mlastnode.png new file mode 100644 index 0000000..0b63f6d Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2mlastnode.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2mnode.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2mnode.png new file mode 100644 index 0000000..0b63f6d Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2mnode.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2mo.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2mo.png new file mode 100644 index 0000000..4bfb80f Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2mo.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2node.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2node.png new file mode 100644 index 0000000..63c605b Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2node.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2ns.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2ns.png new file mode 100644 index 0000000..72e3d71 Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2ns.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2plastnode.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2plastnode.png new file mode 100644 index 0000000..c6ee22f Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2plastnode.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2pnode.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2pnode.png new file mode 100644 index 0000000..c6ee22f Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2pnode.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2splitbar.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2splitbar.png new file mode 100644 index 0000000..fe895f2 Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2splitbar.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2vertline.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2vertline.png new file mode 100644 index 0000000..63c605b Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/ftv2vertline.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/functions.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/functions.html new file mode 100644 index 0000000..50151b1 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/functions.html @@ -0,0 +1,126 @@ + + + + + + +Modbus Master and Slave for Arduino: Class Members + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + + +
+
+
Here is a list of all class members with links to the classes they belong to:
+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/functions_func.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/functions_func.html new file mode 100644 index 0000000..2d18bd7 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/functions_func.html @@ -0,0 +1,111 @@ + + + + + + +Modbus Master and Slave for Arduino: Class Members - Functions + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + + +
+
+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/functions_vars.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/functions_vars.html new file mode 100644 index 0000000..dcecec1 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/functions_vars.html @@ -0,0 +1,81 @@ + + + + + + +Modbus Master and Slave for Arduino: Class Members - Variables + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + + +
+
+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/globals.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/globals.html new file mode 100644 index 0000000..da39994 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/globals.html @@ -0,0 +1,233 @@ + + + + + + +Modbus Master and Slave for Arduino: File Members + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + + + +
+
+
Here is a list of all file members with links to the files they belong to:
+ +

- a -

+ + +

- b -

+ + +

- c -

+ + +

- e -

+ + +

- f -

+ + +

- i -

+ + +

- m -

+ + +

- n -

+ + +

- r -

+ + +

- t -

+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/globals_defs.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/globals_defs.html new file mode 100644 index 0000000..3bb4d7f --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/globals_defs.html @@ -0,0 +1,73 @@ + + + + + + +Modbus Master and Slave for Arduino: File Members + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + + +
+
+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/globals_enum.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/globals_enum.html new file mode 100644 index 0000000..4b289fe --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/globals_enum.html @@ -0,0 +1,79 @@ + + + + + + +Modbus Master and Slave for Arduino: File Members + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + + +
+
+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/globals_eval.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/globals_eval.html new file mode 100644 index 0000000..1d9d736 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/globals_eval.html @@ -0,0 +1,207 @@ + + + + + + +Modbus Master and Slave for Arduino: File Members + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + + + +
+
+  + +

- a -

+ + +

- b -

+ + +

- c -

+ + +

- e -

+ + +

- f -

+ + +

- i -

+ + +

- m -

+ + +

- n -

+ + +

- r -

+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/globals_vars.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/globals_vars.html new file mode 100644 index 0000000..8f00b2b --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/globals_vars.html @@ -0,0 +1,70 @@ + + + + + + +Modbus Master and Slave for Arduino: File Members + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + + +
+
+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/group__buffer.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/group__buffer.html new file mode 100644 index 0000000..c3e941e --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/group__buffer.html @@ -0,0 +1,184 @@ + + + + + + +Modbus Master and Slave for Arduino: Modbus Buffer Management + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + +
+
+ +
+
Modbus Buffer Management
+
+
+ + + + + + + + + + + + + + + + +

+Functions

uint16_t Modbus::getInCnt ()
 number of incoming messages More...
 
uint16_t Modbus::getOutCnt ()
 number of outcoming messages More...
 
uint16_t Modbus::getErrCnt ()
 error counter More...
 
uint8_t Modbus::getState ()
 
uint8_t Modbus::getLastError ()
 get last error message More...
 
+

Detailed Description

+

Function Documentation

+ +
+
+ + + + + + + +
uint16_t Modbus::getErrCnt ()
+
+ +

error counter

+

Get errors counter value This can be useful to diagnose communication.

+
Returns
errors counter
+ +

Definition at line 386 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + + + + +
uint16_t Modbus::getInCnt ()
+
+ +

number of incoming messages

+

Get input messages counter value This can be useful to diagnose communication.

+
Returns
input messages counter
+ +

Definition at line 362 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + + + + +
uint8_t Modbus::getLastError ()
+
+ +

get last error message

+

Get the last error in the protocol processor

+

NO_REPLY = 255 Time-out

+
Returns
EXC_FUNC_CODE = 1 Function code not available
+
+EXC_ADDR_RANGE = 2 Address beyond available space for Modbus registers
+
+EXC_REGS_QUANT = 3 Coils or registers number beyond the available space
+ +

Definition at line 409 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + + + + +
uint16_t Modbus::getOutCnt ()
+
+ +

number of outcoming messages

+

Get transmitted messages counter value This can be useful to diagnose communication.

+
Returns
transmitted messages counter
+ +

Definition at line 374 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + + + + +
uint8_t Modbus::getState ()
+
+

Get modbus master state

+
Returns
= 0 IDLE, = 1 WAITING FOR ANSWER
+ +

Definition at line 396 of file ModbusRtu.h.

+ +
+
+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/group__discrete.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/group__discrete.html new file mode 100644 index 0000000..15de7c2 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/group__discrete.html @@ -0,0 +1,55 @@ + + + + + + +Modbus Master and Slave for Arduino: Modbus Function Codes for Discrete Coils/Inputs + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + +
+
+
+
Modbus Function Codes for Discrete Coils/Inputs
+
+
+

Detailed Description

+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/group__loop.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/group__loop.html new file mode 100644 index 0000000..f90e3f8 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/group__loop.html @@ -0,0 +1,186 @@ + + + + + + +Modbus Master and Slave for Arduino: Modbus Object Management + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + +
+
+ +
+
Modbus Object Management
+
+
+ + + + + + + + + + + + + + +

+Functions

boolean Modbus::getTimeOutState ()
 get communication watch-dog timer state More...
 
int8_t Modbus::query (modbus_t telegram)
 only for master More...
 
int8_t Modbus::poll ()
 cyclic poll for master More...
 
int8_t Modbus::poll (uint16_t *regs, uint8_t u8size)
 cyclic poll for slave More...
 
+

Detailed Description

+

Function Documentation

+ +
+
+ + + + + + + +
boolean Modbus::getTimeOutState ()
+
+ +

get communication watch-dog timer state

+

Return communication Watchdog state. It could be usefull to reset outputs if the watchdog is fired.

+
Returns
TRUE if millis() > u32timeOut
+ +

Definition at line 350 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + + + + +
int8_t Modbus::poll ()
+
+ +

cyclic poll for master

+

*** Only for Modbus Master *** This method checks if there is any incoming answer if pending. If there is no answer, it would change Master state to COM_IDLE. This method must be called only at loop section. Avoid any delay() function.

+

Any incoming data would be redirected to au16regs pointer, as defined in its modbus_t query telegram.

+

nothing

+
Returns
errors counter
+ +

Definition at line 513 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int8_t Modbus::poll (uint16_t * regs,
uint8_t u8size 
)
+
+ +

cyclic poll for slave

+

*** Only for Modbus Slave *** This method checks if there is any incoming query Afterwards, it would shoot a validation routine plus a register query Avoid any delay() function !!!! After a successful frame between the Master and the Slave, the time-out timer is reset.

+
Parameters
+ + + +
*regsregister table for communication exchange
u8sizesize of the register table
+
+
+
Returns
0 if no query, 1..4 if communication error, >4 if correct query processed
+ +

Definition at line 588 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + + + + + +
int8_t Modbus::query (modbus_t telegram)
+
+ +

only for master

+

*** Only Modbus Master *** Generate a query to an slave with a modbus_t telegram structure The Master must be in COM_IDLE mode. After it, its state would be COM_WAITING. This method has to be called only in loop() section.

+
See Also
modbus_t
+
Parameters
+ + +
modbus_tmodbus telegram structure (id, fct, ...)
+
+
+
Todo:
finish function 15
+ +

Definition at line 425 of file ModbusRtu.h.

+ +
+
+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/group__register.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/group__register.html new file mode 100644 index 0000000..eb40488 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/group__register.html @@ -0,0 +1,55 @@ + + + + + + +Modbus Master and Slave for Arduino: Modbus Function Codes for Holding/Input Registers + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + +
+
+
+
Modbus Function Codes for Holding/Input Registers
+
+
+

Detailed Description

+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/group__setup.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/group__setup.html new file mode 100644 index 0000000..295df48 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/group__setup.html @@ -0,0 +1,201 @@ + + + + + + +Modbus Master and Slave for Arduino: Modbus Object Instantiation/Initialization + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + +
+
+ +
+
Modbus Object Instantiation/Initialization
+
+
+ + + + + + + + + + + + + + + + + +

+Functions

 Modbus::Modbus ()
 Default Constructor for Master through Serial. More...
 
void Modbus::begin (long u32speed)
 Initialize class object. More...
 
void Modbus::setID (uint8_t u8id)
 write new ID for the slave More...
 
uint8_t Modbus::getID ()
 get slave ID between 1 and 247 More...
 
void Modbus::setTimeOut (uint16_t u16timeout)
 write communication watch-dog timer More...
 
+

Detailed Description

+

Function Documentation

+ +
+
+ + + + + + + + +
void Modbus::begin (long u32speed)
+
+ +

Initialize class object.

+

Sets up the serial port using specified baud rate. Call once class has been instantiated, typically within setup().

+
See Also
http://arduino.cc/en/Serial/Begin#.Uy4CJ6aKlHY
+
Parameters
+ + + +
speedbaud rate, in standard increments (300..115200)
configdata frame settings (data length, parity and stop bits)
+
+
+ +

Definition at line 250 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + + + + +
uint8_t Modbus::getID ()
+
+ +

get slave ID between 1 and 247

+

Method to read current slave ID address.

+
Returns
u8id current slave address between 1 and 247
+ +

Definition at line 323 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + + + + +
Modbus::Modbus ()
+
+ +

Default Constructor for Master through Serial.

+ +

Definition at line 204 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + + + + + +
void Modbus::setID (uint8_t u8id)
+
+ +

write new ID for the slave

+

Method to write a new slave ID address.

+
Parameters
+ + +
u8idnew slave address between 1 and 247
+
+
+ +

Definition at line 310 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + + + + + +
void Modbus::setTimeOut (uint16_t u16timeOut)
+
+ +

write communication watch-dog timer

+

Initialize time-out parameter.

+

Call once class has been instantiated, typically within setup(). The time-out timer is reset each time that there is a successful communication between Master and Slave. It works for both.

+
Parameters
+ + +
time-outvalue (ms)
+
+
+ +

Definition at line 338 of file ModbusRtu.h.

+ +
+
+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/index.hhc b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/index.hhc new file mode 100644 index 0000000..5d4eef8 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/index.hhc @@ -0,0 +1,178 @@ + + + + + +
    +
  • +
  • +
      +
    • +
        +
      • +
      • +
      • +
      • +
      • +
      +
    • +
        +
      • +
      • +
      • +
      • +
      +
    • +
        +
      • +
      • +
      • +
      • +
      • +
      +
    • +
        +
      +
    • +
        +
      +
    +
  • +
      +
    • +
        +
      • +
          +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        +
      • +
          +
        • +
        • +
        • +
        • +
        • +
        +
      +
    • +
    • +
        +
      • +
      • +
      • +
      +
    +
  • +
      +
    • +
        +
      • +
          +
        • +
            +
          • +
          • +
          • +
          • +
          • +
          +
        • +
            +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
            +
          • +
          • +
          +
        • +
            +
          • +
          • +
          • +
          • +
          • +
          +
        • +
            +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          +
        • +
            +
          • +
          • +
          • +
          • +
          • +
          • +
          • +
          +
        • +
        +
      +
    • +
        +
      • +
      • +
      • +
      • +
      • +
      +
    +
+ + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/index.hhk b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/index.hhk new file mode 100644 index 0000000..9a9a2df --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/index.hhk @@ -0,0 +1,203 @@ + + + + + +
    +
  • +
  • +
  • +
  • +
      +
    • +
    • +
    +
  • +
      +
    • +
    • +
    • +
    • +
    • +
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
      +
    • +
    • +
    +
  • +
      +
    • +
    • +
    +
  • +
      +
    • +
    • +
    +
  • +
      +
    • +
    • +
    +
  • +
      +
    • +
    • +
    +
  • +
      +
    • +
    • +
    +
  • +
  • +
      +
    • +
    • +
    +
  • +
  • +
      +
    • +
    • +
    • +
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
      +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    +
  • +
      +
    • +
    • +
    • +
    • +
    • +
    +
  • +
      +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    +
  • +
  • +
  • +
  • +
      +
    • +
    • +
    +
  • +
      +
    • +
    • +
    +
  • +
  • +
      +
    • +
    • +
    +
  • +
      +
    • +
    • +
    +
  • +
      +
    • +
    • +
    • +
    • +
    • +
    +
  • +
  • +
  • +
  • +
  • +
  • +
+ + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/index.hhp b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/index.hhp new file mode 100644 index 0000000..789dbbd --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/index.hhp @@ -0,0 +1,69 @@ +[OPTIONS] +Compatibility=1.1 +Full-text search=Yes +Contents file=index.hhc +Default Window=main +Default topic=index.html +Index file=index.hhk +Language=0x409 English (United States) +Title=Modbus Master and Slave for Arduino + +[WINDOWS] +main="Modbus Master and Slave for Arduino","index.hhc","index.hhk","index.html","index.html",,,,,0x23520,,0x10387e,,,,,,,,0 + +[FILES] +_modbus_rtu_8h_source.html +_modbus_rtu_8h.html +todo.html +group__setup.html +group__loop.html +group__buffer.html +group__discrete.html +group__register.html +class_modbus.html +class_modbus-members.html +structmodbus__t.html +structmodbus__t-members.html +index.html +pages.html +modules.html +annotated.html +classes.html +functions.html +functions_func.html +functions_vars.html +files.html +globals.html +globals_vars.html +globals_enum.html +globals_eval.html +globals_defs.html +tab_a.png +tab_b.png +tab_h.png +tab_s.png +nav_h.png +nav_f.png +bc_s.png +doxygen.png +closed.png +open.png +bdwn.png +sync_on.png +sync_off.png +ftv2blank.png +ftv2doc.png +ftv2folderclosed.png +ftv2folderopen.png +ftv2ns.png +ftv2mo.png +ftv2cl.png +ftv2lastnode.png +ftv2link.png +ftv2mlastnode.png +ftv2mnode.png +ftv2node.png +ftv2plastnode.png +ftv2pnode.png +ftv2vertline.png +ftv2splitbar.png diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/index.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/index.html new file mode 100644 index 0000000..551c1ef --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/index.html @@ -0,0 +1,54 @@ + + + + + + +Modbus Master and Slave for Arduino: Main Page + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + +
+
+
+
Modbus Master and Slave for Arduino Documentation
+
+
+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/modules.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/modules.html new file mode 100644 index 0000000..f78fcc9 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/modules.html @@ -0,0 +1,63 @@ + + + + + + +Modbus Master and Slave for Arduino: Modules + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + +
+
+
+
Modules
+
+ + + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/nav_f.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/nav_f.png new file mode 100644 index 0000000..72a58a5 Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/nav_f.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/nav_g.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/nav_g.png new file mode 100644 index 0000000..2093a23 Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/nav_g.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/nav_h.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/nav_h.png new file mode 100644 index 0000000..33389b1 Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/nav_h.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/open.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/open.png new file mode 100644 index 0000000..30f75c7 Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/open.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/pages.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/pages.html new file mode 100644 index 0000000..a24422d --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/pages.html @@ -0,0 +1,59 @@ + + + + + + +Modbus Master and Slave for Arduino: Related Pages + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + +
+
+
+
Related Pages
+
+
+
Here is a list of all related documentation pages:
+ + +
\Todo List
+
+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/structmodbus__t-members.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/structmodbus__t-members.html new file mode 100644 index 0000000..a3cd981 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/structmodbus__t-members.html @@ -0,0 +1,69 @@ + + + + + + +Modbus Master and Slave for Arduino: Member List + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + +
+
+
+
modbus_t Member List
+
+
+ +

This is the complete list of members for modbus_t, including all inherited members.

+ + + + + + +
au16regmodbus_t
u16CoilsNomodbus_t
u16RegAddmodbus_t
u8fctmodbus_t
u8idmodbus_t
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/structmodbus__t.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/structmodbus__t.html new file mode 100644 index 0000000..5b55617 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/structmodbus__t.html @@ -0,0 +1,166 @@ + + + + + + +Modbus Master and Slave for Arduino: modbus_t Struct Reference + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + + +
+
+ +
+
modbus_t Struct Reference
+
+
+ +

Master query structure: This includes all the necessary fields to make the Master generate a Modbus query. A Master may keep several of these structures and send them cyclically or use them according to program needs. + More...

+ +

#include <ModbusRtu.h>

+ + + + + + + + + + + + +

+Public Attributes

uint8_t u8id
 
uint8_t u8fct
 
uint16_t u16RegAdd
 
uint16_t u16CoilsNo
 
uint16_t * au16reg
 
+

Detailed Description

+

Master query structure: This includes all the necessary fields to make the Master generate a Modbus query. A Master may keep several of these structures and send them cyclically or use them according to program needs.

+ +

Definition at line 48 of file ModbusRtu.h.

+

Member Data Documentation

+ +
+
+ + + + +
uint16_t* modbus_t::au16reg
+
+

Pointer to memory image in master

+ +

Definition at line 53 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + +
uint16_t modbus_t::u16CoilsNo
+
+

Number of coils or registers to access

+ +

Definition at line 52 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + +
uint16_t modbus_t::u16RegAdd
+
+

Address of the first register to access at slave/s

+ +

Definition at line 51 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + +
uint8_t modbus_t::u8fct
+
+

Function code: 1, 2, 3, 4, 5, 6, 15 or 16

+ +

Definition at line 50 of file ModbusRtu.h.

+ +
+
+ +
+
+ + + + +
uint8_t modbus_t::u8id
+
+

Slave address between 1 and 247. 0 means broadcast

+ +

Definition at line 49 of file ModbusRtu.h.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/sync_off.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/sync_off.png new file mode 100644 index 0000000..3b443fc Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/sync_off.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/sync_on.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/sync_on.png new file mode 100644 index 0000000..e08320f Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/sync_on.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/tab_a.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/tab_a.png new file mode 100644 index 0000000..3b725c4 Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/tab_a.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/tab_b.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/tab_b.png new file mode 100644 index 0000000..e2b4a86 Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/tab_b.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/tab_h.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/tab_h.png new file mode 100644 index 0000000..fd5cb70 Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/tab_h.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/tab_s.png b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/tab_s.png new file mode 100644 index 0000000..ab478c9 Binary files /dev/null and b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/tab_s.png differ diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/tabs.css b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/tabs.css new file mode 100644 index 0000000..9cf578f --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/tabs.css @@ -0,0 +1,60 @@ +.tabs, .tabs2, .tabs3 { + background-image: url('tab_b.png'); + width: 100%; + z-index: 101; + font-size: 13px; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +} + +.tabs2 { + font-size: 10px; +} +.tabs3 { + font-size: 9px; +} + +.tablist { + margin: 0; + padding: 0; + display: table; +} + +.tablist li { + float: left; + display: table-cell; + background-image: url('tab_b.png'); + line-height: 36px; + list-style: none; +} + +.tablist a { + display: block; + padding: 0 20px; + font-weight: bold; + background-image:url('tab_s.png'); + background-repeat:no-repeat; + background-position:right; + color: #283A5D; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; + outline: none; +} + +.tabs3 .tablist a { + padding: 0 10px; +} + +.tablist a:hover { + background-image: url('tab_h.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); + text-decoration: none; +} + +.tablist li.current a { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/todo.html b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/todo.html new file mode 100644 index 0000000..9721b93 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/html/todo.html @@ -0,0 +1,58 @@ + + + + + + +Modbus Master and Slave for Arduino: Todo List + + + + + + +
+
+ + + + + + +
+
Modbus Master and Slave for Arduino +  1.2 +
+
Arduino library for implementing a Modbus Master or Slave through Serial port
+
+
+ + + +
+
+
+
Todo List
+
+
+
+
Member Modbus::query (modbus_t telegram)
+
finish function 15
+
+
+ + + + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/Makefile b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/Makefile new file mode 100644 index 0000000..3cc085f --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/Makefile @@ -0,0 +1,21 @@ +all: refman.pdf + +pdf: refman.pdf + +refman.pdf: clean refman.tex + pdflatex refman + makeindex refman.idx + pdflatex refman + latex_count=5 ; \ + while egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\ + do \ + echo "Rerunning latex...." ;\ + pdflatex refman ;\ + latex_count=`expr $$latex_count - 1` ;\ + done + makeindex refman.idx + pdflatex refman + + +clean: + rm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/_modbus_rtu_8h.tex b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/_modbus_rtu_8h.tex new file mode 100644 index 0000000..6e481a5 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/_modbus_rtu_8h.tex @@ -0,0 +1,291 @@ +\hypertarget{_modbus_rtu_8h}{\section{Modbus\-Rtu.\-h File Reference} +\label{_modbus_rtu_8h}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}} +} +\subsection*{Classes} +\begin{DoxyCompactItemize} +\item +struct \hyperlink{structmodbus__t}{modbus\-\_\-t} +\begin{DoxyCompactList}\small\item\em Master query structure\-: This includes all the necessary fields to make the Master generate a \hyperlink{class_modbus}{Modbus} query. A Master may keep several of these structures and send them cyclically or use them according to program needs. \end{DoxyCompactList}\item +class \hyperlink{class_modbus}{Modbus} +\begin{DoxyCompactList}\small\item\em Arduino class library for communicating with \hyperlink{class_modbus}{Modbus} devices over U\-S\-B/\-R\-S232/485 (via R\-T\-U protocol). \end{DoxyCompactList}\end{DoxyCompactItemize} +\subsection*{Macros} +\begin{DoxyCompactItemize} +\item +\#define \hyperlink{_modbus_rtu_8h_ac5a7c6ee8dea0ccb09dfc611bd08a0ac}{T35}~5 +\item +\#define \hyperlink{_modbus_rtu_8h_a1d5dab30b404fab91608086105afc78c}{M\-A\-X\-\_\-\-B\-U\-F\-F\-E\-R}~64 +\begin{DoxyCompactList}\small\item\em maximum size for the communication buffer in bytes \end{DoxyCompactList}\end{DoxyCompactItemize} +\subsection*{Enumerations} +\begin{DoxyCompactItemize} +\item +enum \{ \hyperlink{_modbus_rtu_8h_a06fc87d81c62e9abb8790b6e5713c55bad1acb34c5312efc75c4a007eae09433b}{R\-E\-S\-P\-O\-N\-S\-E\-\_\-\-S\-I\-Z\-E} = 6, +\hyperlink{_modbus_rtu_8h_a06fc87d81c62e9abb8790b6e5713c55ba4bf89c487b3f7e29d56eb3fe657d6c05}{E\-X\-C\-E\-P\-T\-I\-O\-N\-\_\-\-S\-I\-Z\-E} = 3, +\hyperlink{_modbus_rtu_8h_a06fc87d81c62e9abb8790b6e5713c55baefcc8f6d8d181aaef9d131a357b1a332}{C\-H\-E\-C\-K\-S\-U\-M\-\_\-\-S\-I\-Z\-E} = 2 + \} +\item +enum \hyperlink{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230ba}{M\-E\-S\-S\-A\-G\-E} \{ \\* +\hyperlink{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baa001479a58fb44c39a29b20d565081a68}{I\-D} = 0, +\hyperlink{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baa389e03ce61ac2d93fd54069187ab58af}{F\-U\-N\-C}, +\hyperlink{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baad19e7653c9276b91fb590af017de192c}{A\-D\-D\-\_\-\-H\-I}, +\hyperlink{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baa2cbdff2e20e58233096845bf42acc97c}{A\-D\-D\-\_\-\-L\-O}, +\\* +\hyperlink{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baa61f961bb4614db2fc51125331f79a9d6}{N\-B\-\_\-\-H\-I}, +\hyperlink{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baa22b2a3a58501a5bbe69ef569aa7fb30f}{N\-B\-\_\-\-L\-O}, +\hyperlink{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baaf84036e1dd68a2e160c3394fc083e892}{B\-Y\-T\-E\-\_\-\-C\-N\-T} + \} +\begin{DoxyCompactList}\small\item\em Indexes to telegram frame positions. \end{DoxyCompactList}\item +enum \hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6}{M\-B\-\_\-\-F\-C} \{ \\* +\hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a513dc96919a5d5c75f129c1b5b2afea9}{M\-B\-\_\-\-F\-C\-\_\-\-N\-O\-N\-E} = 0, +\hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a0b2250567e3e0e43522a64cdce637ce0}{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-C\-O\-I\-L\-S} = 1, +\hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6ac2b52680d6c0bbe3d3e0e9ec7a88fc2e}{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-D\-I\-S\-C\-R\-E\-T\-E\-\_\-\-I\-N\-P\-U\-T} = 2, +\hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a0c6066cf0a67a1bb349da35ef31e4e8f}{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R\-S} = 3, +\\* +\hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a9b2d4a3fb96e4af559d5330ad0c01c07}{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-I\-N\-P\-U\-T\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R} = 4, +\hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a90126d6c25fb5711c103e819ccda01c7}{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-C\-O\-I\-L} = 5, +\hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a74e1ffd48177f0e7e33c2c968a1bd86f}{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R} = 6, +\hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6ac69c42d25cbc0ef303de57bd3d0e2304}{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-M\-U\-L\-T\-I\-P\-L\-E\-\_\-\-C\-O\-I\-L\-S} = 15, +\\* +\hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a2ccdcde4f07865ffb47fbea0a01026bb}{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-M\-U\-L\-T\-I\-P\-L\-E\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R\-S} = 16 + \} +\begin{DoxyCompactList}\small\item\em \hyperlink{class_modbus}{Modbus} function codes summary. These are the implement function codes either for Master or for Slave. \end{DoxyCompactList}\item +enum \hyperlink{_modbus_rtu_8h_a4f165b5bd333856a84635b2594013982}{C\-O\-M\-\_\-\-S\-T\-A\-T\-E\-S} \{ \hyperlink{_modbus_rtu_8h_a4f165b5bd333856a84635b2594013982a3e262bfb13968e43ab8ea55a03ba8b20}{C\-O\-M\-\_\-\-I\-D\-L\-E} = 0, +\hyperlink{_modbus_rtu_8h_a4f165b5bd333856a84635b2594013982ad70b4cc84cc2f21d8b46f73f186dae6b}{C\-O\-M\-\_\-\-W\-A\-I\-T\-I\-N\-G} = 1 + \} +\item +enum \hyperlink{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1}{E\-R\-R\-\_\-\-L\-I\-S\-T} \{ \\* +\hyperlink{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1a12a9ad0aaae512b253a9da9ea19f2b04}{E\-R\-R\-\_\-\-N\-O\-T\-\_\-\-M\-A\-S\-T\-E\-R} = -\/1, +\hyperlink{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1a7d2c6c1b333f4b566c613e52b62ab901}{E\-R\-R\-\_\-\-P\-O\-L\-L\-I\-N\-G} = -\/2, +\hyperlink{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1aafd42890a0ce129e23977fc1aca4044b}{E\-R\-R\-\_\-\-B\-U\-F\-F\-\_\-\-O\-V\-E\-R\-F\-L\-O\-W} = -\/3, +\hyperlink{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1a918477ee2e5e31f01b03a83f472b63b0}{E\-R\-R\-\_\-\-B\-A\-D\-\_\-\-C\-R\-C} = -\/4, +\\* +\hyperlink{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1ab4be9b5f7e8905633a3c045157f1dd0a}{E\-R\-R\-\_\-\-E\-X\-C\-E\-P\-T\-I\-O\-N} = -\/5 + \} +\item +enum \{ \\* +\hyperlink{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7aa04c58a8cc2e7777f6f781e8d51524ae}{N\-O\-\_\-\-R\-E\-P\-L\-Y} = 255, +\hyperlink{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7ad82ec66545269170f1401af6e418e8f2}{E\-X\-C\-\_\-\-F\-U\-N\-C\-\_\-\-C\-O\-D\-E} = 1, +\hyperlink{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7ad3899b13b2069997f5db7f18e9978280}{E\-X\-C\-\_\-\-A\-D\-D\-R\-\_\-\-R\-A\-N\-G\-E} = 2, +\hyperlink{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7a062e13fdfefabb1d620506a526be3920}{E\-X\-C\-\_\-\-R\-E\-G\-S\-\_\-\-Q\-U\-A\-N\-T} = 3, +\\* +\hyperlink{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7a00e93edc9146c12fd21490d1a0d15f89}{E\-X\-C\-\_\-\-E\-X\-E\-C\-U\-T\-E} = 4 + \} +\end{DoxyCompactItemize} +\subsection*{Variables} +\begin{DoxyCompactItemize} +\item +const unsigned char \hyperlink{_modbus_rtu_8h_aede21762dc4aa80a14df8dd40ef105f0}{fctsupported} \mbox{[}$\,$\mbox{]} +\end{DoxyCompactItemize} + + +\subsection{Detailed Description} +\begin{DoxyVersion}{Version} +1.\-2 +\end{DoxyVersion} +\begin{DoxyDate}{Date} +2014.\-09.\-09 +\end{DoxyDate} +\begin{DoxyAuthor}{Author} +Samuel Marco i Armengol \href{mailto:sammarcoarmengol@gmail.com}{\tt sammarcoarmengol@gmail.\-com} +\end{DoxyAuthor} +Arduino library for communicating with \hyperlink{class_modbus}{Modbus} devices over R\-S232/\-U\-S\-B/485 via R\-T\-U protocol. + +Further information\-: \href{http://modbus.org/}{\tt http\-://modbus.\-org/} \href{http://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf}{\tt http\-://modbus.\-org/docs/\-Modbus\-\_\-over\-\_\-serial\-\_\-line\-\_\-\-V1\-\_\-02.\-pdf} + +This library is free software; you can redistribute it and/or modify it under the terms of the G\-N\-U Lesser General Public License as published by the Free Software Foundation; version 2.\-1 of the License. + +This library is distributed in the hope that it will be useful, but W\-I\-T\-H\-O\-U\-T A\-N\-Y W\-A\-R\-R\-A\-N\-T\-Y; without even the implied warranty of M\-E\-R\-C\-H\-A\-N\-T\-A\-B\-I\-L\-I\-T\-Y or F\-I\-T\-N\-E\-S\-S F\-O\-R A P\-A\-R\-T\-I\-C\-U\-L\-A\-R P\-U\-R\-P\-O\-S\-E. See the G\-N\-U Lesser General Public License for more details. + +You should have received a copy of the G\-N\-U Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, M\-A 02110-\/1301 U\-S\-A + +Definition in file \hyperlink{_modbus_rtu_8h_source}{Modbus\-Rtu.\-h}. + + + +\subsection{Macro Definition Documentation} +\hypertarget{_modbus_rtu_8h_a1d5dab30b404fab91608086105afc78c}{\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!M\-A\-X\-\_\-\-B\-U\-F\-F\-E\-R@{M\-A\-X\-\_\-\-B\-U\-F\-F\-E\-R}} +\index{M\-A\-X\-\_\-\-B\-U\-F\-F\-E\-R@{M\-A\-X\-\_\-\-B\-U\-F\-F\-E\-R}!ModbusRtu.h@{Modbus\-Rtu.\-h}} +\subsubsection[{M\-A\-X\-\_\-\-B\-U\-F\-F\-E\-R}]{\setlength{\rightskip}{0pt plus 5cm}\#define M\-A\-X\-\_\-\-B\-U\-F\-F\-E\-R~64}}\label{_modbus_rtu_8h_a1d5dab30b404fab91608086105afc78c} + + +maximum size for the communication buffer in bytes + + + +Definition at line 133 of file Modbus\-Rtu.\-h. + +\hypertarget{_modbus_rtu_8h_ac5a7c6ee8dea0ccb09dfc611bd08a0ac}{\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!T35@{T35}} +\index{T35@{T35}!ModbusRtu.h@{Modbus\-Rtu.\-h}} +\subsubsection[{T35}]{\setlength{\rightskip}{0pt plus 5cm}\#define T35~5}}\label{_modbus_rtu_8h_ac5a7c6ee8dea0ccb09dfc611bd08a0ac} + + +Definition at line 132 of file Modbus\-Rtu.\-h. + + + +\subsection{Enumeration Type Documentation} +\hypertarget{_modbus_rtu_8h_a06fc87d81c62e9abb8790b6e5713c55b}{\subsubsection[{anonymous enum}]{\setlength{\rightskip}{0pt plus 5cm}anonymous enum}}\label{_modbus_rtu_8h_a06fc87d81c62e9abb8790b6e5713c55b} +\begin{Desc} +\item[Enumerator]\par +\begin{description} +\index{R\-E\-S\-P\-O\-N\-S\-E\-\_\-\-S\-I\-Z\-E@{R\-E\-S\-P\-O\-N\-S\-E\-\_\-\-S\-I\-Z\-E}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!R\-E\-S\-P\-O\-N\-S\-E\-\_\-\-S\-I\-Z\-E@{R\-E\-S\-P\-O\-N\-S\-E\-\_\-\-S\-I\-Z\-E}}\item[{\em +\hypertarget{_modbus_rtu_8h_a06fc87d81c62e9abb8790b6e5713c55bad1acb34c5312efc75c4a007eae09433b}{R\-E\-S\-P\-O\-N\-S\-E\-\_\-\-S\-I\-Z\-E}\label{_modbus_rtu_8h_a06fc87d81c62e9abb8790b6e5713c55bad1acb34c5312efc75c4a007eae09433b} +}]\index{E\-X\-C\-E\-P\-T\-I\-O\-N\-\_\-\-S\-I\-Z\-E@{E\-X\-C\-E\-P\-T\-I\-O\-N\-\_\-\-S\-I\-Z\-E}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!E\-X\-C\-E\-P\-T\-I\-O\-N\-\_\-\-S\-I\-Z\-E@{E\-X\-C\-E\-P\-T\-I\-O\-N\-\_\-\-S\-I\-Z\-E}}\item[{\em +\hypertarget{_modbus_rtu_8h_a06fc87d81c62e9abb8790b6e5713c55ba4bf89c487b3f7e29d56eb3fe657d6c05}{E\-X\-C\-E\-P\-T\-I\-O\-N\-\_\-\-S\-I\-Z\-E}\label{_modbus_rtu_8h_a06fc87d81c62e9abb8790b6e5713c55ba4bf89c487b3f7e29d56eb3fe657d6c05} +}]\index{C\-H\-E\-C\-K\-S\-U\-M\-\_\-\-S\-I\-Z\-E@{C\-H\-E\-C\-K\-S\-U\-M\-\_\-\-S\-I\-Z\-E}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!C\-H\-E\-C\-K\-S\-U\-M\-\_\-\-S\-I\-Z\-E@{C\-H\-E\-C\-K\-S\-U\-M\-\_\-\-S\-I\-Z\-E}}\item[{\em +\hypertarget{_modbus_rtu_8h_a06fc87d81c62e9abb8790b6e5713c55baefcc8f6d8d181aaef9d131a357b1a332}{C\-H\-E\-C\-K\-S\-U\-M\-\_\-\-S\-I\-Z\-E}\label{_modbus_rtu_8h_a06fc87d81c62e9abb8790b6e5713c55baefcc8f6d8d181aaef9d131a357b1a332} +}]\end{description} +\end{Desc} + + +Definition at line 57 of file Modbus\-Rtu.\-h. + +\hypertarget{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7}{\subsubsection[{anonymous enum}]{\setlength{\rightskip}{0pt plus 5cm}anonymous enum}}\label{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7} +\begin{Desc} +\item[Enumerator]\par +\begin{description} +\index{N\-O\-\_\-\-R\-E\-P\-L\-Y@{N\-O\-\_\-\-R\-E\-P\-L\-Y}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!N\-O\-\_\-\-R\-E\-P\-L\-Y@{N\-O\-\_\-\-R\-E\-P\-L\-Y}}\item[{\em +\hypertarget{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7aa04c58a8cc2e7777f6f781e8d51524ae}{N\-O\-\_\-\-R\-E\-P\-L\-Y}\label{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7aa04c58a8cc2e7777f6f781e8d51524ae} +}]\index{E\-X\-C\-\_\-\-F\-U\-N\-C\-\_\-\-C\-O\-D\-E@{E\-X\-C\-\_\-\-F\-U\-N\-C\-\_\-\-C\-O\-D\-E}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!E\-X\-C\-\_\-\-F\-U\-N\-C\-\_\-\-C\-O\-D\-E@{E\-X\-C\-\_\-\-F\-U\-N\-C\-\_\-\-C\-O\-D\-E}}\item[{\em +\hypertarget{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7ad82ec66545269170f1401af6e418e8f2}{E\-X\-C\-\_\-\-F\-U\-N\-C\-\_\-\-C\-O\-D\-E}\label{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7ad82ec66545269170f1401af6e418e8f2} +}]\index{E\-X\-C\-\_\-\-A\-D\-D\-R\-\_\-\-R\-A\-N\-G\-E@{E\-X\-C\-\_\-\-A\-D\-D\-R\-\_\-\-R\-A\-N\-G\-E}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!E\-X\-C\-\_\-\-A\-D\-D\-R\-\_\-\-R\-A\-N\-G\-E@{E\-X\-C\-\_\-\-A\-D\-D\-R\-\_\-\-R\-A\-N\-G\-E}}\item[{\em +\hypertarget{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7ad3899b13b2069997f5db7f18e9978280}{E\-X\-C\-\_\-\-A\-D\-D\-R\-\_\-\-R\-A\-N\-G\-E}\label{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7ad3899b13b2069997f5db7f18e9978280} +}]\index{E\-X\-C\-\_\-\-R\-E\-G\-S\-\_\-\-Q\-U\-A\-N\-T@{E\-X\-C\-\_\-\-R\-E\-G\-S\-\_\-\-Q\-U\-A\-N\-T}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!E\-X\-C\-\_\-\-R\-E\-G\-S\-\_\-\-Q\-U\-A\-N\-T@{E\-X\-C\-\_\-\-R\-E\-G\-S\-\_\-\-Q\-U\-A\-N\-T}}\item[{\em +\hypertarget{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7a062e13fdfefabb1d620506a526be3920}{E\-X\-C\-\_\-\-R\-E\-G\-S\-\_\-\-Q\-U\-A\-N\-T}\label{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7a062e13fdfefabb1d620506a526be3920} +}]\index{E\-X\-C\-\_\-\-E\-X\-E\-C\-U\-T\-E@{E\-X\-C\-\_\-\-E\-X\-E\-C\-U\-T\-E}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!E\-X\-C\-\_\-\-E\-X\-E\-C\-U\-T\-E@{E\-X\-C\-\_\-\-E\-X\-E\-C\-U\-T\-E}}\item[{\em +\hypertarget{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7a00e93edc9146c12fd21490d1a0d15f89}{E\-X\-C\-\_\-\-E\-X\-E\-C\-U\-T\-E}\label{_modbus_rtu_8h_adf764cbdea00d65edcd07bb9953ad2b7a00e93edc9146c12fd21490d1a0d15f89} +}]\end{description} +\end{Desc} + + +Definition at line 113 of file Modbus\-Rtu.\-h. + +\hypertarget{_modbus_rtu_8h_a4f165b5bd333856a84635b2594013982}{\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!C\-O\-M\-\_\-\-S\-T\-A\-T\-E\-S@{C\-O\-M\-\_\-\-S\-T\-A\-T\-E\-S}} +\index{C\-O\-M\-\_\-\-S\-T\-A\-T\-E\-S@{C\-O\-M\-\_\-\-S\-T\-A\-T\-E\-S}!ModbusRtu.h@{Modbus\-Rtu.\-h}} +\subsubsection[{C\-O\-M\-\_\-\-S\-T\-A\-T\-E\-S}]{\setlength{\rightskip}{0pt plus 5cm}enum {\bf C\-O\-M\-\_\-\-S\-T\-A\-T\-E\-S}}}\label{_modbus_rtu_8h_a4f165b5bd333856a84635b2594013982} +\begin{Desc} +\item[Enumerator]\par +\begin{description} +\index{C\-O\-M\-\_\-\-I\-D\-L\-E@{C\-O\-M\-\_\-\-I\-D\-L\-E}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!C\-O\-M\-\_\-\-I\-D\-L\-E@{C\-O\-M\-\_\-\-I\-D\-L\-E}}\item[{\em +\hypertarget{_modbus_rtu_8h_a4f165b5bd333856a84635b2594013982a3e262bfb13968e43ab8ea55a03ba8b20}{C\-O\-M\-\_\-\-I\-D\-L\-E}\label{_modbus_rtu_8h_a4f165b5bd333856a84635b2594013982a3e262bfb13968e43ab8ea55a03ba8b20} +}]\index{C\-O\-M\-\_\-\-W\-A\-I\-T\-I\-N\-G@{C\-O\-M\-\_\-\-W\-A\-I\-T\-I\-N\-G}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!C\-O\-M\-\_\-\-W\-A\-I\-T\-I\-N\-G@{C\-O\-M\-\_\-\-W\-A\-I\-T\-I\-N\-G}}\item[{\em +\hypertarget{_modbus_rtu_8h_a4f165b5bd333856a84635b2594013982ad70b4cc84cc2f21d8b46f73f186dae6b}{C\-O\-M\-\_\-\-W\-A\-I\-T\-I\-N\-G}\label{_modbus_rtu_8h_a4f165b5bd333856a84635b2594013982ad70b4cc84cc2f21d8b46f73f186dae6b} +}]\end{description} +\end{Desc} + + +Definition at line 99 of file Modbus\-Rtu.\-h. + +\hypertarget{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1}{\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!E\-R\-R\-\_\-\-L\-I\-S\-T@{E\-R\-R\-\_\-\-L\-I\-S\-T}} +\index{E\-R\-R\-\_\-\-L\-I\-S\-T@{E\-R\-R\-\_\-\-L\-I\-S\-T}!ModbusRtu.h@{Modbus\-Rtu.\-h}} +\subsubsection[{E\-R\-R\-\_\-\-L\-I\-S\-T}]{\setlength{\rightskip}{0pt plus 5cm}enum {\bf E\-R\-R\-\_\-\-L\-I\-S\-T}}}\label{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1} +\begin{Desc} +\item[Enumerator]\par +\begin{description} +\index{E\-R\-R\-\_\-\-N\-O\-T\-\_\-\-M\-A\-S\-T\-E\-R@{E\-R\-R\-\_\-\-N\-O\-T\-\_\-\-M\-A\-S\-T\-E\-R}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!E\-R\-R\-\_\-\-N\-O\-T\-\_\-\-M\-A\-S\-T\-E\-R@{E\-R\-R\-\_\-\-N\-O\-T\-\_\-\-M\-A\-S\-T\-E\-R}}\item[{\em +\hypertarget{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1a12a9ad0aaae512b253a9da9ea19f2b04}{E\-R\-R\-\_\-\-N\-O\-T\-\_\-\-M\-A\-S\-T\-E\-R}\label{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1a12a9ad0aaae512b253a9da9ea19f2b04} +}]\index{E\-R\-R\-\_\-\-P\-O\-L\-L\-I\-N\-G@{E\-R\-R\-\_\-\-P\-O\-L\-L\-I\-N\-G}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!E\-R\-R\-\_\-\-P\-O\-L\-L\-I\-N\-G@{E\-R\-R\-\_\-\-P\-O\-L\-L\-I\-N\-G}}\item[{\em +\hypertarget{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1a7d2c6c1b333f4b566c613e52b62ab901}{E\-R\-R\-\_\-\-P\-O\-L\-L\-I\-N\-G}\label{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1a7d2c6c1b333f4b566c613e52b62ab901} +}]\index{E\-R\-R\-\_\-\-B\-U\-F\-F\-\_\-\-O\-V\-E\-R\-F\-L\-O\-W@{E\-R\-R\-\_\-\-B\-U\-F\-F\-\_\-\-O\-V\-E\-R\-F\-L\-O\-W}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!E\-R\-R\-\_\-\-B\-U\-F\-F\-\_\-\-O\-V\-E\-R\-F\-L\-O\-W@{E\-R\-R\-\_\-\-B\-U\-F\-F\-\_\-\-O\-V\-E\-R\-F\-L\-O\-W}}\item[{\em +\hypertarget{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1aafd42890a0ce129e23977fc1aca4044b}{E\-R\-R\-\_\-\-B\-U\-F\-F\-\_\-\-O\-V\-E\-R\-F\-L\-O\-W}\label{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1aafd42890a0ce129e23977fc1aca4044b} +}]\index{E\-R\-R\-\_\-\-B\-A\-D\-\_\-\-C\-R\-C@{E\-R\-R\-\_\-\-B\-A\-D\-\_\-\-C\-R\-C}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!E\-R\-R\-\_\-\-B\-A\-D\-\_\-\-C\-R\-C@{E\-R\-R\-\_\-\-B\-A\-D\-\_\-\-C\-R\-C}}\item[{\em +\hypertarget{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1a918477ee2e5e31f01b03a83f472b63b0}{E\-R\-R\-\_\-\-B\-A\-D\-\_\-\-C\-R\-C}\label{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1a918477ee2e5e31f01b03a83f472b63b0} +}]\index{E\-R\-R\-\_\-\-E\-X\-C\-E\-P\-T\-I\-O\-N@{E\-R\-R\-\_\-\-E\-X\-C\-E\-P\-T\-I\-O\-N}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!E\-R\-R\-\_\-\-E\-X\-C\-E\-P\-T\-I\-O\-N@{E\-R\-R\-\_\-\-E\-X\-C\-E\-P\-T\-I\-O\-N}}\item[{\em +\hypertarget{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1ab4be9b5f7e8905633a3c045157f1dd0a}{E\-R\-R\-\_\-\-E\-X\-C\-E\-P\-T\-I\-O\-N}\label{_modbus_rtu_8h_a792f00821300f1c7c768db990db646c1ab4be9b5f7e8905633a3c045157f1dd0a} +}]\end{description} +\end{Desc} + + +Definition at line 105 of file Modbus\-Rtu.\-h. + +\hypertarget{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6}{\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!M\-B\-\_\-\-F\-C@{M\-B\-\_\-\-F\-C}} +\index{M\-B\-\_\-\-F\-C@{M\-B\-\_\-\-F\-C}!ModbusRtu.h@{Modbus\-Rtu.\-h}} +\subsubsection[{M\-B\-\_\-\-F\-C}]{\setlength{\rightskip}{0pt plus 5cm}enum {\bf M\-B\-\_\-\-F\-C}}}\label{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6} + + +\hyperlink{class_modbus}{Modbus} function codes summary. These are the implement function codes either for Master or for Slave. + +\begin{DoxySeeAlso}{See Also} +also \hyperlink{_modbus_rtu_8h_aede21762dc4aa80a14df8dd40ef105f0}{fctsupported} + +also \hyperlink{structmodbus__t}{modbus\-\_\-t} +\end{DoxySeeAlso} +\begin{Desc} +\item[Enumerator]\par +\begin{description} +\index{M\-B\-\_\-\-F\-C\-\_\-\-N\-O\-N\-E@{M\-B\-\_\-\-F\-C\-\_\-\-N\-O\-N\-E}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!M\-B\-\_\-\-F\-C\-\_\-\-N\-O\-N\-E@{M\-B\-\_\-\-F\-C\-\_\-\-N\-O\-N\-E}}\item[{\em +\hypertarget{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a513dc96919a5d5c75f129c1b5b2afea9}{M\-B\-\_\-\-F\-C\-\_\-\-N\-O\-N\-E}\label{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a513dc96919a5d5c75f129c1b5b2afea9} +}]null operator \index{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-C\-O\-I\-L\-S@{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-C\-O\-I\-L\-S}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-C\-O\-I\-L\-S@{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-C\-O\-I\-L\-S}}\item[{\em +\hypertarget{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a0b2250567e3e0e43522a64cdce637ce0}{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-C\-O\-I\-L\-S}\label{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a0b2250567e3e0e43522a64cdce637ce0} +}]F\-C\-T=1 -\/$>$ read coils or digital outputs \index{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-D\-I\-S\-C\-R\-E\-T\-E\-\_\-\-I\-N\-P\-U\-T@{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-D\-I\-S\-C\-R\-E\-T\-E\-\_\-\-I\-N\-P\-U\-T}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-D\-I\-S\-C\-R\-E\-T\-E\-\_\-\-I\-N\-P\-U\-T@{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-D\-I\-S\-C\-R\-E\-T\-E\-\_\-\-I\-N\-P\-U\-T}}\item[{\em +\hypertarget{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6ac2b52680d6c0bbe3d3e0e9ec7a88fc2e}{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-D\-I\-S\-C\-R\-E\-T\-E\-\_\-\-I\-N\-P\-U\-T}\label{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6ac2b52680d6c0bbe3d3e0e9ec7a88fc2e} +}]F\-C\-T=2 -\/$>$ read digital inputs \index{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R\-S@{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R\-S}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R\-S@{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R\-S}}\item[{\em +\hypertarget{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a0c6066cf0a67a1bb349da35ef31e4e8f}{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R\-S}\label{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a0c6066cf0a67a1bb349da35ef31e4e8f} +}]F\-C\-T=3 -\/$>$ read registers or analog outputs \index{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-I\-N\-P\-U\-T\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R@{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-I\-N\-P\-U\-T\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-I\-N\-P\-U\-T\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R@{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-I\-N\-P\-U\-T\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R}}\item[{\em +\hypertarget{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a9b2d4a3fb96e4af559d5330ad0c01c07}{M\-B\-\_\-\-F\-C\-\_\-\-R\-E\-A\-D\-\_\-\-I\-N\-P\-U\-T\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R}\label{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a9b2d4a3fb96e4af559d5330ad0c01c07} +}]F\-C\-T=4 -\/$>$ read analog inputs \index{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-C\-O\-I\-L@{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-C\-O\-I\-L}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-C\-O\-I\-L@{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-C\-O\-I\-L}}\item[{\em +\hypertarget{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a90126d6c25fb5711c103e819ccda01c7}{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-C\-O\-I\-L}\label{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a90126d6c25fb5711c103e819ccda01c7} +}]F\-C\-T=5 -\/$>$ write single coil or output \index{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R@{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R@{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R}}\item[{\em +\hypertarget{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a74e1ffd48177f0e7e33c2c968a1bd86f}{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R}\label{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a74e1ffd48177f0e7e33c2c968a1bd86f} +}]F\-C\-T=6 -\/$>$ write single register \index{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-M\-U\-L\-T\-I\-P\-L\-E\-\_\-\-C\-O\-I\-L\-S@{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-M\-U\-L\-T\-I\-P\-L\-E\-\_\-\-C\-O\-I\-L\-S}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-M\-U\-L\-T\-I\-P\-L\-E\-\_\-\-C\-O\-I\-L\-S@{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-M\-U\-L\-T\-I\-P\-L\-E\-\_\-\-C\-O\-I\-L\-S}}\item[{\em +\hypertarget{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6ac69c42d25cbc0ef303de57bd3d0e2304}{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-M\-U\-L\-T\-I\-P\-L\-E\-\_\-\-C\-O\-I\-L\-S}\label{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6ac69c42d25cbc0ef303de57bd3d0e2304} +}]F\-C\-T=15 -\/$>$ write multiple coils or outputs \index{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-M\-U\-L\-T\-I\-P\-L\-E\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R\-S@{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-M\-U\-L\-T\-I\-P\-L\-E\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R\-S}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-M\-U\-L\-T\-I\-P\-L\-E\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R\-S@{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-M\-U\-L\-T\-I\-P\-L\-E\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R\-S}}\item[{\em +\hypertarget{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a2ccdcde4f07865ffb47fbea0a01026bb}{M\-B\-\_\-\-F\-C\-\_\-\-W\-R\-I\-T\-E\-\_\-\-M\-U\-L\-T\-I\-P\-L\-E\-\_\-\-R\-E\-G\-I\-S\-T\-E\-R\-S}\label{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a2ccdcde4f07865ffb47fbea0a01026bb} +}]F\-C\-T=16 -\/$>$ write multiple registers \end{description} +\end{Desc} + + +Definition at line 87 of file Modbus\-Rtu.\-h. + +\hypertarget{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230ba}{\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!M\-E\-S\-S\-A\-G\-E@{M\-E\-S\-S\-A\-G\-E}} +\index{M\-E\-S\-S\-A\-G\-E@{M\-E\-S\-S\-A\-G\-E}!ModbusRtu.h@{Modbus\-Rtu.\-h}} +\subsubsection[{M\-E\-S\-S\-A\-G\-E}]{\setlength{\rightskip}{0pt plus 5cm}enum {\bf M\-E\-S\-S\-A\-G\-E}}}\label{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230ba} + + +Indexes to telegram frame positions. + +\begin{Desc} +\item[Enumerator]\par +\begin{description} +\index{I\-D@{I\-D}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!I\-D@{I\-D}}\item[{\em +\hypertarget{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baa001479a58fb44c39a29b20d565081a68}{I\-D}\label{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baa001479a58fb44c39a29b20d565081a68} +}]I\-D field. \index{F\-U\-N\-C@{F\-U\-N\-C}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!F\-U\-N\-C@{F\-U\-N\-C}}\item[{\em +\hypertarget{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baa389e03ce61ac2d93fd54069187ab58af}{F\-U\-N\-C}\label{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baa389e03ce61ac2d93fd54069187ab58af} +}]Function code position. \index{A\-D\-D\-\_\-\-H\-I@{A\-D\-D\-\_\-\-H\-I}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!A\-D\-D\-\_\-\-H\-I@{A\-D\-D\-\_\-\-H\-I}}\item[{\em +\hypertarget{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baad19e7653c9276b91fb590af017de192c}{A\-D\-D\-\_\-\-H\-I}\label{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baad19e7653c9276b91fb590af017de192c} +}]Address high byte. \index{A\-D\-D\-\_\-\-L\-O@{A\-D\-D\-\_\-\-L\-O}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!A\-D\-D\-\_\-\-L\-O@{A\-D\-D\-\_\-\-L\-O}}\item[{\em +\hypertarget{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baa2cbdff2e20e58233096845bf42acc97c}{A\-D\-D\-\_\-\-L\-O}\label{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baa2cbdff2e20e58233096845bf42acc97c} +}]Address low byte. \index{N\-B\-\_\-\-H\-I@{N\-B\-\_\-\-H\-I}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!N\-B\-\_\-\-H\-I@{N\-B\-\_\-\-H\-I}}\item[{\em +\hypertarget{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baa61f961bb4614db2fc51125331f79a9d6}{N\-B\-\_\-\-H\-I}\label{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baa61f961bb4614db2fc51125331f79a9d6} +}]Number of coils or registers high byte. \index{N\-B\-\_\-\-L\-O@{N\-B\-\_\-\-L\-O}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!N\-B\-\_\-\-L\-O@{N\-B\-\_\-\-L\-O}}\item[{\em +\hypertarget{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baa22b2a3a58501a5bbe69ef569aa7fb30f}{N\-B\-\_\-\-L\-O}\label{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baa22b2a3a58501a5bbe69ef569aa7fb30f} +}]Number of coils or registers low byte. \index{B\-Y\-T\-E\-\_\-\-C\-N\-T@{B\-Y\-T\-E\-\_\-\-C\-N\-T}!Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}}\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!B\-Y\-T\-E\-\_\-\-C\-N\-T@{B\-Y\-T\-E\-\_\-\-C\-N\-T}}\item[{\em +\hypertarget{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baaf84036e1dd68a2e160c3394fc083e892}{B\-Y\-T\-E\-\_\-\-C\-N\-T}\label{_modbus_rtu_8h_aa9996e8b4648c78acf6cde2401e230baaf84036e1dd68a2e160c3394fc083e892} +}]byte counter \end{description} +\end{Desc} + + +Definition at line 68 of file Modbus\-Rtu.\-h. + + + +\subsection{Variable Documentation} +\hypertarget{_modbus_rtu_8h_aede21762dc4aa80a14df8dd40ef105f0}{\index{Modbus\-Rtu.\-h@{Modbus\-Rtu.\-h}!fctsupported@{fctsupported}} +\index{fctsupported@{fctsupported}!ModbusRtu.h@{Modbus\-Rtu.\-h}} +\subsubsection[{fctsupported}]{\setlength{\rightskip}{0pt plus 5cm}const unsigned char fctsupported\mbox{[}$\,$\mbox{]}}}\label{_modbus_rtu_8h_aede21762dc4aa80a14df8dd40ef105f0} +{\bfseries Initial value\-:} +\begin{DoxyCode} += \{ + \hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a0b2250567e3e0e43522a64cdce637ce0}{MB\_FC\_READ\_COILS}, + \hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6ac2b52680d6c0bbe3d3e0e9ec7a88fc2e}{MB\_FC\_READ\_DISCRETE\_INPUT}, + \hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a0c6066cf0a67a1bb349da35ef31e4e8f}{MB\_FC\_READ\_REGISTERS}, + \hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a9b2d4a3fb96e4af559d5330ad0c01c07}{MB\_FC\_READ\_INPUT\_REGISTER}, + \hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a90126d6c25fb5711c103e819ccda01c7}{MB\_FC\_WRITE\_COIL}, + \hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a74e1ffd48177f0e7e33c2c968a1bd86f}{MB\_FC\_WRITE\_REGISTER}, + \hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6ac69c42d25cbc0ef303de57bd3d0e2304}{MB\_FC\_WRITE\_MULTIPLE\_COILS}, + \hyperlink{_modbus_rtu_8h_aff1341ea5077cc6097a0d7db89be4cf6a2ccdcde4f07865ffb47fbea0a01026bb}{MB\_FC\_WRITE\_MULTIPLE\_REGISTERS} +\} +\end{DoxyCode} + + +Definition at line 121 of file Modbus\-Rtu.\-h. + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/annotated.tex b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/annotated.tex new file mode 100644 index 0000000..5674754 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/annotated.tex @@ -0,0 +1,5 @@ +\section{Class List} +Here are the classes, structs, unions and interfaces with brief descriptions\-:\begin{DoxyCompactList} +\item\contentsline{section}{\hyperlink{class_modbus}{Modbus} \\*Arduino class library for communicating with \hyperlink{class_modbus}{Modbus} devices over U\-S\-B/\-R\-S232/485 (via R\-T\-U protocol) }{\pageref{class_modbus}}{} +\item\contentsline{section}{\hyperlink{structmodbus__t}{modbus\-\_\-t} \\*Master query structure\-: This includes all the necessary fields to make the Master generate a \hyperlink{class_modbus}{Modbus} query. A Master may keep several of these structures and send them cyclically or use them according to program needs }{\pageref{structmodbus__t}}{} +\end{DoxyCompactList} diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/class_modbus.tex b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/class_modbus.tex new file mode 100644 index 0000000..2655e3f --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/class_modbus.tex @@ -0,0 +1,129 @@ +\hypertarget{class_modbus}{\section{Modbus Class Reference} +\label{class_modbus}\index{Modbus@{Modbus}} +} + + +Arduino class library for communicating with \hyperlink{class_modbus}{Modbus} devices over U\-S\-B/\-R\-S232/485 (via R\-T\-U protocol). + + + + +{\ttfamily \#include $<$Modbus\-Rtu.\-h$>$} + +\subsection*{Public Member Functions} +\begin{DoxyCompactItemize} +\item +\hyperlink{group__setup_ga101809cdd4734537bab58dc315a840b4}{Modbus} () +\begin{DoxyCompactList}\small\item\em Default Constructor for Master through Serial. \end{DoxyCompactList}\item +\hyperlink{class_modbus_afbbf7c81565d8e1ea1cd5890a96e7507}{Modbus} (uint8\-\_\-t u8id, uint8\-\_\-t u8serno) +\item +\hyperlink{class_modbus_a5e23a7b669d0c2d5be1c0054c7c54dca}{Modbus} (uint8\-\_\-t u8id, uint8\-\_\-t u8serno, uint8\-\_\-t u8txenpin) +\item +void \hyperlink{group__setup_ga475a4fa0fac491307b10c4529ad6d2a0}{begin} (long u32speed) +\begin{DoxyCompactList}\small\item\em Initialize class object. \end{DoxyCompactList}\item +void \hyperlink{class_modbus_a4f9673a3d113c49af69cb87b030ef099}{begin} () +\item +void \hyperlink{group__setup_gaf828190ebe24efb1b3b1957429f3872e}{set\-Time\-Out} (uint16\-\_\-t u16timeout) +\begin{DoxyCompactList}\small\item\em write communication watch-\/dog timer \end{DoxyCompactList}\item +uint16\-\_\-t \hyperlink{class_modbus_ac860024db3117a2ef907d0325b2fb7a1}{get\-Time\-Out} () +\begin{DoxyCompactList}\small\item\em get communication watch-\/dog timer value \end{DoxyCompactList}\item +boolean \hyperlink{group__loop_gaf6dd413191ed8a833022046873e0a063}{get\-Time\-Out\-State} () +\begin{DoxyCompactList}\small\item\em get communication watch-\/dog timer state \end{DoxyCompactList}\item +int8\-\_\-t \hyperlink{group__loop_ga19398cabed57b6d085d014af6c149f54}{query} (\hyperlink{structmodbus__t}{modbus\-\_\-t} telegram) +\begin{DoxyCompactList}\small\item\em only for master \end{DoxyCompactList}\item +int8\-\_\-t \hyperlink{group__loop_ga53bde78490c1cd8e3c070a676bdcfb0d}{poll} () +\begin{DoxyCompactList}\small\item\em cyclic poll for master \end{DoxyCompactList}\item +int8\-\_\-t \hyperlink{group__loop_gab3ef20562fc8cee14fc85f7e276890b5}{poll} (uint16\-\_\-t $\ast$regs, uint8\-\_\-t u8size) +\begin{DoxyCompactList}\small\item\em cyclic poll for slave \end{DoxyCompactList}\item +uint16\-\_\-t \hyperlink{group__buffer_ga4fa6ede8df85b7cc70b1282b9547378a}{get\-In\-Cnt} () +\begin{DoxyCompactList}\small\item\em number of incoming messages \end{DoxyCompactList}\item +uint16\-\_\-t \hyperlink{group__buffer_ga6f831ecaf3678c27dafb663a28bf81f0}{get\-Out\-Cnt} () +\begin{DoxyCompactList}\small\item\em number of outcoming messages \end{DoxyCompactList}\item +uint16\-\_\-t \hyperlink{group__buffer_ga6883c7f3ff12f084ed56d559d4e06ed0}{get\-Err\-Cnt} () +\begin{DoxyCompactList}\small\item\em error counter \end{DoxyCompactList}\item +uint8\-\_\-t \hyperlink{group__setup_ga6449894306ff8cc5d4caff09b1b0d1ce}{get\-I\-D} () +\begin{DoxyCompactList}\small\item\em get slave I\-D between 1 and 247 \end{DoxyCompactList}\item +uint8\-\_\-t \hyperlink{group__buffer_ga2f39717d957a929af488c9120488fcdc}{get\-State} () +\item +uint8\-\_\-t \hyperlink{group__buffer_gace7f726db13adc8feeceab987b719531}{get\-Last\-Error} () +\begin{DoxyCompactList}\small\item\em get last error message \end{DoxyCompactList}\item +void \hyperlink{group__setup_ga9bd497e97ac1777d4f0d4171078d60e0}{set\-I\-D} (uint8\-\_\-t u8id) +\begin{DoxyCompactList}\small\item\em write new I\-D for the slave \end{DoxyCompactList}\item +void \hyperlink{class_modbus_a0d80101b650344c712a085c4bb005c4c}{end} () +\begin{DoxyCompactList}\small\item\em finish any communication and release serial communication port \end{DoxyCompactList}\end{DoxyCompactItemize} + + +\subsection{Detailed Description} +Arduino class library for communicating with \hyperlink{class_modbus}{Modbus} devices over U\-S\-B/\-R\-S232/485 (via R\-T\-U protocol). + +Definition at line 141 of file Modbus\-Rtu.\-h. + + + +\subsection{Constructor \& Destructor Documentation} +\hypertarget{class_modbus_afbbf7c81565d8e1ea1cd5890a96e7507}{\index{Modbus@{Modbus}!Modbus@{Modbus}} +\index{Modbus@{Modbus}!Modbus@{Modbus}} +\subsubsection[{Modbus}]{\setlength{\rightskip}{0pt plus 5cm}Modbus\-::\-Modbus ( +\begin{DoxyParamCaption} +\item[{uint8\-\_\-t}]{u8id, } +\item[{uint8\-\_\-t}]{u8serno} +\end{DoxyParamCaption} +)}}\label{class_modbus_afbbf7c81565d8e1ea1cd5890a96e7507} + + +Definition at line 218 of file Modbus\-Rtu.\-h. + +\hypertarget{class_modbus_a5e23a7b669d0c2d5be1c0054c7c54dca}{\index{Modbus@{Modbus}!Modbus@{Modbus}} +\index{Modbus@{Modbus}!Modbus@{Modbus}} +\subsubsection[{Modbus}]{\setlength{\rightskip}{0pt plus 5cm}Modbus\-::\-Modbus ( +\begin{DoxyParamCaption} +\item[{uint8\-\_\-t}]{u8id, } +\item[{uint8\-\_\-t}]{u8serno, } +\item[{uint8\-\_\-t}]{u8txenpin} +\end{DoxyParamCaption} +)}}\label{class_modbus_a5e23a7b669d0c2d5be1c0054c7c54dca} + + +Definition at line 234 of file Modbus\-Rtu.\-h. + + + +\subsection{Member Function Documentation} +\hypertarget{class_modbus_a4f9673a3d113c49af69cb87b030ef099}{\index{Modbus@{Modbus}!begin@{begin}} +\index{begin@{begin}!Modbus@{Modbus}} +\subsubsection[{begin}]{\setlength{\rightskip}{0pt plus 5cm}void Modbus\-::begin ( +\begin{DoxyParamCaption} +{} +\end{DoxyParamCaption} +)}}\label{class_modbus_a4f9673a3d113c49af69cb87b030ef099} + + +Definition at line 299 of file Modbus\-Rtu.\-h. + +\hypertarget{class_modbus_a0d80101b650344c712a085c4bb005c4c}{\index{Modbus@{Modbus}!end@{end}} +\index{end@{end}!Modbus@{Modbus}} +\subsubsection[{end}]{\setlength{\rightskip}{0pt plus 5cm}void Modbus\-::end ( +\begin{DoxyParamCaption} +{} +\end{DoxyParamCaption} +)}}\label{class_modbus_a0d80101b650344c712a085c4bb005c4c} + + +finish any communication and release serial communication port + +\hypertarget{class_modbus_ac860024db3117a2ef907d0325b2fb7a1}{\index{Modbus@{Modbus}!get\-Time\-Out@{get\-Time\-Out}} +\index{get\-Time\-Out@{get\-Time\-Out}!Modbus@{Modbus}} +\subsubsection[{get\-Time\-Out}]{\setlength{\rightskip}{0pt plus 5cm}uint16\-\_\-t Modbus\-::get\-Time\-Out ( +\begin{DoxyParamCaption} +{} +\end{DoxyParamCaption} +)}}\label{class_modbus_ac860024db3117a2ef907d0325b2fb7a1} + + +get communication watch-\/dog timer value + + + +The documentation for this class was generated from the following file\-:\begin{DoxyCompactItemize} +\item +\hyperlink{_modbus_rtu_8h}{Modbus\-Rtu.\-h}\end{DoxyCompactItemize} diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/doxygen.sty b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/doxygen.sty new file mode 100644 index 0000000..199abf8 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/doxygen.sty @@ -0,0 +1,464 @@ +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{doxygen} + +% Packages used by this style file +\RequirePackage{alltt} +\RequirePackage{array} +\RequirePackage{calc} +\RequirePackage{float} +\RequirePackage{ifthen} +\RequirePackage{verbatim} +\RequirePackage[table]{xcolor} +\RequirePackage{xtab} + +%---------- Internal commands used in this style file ---------------- + +\newcommand{\ensurespace}[1]{% + \begingroup% + \setlength{\dimen@}{#1}% + \vskip\z@\@plus\dimen@% + \penalty -100\vskip\z@\@plus -\dimen@% + \vskip\dimen@% + \penalty 9999% + \vskip -\dimen@% + \vskip\z@skip% hide the previous |\vskip| from |\addvspace| + \endgroup% +} + +\newcommand{\DoxyLabelFont}{} +\newcommand{\entrylabel}[1]{% + {% + \parbox[b]{\labelwidth-4pt}{% + \makebox[0pt][l]{\DoxyLabelFont#1}% + \vspace{1.5\baselineskip}% + }% + }% +} + +\newenvironment{DoxyDesc}[1]{% + \ensurespace{4\baselineskip}% + \begin{list}{}{% + \settowidth{\labelwidth}{20pt}% + \setlength{\parsep}{0pt}% + \setlength{\itemsep}{0pt}% + \setlength{\leftmargin}{\labelwidth+\labelsep}% + \renewcommand{\makelabel}{\entrylabel}% + }% + \item[#1]% +}{% + \end{list}% +} + +\newsavebox{\xrefbox} +\newlength{\xreflength} +\newcommand{\xreflabel}[1]{% + \sbox{\xrefbox}{#1}% + \setlength{\xreflength}{\wd\xrefbox}% + \ifthenelse{\xreflength>\labelwidth}{% + \begin{minipage}{\textwidth}% + \setlength{\parindent}{0pt}% + \hangindent=15pt\bfseries #1\vspace{1.2\itemsep}% + \end{minipage}% + }{% + \parbox[b]{\labelwidth}{\makebox[0pt][l]{\textbf{#1}}}% + }% +} + +%---------- Commands used by doxygen LaTeX output generator ---------- + +% Used by
 ... 
+\newenvironment{DoxyPre}{% + \small% + \begin{alltt}% +}{% + \end{alltt}% + \normalsize% +} + +% Used by @code ... @endcode +\newenvironment{DoxyCode}{% + \par% + \scriptsize% + \begin{alltt}% +}{% + \end{alltt}% + \normalsize% +} + +% Used by @example, @include, @includelineno and @dontinclude +\newenvironment{DoxyCodeInclude}{% + \DoxyCode% +}{% + \endDoxyCode% +} + +% Used by @verbatim ... @endverbatim +\newenvironment{DoxyVerb}{% + \footnotesize% + \verbatim% +}{% + \endverbatim% + \normalsize% +} + +% Used by @verbinclude +\newenvironment{DoxyVerbInclude}{% + \DoxyVerb% +}{% + \endDoxyVerb% +} + +% Used by numbered lists (using '-#' or
    ...
) +\newenvironment{DoxyEnumerate}{% + \enumerate% +}{% + \endenumerate% +} + +% Used by bullet lists (using '-', @li, @arg, or
    ...
) +\newenvironment{DoxyItemize}{% + \itemize% +}{% + \enditemize% +} + +% Used by description lists (using
...
) +\newenvironment{DoxyDescription}{% + \description% +}{% + \enddescription% +} + +% Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc +% (only if caption is specified) +\newenvironment{DoxyImage}{% + \begin{figure}[H]% + \begin{center}% +}{% + \end{center}% + \end{figure}% +} + +% Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc +% (only if no caption is specified) +\newenvironment{DoxyImageNoCaption}{% +}{% +} + +% Used by @attention +\newenvironment{DoxyAttention}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @author and @authors +\newenvironment{DoxyAuthor}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @date +\newenvironment{DoxyDate}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @invariant +\newenvironment{DoxyInvariant}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @note +\newenvironment{DoxyNote}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @post +\newenvironment{DoxyPostcond}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @pre +\newenvironment{DoxyPrecond}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @copyright +\newenvironment{DoxyCopyright}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @remark +\newenvironment{DoxyRemark}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @return and @returns +\newenvironment{DoxyReturn}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @since +\newenvironment{DoxySince}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @see +\newenvironment{DoxySeeAlso}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @version +\newenvironment{DoxyVersion}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @warning +\newenvironment{DoxyWarning}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @internal +\newenvironment{DoxyInternal}[1]{% + \paragraph*{#1}% +}{% +} + +% Used by @par and @paragraph +\newenvironment{DoxyParagraph}[1]{% + \begin{list}{}{% + \settowidth{\labelwidth}{40pt}% + \setlength{\leftmargin}{\labelwidth}% + \setlength{\parsep}{0pt}% + \setlength{\itemsep}{-4pt}% + \renewcommand{\makelabel}{\entrylabel}% + }% + \item[#1]% +}{% + \end{list}% +} + +% Used by parameter lists +\newenvironment{DoxyParams}[2][]{% + \par% + \tabletail{\hline}% + \tablelasttail{\hline}% + \tablefirsthead{}% + \tablehead{}% + \ifthenelse{\equal{#1}{}}% + {\tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]}% + \begin{xtabular}{|>{\raggedleft\hspace{0pt}}p{0.15\textwidth}|% + p{0.805\textwidth}|}}% + {\ifthenelse{\equal{#1}{1}}% + {\tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]}% + \begin{xtabular}{|>{\centering}p{0.10\textwidth}|% + >{\raggedleft\hspace{0pt}}p{0.15\textwidth}|% + p{0.678\textwidth}|}}% + {\tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]}% + \begin{xtabular}{|>{\centering}p{0.10\textwidth}|% + >{\centering\hspace{0pt}}p{0.15\textwidth}|% + >{\raggedleft\hspace{0pt}}p{0.15\textwidth}|% + p{0.501\textwidth}|}}% + }\hline% +}{% + \end{xtabular}% + \tablefirsthead{}% + \vspace{6pt}% +} + +% Used for fields of simple structs +\newenvironment{DoxyFields}[1]{% + \par% + \tabletail{\hline}% + \tablelasttail{\hline}% + \tablehead{}% + \tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]}% + \begin{xtabular}{|>{\raggedleft\hspace{0pt}}p{0.15\textwidth}|% + p{0.15\textwidth}|% + p{0.63\textwidth}|}% + \hline% +}{% + \end{xtabular}% + \tablefirsthead{}% + \vspace{6pt}% +} + +% Used for parameters within a detailed function description +\newenvironment{DoxyParamCaption}{% + \renewcommand{\item}[2][]{##1 {\em ##2}}% +}{% +} + +% Used by return value lists +\newenvironment{DoxyRetVals}[1]{% + \par% + \tabletail{\hline}% + \tablelasttail{\hline}% + \tablehead{}% + \tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]}% + \begin{xtabular}{|>{\raggedleft\hspace{0pt}}p{0.25\textwidth}|% + p{0.705\textwidth}|}% + \hline% +}{% + \end{xtabular}% + \tablefirsthead{}% + \vspace{6pt}% +} + +% Used by exception lists +\newenvironment{DoxyExceptions}[1]{% + \par% + \tabletail{\hline}% + \tablelasttail{\hline}% + \tablehead{}% + \tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]}% + \begin{xtabular}{|>{\raggedleft\hspace{0pt}}p{0.25\textwidth}|% + p{0.705\textwidth}|}% + \hline% +}{% + \end{xtabular}% + \tablefirsthead{}% + \vspace{6pt}% +} + +% Used by template parameter lists +\newenvironment{DoxyTemplParams}[1]{% + \par% + \tabletail{\hline}% + \tablelasttail{\hline}% + \tablehead{}% + \tablefirsthead{\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]}% + \begin{xtabular}{|>{\raggedleft\hspace{0pt}}p{0.25\textwidth}|% + p{0.705\textwidth}|}% + \hline% +}{% + \end{xtabular}% + \tablefirsthead{}% + \vspace{6pt}% +} + +% Used for member lists +\newenvironment{DoxyCompactItemize}{% + \begin{itemize}% + \setlength{\itemsep}{-3pt}% + \setlength{\parsep}{0pt}% + \setlength{\topsep}{0pt}% + \setlength{\partopsep}{0pt}% +}{% + \end{itemize}% +} + +% Used for member descriptions +\newenvironment{DoxyCompactList}{% + \begin{list}{}{% + \setlength{\leftmargin}{0.5cm}% + \setlength{\itemsep}{0pt}% + \setlength{\parsep}{0pt}% + \setlength{\topsep}{0pt}% + \renewcommand{\makelabel}{\hfill}% + }% +}{% + \end{list}% +} + +% Used for reference lists (@bug, @deprecated, @todo, etc.) +\newenvironment{DoxyRefList}{% + \begin{list}{}{% + \setlength{\labelwidth}{10pt}% + \setlength{\leftmargin}{\labelwidth}% + \addtolength{\leftmargin}{\labelsep}% + \renewcommand{\makelabel}{\xreflabel}% + }% +}{% + \end{list}% +} + +% Used by @bug, @deprecated, @todo, etc. +\newenvironment{DoxyRefDesc}[1]{% + \begin{list}{}{% + \renewcommand\makelabel[1]{\textbf{##1}}% + \settowidth\labelwidth{\makelabel{#1}}% + \setlength\leftmargin{\labelwidth+\labelsep}% + }% +}{% + \end{list}% +} + +% Used by parameter lists and simple sections +\newenvironment{Desc} +{\begin{list}{}{% + \settowidth{\labelwidth}{40pt}% + \setlength{\leftmargin}{\labelwidth}% + \setlength{\parsep}{0pt}% + \setlength{\itemsep}{-4pt}% + \renewcommand{\makelabel}{\entrylabel}% + } +}{% + \end{list}% +} + +% Used by tables +\newcommand{\PBS}[1]{\let\temp=\\#1\let\\=\temp}% +\newlength{\tmplength}% +\newenvironment{TabularC}[1]% +{% +\setlength{\tmplength}% + {\linewidth/(#1)-\tabcolsep*2-\arrayrulewidth*(#1+1)/(#1)}% + \par\begin{xtabular*}{\linewidth}% + {*{#1}{|>{\PBS\raggedright\hspace{0pt}}p{\the\tmplength}}|}% +}% +{\end{xtabular*}\par}% + +% Used for member group headers +\newenvironment{Indent}{% + \begin{list}{}{% + \setlength{\leftmargin}{0.5cm}% + }% + \item[]\ignorespaces% +}{% + \unskip% + \end{list}% +} + +% Used when hyperlinks are turned off +\newcommand{\doxyref}[3]{% + \textbf{#1} (\textnormal{#2}\,\pageref{#3})% +} + +% Used for syntax highlighting +\definecolor{comment}{rgb}{0.5,0.0,0.0} +\definecolor{keyword}{rgb}{0.0,0.5,0.0} +\definecolor{keywordtype}{rgb}{0.38,0.25,0.125} +\definecolor{keywordflow}{rgb}{0.88,0.5,0.0} +\definecolor{preprocessor}{rgb}{0.5,0.38,0.125} +\definecolor{stringliteral}{rgb}{0.0,0.125,0.25} +\definecolor{charliteral}{rgb}{0.0,0.5,0.5} +\definecolor{vhdldigit}{rgb}{1.0,0.0,1.0} +\definecolor{vhdlkeyword}{rgb}{0.43,0.0,0.43} +\definecolor{vhdllogic}{rgb}{1.0,0.0,0.0} +\definecolor{vhdlchar}{rgb}{0.0,0.0,0.0} diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/files.tex b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/files.tex new file mode 100644 index 0000000..1231238 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/files.tex @@ -0,0 +1,4 @@ +\section{File List} +Here is a list of all files with brief descriptions\-:\begin{DoxyCompactList} +\item\contentsline{section}{\hyperlink{_modbus_rtu_8h}{Modbus\-Rtu.\-h} }{\pageref{_modbus_rtu_8h}}{} +\end{DoxyCompactList} diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/group__buffer.tex b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/group__buffer.tex new file mode 100644 index 0000000..5121a77 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/group__buffer.tex @@ -0,0 +1,122 @@ +\hypertarget{group__buffer}{\section{Modbus Buffer Management} +\label{group__buffer}\index{Modbus Buffer Management@{Modbus Buffer Management}} +} +\subsection*{Functions} +\begin{DoxyCompactItemize} +\item +uint16\-\_\-t \hyperlink{group__buffer_ga4fa6ede8df85b7cc70b1282b9547378a}{Modbus\-::get\-In\-Cnt} () +\begin{DoxyCompactList}\small\item\em number of incoming messages \end{DoxyCompactList}\item +uint16\-\_\-t \hyperlink{group__buffer_ga6f831ecaf3678c27dafb663a28bf81f0}{Modbus\-::get\-Out\-Cnt} () +\begin{DoxyCompactList}\small\item\em number of outcoming messages \end{DoxyCompactList}\item +uint16\-\_\-t \hyperlink{group__buffer_ga6883c7f3ff12f084ed56d559d4e06ed0}{Modbus\-::get\-Err\-Cnt} () +\begin{DoxyCompactList}\small\item\em error counter \end{DoxyCompactList}\item +uint8\-\_\-t \hyperlink{group__buffer_ga2f39717d957a929af488c9120488fcdc}{Modbus\-::get\-State} () +\item +uint8\-\_\-t \hyperlink{group__buffer_gace7f726db13adc8feeceab987b719531}{Modbus\-::get\-Last\-Error} () +\begin{DoxyCompactList}\small\item\em get last error message \end{DoxyCompactList}\end{DoxyCompactItemize} + + +\subsection{Detailed Description} + + +\subsection{Function Documentation} +\hypertarget{group__buffer_ga6883c7f3ff12f084ed56d559d4e06ed0}{\index{Modbus Buffer Management@{Modbus Buffer Management}!get\-Err\-Cnt@{get\-Err\-Cnt}} +\index{get\-Err\-Cnt@{get\-Err\-Cnt}!Modbus Buffer Management@{Modbus Buffer Management}} +\subsubsection[{get\-Err\-Cnt}]{\setlength{\rightskip}{0pt plus 5cm}uint16\-\_\-t Modbus\-::get\-Err\-Cnt ( +\begin{DoxyParamCaption} +{} +\end{DoxyParamCaption} +)}}\label{group__buffer_ga6883c7f3ff12f084ed56d559d4e06ed0} + + +error counter + +Get errors counter value This can be useful to diagnose communication. + +\begin{DoxyReturn}{Returns} +errors counter +\end{DoxyReturn} + + +Definition at line 386 of file Modbus\-Rtu.\-h. + +\hypertarget{group__buffer_ga4fa6ede8df85b7cc70b1282b9547378a}{\index{Modbus Buffer Management@{Modbus Buffer Management}!get\-In\-Cnt@{get\-In\-Cnt}} +\index{get\-In\-Cnt@{get\-In\-Cnt}!Modbus Buffer Management@{Modbus Buffer Management}} +\subsubsection[{get\-In\-Cnt}]{\setlength{\rightskip}{0pt plus 5cm}uint16\-\_\-t Modbus\-::get\-In\-Cnt ( +\begin{DoxyParamCaption} +{} +\end{DoxyParamCaption} +)}}\label{group__buffer_ga4fa6ede8df85b7cc70b1282b9547378a} + + +number of incoming messages + +Get input messages counter value This can be useful to diagnose communication. + +\begin{DoxyReturn}{Returns} +input messages counter +\end{DoxyReturn} + + +Definition at line 362 of file Modbus\-Rtu.\-h. + +\hypertarget{group__buffer_gace7f726db13adc8feeceab987b719531}{\index{Modbus Buffer Management@{Modbus Buffer Management}!get\-Last\-Error@{get\-Last\-Error}} +\index{get\-Last\-Error@{get\-Last\-Error}!Modbus Buffer Management@{Modbus Buffer Management}} +\subsubsection[{get\-Last\-Error}]{\setlength{\rightskip}{0pt plus 5cm}uint8\-\_\-t Modbus\-::get\-Last\-Error ( +\begin{DoxyParamCaption} +{} +\end{DoxyParamCaption} +)}}\label{group__buffer_gace7f726db13adc8feeceab987b719531} + + +get last error message + +Get the last error in the protocol processor + +N\-O\-\_\-\-R\-E\-P\-L\-Y = 255 Time-\/out \begin{DoxyReturn}{Returns} +E\-X\-C\-\_\-\-F\-U\-N\-C\-\_\-\-C\-O\-D\-E = 1 Function code not available + +E\-X\-C\-\_\-\-A\-D\-D\-R\-\_\-\-R\-A\-N\-G\-E = 2 Address beyond available space for \hyperlink{class_modbus}{Modbus} registers + +E\-X\-C\-\_\-\-R\-E\-G\-S\-\_\-\-Q\-U\-A\-N\-T = 3 Coils or registers number beyond the available space +\end{DoxyReturn} + + +Definition at line 409 of file Modbus\-Rtu.\-h. + +\hypertarget{group__buffer_ga6f831ecaf3678c27dafb663a28bf81f0}{\index{Modbus Buffer Management@{Modbus Buffer Management}!get\-Out\-Cnt@{get\-Out\-Cnt}} +\index{get\-Out\-Cnt@{get\-Out\-Cnt}!Modbus Buffer Management@{Modbus Buffer Management}} +\subsubsection[{get\-Out\-Cnt}]{\setlength{\rightskip}{0pt plus 5cm}uint16\-\_\-t Modbus\-::get\-Out\-Cnt ( +\begin{DoxyParamCaption} +{} +\end{DoxyParamCaption} +)}}\label{group__buffer_ga6f831ecaf3678c27dafb663a28bf81f0} + + +number of outcoming messages + +Get transmitted messages counter value This can be useful to diagnose communication. + +\begin{DoxyReturn}{Returns} +transmitted messages counter +\end{DoxyReturn} + + +Definition at line 374 of file Modbus\-Rtu.\-h. + +\hypertarget{group__buffer_ga2f39717d957a929af488c9120488fcdc}{\index{Modbus Buffer Management@{Modbus Buffer Management}!get\-State@{get\-State}} +\index{get\-State@{get\-State}!Modbus Buffer Management@{Modbus Buffer Management}} +\subsubsection[{get\-State}]{\setlength{\rightskip}{0pt plus 5cm}uint8\-\_\-t Modbus\-::get\-State ( +\begin{DoxyParamCaption} +{} +\end{DoxyParamCaption} +)}}\label{group__buffer_ga2f39717d957a929af488c9120488fcdc} +Get modbus master state + +\begin{DoxyReturn}{Returns} += 0 I\-D\-L\-E, = 1 W\-A\-I\-T\-I\-N\-G F\-O\-R A\-N\-S\-W\-E\-R +\end{DoxyReturn} + + +Definition at line 396 of file Modbus\-Rtu.\-h. + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/group__discrete.tex b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/group__discrete.tex new file mode 100644 index 0000000..2406e3c --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/group__discrete.tex @@ -0,0 +1,6 @@ +\hypertarget{group__discrete}{\section{Modbus Function Codes for Discrete Coils/\-Inputs} +\label{group__discrete}\index{Modbus Function Codes for Discrete Coils/\-Inputs@{Modbus Function Codes for Discrete Coils/\-Inputs}} +} + + +\subsection{Detailed Description} diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/group__loop.tex b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/group__loop.tex new file mode 100644 index 0000000..ead71a6 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/group__loop.tex @@ -0,0 +1,117 @@ +\hypertarget{group__loop}{\section{Modbus Object Management} +\label{group__loop}\index{Modbus Object Management@{Modbus Object Management}} +} +\subsection*{Functions} +\begin{DoxyCompactItemize} +\item +boolean \hyperlink{group__loop_gaf6dd413191ed8a833022046873e0a063}{Modbus\-::get\-Time\-Out\-State} () +\begin{DoxyCompactList}\small\item\em get communication watch-\/dog timer state \end{DoxyCompactList}\item +int8\-\_\-t \hyperlink{group__loop_ga19398cabed57b6d085d014af6c149f54}{Modbus\-::query} (\hyperlink{structmodbus__t}{modbus\-\_\-t} telegram) +\begin{DoxyCompactList}\small\item\em only for master \end{DoxyCompactList}\item +int8\-\_\-t \hyperlink{group__loop_ga53bde78490c1cd8e3c070a676bdcfb0d}{Modbus\-::poll} () +\begin{DoxyCompactList}\small\item\em cyclic poll for master \end{DoxyCompactList}\item +int8\-\_\-t \hyperlink{group__loop_gab3ef20562fc8cee14fc85f7e276890b5}{Modbus\-::poll} (uint16\-\_\-t $\ast$regs, uint8\-\_\-t u8size) +\begin{DoxyCompactList}\small\item\em cyclic poll for slave \end{DoxyCompactList}\end{DoxyCompactItemize} + + +\subsection{Detailed Description} + + +\subsection{Function Documentation} +\hypertarget{group__loop_gaf6dd413191ed8a833022046873e0a063}{\index{Modbus Object Management@{Modbus Object Management}!get\-Time\-Out\-State@{get\-Time\-Out\-State}} +\index{get\-Time\-Out\-State@{get\-Time\-Out\-State}!Modbus Object Management@{Modbus Object Management}} +\subsubsection[{get\-Time\-Out\-State}]{\setlength{\rightskip}{0pt plus 5cm}boolean Modbus\-::get\-Time\-Out\-State ( +\begin{DoxyParamCaption} +{} +\end{DoxyParamCaption} +)}}\label{group__loop_gaf6dd413191ed8a833022046873e0a063} + + +get communication watch-\/dog timer state + +Return communication Watchdog state. It could be usefull to reset outputs if the watchdog is fired. + +\begin{DoxyReturn}{Returns} +T\-R\-U\-E if millis() $>$ u32time\-Out +\end{DoxyReturn} + + +Definition at line 350 of file Modbus\-Rtu.\-h. + +\hypertarget{group__loop_ga53bde78490c1cd8e3c070a676bdcfb0d}{\index{Modbus Object Management@{Modbus Object Management}!poll@{poll}} +\index{poll@{poll}!Modbus Object Management@{Modbus Object Management}} +\subsubsection[{poll}]{\setlength{\rightskip}{0pt plus 5cm}int8\-\_\-t Modbus\-::poll ( +\begin{DoxyParamCaption} +{} +\end{DoxyParamCaption} +)}}\label{group__loop_ga53bde78490c1cd8e3c070a676bdcfb0d} + + +cyclic poll for master + +$\ast$$\ast$$\ast$ Only for \hyperlink{class_modbus}{Modbus} Master $\ast$$\ast$$\ast$ This method checks if there is any incoming answer if pending. If there is no answer, it would change Master state to C\-O\-M\-\_\-\-I\-D\-L\-E. This method must be called only at loop section. Avoid any delay() function. + +Any incoming data would be redirected to au16regs pointer, as defined in its \hyperlink{structmodbus__t}{modbus\-\_\-t} query telegram. + +nothing \begin{DoxyReturn}{Returns} +errors counter +\end{DoxyReturn} + + +Definition at line 513 of file Modbus\-Rtu.\-h. + +\hypertarget{group__loop_gab3ef20562fc8cee14fc85f7e276890b5}{\index{Modbus Object Management@{Modbus Object Management}!poll@{poll}} +\index{poll@{poll}!Modbus Object Management@{Modbus Object Management}} +\subsubsection[{poll}]{\setlength{\rightskip}{0pt plus 5cm}int8\-\_\-t Modbus\-::poll ( +\begin{DoxyParamCaption} +\item[{uint16\-\_\-t $\ast$}]{regs, } +\item[{uint8\-\_\-t}]{u8size} +\end{DoxyParamCaption} +)}}\label{group__loop_gab3ef20562fc8cee14fc85f7e276890b5} + + +cyclic poll for slave + +$\ast$$\ast$$\ast$ Only for \hyperlink{class_modbus}{Modbus} Slave $\ast$$\ast$$\ast$ This method checks if there is any incoming query Afterwards, it would shoot a validation routine plus a register query Avoid any delay() function !!!! After a successful frame between the Master and the Slave, the time-\/out timer is reset. + + +\begin{DoxyParams}{Parameters} +{\em $\ast$regs} & register table for communication exchange \\ +\hline +{\em u8size} & size of the register table \\ +\hline +\end{DoxyParams} +\begin{DoxyReturn}{Returns} +0 if no query, 1..4 if communication error, $>$4 if correct query processed +\end{DoxyReturn} + + +Definition at line 588 of file Modbus\-Rtu.\-h. + +\hypertarget{group__loop_ga19398cabed57b6d085d014af6c149f54}{\index{Modbus Object Management@{Modbus Object Management}!query@{query}} +\index{query@{query}!Modbus Object Management@{Modbus Object Management}} +\subsubsection[{query}]{\setlength{\rightskip}{0pt plus 5cm}int8\-\_\-t Modbus\-::query ( +\begin{DoxyParamCaption} +\item[{{\bf modbus\-\_\-t}}]{telegram} +\end{DoxyParamCaption} +)}}\label{group__loop_ga19398cabed57b6d085d014af6c149f54} + + +only for master + +$\ast$$\ast$$\ast$ Only \hyperlink{class_modbus}{Modbus} Master $\ast$$\ast$$\ast$ Generate a query to an slave with a \hyperlink{structmodbus__t}{modbus\-\_\-t} telegram structure The Master must be in C\-O\-M\-\_\-\-I\-D\-L\-E mode. After it, its state would be C\-O\-M\-\_\-\-W\-A\-I\-T\-I\-N\-G. This method has to be called only in loop() section. + +\begin{DoxySeeAlso}{See Also} +\hyperlink{structmodbus__t}{modbus\-\_\-t} +\end{DoxySeeAlso} + +\begin{DoxyParams}{Parameters} +{\em \hyperlink{structmodbus__t}{modbus\-\_\-t}} & modbus telegram structure (id, fct, ...)\\ +\hline +\end{DoxyParams} +\begin{DoxyRefDesc}{Todo} +\item[\hyperlink{todo__todo000001}{Todo}]finish function 15 \end{DoxyRefDesc} + + +Definition at line 425 of file Modbus\-Rtu.\-h. + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/group__register.tex b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/group__register.tex new file mode 100644 index 0000000..2127655 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/group__register.tex @@ -0,0 +1,6 @@ +\hypertarget{group__register}{\section{Modbus Function Codes for Holding/\-Input Registers} +\label{group__register}\index{Modbus Function Codes for Holding/\-Input Registers@{Modbus Function Codes for Holding/\-Input Registers}} +} + + +\subsection{Detailed Description} diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/group__setup.tex b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/group__setup.tex new file mode 100644 index 0000000..4c9fbd4 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/group__setup.tex @@ -0,0 +1,130 @@ +\hypertarget{group__setup}{\section{Modbus Object Instantiation/\-Initialization} +\label{group__setup}\index{Modbus Object Instantiation/\-Initialization@{Modbus Object Instantiation/\-Initialization}} +} +\subsection*{Functions} +\begin{DoxyCompactItemize} +\item +\hyperlink{group__setup_ga101809cdd4734537bab58dc315a840b4}{Modbus\-::\-Modbus} () +\begin{DoxyCompactList}\small\item\em Default Constructor for Master through Serial. \end{DoxyCompactList}\item +void \hyperlink{group__setup_ga475a4fa0fac491307b10c4529ad6d2a0}{Modbus\-::begin} (long u32speed) +\begin{DoxyCompactList}\small\item\em Initialize class object. \end{DoxyCompactList}\item +void \hyperlink{group__setup_ga9bd497e97ac1777d4f0d4171078d60e0}{Modbus\-::set\-I\-D} (uint8\-\_\-t u8id) +\begin{DoxyCompactList}\small\item\em write new I\-D for the slave \end{DoxyCompactList}\item +uint8\-\_\-t \hyperlink{group__setup_ga6449894306ff8cc5d4caff09b1b0d1ce}{Modbus\-::get\-I\-D} () +\begin{DoxyCompactList}\small\item\em get slave I\-D between 1 and 247 \end{DoxyCompactList}\item +void \hyperlink{group__setup_gaf828190ebe24efb1b3b1957429f3872e}{Modbus\-::set\-Time\-Out} (uint16\-\_\-t u16timeout) +\begin{DoxyCompactList}\small\item\em write communication watch-\/dog timer \end{DoxyCompactList}\end{DoxyCompactItemize} + + +\subsection{Detailed Description} + + +\subsection{Function Documentation} +\hypertarget{group__setup_ga475a4fa0fac491307b10c4529ad6d2a0}{\index{Modbus Object Instantiation/\-Initialization@{Modbus Object Instantiation/\-Initialization}!begin@{begin}} +\index{begin@{begin}!Modbus Object Instantiation/Initialization@{Modbus Object Instantiation/\-Initialization}} +\subsubsection[{begin}]{\setlength{\rightskip}{0pt plus 5cm}void Modbus\-::begin ( +\begin{DoxyParamCaption} +\item[{long}]{u32speed} +\end{DoxyParamCaption} +)}}\label{group__setup_ga475a4fa0fac491307b10c4529ad6d2a0} + + +Initialize class object. + +Sets up the serial port using specified baud rate. Call once class has been instantiated, typically within setup(). + +\begin{DoxySeeAlso}{See Also} +\href{http://arduino.cc/en/Serial/Begin#.Uy4CJ6aKlHY}{\tt http\-://arduino.\-cc/en/\-Serial/\-Begin\#.\-Uy4\-C\-J6a\-Kl\-H\-Y} +\end{DoxySeeAlso} + +\begin{DoxyParams}{Parameters} +{\em speed} & baud rate, in standard increments (300..115200) \\ +\hline +{\em config} & data frame settings (data length, parity and stop bits) \\ +\hline +\end{DoxyParams} + + +Definition at line 250 of file Modbus\-Rtu.\-h. + +\hypertarget{group__setup_ga6449894306ff8cc5d4caff09b1b0d1ce}{\index{Modbus Object Instantiation/\-Initialization@{Modbus Object Instantiation/\-Initialization}!get\-I\-D@{get\-I\-D}} +\index{get\-I\-D@{get\-I\-D}!Modbus Object Instantiation/Initialization@{Modbus Object Instantiation/\-Initialization}} +\subsubsection[{get\-I\-D}]{\setlength{\rightskip}{0pt plus 5cm}uint8\-\_\-t Modbus\-::get\-I\-D ( +\begin{DoxyParamCaption} +{} +\end{DoxyParamCaption} +)}}\label{group__setup_ga6449894306ff8cc5d4caff09b1b0d1ce} + + +get slave I\-D between 1 and 247 + +Method to read current slave I\-D address. + +\begin{DoxyReturn}{Returns} +u8id current slave address between 1 and 247 +\end{DoxyReturn} + + +Definition at line 323 of file Modbus\-Rtu.\-h. + +\hypertarget{group__setup_ga101809cdd4734537bab58dc315a840b4}{\index{Modbus Object Instantiation/\-Initialization@{Modbus Object Instantiation/\-Initialization}!Modbus@{Modbus}} +\index{Modbus@{Modbus}!Modbus Object Instantiation/Initialization@{Modbus Object Instantiation/\-Initialization}} +\subsubsection[{Modbus}]{\setlength{\rightskip}{0pt plus 5cm}Modbus\-::\-Modbus ( +\begin{DoxyParamCaption} +{} +\end{DoxyParamCaption} +)}}\label{group__setup_ga101809cdd4734537bab58dc315a840b4} + + +Default Constructor for Master through Serial. + + + +Definition at line 204 of file Modbus\-Rtu.\-h. + +\hypertarget{group__setup_ga9bd497e97ac1777d4f0d4171078d60e0}{\index{Modbus Object Instantiation/\-Initialization@{Modbus Object Instantiation/\-Initialization}!set\-I\-D@{set\-I\-D}} +\index{set\-I\-D@{set\-I\-D}!Modbus Object Instantiation/Initialization@{Modbus Object Instantiation/\-Initialization}} +\subsubsection[{set\-I\-D}]{\setlength{\rightskip}{0pt plus 5cm}void Modbus\-::set\-I\-D ( +\begin{DoxyParamCaption} +\item[{uint8\-\_\-t}]{u8id} +\end{DoxyParamCaption} +)}}\label{group__setup_ga9bd497e97ac1777d4f0d4171078d60e0} + + +write new I\-D for the slave + +Method to write a new slave I\-D address. + + +\begin{DoxyParams}{Parameters} +{\em u8id} & new slave address between 1 and 247 \\ +\hline +\end{DoxyParams} + + +Definition at line 310 of file Modbus\-Rtu.\-h. + +\hypertarget{group__setup_gaf828190ebe24efb1b3b1957429f3872e}{\index{Modbus Object Instantiation/\-Initialization@{Modbus Object Instantiation/\-Initialization}!set\-Time\-Out@{set\-Time\-Out}} +\index{set\-Time\-Out@{set\-Time\-Out}!Modbus Object Instantiation/Initialization@{Modbus Object Instantiation/\-Initialization}} +\subsubsection[{set\-Time\-Out}]{\setlength{\rightskip}{0pt plus 5cm}void Modbus\-::set\-Time\-Out ( +\begin{DoxyParamCaption} +\item[{uint16\-\_\-t}]{u16time\-Out} +\end{DoxyParamCaption} +)}}\label{group__setup_gaf828190ebe24efb1b3b1957429f3872e} + + +write communication watch-\/dog timer + +Initialize time-\/out parameter. + +Call once class has been instantiated, typically within setup(). The time-\/out timer is reset each time that there is a successful communication between Master and Slave. It works for both. + + +\begin{DoxyParams}{Parameters} +{\em time-\/out} & value (ms) \\ +\hline +\end{DoxyParams} + + +Definition at line 338 of file Modbus\-Rtu.\-h. + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/modules.tex b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/modules.tex new file mode 100644 index 0000000..00365d6 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/modules.tex @@ -0,0 +1,8 @@ +\section{Modules} +Here is a list of all modules\-:\begin{DoxyCompactList} +\item \contentsline{section}{Modbus Object Instantiation/\-Initialization}{\pageref{group__setup}}{} +\item \contentsline{section}{Modbus Object Management}{\pageref{group__loop}}{} +\item \contentsline{section}{Modbus Buffer Management}{\pageref{group__buffer}}{} +\item \contentsline{section}{Modbus Function Codes for Discrete Coils/\-Inputs}{\pageref{group__discrete}}{} +\item \contentsline{section}{Modbus Function Codes for Holding/\-Input Registers}{\pageref{group__register}}{} +\end{DoxyCompactList} diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/refman.tex b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/refman.tex new file mode 100644 index 0000000..6845e48 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/refman.tex @@ -0,0 +1,162 @@ +\documentclass[twoside]{book} + +% Packages required by doxygen +\usepackage{calc} +\usepackage{doxygen} +\usepackage{graphicx} +\usepackage[utf8]{inputenc} +\usepackage{makeidx} +\usepackage{multicol} +\usepackage{multirow} +\usepackage{textcomp} +\usepackage[table]{xcolor} + +% Font selection +\usepackage[T1]{fontenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{amssymb} +\usepackage{sectsty} +\renewcommand{\familydefault}{\sfdefault} +\allsectionsfont{% + \fontseries{bc}\selectfont% + \color{darkgray}% +} +\renewcommand{\DoxyLabelFont}{% + \fontseries{bc}\selectfont% + \color{darkgray}% +} + +% Page & text layout +\usepackage{geometry} +\geometry{% + a4paper,% + top=2.5cm,% + bottom=2.5cm,% + left=2.5cm,% + right=2.5cm% +} +\tolerance=750 +\hfuzz=15pt +\hbadness=750 +\setlength{\emergencystretch}{15pt} +\setlength{\parindent}{0cm} +\setlength{\parskip}{0.2cm} +\makeatletter +\renewcommand{\paragraph}{% + \@startsection{paragraph}{4}{0ex}{-1.0ex}{1.0ex}{% + \normalfont\normalsize\bfseries\SS@parafont% + }% +} +\renewcommand{\subparagraph}{% + \@startsection{subparagraph}{5}{0ex}{-1.0ex}{1.0ex}{% + \normalfont\normalsize\bfseries\SS@subparafont% + }% +} +\makeatother + +% Headers & footers +\usepackage{fancyhdr} +\pagestyle{fancyplain} +\fancyhead[LE]{\fancyplain{}{\bfseries\thepage}} +\fancyhead[CE]{\fancyplain{}{}} +\fancyhead[RE]{\fancyplain{}{\bfseries\leftmark}} +\fancyhead[LO]{\fancyplain{}{\bfseries\rightmark}} +\fancyhead[CO]{\fancyplain{}{}} +\fancyhead[RO]{\fancyplain{}{\bfseries\thepage}} +\fancyfoot[LE]{\fancyplain{}{}} +\fancyfoot[CE]{\fancyplain{}{}} +\fancyfoot[RE]{\fancyplain{}{\bfseries\scriptsize Generated on Tue Sep 9 2014 21:52:15 for Modbus Master and Slave for Arduino by Doxygen }} +\fancyfoot[LO]{\fancyplain{}{\bfseries\scriptsize Generated on Tue Sep 9 2014 21:52:15 for Modbus Master and Slave for Arduino by Doxygen }} +\fancyfoot[CO]{\fancyplain{}{}} +\fancyfoot[RO]{\fancyplain{}{}} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\chaptermark}[1]{% + \markboth{#1}{}% +} +\renewcommand{\sectionmark}[1]{% + \markright{\thesection\ #1}% +} + +% Indices & bibliography +\usepackage{natbib} +\usepackage[titles]{tocloft} +\setcounter{tocdepth}{3} +\setcounter{secnumdepth}{5} +\makeindex + +% Hyperlinks (required, but should be loaded last) +\usepackage{ifpdf} +\ifpdf + \usepackage[pdftex,pagebackref=true]{hyperref} +\else + \usepackage[ps2pdf,pagebackref=true]{hyperref} +\fi +\hypersetup{% + colorlinks=true,% + linkcolor=blue,% + citecolor=blue,% + unicode% +} + +% Custom commands +\newcommand{\clearemptydoublepage}{% + \newpage{\pagestyle{empty}\cleardoublepage}% +} + + +%===== C O N T E N T S ===== + +\begin{document} + +% Titlepage & ToC +\hypersetup{pageanchor=false} +\pagenumbering{roman} +\begin{titlepage} +\vspace*{7cm} +\begin{center}% +{\Large Modbus Master and Slave for Arduino \\[1ex]\large 1.\-2 }\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.4}\\ +\vspace*{0.5cm} +{\small Tue Sep 9 2014 21:52:15}\\ +\end{center} +\end{titlepage} +\clearemptydoublepage +\tableofcontents +\clearemptydoublepage +\pagenumbering{arabic} +\hypersetup{pageanchor=true} + +%--- Begin generated contents --- +\chapter{Todo List} +\label{todo} +\hypertarget{todo}{} +\input{todo} +\chapter{Module Index} +\input{modules} +\chapter{Class Index} +\input{annotated} +\chapter{File Index} +\input{files} +\chapter{Module Documentation} +\input{group__setup} +\include{group__loop} +\include{group__buffer} +\include{group__discrete} +\include{group__register} +\chapter{Class Documentation} +\input{class_modbus} +\input{structmodbus__t} +\chapter{File Documentation} +\input{_modbus_rtu_8h} +%--- End generated contents --- + +% Index +\newpage +\phantomsection +\addcontentsline{toc}{part}{Index} +\printindex + +\end{document} diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/structmodbus__t.tex b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/structmodbus__t.tex new file mode 100644 index 0000000..17ed743 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/structmodbus__t.tex @@ -0,0 +1,75 @@ +\hypertarget{structmodbus__t}{\section{modbus\-\_\-t Struct Reference} +\label{structmodbus__t}\index{modbus\-\_\-t@{modbus\-\_\-t}} +} + + +Master query structure\-: This includes all the necessary fields to make the Master generate a \hyperlink{class_modbus}{Modbus} query. A Master may keep several of these structures and send them cyclically or use them according to program needs. + + + + +{\ttfamily \#include $<$Modbus\-Rtu.\-h$>$} + +\subsection*{Public Attributes} +\begin{DoxyCompactItemize} +\item +uint8\-\_\-t \hyperlink{structmodbus__t_af78ad11f93e63022a1c279de7206358c}{u8id} +\item +uint8\-\_\-t \hyperlink{structmodbus__t_a57d1630d4548e5d50d79e206a48b09bc}{u8fct} +\item +uint16\-\_\-t \hyperlink{structmodbus__t_a224ead9ff72467696e94fba9cf06bd3c}{u16\-Reg\-Add} +\item +uint16\-\_\-t \hyperlink{structmodbus__t_a5b9cee9c1a9415d927543f6cf054eb43}{u16\-Coils\-No} +\item +uint16\-\_\-t $\ast$ \hyperlink{structmodbus__t_a36212dd6316cbffb8ea31b2a2f5ae1be}{au16reg} +\end{DoxyCompactItemize} + + +\subsection{Detailed Description} +Master query structure\-: This includes all the necessary fields to make the Master generate a \hyperlink{class_modbus}{Modbus} query. A Master may keep several of these structures and send them cyclically or use them according to program needs. + +Definition at line 48 of file Modbus\-Rtu.\-h. + + + +\subsection{Member Data Documentation} +\hypertarget{structmodbus__t_a36212dd6316cbffb8ea31b2a2f5ae1be}{\index{modbus\-\_\-t@{modbus\-\_\-t}!au16reg@{au16reg}} +\index{au16reg@{au16reg}!modbus_t@{modbus\-\_\-t}} +\subsubsection[{au16reg}]{\setlength{\rightskip}{0pt plus 5cm}uint16\-\_\-t$\ast$ modbus\-\_\-t\-::au16reg}}\label{structmodbus__t_a36212dd6316cbffb8ea31b2a2f5ae1be} +Pointer to memory image in master + +Definition at line 53 of file Modbus\-Rtu.\-h. + +\hypertarget{structmodbus__t_a5b9cee9c1a9415d927543f6cf054eb43}{\index{modbus\-\_\-t@{modbus\-\_\-t}!u16\-Coils\-No@{u16\-Coils\-No}} +\index{u16\-Coils\-No@{u16\-Coils\-No}!modbus_t@{modbus\-\_\-t}} +\subsubsection[{u16\-Coils\-No}]{\setlength{\rightskip}{0pt plus 5cm}uint16\-\_\-t modbus\-\_\-t\-::u16\-Coils\-No}}\label{structmodbus__t_a5b9cee9c1a9415d927543f6cf054eb43} +Number of coils or registers to access + +Definition at line 52 of file Modbus\-Rtu.\-h. + +\hypertarget{structmodbus__t_a224ead9ff72467696e94fba9cf06bd3c}{\index{modbus\-\_\-t@{modbus\-\_\-t}!u16\-Reg\-Add@{u16\-Reg\-Add}} +\index{u16\-Reg\-Add@{u16\-Reg\-Add}!modbus_t@{modbus\-\_\-t}} +\subsubsection[{u16\-Reg\-Add}]{\setlength{\rightskip}{0pt plus 5cm}uint16\-\_\-t modbus\-\_\-t\-::u16\-Reg\-Add}}\label{structmodbus__t_a224ead9ff72467696e94fba9cf06bd3c} +Address of the first register to access at slave/s + +Definition at line 51 of file Modbus\-Rtu.\-h. + +\hypertarget{structmodbus__t_a57d1630d4548e5d50d79e206a48b09bc}{\index{modbus\-\_\-t@{modbus\-\_\-t}!u8fct@{u8fct}} +\index{u8fct@{u8fct}!modbus_t@{modbus\-\_\-t}} +\subsubsection[{u8fct}]{\setlength{\rightskip}{0pt plus 5cm}uint8\-\_\-t modbus\-\_\-t\-::u8fct}}\label{structmodbus__t_a57d1630d4548e5d50d79e206a48b09bc} +Function code\-: 1, 2, 3, 4, 5, 6, 15 or 16 + +Definition at line 50 of file Modbus\-Rtu.\-h. + +\hypertarget{structmodbus__t_af78ad11f93e63022a1c279de7206358c}{\index{modbus\-\_\-t@{modbus\-\_\-t}!u8id@{u8id}} +\index{u8id@{u8id}!modbus_t@{modbus\-\_\-t}} +\subsubsection[{u8id}]{\setlength{\rightskip}{0pt plus 5cm}uint8\-\_\-t modbus\-\_\-t\-::u8id}}\label{structmodbus__t_af78ad11f93e63022a1c279de7206358c} +Slave address between 1 and 247. 0 means broadcast + +Definition at line 49 of file Modbus\-Rtu.\-h. + + + +The documentation for this struct was generated from the following file\-:\begin{DoxyCompactItemize} +\item +\hyperlink{_modbus_rtu_8h}{Modbus\-Rtu.\-h}\end{DoxyCompactItemize} diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/todo.tex b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/todo.tex new file mode 100644 index 0000000..f715559 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/latex/todo.tex @@ -0,0 +1,6 @@ + +\begin{DoxyRefList} +\item[\label{todo__todo000001}% +\hypertarget{todo__todo000001}{}% +Member \hyperlink{group__loop_ga19398cabed57b6d085d014af6c149f54}{Modbus\-:\-:query} (\hyperlink{structmodbus__t}{modbus\-\_\-t} telegram)]finish function 15 +\end{DoxyRefList} \ No newline at end of file diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/rtf/refman.rtf b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/rtf/refman.rtf new file mode 100644 index 0000000..105c995 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/documentation/rtf/refman.rtf @@ -0,0 +1,1546 @@ +{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033 +{\fonttbl {\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;} +{\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;} +{\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;} +} +{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;} +{\stylesheet +{\widctlpar\adjustright \fs20\cgrid \snext0 Normal;} +{\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid \sbasedon0 \snext0 heading 1;} +{\s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid \sbasedon0 \snext0 heading 2;} +{\s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid \sbasedon0 \snext0 heading 3;} +{\s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid \sbasedon0 \snext0 heading 4;}{\*\cs10 \additive Default Paragraph Font;} +{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid \sbasedon0 \snext0 heading 5;}{\*\cs10 \additive Default Paragraph Font;} +{\s15\qc\sb240\sa60\widctlpar\outlinelevel0\adjustright \b\f1\fs32\kerning28\cgrid \sbasedon0 \snext15 Title;} +{\s16\qc\sa60\widctlpar\outlinelevel1\adjustright \f1\cgrid \sbasedon0 \snext16 Subtitle;} +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid \sbasedon0 \snext17 BodyText;} +{\s18\widctlpar\fs22\cgrid \sbasedon0 \snext18 DenseText;} +{\s28\widctlpar\tqc\tx4320\tqr\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext28 header;} +{\s29\widctlpar\tqc\tx4320\tqr\tx8640\qr\adjustright \fs20\cgrid \sbasedon0 \snext29 footer;} +{\s30\li360\sa60\sb120\keepn\widctlpar\adjustright \b\f1\fs20\cgrid \sbasedon0 \snext30 GroupHeader;} +{\s40\li0\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext41 Code Example 0;} +{\s41\li360\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext42 Code Example 1;} +{\s42\li720\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext43 Code Example 2;} +{\s43\li1080\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext44 Code Example 3;} +{\s44\li1440\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext45 Code Example 4;} +{\s45\li1800\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext46 Code Example 5;} +{\s46\li2160\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext47 Code Example 6;} +{\s47\li2520\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext48 Code Example 7;} +{\s48\li2880\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext49 Code Example 8;} +{\s49\li3240\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext49 Code Example 9;} +{\s50\li0\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext51 List Continue 0;} +{\s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext52 List Continue 1;} +{\s52\li720\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext53 List Continue 2;} +{\s53\li1080\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext54 List Continue 3;} +{\s54\li1440\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext55 List Continue 4;} +{\s55\li1800\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext56 List Continue 5;} +{\s56\li2160\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext57 List Continue 6;} +{\s57\li2520\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext58 List Continue 7;} +{\s58\li2880\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext59 List Continue 8;} +{\s59\li3240\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext59 List Continue 9;} +{\s60\li0\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext61 DescContinue 0;} +{\s61\li360\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext62 DescContinue 1;} +{\s62\li720\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext63 DescContinue 2;} +{\s63\li1080\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext64 DescContinue 3;} +{\s64\li1440\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext65 DescContinue 4;} +{\s65\li1800\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext66 DescContinue 5;} +{\s66\li2160\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext67 DescContinue 6;} +{\s67\li2520\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext68 DescContinue 7;} +{\s68\li2880\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext69 DescContinue 8;} +{\s69\li3240\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext69 DescContinue 9;} +{\s70\li0\sa30\sb30\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext81 LatexTOC 0;} +{\s71\li360\sa27\sb27\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext82 LatexTOC 1;} +{\s72\li720\sa24\sb24\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext83 LatexTOC 2;} +{\s73\li1080\sa21\sb21\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext84 LatexTOC 3;} +{\s74\li1440\sa18\sb18\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext85 LatexTOC 4;} +{\s75\li1800\sa15\sb15\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext86 LatexTOC 5;} +{\s76\li2160\sa12\sb12\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext87 LatexTOC 6;} +{\s77\li2520\sa9\sb9\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext88 LatexTOC 7;} +{\s78\li2880\sa6\sb6\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext89 LatexTOC 8;} +{\s79\li3240\sa3\sb3\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext89 LatexTOC 9;} +{\s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid \sbasedon0 \snext81 \sautoupd List Bullet 0;} +{\s81\fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec }\ls2\adjustright \fs20\cgrid \sbasedon0 \snext82 \sautoupd List Bullet 1;} +{\s82\fi-360\li1080\widctlpar\jclisttab\tx1080{\*\pn \pnlvlbody\ilvl0\ls3\pnrnot0\pndec }\ls3\adjustright \fs20\cgrid \sbasedon0 \snext83 \sautoupd List Bullet 2;} +{\s83\fi-360\li1440\widctlpar\jclisttab\tx1440{\*\pn \pnlvlbody\ilvl0\ls4\pnrnot0\pndec }\ls4\adjustright \fs20\cgrid \sbasedon0 \snext84 \sautoupd List Bullet 3;} +{\s84\fi-360\li1800\widctlpar\jclisttab\tx1800{\*\pn \pnlvlbody\ilvl0\ls5\pnrnot0\pndec }\ls5\adjustright \fs20\cgrid \sbasedon0 \snext85 \sautoupd List Bullet 4;} +{\s85\fi-360\li2160\widctlpar\jclisttab\tx2160{\*\pn \pnlvlbody\ilvl0\ls6\pnrnot0\pndec }\ls6\adjustright \fs20\cgrid \sbasedon0 \snext86 \sautoupd List Bullet 5;} +{\s86\fi-360\li2520\widctlpar\jclisttab\tx2520{\*\pn \pnlvlbody\ilvl0\ls7\pnrnot0\pndec }\ls7\adjustright \fs20\cgrid \sbasedon0 \snext87 \sautoupd List Bullet 6;} +{\s87\fi-360\li2880\widctlpar\jclisttab\tx2880{\*\pn \pnlvlbody\ilvl0\ls8\pnrnot0\pndec }\ls8\adjustright \fs20\cgrid \sbasedon0 \snext88 \sautoupd List Bullet 7;} +{\s88\fi-360\li3240\widctlpar\jclisttab\tx3240{\*\pn \pnlvlbody\ilvl0\ls9\pnrnot0\pndec }\ls9\adjustright \fs20\cgrid \sbasedon0 \snext89 \sautoupd List Bullet 8;} +{\s89\fi-360\li3600\widctlpar\jclisttab\tx3600{\*\pn \pnlvlbody\ilvl0\ls10\pnrnot0\pndec }\ls10\adjustright \fs20\cgrid \sbasedon0 \snext89 \sautoupd List Bullet 9;} +{\s90\fi-360\li360\widctlpar\fs20\cgrid \sbasedon0 \snext91 \sautoupd List Enum 0;} +{\s91\fi-360\li720\widctlpar\fs20\cgrid \sbasedon0 \snext92 \sautoupd List Enum 1;} +{\s92\fi-360\li1080\widctlpar\fs20\cgrid \sbasedon0 \snext93 \sautoupd List Enum 2;} +{\s93\fi-360\li1440\widctlpar\fs20\cgrid \sbasedon0 \snext94 \sautoupd List Enum 3;} +{\s94\fi-360\li1800\widctlpar\fs20\cgrid \sbasedon0 \snext95 \sautoupd List Enum 4;} +{\s95\fi-360\li2160\widctlpar\fs20\cgrid \sbasedon0 \snext96 \sautoupd List Enum 5;} +{\s96\fi-360\li2520\widctlpar\fs20\cgrid \sbasedon0 \snext96 \sautoupd List Enum 5;} +{\s97\fi-360\li2880\widctlpar\fs20\cgrid \sbasedon0 \snext98 \sautoupd List Enum 7;} +{\s98\fi-360\li3240\widctlpar\fs20\cgrid \sbasedon0 \snext99 \sautoupd List Enum 8;} +{\s99\fi-360\li3600\widctlpar\fs20\cgrid \sbasedon0 \snext99 \sautoupd List Enum 9;} +} +{\comment begin body} +{\info +{\title {\comment Modbus Master and Slave for Arduino {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +1.2 \par +}}Modbus Master and Slave for Arduino} +{\comment Generated byDoxgyen. } +{\creatim \yr2014\mo9\dy9\hr21\min52\sec15} +}\pard\plain +\sectd\pgnlcrm +{\footer \s29\widctlpar\tqc\tx4320\tqr\tx8640\qr\adjustright \fs20\cgrid {\chpgn}} +\pard\plain \s16\qc\sa60\widctlpar\outlinelevel1\adjustright \f1\cgrid +\vertalc\qc\par\par\par\par\par\par\par +\pard\plain \s15\qc\sb240\sa60\widctlpar\outlinelevel0\adjustright \b\f1\fs32\kerning28\cgrid +{\field\fldedit {\*\fldinst TITLE \\*MERGEFORMAT}{\fldrslt TITLE}}\par +\pard\plain \s16\qc\sa60\widctlpar\outlinelevel1\adjustright \f1\cgrid +\par +\par\par\par\par\par\par\par\par\par\par\par\par +\pard\plain \s16\qc\sa60\widctlpar\outlinelevel1\adjustright \f1\cgrid +{\field\fldedit {\*\fldinst AUTHOR \\*MERGEFORMAT}{\fldrslt AUTHOR}}\par +Version 1.2\par{\field\fldedit {\*\fldinst CREATEDATE \\*MERGEFORMAT}{\fldrslt CREATEDATE}}\par +\page\page\vertalt +\pard\plain +\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid Table of Contents\par +\pard\plain \par +{\field\fldedit {\*\fldinst TOC \\f \\*MERGEFORMAT}{\fldrslt Table of contents}}\par +\pard\plain +\sect \sbkpage \pgndec \pgnrestart +\sect \sectd \sbknone +{\footer \s29\widctlpar\tqc\tx4320\tqr\tx8640\qr\adjustright \fs20\cgrid {\chpgn}} + +\pard\plain \sect\sbkpage +\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid +Todo List{\tc \v Todo List}\par \pard\plain +{\bkmkstart AAAAAAAACV} +{\bkmkend AAAAAAAACV} +\par \pard\plain +{ +\pard\plain \s17\sa60\sb30\widctlpar\qj \fs22\cgrid {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +{\bkmkstart AAAAAAAABP} +{\bkmkend AAAAAAAABP} +Member {\b Modbus::query} ({\b modbus_t} telegram)\par +} +{\pard\plain \s61\li360\widctlpar\ql\adjustright \fs20\cgrid finish function 15 \par} +}} + +\pard\plain \sect\sbkpage +\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid +Module Index\par \pard\plain +{\tc \v Module Index} +\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid +Modules\par \pard\plain +{ +\pard\plain \s17\sa60\sb30\widctlpar\qj \fs22\cgrid Here is a list of all modules:} +{ +\par +\pard\plain \s71\li360\sa27\sb27\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid +Modbus Object Instantiation/Initialization\tab {\field\fldedit {\*\fldinst PAGEREF AAAAAAAABQ \\*MERGEFORMAT}{\fldrslt pagenum}} +\par +Modbus Object Management\tab {\field\fldedit {\*\fldinst PAGEREF AAAAAAAABW \\*MERGEFORMAT}{\fldrslt pagenum}} +\par +Modbus Buffer Management\tab {\field\fldedit {\*\fldinst PAGEREF AAAAAAAACB \\*MERGEFORMAT}{\fldrslt pagenum}} +\par +Modbus Function Codes for Discrete Coils/Inputs\tab {\field\fldedit {\*\fldinst PAGEREF AAAAAAAACH \\*MERGEFORMAT}{\fldrslt pagenum}} +\par +Modbus Function Codes for Holding/Input Registers\tab {\field\fldedit {\*\fldinst PAGEREF AAAAAAAACI \\*MERGEFORMAT}{\fldrslt pagenum}} +\par +} +\pard\plain \sect\sbkpage +\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid +Class Index\par \pard\plain +{\tc \v Class Index} +\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid +Class List\par \pard\plain +{ +\pard\plain \s17\sa60\sb30\widctlpar\qj \fs22\cgrid Here are the classes, structs, unions and interfaces with brief descriptions:} +{ +\par +\pard\plain \s71\li360\sa27\sb27\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid +{\b {\b Modbus} ({\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Arduino class library for communicating with {\b Modbus} devices over USB/RS232/485 (via RTU protocol) })} \tab {\field\fldedit {\*\fldinst PAGEREF AAAAAAAACJ \\*MERGEFORMAT}{\fldrslt pagenum}} +\par +{\b {\b modbus_t} ({\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Master query structure: This includes all the necessary fields to make the Master generate a {\b Modbus} query. A Master may keep several of these structures and send them cyclically or use them according to program needs })} \tab {\field\fldedit {\*\fldinst PAGEREF AAAAAAAACP \\*MERGEFORMAT}{\fldrslt pagenum}} +\par +\par} +\pard\plain \sect\sbkpage +\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid +File Index\par \pard\plain +{\tc \v File Index} +\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid +File List\par \pard\plain +{ +\pard\plain \s17\sa60\sb30\widctlpar\qj \fs22\cgrid Here is a list of all files with brief descriptions:} +{ +\par +\pard\plain \s71\li360\sa27\sb27\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid +{\b {\b ModbusRtu.h} } \tab {\field\fldedit {\*\fldinst PAGEREF AAAAAAAAAA \\*MERGEFORMAT}{\fldrslt pagenum}} +\par +\par} +\pard\plain \sect\sbkpage +\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid +Module Documentation{\tc \v Module Documentation} +\par \pard\plain +\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid +Modbus Object Instantiation/Initialization\par \pard\plain +{\tc\tcl2 \v Modbus Object Instantiation/Initialization} +{\xe \v Modbus Object Instantiation/Initialization} +{\bkmkstart AAAAAAAABQ} +{\bkmkend AAAAAAAABQ} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Functions\par +\pard\plain + +{ +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +{\b Modbus::Modbus} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Default Constructor for Master through Serial. }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +void {\b Modbus::begin} (long u32speed)\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Initialize class object. }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +void {\b Modbus::setID} (uint8_t u8id)\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +write new ID for the slave }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint8_t {\b Modbus::getID} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +get slave ID between 1 and 247 }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +void {\b Modbus::setTimeOut} (uint16_t u16timeout)\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +write communication watch-dog timer }{ +}\par +}} +} +{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Detailed Description\par +\pard\plain +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +\par +}{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Function Documentation\par +\pard\plain +{\xe \v begin\:Modbus Object Instantiation/Initialization} +{\xe \v Modbus Object Instantiation/Initialization\:begin} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +void Modbus::begin (long {\i u32speed})}} +\par +{\bkmkstart AAAAAAAABR} +{\bkmkend AAAAAAAABR} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Initialize class object. }}\par +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Sets up the serial port using specified baud rate. Call once class has been instantiated, typically within setup().\par +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +See Also:\par}\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid {\f2 http://arduino.cc/en/Serial/Begin#.Uy4CJ6aKlHY} \par +}{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Parameters:\par} +\pard\plain \s61\li360\widctlpar\ql\adjustright \fs20\cgrid \trowd \trgaph108\trleft426\tblind426\trbrdrt\brdrs\brdrw10\brdrcf15 \trbrdrl\brdrs\brdrw10\brdrcf15 \trbrdrb\brdrs\brdrw10\brdrcf15 \trbrdrr\brdrs\brdrw10\brdrcf15 \trbrdrh\brdrs\brdrw10\brdrcf15 \trbrdrv\brdrs\brdrw10\brdrcf15 +\clvertalt\clbrdrt\brdrs\brdrw10\brdrcf15 \clbrdrl\brdrs\brdrw10\brdrcf15 \clbrdrb\brdrs\brdrw10\brdrcf15 \clbrdrr \brdrs\brdrw10\brdrcf15 \cltxlrtb \cellx2187 +\clvertalt\clbrdrt\brdrs\brdrw10\brdrcf15 \clbrdrl\brdrs\brdrw10\brdrcf15 \clbrdrb\brdrs\brdrw10\brdrcf15 \clbrdrr \brdrs\brdrw10\brdrcf15 \cltxlrtb \cellx8748 +\pard \widctlpar\intbl\adjustright +{{\i speed} \cell }{baud rate, in standard increments (300..115200) \cell } +{\row } +\trowd \trgaph108\trleft426\tblind426\trbrdrt\brdrs\brdrw10\brdrcf15 \trbrdrl\brdrs\brdrw10\brdrcf15 \trbrdrb\brdrs\brdrw10\brdrcf15 \trbrdrr\brdrs\brdrw10\brdrcf15 \trbrdrh\brdrs\brdrw10\brdrcf15 \trbrdrv\brdrs\brdrw10\brdrcf15 +\clvertalt\clbrdrt\brdrs\brdrw10\brdrcf15 \clbrdrl\brdrs\brdrw10\brdrcf15 \clbrdrb\brdrs\brdrw10\brdrcf15 \clbrdrr \brdrs\brdrw10\brdrcf15 \cltxlrtb \cellx2187 +\clvertalt\clbrdrt\brdrs\brdrw10\brdrcf15 \clbrdrl\brdrs\brdrw10\brdrcf15 \clbrdrb\brdrs\brdrw10\brdrcf15 \clbrdrr \brdrs\brdrw10\brdrcf15 \cltxlrtb \cellx8748 +\pard \widctlpar\intbl\adjustright +{{\i config} \cell }{data frame settings (data length, parity and stop bits) \cell } +{\row } +} +}{ +Definition at line 250 of file ModbusRtu.h.}\par +} +{\xe \v getID\:Modbus Object Instantiation/Initialization} +{\xe \v Modbus Object Instantiation/Initialization\:getID} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +uint8_t Modbus::getID ()}} +\par +{\bkmkstart AAAAAAAABS} +{\bkmkend AAAAAAAABS} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +get slave ID between 1 and 247 }}\par +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Method to read current slave ID address.\par +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Returns:\par}\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid u8id current slave address between 1 and 247 \par +}}{ +Definition at line 323 of file ModbusRtu.h.}\par +} +{\xe \v Modbus\:Modbus Object Instantiation/Initialization} +{\xe \v Modbus Object Instantiation/Initialization\:Modbus} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +Modbus::Modbus ()}} +\par +{\bkmkstart AAAAAAAABT} +{\bkmkend AAAAAAAABT} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Default Constructor for Master through Serial. }}\par +{ +Definition at line 204 of file ModbusRtu.h.}\par +} +{\xe \v setID\:Modbus Object Instantiation/Initialization} +{\xe \v Modbus Object Instantiation/Initialization\:setID} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +void Modbus::setID (uint8_t {\i u8id})}} +\par +{\bkmkstart AAAAAAAABU} +{\bkmkend AAAAAAAABU} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +write new ID for the slave }}\par +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Method to write a new slave ID address.\par +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Parameters:\par} +\pard\plain \s61\li360\widctlpar\ql\adjustright \fs20\cgrid \trowd \trgaph108\trleft426\tblind426\trbrdrt\brdrs\brdrw10\brdrcf15 \trbrdrl\brdrs\brdrw10\brdrcf15 \trbrdrb\brdrs\brdrw10\brdrcf15 \trbrdrr\brdrs\brdrw10\brdrcf15 \trbrdrh\brdrs\brdrw10\brdrcf15 \trbrdrv\brdrs\brdrw10\brdrcf15 +\clvertalt\clbrdrt\brdrs\brdrw10\brdrcf15 \clbrdrl\brdrs\brdrw10\brdrcf15 \clbrdrb\brdrs\brdrw10\brdrcf15 \clbrdrr \brdrs\brdrw10\brdrcf15 \cltxlrtb \cellx2187 +\clvertalt\clbrdrt\brdrs\brdrw10\brdrcf15 \clbrdrl\brdrs\brdrw10\brdrcf15 \clbrdrb\brdrs\brdrw10\brdrcf15 \clbrdrr \brdrs\brdrw10\brdrcf15 \cltxlrtb \cellx8748 +\pard \widctlpar\intbl\adjustright +{{\i u8id} \cell }{new slave address between 1 and 247 \cell } +{\row } +} +}{ +Definition at line 310 of file ModbusRtu.h.}\par +} +{\xe \v setTimeOut\:Modbus Object Instantiation/Initialization} +{\xe \v Modbus Object Instantiation/Initialization\:setTimeOut} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +void Modbus::setTimeOut (uint16_t {\i u16timeOut})}} +\par +{\bkmkstart AAAAAAAABV} +{\bkmkend AAAAAAAABV} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +write communication watch-dog timer }}\par +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Initialize time-out parameter.\par +Call once class has been instantiated, typically within setup(). The time-out timer is reset each time that there is a successful communication between Master and Slave. It works for both.\par +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Parameters:\par} +\pard\plain \s61\li360\widctlpar\ql\adjustright \fs20\cgrid \trowd \trgaph108\trleft426\tblind426\trbrdrt\brdrs\brdrw10\brdrcf15 \trbrdrl\brdrs\brdrw10\brdrcf15 \trbrdrb\brdrs\brdrw10\brdrcf15 \trbrdrr\brdrs\brdrw10\brdrcf15 \trbrdrh\brdrs\brdrw10\brdrcf15 \trbrdrv\brdrs\brdrw10\brdrcf15 +\clvertalt\clbrdrt\brdrs\brdrw10\brdrcf15 \clbrdrl\brdrs\brdrw10\brdrcf15 \clbrdrb\brdrs\brdrw10\brdrcf15 \clbrdrr \brdrs\brdrw10\brdrcf15 \cltxlrtb \cellx2187 +\clvertalt\clbrdrt\brdrs\brdrw10\brdrcf15 \clbrdrl\brdrs\brdrw10\brdrcf15 \clbrdrb\brdrs\brdrw10\brdrcf15 \clbrdrr \brdrs\brdrw10\brdrcf15 \cltxlrtb \cellx8748 +\pard \widctlpar\intbl\adjustright +{{\i time-out} \cell }{value (ms) \cell } +{\row } +} +}{ +Definition at line 338 of file ModbusRtu.h.}\par +} +\par \pard\plain +\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid +Modbus Object Management\par \pard\plain +{\tc\tcl2 \v Modbus Object Management} +{\xe \v Modbus Object Management} +{\bkmkstart AAAAAAAABW} +{\bkmkend AAAAAAAABW} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Functions\par +\pard\plain + +{ +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +boolean {\b Modbus::getTimeOutState} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +get communication watch-dog timer state }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +int8_t {\b Modbus::query} ({\b modbus_t} telegram)\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +only for master }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +int8_t {\b Modbus::poll} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +cyclic poll for master }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +int8_t {\b Modbus::poll} (uint16_t *regs, uint8_t u8size)\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +cyclic poll for slave }{ +}\par +}} +} +{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Detailed Description\par +\pard\plain +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +\par +}{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Function Documentation\par +\pard\plain +{\xe \v getTimeOutState\:Modbus Object Management} +{\xe \v Modbus Object Management\:getTimeOutState} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +boolean Modbus::getTimeOutState ()}} +\par +{\bkmkstart AAAAAAAABX} +{\bkmkend AAAAAAAABX} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +get communication watch-dog timer state }}\par +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Return communication Watchdog state. It could be usefull to reset outputs if the watchdog is fired.\par +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Returns:\par}\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid TRUE if millis() > u32timeOut \par +}}{ +Definition at line 350 of file ModbusRtu.h.}\par +} +{\xe \v poll\:Modbus Object Management} +{\xe \v Modbus Object Management\:poll} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +int8_t Modbus::poll ()}} +\par +{\bkmkstart AAAAAAAABY} +{\bkmkend AAAAAAAABY} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +cyclic poll for master }}\par +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +*** Only for {\b Modbus} Master *** This method checks if there is any incoming answer if pending. If there is no answer, it would change Master state to COM_IDLE. This method must be called only at loop section. Avoid any delay() function.\par +Any incoming data would be redirected to au16regs pointer, as defined in its {\b modbus_t} query telegram.\par +nothing \par +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Returns:\par}\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid errors counter \par +}}{ +Definition at line 513 of file ModbusRtu.h.}\par +} +{\xe \v poll\:Modbus Object Management} +{\xe \v Modbus Object Management\:poll} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +int8_t Modbus::poll (uint16_t * {\i regs}, uint8_t {\i u8size})}} +\par +{\bkmkstart AAAAAAAABZ} +{\bkmkend AAAAAAAABZ} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +cyclic poll for slave }}\par +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +*** Only for {\b Modbus} Slave *** This method checks if there is any incoming query Afterwards, it would shoot a validation routine plus a register query Avoid any delay() function !!!! After a successful frame between the Master and the Slave, the time-out timer is reset.\par +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Parameters:\par} +\pard\plain \s61\li360\widctlpar\ql\adjustright \fs20\cgrid \trowd \trgaph108\trleft426\tblind426\trbrdrt\brdrs\brdrw10\brdrcf15 \trbrdrl\brdrs\brdrw10\brdrcf15 \trbrdrb\brdrs\brdrw10\brdrcf15 \trbrdrr\brdrs\brdrw10\brdrcf15 \trbrdrh\brdrs\brdrw10\brdrcf15 \trbrdrv\brdrs\brdrw10\brdrcf15 +\clvertalt\clbrdrt\brdrs\brdrw10\brdrcf15 \clbrdrl\brdrs\brdrw10\brdrcf15 \clbrdrb\brdrs\brdrw10\brdrcf15 \clbrdrr \brdrs\brdrw10\brdrcf15 \cltxlrtb \cellx2187 +\clvertalt\clbrdrt\brdrs\brdrw10\brdrcf15 \clbrdrl\brdrs\brdrw10\brdrcf15 \clbrdrb\brdrs\brdrw10\brdrcf15 \clbrdrr \brdrs\brdrw10\brdrcf15 \cltxlrtb \cellx8748 +\pard \widctlpar\intbl\adjustright +{{\i *regs} \cell }{register table for communication exchange \cell } +{\row } +\trowd \trgaph108\trleft426\tblind426\trbrdrt\brdrs\brdrw10\brdrcf15 \trbrdrl\brdrs\brdrw10\brdrcf15 \trbrdrb\brdrs\brdrw10\brdrcf15 \trbrdrr\brdrs\brdrw10\brdrcf15 \trbrdrh\brdrs\brdrw10\brdrcf15 \trbrdrv\brdrs\brdrw10\brdrcf15 +\clvertalt\clbrdrt\brdrs\brdrw10\brdrcf15 \clbrdrl\brdrs\brdrw10\brdrcf15 \clbrdrb\brdrs\brdrw10\brdrcf15 \clbrdrr \brdrs\brdrw10\brdrcf15 \cltxlrtb \cellx2187 +\clvertalt\clbrdrt\brdrs\brdrw10\brdrcf15 \clbrdrl\brdrs\brdrw10\brdrcf15 \clbrdrb\brdrs\brdrw10\brdrcf15 \clbrdrr \brdrs\brdrw10\brdrcf15 \cltxlrtb \cellx8748 +\pard \widctlpar\intbl\adjustright +{{\i u8size} \cell }{size of the register table \cell } +{\row } +} +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Returns:\par}\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid 0 if no query, 1..4 if communication error, >4 if correct query processed \par +}}{ +Definition at line 588 of file ModbusRtu.h.}\par +} +{\xe \v query\:Modbus Object Management} +{\xe \v Modbus Object Management\:query} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +int8_t Modbus::query ({\b modbus_t} {\i telegram})}} +\par +{\bkmkstart AAAAAAAACA} +{\bkmkend AAAAAAAACA} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +only for master }}\par +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +*** Only {\b Modbus} Master *** Generate a query to an slave with a {\b modbus_t} telegram structure The Master must be in COM_IDLE mode. After it, its state would be COM_WAITING. This method has to be called only in loop() section.\par +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +See Also:\par}\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid {\b modbus_t} \par +}{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Parameters:\par} +\pard\plain \s61\li360\widctlpar\ql\adjustright \fs20\cgrid \trowd \trgaph108\trleft426\tblind426\trbrdrt\brdrs\brdrw10\brdrcf15 \trbrdrl\brdrs\brdrw10\brdrcf15 \trbrdrb\brdrs\brdrw10\brdrcf15 \trbrdrr\brdrs\brdrw10\brdrcf15 \trbrdrh\brdrs\brdrw10\brdrcf15 \trbrdrv\brdrs\brdrw10\brdrcf15 +\clvertalt\clbrdrt\brdrs\brdrw10\brdrcf15 \clbrdrl\brdrs\brdrw10\brdrcf15 \clbrdrb\brdrs\brdrw10\brdrcf15 \clbrdrr \brdrs\brdrw10\brdrcf15 \cltxlrtb \cellx2187 +\clvertalt\clbrdrt\brdrs\brdrw10\brdrcf15 \clbrdrl\brdrs\brdrw10\brdrcf15 \clbrdrb\brdrs\brdrw10\brdrcf15 \clbrdrr \brdrs\brdrw10\brdrcf15 \cltxlrtb \cellx8748 +\pard \widctlpar\intbl\adjustright +{{\i {\b modbus_t}} \cell }{modbus telegram structure (id, fct, ...)\cell } +{\row } +} +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Todo:\par}\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid finish function 15 \par +} +}{ +Definition at line 425 of file ModbusRtu.h.}\par +} +\par \pard\plain +\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid +Modbus Buffer Management\par \pard\plain +{\tc\tcl2 \v Modbus Buffer Management} +{\xe \v Modbus Buffer Management} +{\bkmkstart AAAAAAAACB} +{\bkmkend AAAAAAAACB} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Functions\par +\pard\plain + +{ +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint16_t {\b Modbus::getInCnt} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +number of incoming messages }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint16_t {\b Modbus::getOutCnt} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +number of outcoming messages }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint16_t {\b Modbus::getErrCnt} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +error counter }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint8_t {\b Modbus::getState} ()\par +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint8_t {\b Modbus::getLastError} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +get last error message }{ +}\par +}} +} +{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Detailed Description\par +\pard\plain +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +\par +}{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Function Documentation\par +\pard\plain +{\xe \v getErrCnt\:Modbus Buffer Management} +{\xe \v Modbus Buffer Management\:getErrCnt} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +uint16_t Modbus::getErrCnt ()}} +\par +{\bkmkstart AAAAAAAACC} +{\bkmkend AAAAAAAACC} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +error counter }}\par +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Get errors counter value This can be useful to diagnose communication.\par +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Returns:\par}\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid errors counter \par +}}{ +Definition at line 386 of file ModbusRtu.h.}\par +} +{\xe \v getInCnt\:Modbus Buffer Management} +{\xe \v Modbus Buffer Management\:getInCnt} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +uint16_t Modbus::getInCnt ()}} +\par +{\bkmkstart AAAAAAAACD} +{\bkmkend AAAAAAAACD} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +number of incoming messages }}\par +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Get input messages counter value This can be useful to diagnose communication.\par +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Returns:\par}\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid input messages counter \par +}}{ +Definition at line 362 of file ModbusRtu.h.}\par +} +{\xe \v getLastError\:Modbus Buffer Management} +{\xe \v Modbus Buffer Management\:getLastError} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +uint8_t Modbus::getLastError ()}} +\par +{\bkmkstart AAAAAAAACE} +{\bkmkend AAAAAAAACE} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +get last error message }}\par +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Get the last error in the protocol processor\par +NO_REPLY = 255 Time-out \par +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Returns:\par}\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid EXC_FUNC_CODE = 1 Function code not available \par +EXC_ADDR_RANGE = 2 Address beyond available space for {\b Modbus} registers \par +EXC_REGS_QUANT = 3 Coils or registers number beyond the available space \par +}}{ +Definition at line 409 of file ModbusRtu.h.}\par +} +{\xe \v getOutCnt\:Modbus Buffer Management} +{\xe \v Modbus Buffer Management\:getOutCnt} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +uint16_t Modbus::getOutCnt ()}} +\par +{\bkmkstart AAAAAAAACF} +{\bkmkend AAAAAAAACF} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +number of outcoming messages }}\par +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Get transmitted messages counter value This can be useful to diagnose communication.\par +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Returns:\par}\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid transmitted messages counter \par +}}{ +Definition at line 374 of file ModbusRtu.h.}\par +} +{\xe \v getState\:Modbus Buffer Management} +{\xe \v Modbus Buffer Management\:getState} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +uint8_t Modbus::getState ()}} +\par +{\bkmkstart AAAAAAAACG} +{\bkmkend AAAAAAAACG} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Get modbus master state\par +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Returns:\par}\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid = 0 IDLE, = 1 WAITING FOR ANSWER \par +}}{ +Definition at line 396 of file ModbusRtu.h.}\par +} +\par \pard\plain +\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid +Modbus Function Codes for Discrete Coils/Inputs\par \pard\plain +{\tc\tcl2 \v Modbus Function Codes for Discrete Coils/Inputs} +{\xe \v Modbus Function Codes for Discrete Coils/Inputs} +{\bkmkstart AAAAAAAACH} +{\bkmkend AAAAAAAACH} +{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Detailed Description\par +\pard\plain +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +\par +}\par \pard\plain +\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid +Modbus Function Codes for Holding/Input Registers\par \pard\plain +{\tc\tcl2 \v Modbus Function Codes for Holding/Input Registers} +{\xe \v Modbus Function Codes for Holding/Input Registers} +{\bkmkstart AAAAAAAACI} +{\bkmkend AAAAAAAACI} +{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Detailed Description\par +\pard\plain +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +\par +} +\pard\plain \sect\sbkpage +\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid +Class Documentation{\tc \v Class Documentation} +\par \pard\plain +\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid +Modbus Class Reference\par \pard\plain +{\tc\tcl2 \v Modbus} +{\xe \v Modbus} +{\bkmkstart AAAAAAAACJ} +{\bkmkend AAAAAAAACJ} +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Arduino class library for communicating with {\b Modbus} devices over USB/RS232/485 (via RTU protocol). }}\par +{ +{\f2 #include }}\par +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Public Member Functions\par +\pard\plain + +{ +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +{\b Modbus} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Default Constructor for Master through Serial. }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +{\b Modbus} (uint8_t u8id, uint8_t u8serno)\par +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +{\b Modbus} (uint8_t u8id, uint8_t u8serno, uint8_t u8txenpin)\par +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +void {\b begin} (long u32speed)\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Initialize class object. }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +void {\b begin} ()\par +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +void {\b setTimeOut} (uint16_t u16timeout)\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +write communication watch-dog timer }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint16_t {\b getTimeOut} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +get communication watch-dog timer value }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +boolean {\b getTimeOutState} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +get communication watch-dog timer state }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +int8_t {\b query} ({\b modbus_t} telegram)\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +only for master }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +int8_t {\b poll} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +cyclic poll for master }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +int8_t {\b poll} (uint16_t *regs, uint8_t u8size)\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +cyclic poll for slave }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint16_t {\b getInCnt} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +number of incoming messages }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint16_t {\b getOutCnt} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +number of outcoming messages }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint16_t {\b getErrCnt} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +error counter }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint8_t {\b getID} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +get slave ID between 1 and 247 }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint8_t {\b getState} ()\par +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint8_t {\b getLastError} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +get last error message }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +void {\b setID} (uint8_t u8id)\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +write new ID for the slave }{ +}\par +}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +void {\b end} ()\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +finish any communication and release serial communication port }{ +}\par +}} +} +{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Detailed Description\par +\pard\plain +{ +\pard\plain \s17\sa60\sb30\widctlpar\qj \fs22\cgrid {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Arduino class library for communicating with {\b Modbus} devices over USB/RS232/485 (via RTU protocol). \par +}{ +Definition at line 141 of file ModbusRtu.h.}\par +} +{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Constructor & Destructor Documentation\par +\pard\plain +{\xe \v Modbus\:Modbus} +{\xe \v Modbus\:Modbus} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +Modbus::Modbus (uint8_t {\i u8id}, uint8_t {\i u8serno})}} +\par +{\bkmkstart AAAAAAAACK} +{\bkmkend AAAAAAAACK} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +Definition at line 218 of file ModbusRtu.h.}\par +} +{\xe \v Modbus\:Modbus} +{\xe \v Modbus\:Modbus} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +Modbus::Modbus (uint8_t {\i u8id}, uint8_t {\i u8serno}, uint8_t {\i u8txenpin})}} +\par +{\bkmkstart AAAAAAAACL} +{\bkmkend AAAAAAAACL} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +Definition at line 234 of file ModbusRtu.h.}\par +} +{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Member Function Documentation\par +\pard\plain +{\xe \v begin\:Modbus} +{\xe \v Modbus\:begin} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +void Modbus::begin ()}} +\par +{\bkmkstart AAAAAAAACM} +{\bkmkend AAAAAAAACM} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +Definition at line 299 of file ModbusRtu.h.}\par +} +{\xe \v end\:Modbus} +{\xe \v Modbus\:end} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +void Modbus::end ()}} +\par +{\bkmkstart AAAAAAAACN} +{\bkmkend AAAAAAAACN} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +finish any communication and release serial communication port }}\par +} +{\xe \v getTimeOut\:Modbus} +{\xe \v Modbus\:getTimeOut} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +uint16_t Modbus::getTimeOut ()}} +\par +{\bkmkstart AAAAAAAACO} +{\bkmkend AAAAAAAACO} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +get communication watch-dog timer value }}\par +} +{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +The documentation for this class was generated from the following file:{\par +\pard\plain \s81\fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec }\ls2\adjustright \fs20\cgrid +{\b ModbusRtu.h}\par +}\par \pard\plain + +\pard\plain \sect\sbkpage +\s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid +\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid +modbus_t Struct Reference\par \pard\plain +{\tc\tcl2 \v modbus_t} +{\xe \v modbus_t} +{\bkmkstart AAAAAAAACP} +{\bkmkend AAAAAAAACP} +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Master query structure: This includes all the necessary fields to make the Master generate a {\b Modbus} query. A Master may keep several of these structures and send them cyclically or use them according to program needs. }}\par +{ +{\f2 #include }}\par +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Public Attributes\par +\pard\plain + +{ +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint8_t {\b u8id}\par +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint8_t {\b u8fct}\par +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint16_t {\b u16RegAdd}\par +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint16_t {\b u16CoilsNo}\par +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +uint16_t * {\b au16reg}\par +} +{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Detailed Description\par +\pard\plain +{ +\pard\plain \s17\sa60\sb30\widctlpar\qj \fs22\cgrid {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Master query structure: This includes all the necessary fields to make the Master generate a {\b Modbus} query. A Master may keep several of these structures and send them cyclically or use them according to program needs. \par +}{ +Definition at line 48 of file ModbusRtu.h.}\par +} +{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Member Data Documentation\par +\pard\plain +{\xe \v au16reg\:modbus_t} +{\xe \v modbus_t\:au16reg} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +uint16_t* modbus_t::au16reg}} +\par +{\bkmkstart AAAAAAAACQ} +{\bkmkend AAAAAAAACQ} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Pointer to memory image in master \par +}{ +Definition at line 53 of file ModbusRtu.h.}\par +} +{\xe \v u16CoilsNo\:modbus_t} +{\xe \v modbus_t\:u16CoilsNo} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +uint16_t modbus_t::u16CoilsNo}} +\par +{\bkmkstart AAAAAAAACR} +{\bkmkend AAAAAAAACR} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Number of coils or registers to access \par +}{ +Definition at line 52 of file ModbusRtu.h.}\par +} +{\xe \v u16RegAdd\:modbus_t} +{\xe \v modbus_t\:u16RegAdd} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +uint16_t modbus_t::u16RegAdd}} +\par +{\bkmkstart AAAAAAAACS} +{\bkmkend AAAAAAAACS} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Address of the first register to access at slave/s \par +}{ +Definition at line 51 of file ModbusRtu.h.}\par +} +{\xe \v u8fct\:modbus_t} +{\xe \v modbus_t\:u8fct} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +uint8_t modbus_t::u8fct}} +\par +{\bkmkstart AAAAAAAACT} +{\bkmkend AAAAAAAACT} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Function code: 1, 2, 3, 4, 5, 6, 15 or 16 \par +}{ +Definition at line 50 of file ModbusRtu.h.}\par +} +{\xe \v u8id\:modbus_t} +{\xe \v modbus_t\:u8id} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +uint8_t modbus_t::u8id}} +\par +{\bkmkstart AAAAAAAACU} +{\bkmkend AAAAAAAACU} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Slave address between 1 and 247. 0 means broadcast \par +}{ +Definition at line 49 of file ModbusRtu.h.}\par +} +{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +The documentation for this struct was generated from the following file:{\par +\pard\plain \s81\fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec }\ls2\adjustright \fs20\cgrid +{\b ModbusRtu.h}\par +} +\pard\plain \sect\sbkpage +\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid +File Documentation{\tc \v File Documentation} +\par \pard\plain +\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid +ModbusRtu.h File Reference\par \pard\plain +{\tc\tcl2 \v ModbusRtu.h} +{\xe \v ModbusRtu.h} +{\bkmkstart AAAAAAAAAA} +{\bkmkend AAAAAAAAAA} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Classes\par +\pard\plain + +{ +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +struct {\b modbus_t}\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Master query structure: This includes all the necessary fields to make the Master generate a {\b Modbus} query. A Master may keep several of these structures and send them cyclically or use them according to program needs. }}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +class {\b Modbus}\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Arduino class library for communicating with {\b Modbus} devices over USB/RS232/485 (via RTU protocol). }}} +} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Macros\par +\pard\plain + +{ +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +#define {\b T35}\~ 5\par +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +#define {\b MAX_BUFFER}\~ 64\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +maximum size for the communication buffer in bytes }{ +}\par +}} +} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Enumerations\par +\pard\plain + +{ +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +enum \{ {\b RESPONSE_SIZE} = 6, +{\b EXCEPTION_SIZE} = 3, +{\b CHECKSUM_SIZE} = 2 + \}\par +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +enum {\b MESSAGE} \{ {\b ID} = 0, +{\b FUNC}, +{\b ADD_HI}, +{\b ADD_LO}, +{\b NB_HI}, +{\b NB_LO}, +{\b BYTE_CNT} + \}\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Indexes to telegram frame positions. }}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +enum {\b MB_FC} \{ {\b MB_FC_NONE} = 0, +{\b MB_FC_READ_COILS} = 1, +{\b MB_FC_READ_DISCRETE_INPUT} = 2, +{\b MB_FC_READ_REGISTERS} = 3, +{\b MB_FC_READ_INPUT_REGISTER} = 4, +{\b MB_FC_WRITE_COIL} = 5, +{\b MB_FC_WRITE_REGISTER} = 6, +{\b MB_FC_WRITE_MULTIPLE_COILS} = 15, +{\b MB_FC_WRITE_MULTIPLE_REGISTERS} = 16 + \}\par +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +{\b Modbus} function codes summary. These are the implement function codes either for Master or for Slave. }}} +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +enum {\b COM_STATES} \{ {\b COM_IDLE} = 0, +{\b COM_WAITING} = 1 + \}\par +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +enum {\b ERR_LIST} \{ {\b ERR_NOT_MASTER} = -1, +{\b ERR_POLLING} = -2, +{\b ERR_BUFF_OVERFLOW} = -3, +{\b ERR_BAD_CRC} = -4, +{\b ERR_EXCEPTION} = -5 + \}\par +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +enum \{ {\b NO_REPLY} = 255, +{\b EXC_FUNC_CODE} = 1, +{\b EXC_ADDR_RANGE} = 2, +{\b EXC_REGS_QUANT} = 3, +{\b EXC_EXECUTE} = 4 + \}\par +} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Variables\par +\pard\plain + +{ +\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid +const unsigned char {\b fctsupported} []\par +} +{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Detailed Description\par +\pard\plain +{ +\pard\plain \s17\sa60\sb30\widctlpar\qj \fs22\cgrid {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +\par +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Version:\par}\pard\plain \s61\li360\widctlpar\ql\adjustright \fs20\cgrid 1.2 \par +}{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Date:\par}\pard\plain \s61\li360\widctlpar\ql\adjustright \fs20\cgrid 2014.09.09 \par +}{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +Author:\par}\pard\plain \s61\li360\widctlpar\ql\adjustright \fs20\cgrid Samuel Marco i Armengol {\f2 sammarcoarmengol@gmail.com} \par +}Arduino library for communicating with {\b Modbus} devices over RS232/USB/485 via RTU protocol.\par +Further information: {\f2 http://modbus.org/} {\f2 http://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf}\par +This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; version 2.1 of the License.\par +This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.\par +You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA \par +}{ +Definition in file {\b ModbusRtu.h}.}\par +} +{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Macro Definition Documentation\par +\pard\plain +{\xe \v MAX_BUFFER\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:MAX_BUFFER} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +#define MAX_BUFFER\~ 64}} +\par +{\bkmkstart AAAAAAAAAB} +{\bkmkend AAAAAAAAAB} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +maximum size for the communication buffer in bytes }}\par +{ +Definition at line 133 of file ModbusRtu.h.}\par +} +{\xe \v T35\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:T35} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +#define T35\~ 5}} +\par +{\bkmkstart AAAAAAAAAC} +{\bkmkend AAAAAAAAAC} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +Definition at line 132 of file ModbusRtu.h.}\par +} +{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Enumeration Type Documentation\par +\pard\plain +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +anonymous enum}} +\par +{\bkmkstart AAAAAAAAAD} +{\bkmkend AAAAAAAAAD} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +{{{\b \par +Enumerator}}\par +\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid {\xe \v RESPONSE_SIZE\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:RESPONSE_SIZE} +{\b {\i RESPONSE_SIZE{\bkmkstart AAAAAAAAAE} +{\bkmkend AAAAAAAAAE} +}} \par +{\xe \v EXCEPTION_SIZE\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:EXCEPTION_SIZE} +{\b {\i EXCEPTION_SIZE{\bkmkstart AAAAAAAAAF} +{\bkmkend AAAAAAAAAF} +}} \par +{\xe \v CHECKSUM_SIZE\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:CHECKSUM_SIZE} +{\b {\i CHECKSUM_SIZE{\bkmkstart AAAAAAAAAG} +{\bkmkend AAAAAAAAAG} +}} \par +}{ +Definition at line 57 of file ModbusRtu.h.}\par +} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +anonymous enum}} +\par +{\bkmkstart AAAAAAAAAH} +{\bkmkend AAAAAAAAAH} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +{{{\b \par +Enumerator}}\par +\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid {\xe \v NO_REPLY\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:NO_REPLY} +{\b {\i NO_REPLY{\bkmkstart AAAAAAAAAI} +{\bkmkend AAAAAAAAAI} +}} \par +{\xe \v EXC_FUNC_CODE\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:EXC_FUNC_CODE} +{\b {\i EXC_FUNC_CODE{\bkmkstart AAAAAAAAAJ} +{\bkmkend AAAAAAAAAJ} +}} \par +{\xe \v EXC_ADDR_RANGE\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:EXC_ADDR_RANGE} +{\b {\i EXC_ADDR_RANGE{\bkmkstart AAAAAAAAAK} +{\bkmkend AAAAAAAAAK} +}} \par +{\xe \v EXC_REGS_QUANT\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:EXC_REGS_QUANT} +{\b {\i EXC_REGS_QUANT{\bkmkstart AAAAAAAAAL} +{\bkmkend AAAAAAAAAL} +}} \par +{\xe \v EXC_EXECUTE\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:EXC_EXECUTE} +{\b {\i EXC_EXECUTE{\bkmkstart AAAAAAAAAM} +{\bkmkend AAAAAAAAAM} +}} \par +}{ +Definition at line 113 of file ModbusRtu.h.}\par +} +{\xe \v COM_STATES\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:COM_STATES} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +enum {\b COM_STATES}}} +\par +{\bkmkstart AAAAAAAAAN} +{\bkmkend AAAAAAAAAN} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +{{{\b \par +Enumerator}}\par +\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid {\xe \v COM_IDLE\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:COM_IDLE} +{\b {\i COM_IDLE{\bkmkstart AAAAAAAAAO} +{\bkmkend AAAAAAAAAO} +}} \par +{\xe \v COM_WAITING\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:COM_WAITING} +{\b {\i COM_WAITING{\bkmkstart AAAAAAAAAP} +{\bkmkend AAAAAAAAAP} +}} \par +}{ +Definition at line 99 of file ModbusRtu.h.}\par +} +{\xe \v ERR_LIST\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:ERR_LIST} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +enum {\b ERR_LIST}}} +\par +{\bkmkstart AAAAAAAAAQ} +{\bkmkend AAAAAAAAAQ} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +{{{\b \par +Enumerator}}\par +\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid {\xe \v ERR_NOT_MASTER\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:ERR_NOT_MASTER} +{\b {\i ERR_NOT_MASTER{\bkmkstart AAAAAAAAAR} +{\bkmkend AAAAAAAAAR} +}} \par +{\xe \v ERR_POLLING\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:ERR_POLLING} +{\b {\i ERR_POLLING{\bkmkstart AAAAAAAAAS} +{\bkmkend AAAAAAAAAS} +}} \par +{\xe \v ERR_BUFF_OVERFLOW\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:ERR_BUFF_OVERFLOW} +{\b {\i ERR_BUFF_OVERFLOW{\bkmkstart AAAAAAAAAT} +{\bkmkend AAAAAAAAAT} +}} \par +{\xe \v ERR_BAD_CRC\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:ERR_BAD_CRC} +{\b {\i ERR_BAD_CRC{\bkmkstart AAAAAAAAAU} +{\bkmkend AAAAAAAAAU} +}} \par +{\xe \v ERR_EXCEPTION\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:ERR_EXCEPTION} +{\b {\i ERR_EXCEPTION{\bkmkstart AAAAAAAAAV} +{\bkmkend AAAAAAAAAV} +}} \par +}{ +Definition at line 105 of file ModbusRtu.h.}\par +} +{\xe \v MB_FC\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:MB_FC} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +enum {\b MB_FC}}} +\par +{\bkmkstart AAAAAAAAAW} +{\bkmkend AAAAAAAAAW} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +{\b Modbus} function codes summary. These are the implement function codes either for Master or for Slave. }}\par +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +\par +{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid +See Also:\par}\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid also {\b fctsupported} \par +also {\b modbus_t} \par +}}{{{\b Enumerator}}\par +\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid {\xe \v MB_FC_NONE\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:MB_FC_NONE} +{\b {\i MB_FC_NONE{\bkmkstart AAAAAAAAAX} +{\bkmkend AAAAAAAAAX} +}} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +null operator \par +}{\xe \v MB_FC_READ_COILS\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:MB_FC_READ_COILS} +{\b {\i MB_FC_READ_COILS{\bkmkstart AAAAAAAAAY} +{\bkmkend AAAAAAAAAY} +}} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +FCT=1 -> read coils or digital outputs \par +}{\xe \v MB_FC_READ_DISCRETE_INPUT\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:MB_FC_READ_DISCRETE_INPUT} +{\b {\i MB_FC_READ_DISCRETE_INPUT{\bkmkstart AAAAAAAAAZ} +{\bkmkend AAAAAAAAAZ} +}} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +FCT=2 -> read digital inputs \par +}{\xe \v MB_FC_READ_REGISTERS\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:MB_FC_READ_REGISTERS} +{\b {\i MB_FC_READ_REGISTERS{\bkmkstart AAAAAAAABA} +{\bkmkend AAAAAAAABA} +}} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +FCT=3 -> read registers or analog outputs \par +}{\xe \v MB_FC_READ_INPUT_REGISTER\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:MB_FC_READ_INPUT_REGISTER} +{\b {\i MB_FC_READ_INPUT_REGISTER{\bkmkstart AAAAAAAABB} +{\bkmkend AAAAAAAABB} +}} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +FCT=4 -> read analog inputs \par +}{\xe \v MB_FC_WRITE_COIL\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:MB_FC_WRITE_COIL} +{\b {\i MB_FC_WRITE_COIL{\bkmkstart AAAAAAAABC} +{\bkmkend AAAAAAAABC} +}} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +FCT=5 -> write single coil or output \par +}{\xe \v MB_FC_WRITE_REGISTER\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:MB_FC_WRITE_REGISTER} +{\b {\i MB_FC_WRITE_REGISTER{\bkmkstart AAAAAAAABD} +{\bkmkend AAAAAAAABD} +}} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +FCT=6 -> write single register \par +}{\xe \v MB_FC_WRITE_MULTIPLE_COILS\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:MB_FC_WRITE_MULTIPLE_COILS} +{\b {\i MB_FC_WRITE_MULTIPLE_COILS{\bkmkstart AAAAAAAABE} +{\bkmkend AAAAAAAABE} +}} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +FCT=15 -> write multiple coils or outputs \par +}{\xe \v MB_FC_WRITE_MULTIPLE_REGISTERS\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:MB_FC_WRITE_MULTIPLE_REGISTERS} +{\b {\i MB_FC_WRITE_MULTIPLE_REGISTERS{\bkmkstart AAAAAAAABF} +{\bkmkend AAAAAAAABF} +}} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +FCT=16 -> write multiple registers \par +}}{ +Definition at line 87 of file ModbusRtu.h.}\par +} +{\xe \v MESSAGE\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:MESSAGE} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +enum {\b MESSAGE}}} +\par +{\bkmkstart AAAAAAAABG} +{\bkmkend AAAAAAAABG} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +\par +{ +{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Indexes to telegram frame positions. }}\par +{{{\b Enumerator}}\par +\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid {\xe \v ID\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:ID} +{\b {\i ID{\bkmkstart AAAAAAAABH} +{\bkmkend AAAAAAAABH} +}} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +ID field. \par +}{\xe \v FUNC\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:FUNC} +{\b {\i FUNC{\bkmkstart AAAAAAAABI} +{\bkmkend AAAAAAAABI} +}} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Function code position. \par +}{\xe \v ADD_HI\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:ADD_HI} +{\b {\i ADD_HI{\bkmkstart AAAAAAAABJ} +{\bkmkend AAAAAAAABJ} +}} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Address high byte. \par +}{\xe \v ADD_LO\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:ADD_LO} +{\b {\i ADD_LO{\bkmkstart AAAAAAAABK} +{\bkmkend AAAAAAAABK} +}} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Address low byte. \par +}{\xe \v NB_HI\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:NB_HI} +{\b {\i NB_HI{\bkmkstart AAAAAAAABL} +{\bkmkend AAAAAAAABL} +}} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Number of coils or registers high byte. \par +}{\xe \v NB_LO\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:NB_LO} +{\b {\i NB_LO{\bkmkstart AAAAAAAABM} +{\bkmkend AAAAAAAABM} +}} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +Number of coils or registers low byte. \par +}{\xe \v BYTE_CNT\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:BYTE_CNT} +{\b {\i BYTE_CNT{\bkmkstart AAAAAAAABN} +{\bkmkend AAAAAAAABN} +}} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid +byte counter \par +}}{ +Definition at line 68 of file ModbusRtu.h.}\par +} +{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par} +\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid +Variable Documentation\par +\pard\plain +{\xe \v fctsupported\:ModbusRtu.h} +{\xe \v ModbusRtu.h\:fctsupported} +\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid { +{\b +const unsigned char fctsupported[]}} +\par +{\bkmkstart AAAAAAAABO} +{\bkmkend AAAAAAAABO} +{ +\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid +{\b Initial value:}{ +\pard\plain \s41\li360\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid = \{ \par + MB_FC_READ_COILS,\par + MB_FC_READ_DISCRETE_INPUT,\par + MB_FC_READ_REGISTERS, \par + MB_FC_READ_INPUT_REGISTER,\par + MB_FC_WRITE_COIL,\par + MB_FC_WRITE_REGISTER, \par + MB_FC_WRITE_MULTIPLE_COILS,\par + MB_FC_WRITE_MULTIPLE_REGISTERS\par +\}\par +} +{ +Definition at line 121 of file ModbusRtu.h.}\par +} + +\pard\plain \sect\sbkpage +\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid +\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid Index\par +\pard\plain +{\tc \v Index} +{\field\fldedit {\*\fldinst INDEX \\c2 \\*MERGEFORMAT}{\fldrslt INDEX}} +} \ No newline at end of file diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/RS485_slave/RS485_slave.ino b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/RS485_slave/RS485_slave.ino new file mode 100644 index 0000000..5d6ba8b --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/RS485_slave/RS485_slave.ino @@ -0,0 +1,35 @@ +/** + * Modbus slave example 3: + * The purpose of this example is to link a data array + * from the Arduino to an external device through RS485. + * + * Recommended Modbus Master: QModbus + * http://qmodbus.sourceforge.net/ + */ + +#include + +// assign the Arduino pin that must be connected to RE-DE RS485 transceiver +#define TXEN 4 + +// data array for modbus network sharing +uint16_t au16data[16] = { + 3, 1415, 9265, 4, 2, 7182, 28182, 8, 0, 0, 0, 0, 0, 0, 1, -1 }; + +/** + * Modbus object declaration + * u8id : node id = 0 for master, = 1..247 for slave + * port : serial port + * u8txenpin : 0 for RS-232 and USB-FTDI + * or any pin number > 1 for RS-485 + */ +Modbus slave(1,Serial,TXEN); // this is slave @1 and RS-485 + +void setup() { + Serial.begin( 19200 ); // baud-rate at 19200 + slave.start(); +} + +void loop() { + slave.poll( au16data, 16 ); +} diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/advanced_master/advanced_master.ino b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/advanced_master/advanced_master.ino new file mode 100644 index 0000000..d7101e2 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/advanced_master/advanced_master.ino @@ -0,0 +1,84 @@ +/** + * Modbus master example 2: + * The purpose of this example is to query several sets of data + * from an external Modbus slave device. + * The link media can be USB or RS232. + * + * Recommended Modbus slave: + * diagslave http://www.modbusdriver.com/diagslave.html + * + * In a Linux box, run + * "./diagslave /dev/ttyUSB0 -b 19200 -d 8 -s 1 -p none -m rtu -a 1" + * This is: + * serial port /dev/ttyUSB0 at 19200 baud 8N1 + * RTU mode and address @1 + */ + +#include + +uint16_t au16data[16]; //!< data array for modbus network sharing +uint8_t u8state; //!< machine state +uint8_t u8query; //!< pointer to message query + +/** + * Modbus object declaration + * u8id : node id = 0 for master, = 1..247 for slave + * port : serial port + * u8txenpin : 0 for RS-232 and USB-FTDI + * or any pin number > 1 for RS-485 + */ +Modbus master(0,Serial,0); // this is master and RS-232 or USB-FTDI + +/** + * This is an structe which contains a query to an slave device + */ +modbus_t telegram[2]; + +unsigned long u32wait; + +void setup() { + // telegram 0: read registers + telegram[0].u8id = 1; // slave address + telegram[0].u8fct = 3; // function code (this one is registers read) + telegram[0].u16RegAdd = 0; // start address in slave + telegram[0].u16CoilsNo = 4; // number of elements (coils or registers) to read + telegram[0].au16reg = au16data; // pointer to a memory array in the Arduino + + // telegram 1: write a single register + telegram[1].u8id = 1; // slave address + telegram[1].u8fct = 6; // function code (this one is write a single register) + telegram[1].u16RegAdd = 4; // start address in slave + telegram[1].u16CoilsNo = 1; // number of elements (coils or registers) to read + telegram[1].au16reg = au16data+4; // pointer to a memory array in the Arduino + + Serial.begin( 19200 ); // baud-rate at 19200 + master.start(); + master.setTimeOut( 5000 ); // if there is no answer in 5000 ms, roll over + u32wait = millis() + 1000; + u8state = u8query = 0; +} + +void loop() { + switch( u8state ) { + case 0: + if (millis() > u32wait) u8state++; // wait state + break; + case 1: + master.query( telegram[u8query] ); // send query (only once) + u8state++; + u8query++; + if (u8query > 2) u8query = 0; + break; + case 2: + master.poll(); // check incoming messages + if (master.getState() == COM_IDLE) { + u8state = 0; + u32wait = millis() + 1000; + } + break; + } + + au16data[4] = analogRead( 0 ); + +} + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/advanced_slave/advanced_slave.ino b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/advanced_slave/advanced_slave.ino new file mode 100644 index 0000000..3fe3171 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/advanced_slave/advanced_slave.ino @@ -0,0 +1,129 @@ +/** + * Modbus slave example 2: + * The purpose of this example is to link the Arduino digital and analog + * pins to an external device. + * + * Recommended Modbus Master: QModbus + * http://qmodbus.sourceforge.net/ + * + * Editado al español por LuxARTS + */ + +//Incluye la librería del protocolo Modbus +#include +#define ID 1 + +//Crear instancia +Modbus slave(ID, Serial, 0); //ID del nodo. 0 para el master, 1-247 para esclavo + //Puerto serie (0 = TX: 1 - RX: 0) + //Protocolo serie. 0 para RS-232 + USB (default), cualquier pin mayor a 1 para RS-485 +boolean led; +int8_t state = 0; +unsigned long tempus; + +uint16_t au16data[9]; //La tabla de registros que se desea compartir por la red + +/********************************************************* + Configuración del programa +*********************************************************/ +void setup() { + io_setup(); //configura las entradas y salidas + + Serial.begin(19200); //Abre la comunicación como esclavo + slave.start(); + tempus = millis() + 100; //Guarda el tiempo actual + 100ms + digitalWrite(13, HIGH ); //Prende el led del pin 13 (el de la placa) +} + +/********************************************************* + Inicio del programa +*********************************************************/ +void loop() { + //Comprueba el buffer de entrada + state = slave.poll( au16data, 9 ); //Parámetros: Tabla de registros para el intercambio de info + // Tamaño de la tabla de registros + //Devuelve 0 si no hay pedido de datos + //Devuelve 1 al 4 si hubo error de comunicación + //Devuelve mas de 4 si se procesó correctamente el pedido + + if (state > 4) { //Si es mayor a 4 = el pedido fué correcto + tempus = millis() + 50; //Tiempo actual + 50ms + digitalWrite(13, HIGH);//Prende el led + } + if (millis() > tempus) digitalWrite(13, LOW );//Apaga el led 50ms después + + //Actualiza los pines de Arduino con la tabla de Modbus + io_poll(); +} + +/** + * pin maping: + * 2 - digital input + * 3 - digital input + * 4 - digital input + * 5 - digital input + * 6 - digital output + * 7 - digital output + * 8 - digital output + * 9 - digital output + * 10 - analog output + * 11 - analog output + * 14 - analog input + * 15 - analog input + * + * pin 13 reservado para ver el estado de la comunicación + */ +void io_setup() { + pinMode(2, INPUT); + pinMode(3, INPUT); + pinMode(4, INPUT); + pinMode(5, INPUT); + pinMode(6, OUTPUT); + pinMode(7, OUTPUT); + pinMode(8, OUTPUT); + pinMode(9, OUTPUT); + pinMode(10, OUTPUT); + pinMode(11, OUTPUT); + pinMode(13, OUTPUT); + + digitalWrite(6, LOW ); + digitalWrite(7, LOW ); + digitalWrite(8, LOW ); + digitalWrite(9, LOW ); + digitalWrite(13, HIGH ); //Led del pin 13 de la placa + analogWrite(10, 0 ); //PWM 0% + analogWrite(11, 0 ); //PWM 0% +} + +/********************************************************* +Enlaza la tabla de registros con los pines +*********************************************************/ +void io_poll() { + // digital inputs -> au16data[0] + // Lee las entradas digitales y las guarda en bits de la primera variable del vector + // (es lo mismo que hacer una máscara) + bitWrite( au16data[0], 0, digitalRead( 2 )); //Lee el pin 2 de Arduino y lo guarda en el bit 0 de la variable au16data[0] + bitWrite( au16data[0], 1, digitalRead( 3 )); + bitWrite( au16data[0], 2, digitalRead( 4 )); + bitWrite( au16data[0], 3, digitalRead( 5 )); + + // digital outputs -> au16data[1] + // Lee los bits de la segunda variable y los pone en las salidas digitales + digitalWrite( 6, bitRead( au16data[1], 0 )); //Lee el bit 0 de la variable au16data[1] y lo pone en el pin 6 de Arduino + digitalWrite( 7, bitRead( au16data[1], 1 )); + digitalWrite( 8, bitRead( au16data[1], 2 )); + digitalWrite( 9, bitRead( au16data[1], 3 )); + + // Cambia el valor del PWM + analogWrite( 10, au16data[2] ); //El valor de au16data[2] se escribe en la salida de PWM del pin 10 de Arduino. (siendo 0=0% y 255=100%) + analogWrite( 11, au16data[3] ); + + // Lee las entradas analógicas (ADC) + au16data[4] = analogRead( 0 ); //El valor analógico leido en el pin A0 se guarda en au16data[4]. (siendo 0=0v y 1023=5v) + au16data[5] = analogRead( 1 ); + + // Diagnóstico de la comunicación (para debug) + au16data[6] = slave.getInCnt(); //Devuelve cuantos mensajes se recibieron + au16data[7] = slave.getOutCnt(); //Devuelve cuantos mensajes se transmitieron + au16data[8] = slave.getErrCnt(); //Devuelve cuantos errores hubieron +} diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/simple_master/simple_master.ino b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/simple_master/simple_master.ino new file mode 100644 index 0000000..8b09176 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/simple_master/simple_master.ino @@ -0,0 +1,71 @@ +/** + * Modbus master example 1: + * The purpose of this example is to query an array of data + * from an external Modbus slave device. + * The link media can be USB or RS232. + * + * Recommended Modbus slave: + * diagslave http://www.modbusdriver.com/diagslave.html + * + * In a Linux box, run + * "./diagslave /dev/ttyUSB0 -b 19200 -d 8 -s 1 -p none -m rtu -a 1" + * This is: + * serial port /dev/ttyUSB0 at 19200 baud 8N1 + * RTU mode and address @1 + */ + +#include + +// data array for modbus network sharing +uint16_t au16data[16]; +uint8_t u8state; + +/** + * Modbus object declaration + * u8id : node id = 0 for master, = 1..247 for slave + * port : serial port + * u8txenpin : 0 for RS-232 and USB-FTDI + * or any pin number > 1 for RS-485 + */ +Modbus master(0,Serial,0); // this is master and RS-232 or USB-FTDI + +/** + * This is an structe which contains a query to an slave device + */ +modbus_t telegram; + +unsigned long u32wait; + +void setup() { + Serial.begin( 19200 ); // baud-rate at 19200 + master.start(); + master.setTimeOut( 2000 ); // if there is no answer in 2000 ms, roll over + u32wait = millis() + 1000; + u8state = 0; +} + +void loop() { + switch( u8state ) { + case 0: + if (millis() > u32wait) u8state++; // wait state + break; + case 1: + telegram.u8id = 1; // slave address + telegram.u8fct = 3; // function code (this one is registers read) + telegram.u16RegAdd = 1; // start address in slave + telegram.u16CoilsNo = 4; // number of elements (coils or registers) to read + telegram.au16reg = au16data; // pointer to a memory array in the Arduino + + master.query( telegram ); // send query (only once) + u8state++; + break; + case 2: + master.poll(); // check incoming messages + if (master.getState() == COM_IDLE) { + u8state = 0; + u32wait = millis() + 100; + } + break; + } +} + diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/simple_slave/simple_slave.ino b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/simple_slave/simple_slave.ino new file mode 100644 index 0000000..ebe69ea --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/simple_slave/simple_slave.ino @@ -0,0 +1,32 @@ +/** + * Modbus slave example 1: + * The purpose of this example is to link a data array + * from the Arduino to an external device. + * + * Recommended Modbus Master: QModbus + * http://qmodbus.sourceforge.net/ + */ + +#include + +// data array for modbus network sharing +uint16_t au16data[16] = { + 3, 1415, 9265, 4, 2, 7182, 28182, 8, 0, 0, 0, 0, 0, 0, 1, -1 }; + +/** + * Modbus object declaration + * u8id : node id = 0 for master, = 1..247 for slave + * port : serial port + * u8txenpin : 0 for RS-232 and USB-FTDI + * or any pin number > 1 for RS-485 + */ +Modbus slave(1,Serial,0); // this is slave @1 and RS-232 or USB-FTDI + +void setup() { + Serial.begin( 19200 ); // baud-rate at 19200 + slave.start(); +} + +void loop() { + slave.poll( au16data, 16 ); +} diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/simple_slave2/simple_slave2.ino b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/simple_slave2/simple_slave2.ino new file mode 100644 index 0000000..245fcd3 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/simple_slave2/simple_slave2.ino @@ -0,0 +1,32 @@ +/** + * Modbus slave example 2: + * The purpose of this example is to link a data array + * from the Arduino to an external device. + * + * Recommended Modbus Master: modpoll + * http://www.modbusdriver.com/modpoll.html + */ + +#include + +// data array for modbus network sharing +uint16_t au16data[16] = { + 3, 1415, 9265, 4, 2, 7182, 28182, 8, 0, 0, 0, 0, 0, 0, 1, -1 }; + +/** + * Modbus object declaration + * u8id : node id = 0 for master, = 1..247 for slave + * port : serial port + * u8txenpin : 0 for RS-232 and USB-FTDI + * or any pin number > 1 for RS-485 + */ +Modbus slave(1,Serial,0); // this is slave @1 and RS-232 or USB-FTDI + +void setup() { + Serial.begin( 19200, SERIAL_8E1 ); // 19200 baud, 8-bits, even, 1-bit stop + slave.start(); +} + +void loop() { + slave.poll( au16data, 16 ); +} diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/software_serial_simple_master/software_serial_simple_master.ino b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/software_serial_simple_master/software_serial_simple_master.ino new file mode 100644 index 0000000..2e5c532 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/examples/software_serial_simple_master/software_serial_simple_master.ino @@ -0,0 +1,101 @@ +/** + * Modbus master example 2: + * The purpose of this example is to query an array of data + * from an external Modbus slave device. + * This example is similar to "simple_master", but this example + * allows you to use software serial instead of hardware serial + * in case that you want to use D1 & D2 for other purposes. + * The link media can be USB or RS232. + + The circuit: + * software serial rx(D3) connect to tx pin of another device + * software serial tx(D4) connect to rx pin of another device + + * In this example, we will use two important methods so that we can use + * software serial. + * + * 1. Modbus::Modbus(uint8_t u8id) + * This is a constructor for a Master/Slave through USB/RS232C via software serial + * This constructor only specifies u8id (node address) and should be only + * used if you want to use software serial instead of hardware serial. + * This method is called if you create a ModBus object with only on parameter "u8id" + * u8id is the node address of the arduino that will be programmed on, + * 0 for master and 1..247 for slave + * for example: Modbus master(0); + * If you use this constructor you have to begin ModBus object by + * using "void Modbus::begin(SoftwareSerial *softPort, long u32speed)". + * + * 2. void Modbus::begin(SoftwareSerial *sPort, long u32speed) + * Initialize class object. + * This is the method you have to use if you construct the ModBus object by using + * Modbus::Modbus(uint8_t u8id) in order to use software serial and to avoid problems. + * You have to create a SoftwareSerial object on your own, as shown in the example. + * sPort is a pointer to your SoftwareSerial object, u32speed is the baud rate, in + * standard increments (300..115200) + + created long time ago + by smarmengol + modified 29 July 2016 + by Helium6072 + + This example code is in the public domain. + */ + +#include +#include + +// data array for modbus network sharing +uint16_t au16data[16]; +uint8_t u8state; + +SoftwareSerial mySerial(3, 5);//Create a SoftwareSerial object so that we can use software serial. Search "software serial" on Arduino.cc to find out more details. + +/** + * Modbus object declaration + * u8id : node id = 0 for master, = 1..247 for slave + * port : serial port + * u8txenpin : 0 for RS-232 and USB-FTDI + * or any pin number > 1 for RS-485 + */ +Modbus master(0, mySerial); // this is master and RS-232 or USB-FTDI via software serial + +/** + * This is an structe which contains a query to an slave device + */ +modbus_t telegram; + +unsigned long u32wait; + +void setup() { + mySerial.begin(9600);//use the hardware serial if you want to connect to your computer via usb cable, etc. + master.start(); // start the ModBus object. + master.setTimeOut( 2000 ); // if there is no answer in 2000 ms, roll over + u32wait = millis() + 1000; + u8state = 0; +} + +void loop() { + switch( u8state ) { + case 0: + if (millis() > u32wait) u8state++; // wait state + break; + case 1: + telegram.u8id = 104; // slave address + telegram.u8fct = 4; // function code (this one is registers read) + telegram.u16RegAdd = 3; // start address in slave + telegram.u16CoilsNo = 1; // number of elements (coils or registers) to read + telegram.au16reg = au16data; // pointer to a memory array in the Arduino + + master.query( telegram ); // send query (only once) + u8state++; + break; + case 2: + master.poll(); // check incoming messages + if (master.getState() == COM_IDLE) { + u8state = 0; + u32wait = millis() + 2000; + Serial.println(au16data[0]);//Or do something else! + } + break; + } +} diff --git a/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/keywords.txt b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/keywords.txt new file mode 100644 index 0000000..0f7cc91 --- /dev/null +++ b/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/keywords.txt @@ -0,0 +1,30 @@ +####################################### +# Syntax Coloring Map For Modbus-Master-Slave +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### +modbus_t KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +begin KEYWORD2 +poll KEYWORD2 +getInCnt KEYWORD2 +getOutCnt KEYWORD2 +getErrCnt KEYWORD2 +getID KEYWORD2 +getState KEYWORD2 +query KEYWORD2 +setTimeOut KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### +Modbus KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/Версия_3.0/minimalmodbus-2.1.1.dist-info/INSTALLER b/Версия_3.0/minimalmodbus-2.1.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/Версия_3.0/minimalmodbus-2.1.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Версия_3.0/minimalmodbus-2.1.1.dist-info/LICENSE b/Версия_3.0/minimalmodbus-2.1.1.dist-info/LICENSE new file mode 100644 index 0000000..26dfb4f --- /dev/null +++ b/Версия_3.0/minimalmodbus-2.1.1.dist-info/LICENSE @@ -0,0 +1,177 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/Версия_3.0/minimalmodbus-2.1.1.dist-info/METADATA b/Версия_3.0/minimalmodbus-2.1.1.dist-info/METADATA new file mode 100644 index 0000000..fdd0c20 --- /dev/null +++ b/Версия_3.0/minimalmodbus-2.1.1.dist-info/METADATA @@ -0,0 +1,98 @@ +Metadata-Version: 2.1 +Name: minimalmodbus +Version: 2.1.1 +Summary: Easy-to-use Modbus RTU and Modbus ASCII implementation for Python +Keywords: minimalmodbus,modbus,modbus-serial,modbus-RTU,modbus-ASCII +Author: Jonas Berg +Requires-Python: >=3.8 +Description-Content-Type: text/x-rst +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Information Technology +Classifier: Intended Audience :: Science/Research +Classifier: Intended Audience :: Manufacturing +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Natural Language :: English +Classifier: Operating System :: OS Independent +Classifier: Operating System :: POSIX +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Topic :: Communications +Classifier: Topic :: Home Automation +Classifier: Topic :: Scientific/Engineering +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: System :: Hardware :: Hardware Drivers +Classifier: Topic :: Terminals :: Serial +Requires-Dist: pyserial>=3.0 +Project-URL: Changelog, https://github.com/pyhys/minimalmodbus/blob/master/HISTORY.rst +Project-URL: Documentation, https://minimalmodbus.readthedocs.io +Project-URL: Homepage, https://github.com/pyhys/minimalmodbus + +=============================== +MinimalModbus +=============================== + +.. image:: https://github.com/pyhys/minimalmodbus/actions/workflows/build.yml/badge.svg + :target: https://github.com/pyhys/minimalmodbus/actions + :alt: Build Status + +.. image:: https://codecov.io/gh/pyhys/minimalmodbus/branch/master/graph/badge.svg?token=6TcwYCQJHF + :target: https://codecov.io/gh/pyhys/minimalmodbus + :alt: Test coverage report + +.. image:: https://readthedocs.org/projects/minimalmodbus/badge/?version=master + :target: https://readthedocs.org/projects/minimalmodbus/?badge=master + :alt: Documentation Status + +.. image:: https://img.shields.io/pypi/v/minimalmodbus.svg + :target: https://pypi.org/project/minimalmodbus/ + :alt: PyPI page link + + +Easy-to-use Modbus RTU and Modbus ASCII implementation for Python. + +Web resources +------------- + +* **Documentation**: https://minimalmodbus.readthedocs.io +* Source code on **GitHub**: https://github.com/pyhys/minimalmodbus +* Python package index (PyPI) with download: https://pypi.org/project/minimalmodbus/ + +Other web pages: + +* Readthedocs project page: https://readthedocs.org/projects/minimalmodbus/ +* codecov.io project page: https://codecov.io/github/pyhys/minimalmodbus + +Obsolete web pages: + +* Old Travis CI build status page: https://travis-ci.org/pyhys/minimalmodbus +* Old Sourceforge documentation page: http://minimalmodbus.sourceforge.net/ +* Old Sourceforge project page: https://sourceforge.net/projects/minimalmodbus +* Old Sourceforge repository: https://sourceforge.net/p/minimalmodbus/code/HEAD/tree/ + + +Features +-------- +MinimalModbus is an easy-to-use Python module for talking to instruments (slaves) +from a computer (master) using the Modbus protocol, and is intended to be running on the master. +The only dependence is the pySerial module (also pure Python). + +There are convenience functions to handle floats, strings and long integers +(in different byte orders). + +This software supports the 'Modbus RTU' and 'Modbus ASCII' serial communication +versions of the protocol, and is intended for use on Linux, OS X and Windows platforms. +It is open source, and has the Apache License, Version 2.0. + +For Python 3.8 and later. Tested with Python 3.8, 3.9, 3.10, 3.11 and 3.12. + +This package uses semantic versioning. + diff --git a/Версия_3.0/minimalmodbus-2.1.1.dist-info/RECORD b/Версия_3.0/minimalmodbus-2.1.1.dist-info/RECORD new file mode 100644 index 0000000..314e66f --- /dev/null +++ b/Версия_3.0/minimalmodbus-2.1.1.dist-info/RECORD @@ -0,0 +1,8 @@ +__pycache__/minimalmodbus.cpython-312.pyc,, +minimalmodbus-2.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +minimalmodbus-2.1.1.dist-info/LICENSE,sha256=q-eH1HKuIGnpNchOsT_XcFGN-wi5LV8ZDzzX_20fbzI,10100 +minimalmodbus-2.1.1.dist-info/METADATA,sha256=syG35wzFfqt2fQKrj1Zu9tByQAktO-cfhpwjhY5C3q4,4082 +minimalmodbus-2.1.1.dist-info/RECORD,, +minimalmodbus-2.1.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +minimalmodbus-2.1.1.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +minimalmodbus.py,sha256=ZgeO9jIAuUwzSvygc_fY4dJdj0q_Z4fp6oQEvamqnVM,134115 diff --git a/Версия_3.0/minimalmodbus-2.1.1.dist-info/REQUESTED b/Версия_3.0/minimalmodbus-2.1.1.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/Версия_3.0/minimalmodbus-2.1.1.dist-info/WHEEL b/Версия_3.0/minimalmodbus-2.1.1.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/Версия_3.0/minimalmodbus-2.1.1.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.9.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/Версия_3.0/minimalmodbus.py b/Версия_3.0/minimalmodbus.py new file mode 100644 index 0000000..8d22676 --- /dev/null +++ b/Версия_3.0/minimalmodbus.py @@ -0,0 +1,4048 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2023 Jonas Berg +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +"""MinimalModbus: A Python driver for Modbus RTU/ASCII via serial port.""" + +__author__ = "Jonas Berg" +__license__ = "Apache License, Version 2.0" +__url__ = "https://github.com/pyhys/minimalmodbus" +__version__ = "2.1.1" + +import sys + +if sys.version_info < (3, 8, 0): + raise ImportError( + "Your Python version is too old for this version of MinimalModbus" + ) + +import binascii +import enum +import os +import struct +import time +from typing import Any, Dict, List, Optional, Type, Union + +import serial + +_NUMBER_OF_BYTES_BEFORE_REGISTERDATA = 1 # Within the payload +_NUMBER_OF_BYTES_PER_REGISTER = 2 +_MAX_NUMBER_OF_REGISTERS_TO_WRITE = 123 +_MAX_NUMBER_OF_REGISTERS_TO_READ = 125 +_MAX_NUMBER_OF_BITS_TO_WRITE = 1968 # 0x7B0 +_MAX_NUMBER_OF_BITS_TO_READ = 2000 # 0x7D0 +_MAX_NUMBER_OF_DECIMALS = 10 # Some instrument might store 0.00000154 Ampere as 154 etc +_MAX_BYTEORDER_VALUE = 3 +_SECONDS_TO_MILLISECONDS = 1000 +_BROADCAST_DELAY: float = 0.2 # seconds +_BITS_PER_BYTE = 8 +_ASCII_HEADER = b":" +_ASCII_FOOTER = b"\r\n" +_BYTEPOSITION_FOR_ASCII_HEADER = 0 # Relative to plain response +_BYTEPOSITION_FOR_SLAVEADDRESS = 0 # Relative to (stripped) response +_BYTEPOSITION_FOR_FUNCTIONCODE = 1 # Relative to (stripped) response +_BYTEPOSITION_FOR_SLAVE_ERROR_CODE = 2 # Relative to (stripped) response +_BITNUMBER_FUNCTIONCODE_ERRORINDICATION = 7 +_SLAVEADDRESS_BROADCAST = 0 + +# Several instrument instances can share the same serialport +_serialports: Dict[str, serial.Serial] = {} # Key: port name, value: port instance +_latest_read_times: Dict[str, float] = {} # Key: port name, value: timestamp + +# ############### # +# Named constants # +# ############### # + +MODE_RTU: str = "rtu" +"""Use Modbus RTU communication.""" +MODE_ASCII: str = "ascii" +"""Use Modbus ASCII communication.""" + +BYTEORDER_BIG: int = 0 +"""Use big endian byteorder.""" +BYTEORDER_LITTLE: int = 1 +"""Use little endian byteorder.""" +BYTEORDER_BIG_SWAP: int = 2 +"""Use big endian byteorder, with swap.""" +BYTEORDER_LITTLE_SWAP: int = 3 +"""Use litte endian byteorder, with swap.""" + + +@enum.unique +class _Payloadformat(enum.Enum): + BIT = enum.auto() + BITS = enum.auto() + FLOAT = enum.auto() + LONG = enum.auto() + REGISTER = enum.auto() + REGISTERS = enum.auto() + STRING = enum.auto() + + +# ######################## # +# Modbus instrument object # +# ######################## # + + +class Instrument: + """Instrument class for talking to instruments (slaves). + + Uses the Modbus RTU or ASCII protocols (via RS485 or RS232). + + Args: + * port: The serial port name, for example ``/dev/ttyUSB0`` (Linux), + ``/dev/tty.usbserial`` (OS X) or ``COM4`` (Windows). + It is also possible to pass in an already opened ``serial.Serial`` + object (new in version 2.1). + * slaveaddress: Slave address in the range 0 to 247. + Address 0 is for broadcast, and 248-255 are reserved. + * mode: Mode selection. Can be :data:`minimalmodbus.MODE_RTU` or + :data:`minimalmodbus.MODE_ASCII`. + * close_port_after_each_call: If the serial port should be closed after + each call to the instrument. + * debug: Set this to :const:`True` to print the communication details + """ + + def __init__( + self, + port: Union[str, serial.Serial], + slaveaddress: int, + mode: str = MODE_RTU, + close_port_after_each_call: bool = False, + debug: bool = False, + ) -> None: + """Initialize instrument and open corresponding serial port.""" + self.address = slaveaddress + """Slave address (int). Most often set by the constructor (see the class + documentation). + + Slave address 0 is for broadcasting to all slaves (no responses are sent). It is + only possible to write infomation (not read) via broadcast. A long delay is + added after each transmission to allow the slowest slaves to digest the + information. + + New in version 2.0: Support for broadcast + """ + + self.mode = mode + """Slave mode (str), can be :data:`minimalmodbus.MODE_RTU` or + :data:`minimalmodbus.MODE_ASCII`. Most often set by the constructor (see the + class documentation). Defaults to RTU. + + Changing this will not affect how other instruments use the same serial port. + + New in version 0.6. + """ + + self.precalculate_read_size = True + """If this is :const:`False`, the serial port reads until timeout instead of + just reading a specific number of bytes. Defaults to :const:`True`. + + Changing this will not affect how other instruments use the same serial port. + + New in version 0.5. + """ + + self.debug = debug + """Set this to :const:`True` to print the communication details. Defaults to + :const:`False`. + + Most often set by the constructor (see the class documentation). + + Changing this will not affect how other instruments use the same serial port. + """ + + self.clear_buffers_before_each_transaction = True + """If this is :const:`True`, the serial port read and write buffers are cleared + before each request to the instrument, to avoid cumulative byte sync errors + across multiple messages. Defaults to :const:`True`. + + Changing this will not affect how other instruments use the same serial port. + + New in version 1.0. + """ + + self.close_port_after_each_call = close_port_after_each_call + """If this is :const:`True`, the serial port will be closed after each call. + Defaults to :const:`False`. + + Changing this will not affect how other instruments use the same serial port. + + Most often set by the constructor (see the class documentation). + """ + + self.handle_local_echo = False + """Set to to :const:`True` if your RS-485 adaptor has local echo enabled. Then + the transmitted message will immeadiately appear at the receive line of the + RS-485 adaptor. MinimalModbus will then read and discard this data, before + reading the data from the slave. Defaults to :const:`False`. + + Changing this will not affect how other instruments use the same serial port. + + New in version 0.7. + """ + + self.serial: Optional[serial.Serial] = None + """The serial port object as defined by the pySerial module. Created by the + constructor. + + Attributes that could be changed after initialisation: + + - port (str): Serial port name. + - Most often set by the constructor (see the class documentation). + - baudrate (int): Baudrate in Baud. + - Defaults to 19200. + - parity (use PARITY_xxx constants): Parity. See the pySerial module. + - Defaults to :const:`serial.PARITY_NONE`. + - bytesize (int): Bytesize in bits. + - Defaults to 8. + - stopbits (use STOPBITS_xxx constants): Number of stopbits. See pySerial. + - Defaults to :const:`serial.STOPBITS_ONE`. + - timeout (float): Read timeout value in seconds. + - Defaults to 0.05 s. + - write_timeout (float): Write timeout value in seconds. + - Defaults to 2.0 s. + """ + + if _is_serial_object(port): + self.serial = port # type: ignore + elif isinstance(port, str) and ( + port not in _serialports or not _serialports[port] + ): + self._print_debug("Create serial port {}".format(port)) + self.serial = _serialports[port] = serial.Serial( + port=port, + baudrate=19200, + parity=serial.PARITY_NONE, + bytesize=8, + stopbits=1, + timeout=0.05, + write_timeout=2.0, + ) + elif isinstance(port, str): + self._print_debug("Serial port {} already exists".format(port)) + self.serial = _serialports[port] + if (self.serial.port is None) or (not self.serial.is_open): + self._print_debug("Serial port {} is closed. Opening.".format(port)) + self.serial.open() + + if self.serial is None or not _is_serial_object(self.serial): + raise MasterReportedException("Failed to initialise serial port") + + if not self.serial.is_open: + raise MasterReportedException("Failed to open serial port") + + if self.close_port_after_each_call: + self._print_debug("Closing serial port {}".format(port)) + self.serial.close() + + self._latest_roundtrip_time: Optional[float] = None + + def __repr__(self) -> str: + """Give string representation of the :class:`.Instrument` object.""" + template = ( + "{}.{}" + ) + return template.format( + self.__module__, + self.__class__.__name__, + id(self), + self.address, + self.mode, + self.close_port_after_each_call, + self.precalculate_read_size, + self.clear_buffers_before_each_transaction, + self.handle_local_echo, + self.debug, + self.serial, + ) + + @property + def roundtrip_time(self) -> Optional[float]: + """Latest measured round-trip time, in seconds. Read only. + + Note that the value is ``None`` if no data is available. + + The round-trip time is the time from minimalmodbus sends request data, + to the time it receives response data from the instrument. + It is basically the time spent waiting on external communication. + + Note that mimimalmodbus also sleeps (not included in the round trip time), + for example to fulfill the inter-message time interval or to give + slaves time to process broadcasted information. + + New in version 2.0 + """ + return self._latest_roundtrip_time + + def _print_debug(self, text: str) -> None: + if self.debug: + print("MinimalModbus debug mode. " + text) + + # ################################# # + # Methods for talking to the slave # + # ################################# # + + def read_bit(self, registeraddress: int, functioncode: int = 2) -> int: + """Read one bit from the slave (instrument). + + This is for a bit that has its individual address in the instrument. + + Args: + * registeraddress: The slave register address. + * functioncode Modbus function code. Can be 1 or 2. + + Returns: + The bit value 0 or 1. + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + """ + _check_functioncode(functioncode, [1, 2]) + return int( + self._generic_command( + functioncode, + registeraddress, + number_of_bits=1, + payloadformat=_Payloadformat.BIT, + ) + ) + + def write_bit( + self, registeraddress: int, value: int, functioncode: int = 5 + ) -> None: + """Write one bit to the slave (instrument). + + This is for a bit that has its individual address in the instrument. + + Args: + * registeraddress: The slave register address. + * value: 0 or 1, or True or False + * functioncode: Modbus function code. Can be 5 or 15. + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + """ + _check_functioncode(functioncode, [5, 15]) + _check_int(value, minvalue=0, maxvalue=1, description="input value") + self._generic_command( + functioncode, + registeraddress, + value, + number_of_bits=1, + payloadformat=_Payloadformat.BIT, + ) + + def read_bits( + self, registeraddress: int, number_of_bits: int, functioncode: int = 2 + ) -> List[int]: + """Read multiple bits from the slave (instrument). + + This is for bits that have individual addresses in the instrument. + + Args: + * registeraddress: The slave register start address. + * number_of_bits: Number of bits to read + * functioncode: Modbus function code. Can be 1 or 2. + + Returns: + A list of bit values 0 or 1. The first value in the list is for + the bit at the given address. + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + """ + _check_functioncode(functioncode, [1, 2]) + _check_int( + number_of_bits, + minvalue=1, + maxvalue=_MAX_NUMBER_OF_BITS_TO_READ, + description="number of bits", + ) + returnvalue = self._generic_command( + functioncode, + registeraddress, + number_of_bits=number_of_bits, + payloadformat=_Payloadformat.BITS, + ) + # Make sure that we really return a list of integers + assert isinstance(returnvalue, list) + return [int(x) for x in returnvalue] + + def write_bits(self, registeraddress: int, values: List[int]) -> None: + """Write multiple bits to the slave (instrument). + + This is for bits that have individual addresses in the instrument. + + Uses Modbus functioncode 15. + + Args: + * registeraddress: The slave register start address. + * values: List of 0 or 1, or True or False. The first + value in the list is for the bit at the given address. + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + """ + if not isinstance(values, list): + raise TypeError( + 'The "values parameter" must be a list. Given: {0!r}'.format(values) + ) + # Note: The content of the list is checked at content conversion. + _check_int( + len(values), + minvalue=1, + maxvalue=_MAX_NUMBER_OF_BITS_TO_WRITE, + description="length of input list", + ) + + self._generic_command( + 15, + registeraddress, + values, + number_of_bits=len(values), + payloadformat=_Payloadformat.BITS, + ) + + def read_register( + self, + registeraddress: int, + number_of_decimals: int = 0, + functioncode: int = 3, + signed: bool = False, + ) -> Union[int, float]: + """Read an integer from one 16-bit register in the slave, possibly scaling it. + + The slave register can hold integer values in the range 0 to 65535 + ("Unsigned INT16"). + + Args: + * registeraddress: The slave register address. + * number_of_decimals: The number of decimals for content conversion. + * functioncode: Modbus function code. Can be 3 or 4. + * signed: Whether the data should be interpreted as unsigned or signed. + + .. note:: The parameter number_of_decimals was named numberOfDecimals + before MinimalModbus 1.0 + + If a value of 77.0 is stored internally in the slave register as 770, + then use ``number_of_decimals=1`` which will divide the received data by 10 + before returning the value. + + Similarly ``number_of_decimals=2`` will divide the received data by 100 before + returning the value. + + Some manufacturers allow negative values for some registers. Instead of + an allowed integer range 0 to 65535, a range -32768 to 32767 is allowed. + This is implemented as any received value in the upper range (32768 to + 65535) is interpreted as negative value (in the range -32768 to -1). + + Use the parameter ``signed=True`` if reading from a register that can hold + negative values. Then upper range data will be automatically converted into + negative return values (two's complement). + + ============== ================== ================ =============== + ``signed`` Data type in slave Alternative name Range + ============== ================== ================ =============== + :const:`False` Unsigned INT16 Unsigned short 0 to 65535 + :const:`True` INT16 Short -32768 to 32767 + ============== ================== ================ =============== + + Returns: + The register data in numerical value (int or float). + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + """ + _check_functioncode(functioncode, [3, 4]) + _check_int( + number_of_decimals, + minvalue=0, + maxvalue=_MAX_NUMBER_OF_DECIMALS, + description="number of decimals", + ) + _check_bool(signed, description="signed") + returnvalue = self._generic_command( + functioncode, + registeraddress, + number_of_decimals=number_of_decimals, + number_of_registers=1, + signed=signed, + payloadformat=_Payloadformat.REGISTER, + ) + if int(returnvalue) == returnvalue: + return int(returnvalue) + return float(returnvalue) + + def write_register( + self, + registeraddress: int, + value: Union[int, float], + number_of_decimals: int = 0, + functioncode: int = 16, + signed: bool = False, + ) -> None: + """Write an integer to one 16-bit register in the slave, possibly scaling it. + + The slave register can hold integer values in the range 0 to + 65535 ("Unsigned INT16"). + + Args: + * registeraddress: The slave register address. + * value (int or float): The value to store in the slave register (might be + scaled before sending). + * number_of_decimals: The number of decimals for content conversion. + * functioncode: Modbus function code. Can be 6 or 16. + * signed: Whether the data should be interpreted as unsigned or signed. + + .. note:: The parameter number_of_decimals was named numberOfDecimals + before MinimalModbus 1.0 + + To store for example ``value=77.0``, use ``number_of_decimals=1`` if the + slave register will hold it as 770 internally. This will multiply ``value`` by + 10 before sending it to the slave register. + + Similarly ``number_of_decimals=2`` will multiply ``value`` by 100 before sending + it to the slave register. + + As the largest number that can be written to a register is 0xFFFF = 65535, + the ``value`` and ``number_of_decimals`` should max be 65535 when combined. + So when using ``number_of_decimals=3`` the maximum ``value`` is 65.535. + + For discussion on negative values, the range and on alternative names, + see :meth:`.read_register`. + + Use the parameter ``signed=True`` if writing to a register that can hold + negative values. Then negative input will be automatically converted into + upper range data (two's complement). + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + """ + _check_functioncode(functioncode, [6, 16]) + _check_int( + number_of_decimals, + minvalue=0, + maxvalue=_MAX_NUMBER_OF_DECIMALS, + description="number of decimals", + ) + _check_bool(signed, description="signed") + _check_numerical(value, description="input value") + + self._generic_command( + functioncode, + registeraddress, + value, + number_of_decimals=number_of_decimals, + number_of_registers=1, + signed=signed, + payloadformat=_Payloadformat.REGISTER, + ) + + def read_long( + self, + registeraddress: int, + functioncode: int = 3, + signed: bool = False, + byteorder: int = BYTEORDER_BIG, + number_of_registers: int = 2, + ) -> int: + """Read a long integer (32 or 64 bits) from the slave. + + Long integers (32 bits = 4 bytes or 64 bits = 8 bytes) are stored in + two or four consecutive 16-bit registers in the slave respectively. + + Args: + * registeraddress: The slave register start address. + * functioncode: Modbus function code. Can be 3 or 4. + * signed: Whether the data should be interpreted as unsigned or signed. + * byteorder: How multi-register data should be interpreted. + Use the BYTEORDER_xxx constants. Defaults to + :data:`minimalmodbus.BYTEORDER_BIG`. + * number_of_registers: The number of registers allocated for the long. + Can be 2 or 4. (New in version 2.1) + + + ======================= ============== =============== ===================== + ``number_of_registers`` ``signed`` Slave data type Range + ======================= ============== =============== ===================== + 2 :const:`False` Unsigned INT32 0 to 4294967295 + 2 :const:`True` INT32 -2147483648 to 2147483647 + 4 :const:`False` Unsigned INT64 0 to approx 1.8E19 + 4 :const:`True` INT64 Approx -9.2E18 to 9.2E18 + ======================= ============== =============== ===================== + + Returns: + The numerical value. + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + """ + _check_functioncode(functioncode, [3, 4]) + _check_bool(signed, description="signed") + _check_int( + number_of_registers, + minvalue=2, + maxvalue=4, + description="number of registers", + ) + return int( + self._generic_command( + functioncode, + registeraddress, + number_of_registers=number_of_registers, + signed=signed, + byteorder=byteorder, + payloadformat=_Payloadformat.LONG, + ) + ) + + def write_long( + self, + registeraddress: int, + value: int, + signed: bool = False, + byteorder: int = BYTEORDER_BIG, + number_of_registers: int = 2, + ) -> None: + """Write a long integer (32 or 64 bits) to the slave. + + Long integers (32 bits = 4 bytes or 64 bits = 8 bytes) are stored in + two or four consecutive 16-bit registers in the slave respectively. + + Uses Modbus function code 16. + + For discussion on number of bits, number of registers and the range, + see :meth:`.read_long`. + + Args: + * registeraddress: The slave register start address. + * value: The value to store in the slave. + * signed: Whether the data should be interpreted as unsigned or signed. + * byteorder: How multi-register data should be interpreted. + Use the BYTEORDER_xxx constants. Defaults to + :data:`minimalmodbus.BYTEORDER_BIG`. + * number_of_registers: The number of registers allocated for the long. + Can be 2 or 4. (New in version 2.1) + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + """ + MAX_VALUE_LONG = 4294967295 # Unsigned INT32 + MIN_VALUE_LONG = -2147483648 # INT32 + MAX_VALUE_LONG_LONG = 18446744073709551615 # Unsigned INT64 + MIN_VALUE_LONG_LONG = -9223372036854775808 # INT64 + + _check_int( + number_of_registers, + minvalue=2, + maxvalue=4, + description="number of registers", + ) + if number_of_registers == 2: + _check_int( + value, + minvalue=MIN_VALUE_LONG, + maxvalue=MAX_VALUE_LONG, + description="input value", + ) + elif number_of_registers == 4: + _check_int( + value, + minvalue=MIN_VALUE_LONG_LONG, + maxvalue=MAX_VALUE_LONG_LONG, + description="input value", + ) + _check_bool(signed, description="signed") + self._generic_command( + 16, + registeraddress, + value, + number_of_registers=number_of_registers, + signed=signed, + byteorder=byteorder, + payloadformat=_Payloadformat.LONG, + ) + + def read_float( + self, + registeraddress: int, + functioncode: int = 3, + number_of_registers: int = 2, + byteorder: int = BYTEORDER_BIG, + ) -> float: + r"""Read a floating point number from the slave. + + Floats are stored in two or more consecutive 16-bit registers in the slave. + The encoding is according to the standard IEEE 754. + + There are differences in the byte order used by different manufacturers. + A floating point value of 1.0 is encoded (in single precision) as 3f800000 + (hex). In this implementation the data will be sent as ``'\x3f\x80'`` + and ``'\x00\x00'`` to two consecutetive registers by default. Make sure to + test that it makes sense for your instrument. If not, change the + ``byteorder`` argument. + + Args: + * registeraddress : The slave register start address. + * functioncode: Modbus function code. Can be 3 or 4. + * number_of_registers: The number of registers allocated for the float. + Can be 2 or 4. + * byteorder: How multi-register data should be interpreted. + Use the BYTEORDER_xxx constants. Defaults to + :data:`minimalmodbus.BYTEORDER_BIG`. + + .. note:: The parameter number_of_registers was named numberOfRegisters + before MinimalModbus 1.0 + + =============================== ================= =========== ================= + Type of floating point in slave Size Registers Range + =============================== ================= =========== ================= + Single precision (binary32) 32 bits (4 bytes) 2 registers 1.4E-45 to 3.4E38 + Double precision (binary64) 64 bits (8 bytes) 4 registers 5E-324 to 1.8E308 + =============================== ================= =========== ================= + + Returns: + The numerical value. + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + """ + _check_functioncode(functioncode, [3, 4]) + _check_int( + number_of_registers, + minvalue=2, + maxvalue=4, + description="number of registers", + ) + return float( + self._generic_command( + functioncode, + registeraddress, + number_of_registers=number_of_registers, + byteorder=byteorder, + payloadformat=_Payloadformat.FLOAT, + ) + ) + + def write_float( + self, + registeraddress: int, + value: Union[int, float], + number_of_registers: int = 2, + byteorder: int = BYTEORDER_BIG, + ) -> None: + """Write a floating point number to the slave. + + Floats are stored in two or more consecutive 16-bit registers in the slave. + + Uses Modbus function code 16. + + For discussion on precision, number of registers and on byte order, + see :meth:`.read_float`. + + Args: + * registeraddress: The slave register start address. + * value (float or int): The value to store in the slave + * number_of_registers: The number of registers allocated for the float. + Can be 2 or 4. + * byteorder: How multi-register data should be interpreted. + Use the BYTEORDER_xxx constants. Defaults to + :data:`minimalmodbus.BYTEORDER_BIG`. + + .. note:: The parameter number_of_registers was named numberOfRegisters + before MinimalModbus 1.0 + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + """ + _check_numerical(value, description="input value") + _check_int( + number_of_registers, + minvalue=2, + maxvalue=4, + description="number of registers", + ) + self._generic_command( + 16, + registeraddress, + value, + number_of_registers=number_of_registers, + byteorder=byteorder, + payloadformat=_Payloadformat.FLOAT, + ) + + def read_string( + self, registeraddress: int, number_of_registers: int = 16, functioncode: int = 3 + ) -> str: + """Read an ASCII string from the slave. + + Each 16-bit register in the slave are interpreted as two characters + (each 1 byte = 8 bits). For example 16 consecutive registers can hold 32 + characters (32 bytes). + + International characters (Unicode/UTF-8) are not supported. + + Args: + * registeraddress: The slave register start address. + * number_of_registers: The number of registers allocated for the string. + * functioncode: Modbus function code. Can be 3 or 4. + + .. note:: The parameter number_of_registers was named numberOfRegisters + before MinimalModbus 1.0 + + Returns: + The string. + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + """ + _check_functioncode(functioncode, [3, 4]) + _check_int( + number_of_registers, + minvalue=1, + maxvalue=_MAX_NUMBER_OF_REGISTERS_TO_READ, + description="number of registers for read string", + ) + return str( + self._generic_command( + functioncode, + registeraddress, + number_of_registers=number_of_registers, + payloadformat=_Payloadformat.STRING, + ) + ) + + def write_string( + self, registeraddress: int, textstring: str, number_of_registers: int = 16 + ) -> None: + """Write an ASCII string to the slave. + + Each 16-bit register in the slave are interpreted as two characters + (each 1 byte = 8 bits). For example 16 consecutive registers can hold 32 + characters (32 bytes). + + Uses Modbus function code 16. + + International characters (Unicode/UTF-8) are not supported. + + Args: + * registeraddress: The slave register start address. + * textstring: The string to store in the slave, must be ASCII. + * number_of_registers: The number of registers allocated for the string. + + .. note:: The parameter number_of_registers was named numberOfRegisters + before MinimalModbus 1.0 + + If the ``textstring`` is longer than the ``2*number_of_registers``, an + error is raised. Shorter strings are padded with spaces. + + Returns: + None + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + """ + _check_int( + number_of_registers, + minvalue=1, + maxvalue=_MAX_NUMBER_OF_REGISTERS_TO_WRITE, + description="number of registers for write string", + ) + _check_string( + textstring, + "input string", + minlength=1, + maxlength=2 * number_of_registers, + force_ascii=True, + ) + self._generic_command( + 16, + registeraddress, + textstring, + number_of_registers=number_of_registers, + payloadformat=_Payloadformat.STRING, + ) + + def read_registers( + self, registeraddress: int, number_of_registers: int, functioncode: int = 3 + ) -> List[int]: + """Read integers from 16-bit registers in the slave. + + The slave registers can hold integer values in the range 0 to + 65535 ("Unsigned INT16"). + + Args: + * registeraddress: The slave register start address. + * number_of_registers: The number of registers to read, max 125 registers. + * functioncode: Modbus function code. Can be 3 or 4. + + .. note:: The parameter number_of_registers was named numberOfRegisters + before MinimalModbus 1.0 + + Any scaling of the register data, or converting it to negative number + (two's complement) must be done manually. + + Returns: + The register data. The first value in the list is for + the register at the given address. + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + """ + _check_functioncode(functioncode, [3, 4]) + _check_int( + number_of_registers, + minvalue=1, + maxvalue=_MAX_NUMBER_OF_REGISTERS_TO_READ, + description="number of registers", + ) + returnvalue = self._generic_command( + functioncode, + registeraddress, + number_of_registers=number_of_registers, + payloadformat=_Payloadformat.REGISTERS, + ) + # Make sure that we really return a list of integers + assert isinstance(returnvalue, list) + return [int(x) for x in returnvalue] + + def write_registers(self, registeraddress: int, values: List[int]) -> None: + """Write integers to 16-bit registers in the slave. + + The slave register can hold integer values in the range 0 to + 65535 ("Unsigned INT16"). + + Uses Modbus function code 16. + + The number of registers that will be written is defined by the length of + the ``values`` list. + + Args: + * registeraddress: The slave register start address. + * values: The values to store in the slave registers, + max 123 values. The first value in the list is for the register + at the given address. + + .. note:: The parameter number_of_registers was named numberOfRegisters + before MinimalModbus 1.0 + + Any scaling of the register data, or converting it to negative number + (two's complement) must be done manually. + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + """ + if not isinstance(values, list): + raise TypeError( + 'The "values parameter" must be a list. Given: {0!r}'.format(values) + ) + _check_int( + len(values), + minvalue=1, + maxvalue=_MAX_NUMBER_OF_REGISTERS_TO_WRITE, + description="length of input list", + ) + # Note: The content of the list is checked at content conversion. + + self._generic_command( + 16, + registeraddress, + values, + number_of_registers=len(values), + payloadformat=_Payloadformat.REGISTERS, + ) + + # ############### # + # Generic command # + # ############### # + + def _generic_command( + self, + functioncode: int, + registeraddress: int, + value: Union[None, str, int, float, List[int]] = None, + number_of_decimals: int = 0, + number_of_registers: int = 0, + number_of_bits: int = 0, + signed: bool = False, + byteorder: int = BYTEORDER_BIG, + payloadformat: _Payloadformat = _Payloadformat.REGISTER, + ) -> Any: + """Perform generic command for reading and writing registers and bits. + + Args: + * functioncode: Modbus function code. + * registeraddress: The register address. + * value (numerical or string or None or list of int): The value to store + in the register. Depends on payloadformat. + * number_of_decimals: The number of decimals for content conversion. + Only for a single register. + * number_of_registers: The number of registers to read/write. + Only certain values allowed, depends on payloadformat. + * number_of_bits: The number of bits to read/write. + * signed: Whether the data should be interpreted as unsigned or signed. + Only for a single register or for payloadformat='long'. + * byteorder: How multi-register data should be interpreted. + * payloadformat: An _Payloadformat enum + + If a value of 77.0 is stored internally in the slave register as 770, + then use ``number_of_decimals=1`` which will divide the received data + from the slave by 10 before returning the value. Similarly + ``number_of_decimals=2`` will divide the received data by 100 before returning + the value. Same functionality is also used when writing data to the slave. + + Returns: + The register data in numerical value (int or float), or the bit value 0 or + 1 (int), or a list of int, or ``None``. + + Returns ``None`` for all write function codes. + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + """ + ALL_ALLOWED_FUNCTIONCODES = [1, 2, 3, 4, 5, 6, 15, 16] + ALLOWED_FUNCTIONCODES_BROADCAST = [5, 6, 15, 16] + ALLOWED_FUNCTIONCODES = {} + ALLOWED_FUNCTIONCODES[_Payloadformat.BIT] = [1, 2, 5, 15] + ALLOWED_FUNCTIONCODES[_Payloadformat.BITS] = [1, 2, 15] + ALLOWED_FUNCTIONCODES[_Payloadformat.REGISTER] = [3, 4, 6, 16] + ALLOWED_FUNCTIONCODES[_Payloadformat.FLOAT] = [3, 4, 16] + ALLOWED_FUNCTIONCODES[_Payloadformat.STRING] = [3, 4, 16] + ALLOWED_FUNCTIONCODES[_Payloadformat.LONG] = [3, 4, 16] + ALLOWED_FUNCTIONCODES[_Payloadformat.REGISTERS] = [3, 4, 16] + + # Check input values + _check_functioncode(functioncode, ALL_ALLOWED_FUNCTIONCODES) + _check_registeraddress(registeraddress) + _check_int( + number_of_decimals, + minvalue=0, + maxvalue=_MAX_NUMBER_OF_DECIMALS, + description="number of decimals", + ) + _check_int( + number_of_registers, + minvalue=0, + maxvalue=max( + _MAX_NUMBER_OF_REGISTERS_TO_READ, _MAX_NUMBER_OF_REGISTERS_TO_WRITE + ), + description="number of registers", + ) + _check_int( + number_of_bits, + minvalue=0, + maxvalue=max(_MAX_NUMBER_OF_BITS_TO_READ, _MAX_NUMBER_OF_BITS_TO_WRITE), + description="number of bits", + ) + _check_bool(signed, description="signed") + _check_int( + byteorder, + minvalue=0, + maxvalue=_MAX_BYTEORDER_VALUE, + description="byteorder", + ) + + if not isinstance(payloadformat, _Payloadformat): + raise TypeError( + "The payload format should be an enum of type _Payloadformat. " + + "Given: {!r}".format(payloadformat) + ) + + number_of_register_bytes = number_of_registers * _NUMBER_OF_BYTES_PER_REGISTER + + # Check combinations: Payload format and functioncode + if functioncode not in ALLOWED_FUNCTIONCODES[payloadformat]: + raise ValueError( + "Wrong functioncode for payloadformat " + + "{!r}. Given: {!r}.".format(payloadformat, functioncode) + ) + + # Check combinations: Broadcast and functioncode + if ( + self.address == _SLAVEADDRESS_BROADCAST + and functioncode not in ALLOWED_FUNCTIONCODES_BROADCAST + ): + raise ValueError( + f"Wrong functioncode for broadcast. Given: {functioncode!r}" + ) + + # Check combinations: signed + if signed: + if payloadformat not in [_Payloadformat.REGISTER, _Payloadformat.LONG]: + raise ValueError( + 'The "signed" parameter can not be used for this payload format. ' + + "Given format: {!r}.".format(payloadformat) + ) + + # Check combinations: number_of_decimals + if number_of_decimals > 0: + if payloadformat != _Payloadformat.REGISTER: + raise ValueError( + 'The "number_of_decimals" parameter can not be used for this ' + + "payload format. Given format: {0!r}.".format(payloadformat) + ) + + # Check combinations: byteorder + if byteorder: + if payloadformat not in [_Payloadformat.FLOAT, _Payloadformat.LONG]: + raise ValueError( + 'The "byteorder" parameter can not be used for this payload' + + " format. Given format: {0!r}.".format(payloadformat) + ) + + # Check combinations: number of bits + if payloadformat == _Payloadformat.BIT: + if number_of_bits != 1: + raise ValueError( + "For BIT payload format the number of bits should be 1. " + + "Given: {0!r}.".format(number_of_bits) + ) + elif payloadformat == _Payloadformat.BITS: + if number_of_bits < 1: + raise ValueError( + "For BITS payload format the number of bits should be at least 1. " + + "Given: {0!r}.".format(number_of_bits) + ) + elif number_of_bits: + raise ValueError( + "The number_of_bits parameter is wrong for payload format " + + "{0!r}. Given: {1!r}.".format(payloadformat, number_of_bits) + ) + + # Check combinations: Number of registers + if functioncode in [1, 2, 5, 15] and number_of_registers: + raise ValueError( + "The number_of_registers is not valid for this function code. " + + "number_of_registers: {0!r}, functioncode {1}.".format( + number_of_registers, functioncode + ) + ) + if functioncode in [3, 4, 16] and not number_of_registers: + raise ValueError( + "The number_of_registers must be > 0 for functioncode " + + "{}.".format(functioncode) + ) + if functioncode == 6 and number_of_registers != 1: + raise ValueError( + "The number_of_registers must be 1 for functioncode 6. " + + "Given: {}.".format(number_of_registers) + ) + if ( + functioncode == 16 + and payloadformat == _Payloadformat.REGISTER + and number_of_registers != 1 + ): + raise ValueError( + "Wrong number_of_registers when writing to a " + + "single register. Given {0!r}.".format(number_of_registers) + ) + # Note: For function code 16 there is checking also in the content + # conversion functions. + + # Number of registers for float and long + if payloadformat == _Payloadformat.FLOAT and number_of_registers not in [2, 4]: + raise ValueError( + "The number of registers for float must be 2 or 4. " + + "Given {0!r}".format(number_of_registers) + ) + if payloadformat == _Payloadformat.LONG and number_of_registers not in [2, 4]: + raise ValueError( + "The number of registers for long must be 2 or 4. " + + "Given {0!r}".format(number_of_registers) + ) + + # Check combinations: Value + if functioncode in [5, 6, 15, 16] and value is None: + raise ValueError( + "The input value must be given for this function code. " + + "Given {0!r} and {1}.".format(value, functioncode) + ) + if functioncode in [1, 2, 3, 4] and value is not None: + raise ValueError( + "The input value should not be given for this function code. " + + "Given {0!r} and {1}.".format(value, functioncode) + ) + + # Check combinations: Value for numerical + if ( + functioncode == 16 + and payloadformat + in [ + _Payloadformat.REGISTER, + _Payloadformat.FLOAT, + _Payloadformat.LONG, + ] + ) or (functioncode == 6 and payloadformat == _Payloadformat.REGISTER): + if not isinstance(value, (int, float)): + raise TypeError(f"The input value must be numerical. Given: {value!r}") + + # Check combinations: Value for string + if functioncode == 16 and payloadformat == _Payloadformat.STRING: + if not isinstance(value, str): + raise TypeError(f"The input should be a string. Given: {value!r}") + _check_string( + value, "input string", minlength=1, maxlength=number_of_register_bytes + ) + # Note: The string might be padded later, so the length might be shorter + # than number_of_register_bytes. + + # Check combinations: Value for registers + if functioncode == 16 and payloadformat == _Payloadformat.REGISTERS: + if not isinstance(value, list): + raise TypeError( + "The value parameter for payloadformat REGISTERS must be a list. " + + "Given {0!r}.".format(value) + ) + + if len(value) != number_of_registers: + raise ValueError( + "The list length does not match number of registers. " + + "List: {0!r}, Number of registers: {1!r}.".format( + value, number_of_registers + ) + ) + + # Check combinations: Value for bit + if functioncode in [5, 15] and payloadformat == _Payloadformat.BIT: + if not isinstance(value, int): + raise TypeError(f"The input should be an integer. Given: {value!r}") + _check_int( + value, + minvalue=0, + maxvalue=1, + description="input value for payload format BIT", + ) + + # Check combinations: Value for bits + if functioncode == 15 and payloadformat == _Payloadformat.BITS: + if not isinstance(value, list): + raise TypeError( + "The value parameter for payloadformat BITS must be a list. " + + "Given {0!r}.".format(value) + ) + + if len(value) != number_of_bits: + raise ValueError( + "The list length does not match number of bits. " + + "List: {0!r}, Number of registers: {1!r}.".format( + value, number_of_registers + ) + ) + + # Create payload + payload_to_slave = _create_payload( + functioncode, + registeraddress, + value, + number_of_decimals, + number_of_registers, + number_of_bits, + signed, + byteorder, + payloadformat, + ) + + # Communicate with instrument + payload_from_slave = self._perform_command(functioncode, payload_to_slave) + + # There is no response for broadcasts + if self.address == _SLAVEADDRESS_BROADCAST: + return None + + # Parse response payload + return _parse_payload( + payload_from_slave, + functioncode, + registeraddress, + value, + number_of_decimals, + number_of_registers, + number_of_bits, + signed, + byteorder, + payloadformat, + ) + + # #################################### # + # Communication implementation details # + # #################################### # + + def _perform_command(self, functioncode: int, payload_to_slave: bytes) -> bytes: + """Perform the command having the *functioncode*. + + Args: + * functioncode: The function code for the command to be performed. + Can for example be 'Write register' = 16. + * payload_to_slave: Data to be transmitted to the slave (will be + embedded in slaveaddress, CRC etc) + + Returns: + The extracted data payload from the slave. It has been + stripped of CRC etc. + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + + Makes use of the :meth:`_communicate` method. The request is generated + with the :func:`_embed_payload` function, and the parsing of the + response is done with the :func:`_extract_payload` function. + """ + DEFAULT_NUMBER_OF_BYTES_TO_READ = 1000 + + _check_functioncode(functioncode, None) + _check_bytes(payload_to_slave, description="payload") + + # Build request + request_bytes = _embed_payload( + self.address, self.mode, functioncode, payload_to_slave + ) + + # Calculate number of bytes to read + number_of_bytes_to_read = DEFAULT_NUMBER_OF_BYTES_TO_READ + if self.address == _SLAVEADDRESS_BROADCAST: + number_of_bytes_to_read = 0 + elif self.precalculate_read_size: + try: + number_of_bytes_to_read = _predict_response_size( + self.mode, functioncode, payload_to_slave + ) + except Exception: + if self.debug: + template = ( + "Could not precalculate response size for Modbus {} mode. " + + "Will read {} bytes. Request: {!r}" + ) + self._print_debug( + template.format( + self.mode, number_of_bytes_to_read, request_bytes + ) + ) + + # Communicate + response_bytes = self._communicate(request_bytes, number_of_bytes_to_read) + + if number_of_bytes_to_read == 0: + return b"" + + # Extract payload + payload_from_slave = _extract_payload( + response_bytes, self.address, self.mode, functioncode + ) + return payload_from_slave + + def _communicate(self, request: bytes, number_of_bytes_to_read: int) -> bytes: + """Talk to the slave via a serial port. + + Args: + * request: The raw request that is to be sent to the slave. + * number_of_bytes_to_read: Number of bytes to read + + Returns: + The raw data returned from the slave. + + Raises: + TypeError, ValueError, ModbusException, + serial.SerialException (inherited from IOError) + + Sleeps if the previous message arrived less than the "silent period" ago. + + Will block until reaching *number_of_bytes_to_read* or timeout. + + Additional delay will be used after broadcast transmissions (slave address 0). + + If the attribute :attr:`Instrument.debug` is :const:`True`, the communication + details are printed. + + If the attribute :attr:`Instrument.close_port_after_each_call` is :const:`True` + the serial port is closed after each call. + + Timing:: + + Request from master (Master is writing) + | + | Response from slave + | (Master is reading) + | | + --------R-------W-----------------------------R-------W-------------------- + | | | + | |<------- Roundtrip time ------>| + | | + -->|-----|<----- Silent period + + The resolution for Python's :py:func:`time.time()` is lower on Windows than + on Linux. + It is about 16 ms on Windows according to + stackoverflow.com/questions/157359/accurate-timestamping-in-python-logging + """ + _check_bytes(request, minlength=1, description="request") + _check_int(number_of_bytes_to_read) + + self._print_debug( + "Will write to instrument (expecting {} bytes back): {}".format( + number_of_bytes_to_read, _describe_bytes(request) + ) + ) + + if self.serial is None: + raise ModbusException("The serial port instance is None") + + if not self.serial.is_open: + self._print_debug("Opening port {}".format(self.serial.port)) + self.serial.open() + + portname: str = "" + if self.serial.port is not None: + portname = self.serial.port + + if self.clear_buffers_before_each_transaction: + self._print_debug("Clearing serial buffers for port {}".format(portname)) + self.serial.reset_input_buffer() + self.serial.reset_output_buffer() + + # Sleep to make sure 3.5 character times have passed + minimum_silent_period = _calculate_minimum_silent_period(self.serial.baudrate) + time_since_read = time.monotonic() - _latest_read_times.get(portname, 0) + + if time_since_read < minimum_silent_period: + sleep_time = minimum_silent_period - time_since_read + + if self.debug: + template = ( + "Sleeping {:.2f} ms before sending. " + + "Minimum silent period: {:.2f} ms, time since read: {:.2f} ms." + ) + text = template.format( + sleep_time * _SECONDS_TO_MILLISECONDS, + minimum_silent_period * _SECONDS_TO_MILLISECONDS, + time_since_read * _SECONDS_TO_MILLISECONDS, + ) + self._print_debug(text) + + time.sleep(sleep_time) + + elif self.debug: + template = ( + "No sleep required before write. Time since " + + "previous read: {:.2f} ms, minimum silent period: {:.2f} ms." + ) + text = template.format( + time_since_read * _SECONDS_TO_MILLISECONDS, + minimum_silent_period * _SECONDS_TO_MILLISECONDS, + ) + self._print_debug(text) + + # Write request + write_time = time.monotonic() + self.serial.write(request) + + # Read and discard local echo + if self.handle_local_echo: + local_echo_to_discard = self.serial.read(len(request)) + if self.debug: + text = "Discarding this local echo: {}".format( + _describe_bytes(local_echo_to_discard), + ) + self._print_debug(text) + if local_echo_to_discard != request: + template = ( + "Local echo handling is enabled, but the local echo does " + + "not match the sent request. " + + "Request: {}, local echo: {}." + ) + text = template.format( + _describe_bytes(request), + _describe_bytes(local_echo_to_discard), + ) + raise LocalEchoError(text) + + # Read response + if number_of_bytes_to_read > 0: + answer = self.serial.read(number_of_bytes_to_read) + else: + answer = b"" + self.serial.flush() + + read_time = time.monotonic() + _latest_read_times[portname] = read_time + roundtrip_time = read_time - write_time + self._latest_roundtrip_time = roundtrip_time + + if self.close_port_after_each_call: + self._print_debug("Closing port {}".format(portname)) + self.serial.close() + + if self.debug: + if isinstance(self.serial.timeout, float): + timeout_time = self.serial.timeout * _SECONDS_TO_MILLISECONDS + else: + timeout_time = 0 + text = ( + "Response from instrument: {}, roundtrip time: {:.1f} ms." + " Timeout for reading: {:.1f} ms.\n" + ).format( + _describe_bytes(answer), + roundtrip_time, + timeout_time, + ) + self._print_debug(text) + + if not answer and number_of_bytes_to_read > 0: + raise NoResponseError("No communication with the instrument (no answer)") + + if number_of_bytes_to_read == 0: + self._print_debug( + "Broadcast delay: Sleeping for {} s".format(_BROADCAST_DELAY) + ) + time.sleep(_BROADCAST_DELAY) + + return answer + + +# ########## # +# Exceptions # +# ########## # + + +class ModbusException(IOError): + """Base class for Modbus communication exceptions. + + Inherits from IOError, which is an alias for OSError in Python3. + """ + + +class SlaveReportedException(ModbusException): + """Base class for exceptions that the slave (instrument) reports.""" + + +class SlaveDeviceBusyError(SlaveReportedException): + """The slave is busy processing some command.""" + + +class NegativeAcknowledgeError(SlaveReportedException): + """The slave can not fulfil the programming request. + + This typically happens when using function code 13 or 14 decimal. + """ + + +class IllegalRequestError(SlaveReportedException): + """The slave has received an illegal request.""" + + +class MasterReportedException(ModbusException): + """Base class for exceptions that the master (computer) detects.""" + + +class NoResponseError(MasterReportedException): + """No response from the slave.""" + + +class LocalEchoError(MasterReportedException): + """There is some problem with the local echo.""" + + +class InvalidResponseError(MasterReportedException): + """The response does not fulfill the Modbus standad, for example wrong checksum.""" + + +# ################ # +# Payload handling # +# ################ # + + +def _create_payload( + functioncode: int, + registeraddress: int, + value: Union[None, str, int, float, List[int]], + number_of_decimals: int, + number_of_registers: int, + number_of_bits: int, + signed: bool, + byteorder: int, + payloadformat: _Payloadformat, +) -> bytes: + """Create the payload. + + Error checking should have been done before calling this function. + + For argument descriptions, see the :py:meth:`_generic_command` method. + """ + if functioncode in [1, 2]: + return _num_to_two_bytes(registeraddress) + _num_to_two_bytes(number_of_bits) + if functioncode in [3, 4]: + return _num_to_two_bytes(registeraddress) + _num_to_two_bytes( + number_of_registers + ) + if functioncode == 5: + assert isinstance(value, int) + return _num_to_two_bytes(registeraddress) + _bit_to_bytes(value) + if functioncode == 6: + assert isinstance(value, (int, float)) + return _num_to_two_bytes(registeraddress) + _num_to_two_bytes( + value, number_of_decimals, signed=signed + ) + if functioncode == 15: + if payloadformat == _Payloadformat.BIT and isinstance(value, int): + bitlist = [value] + elif payloadformat == _Payloadformat.BITS and isinstance(value, list): + bitlist = value + else: + raise ValueError( + f"Wrong payloadformat {payloadformat} or type " + + "for the value for function code 15" + ) + number_of_bytes_for_bits = _calculate_number_of_bytes_for_bits(number_of_bits) + return ( + _num_to_two_bytes(registeraddress) + + _num_to_two_bytes(number_of_bits) + + number_of_bytes_for_bits.to_bytes(1, "big") + + _bits_to_bytes(bitlist) + ) + if functioncode == 16: + if payloadformat == _Payloadformat.REGISTER: + assert isinstance(value, (int, float)) + registerdata = _num_to_two_bytes(value, number_of_decimals, signed=signed) + elif payloadformat == _Payloadformat.STRING: + assert isinstance(value, str) + registerdata = _textstring_to_bytes(value, number_of_registers) + elif payloadformat == _Payloadformat.LONG: + assert isinstance(value, int) + registerdata = _long_to_bytes(value, signed, number_of_registers, byteorder) + elif payloadformat == _Payloadformat.FLOAT: + assert isinstance(value, float) or isinstance(value, int) + registerdata = _float_to_bytes(value, number_of_registers, byteorder) + elif payloadformat == _Payloadformat.REGISTERS: + assert isinstance(value, list) + registerdata = _valuelist_to_bytes(value, number_of_registers) + else: + raise ValueError( + f"Wrong payloadformat '{payloadformat}' for function code 16" + ) + assert len(registerdata) == number_of_registers * _NUMBER_OF_BYTES_PER_REGISTER + + registerdata_bytecount = len(registerdata) + return ( + _num_to_two_bytes(registeraddress) + + _num_to_two_bytes(number_of_registers) + + registerdata_bytecount.to_bytes(1, "big") + + registerdata + ) + raise ValueError("Wrong function code: " + str(functioncode)) + + +def _parse_payload( + payload: bytes, + functioncode: int, + registeraddress: int, + value: Any, + number_of_decimals: int, + number_of_registers: int, + number_of_bits: int, + signed: bool, + byteorder: int, + payloadformat: _Payloadformat, +) -> Union[None, str, int, float, List[int], List[float]]: + """Extract the payload data from a response. + + Args: + * payload: Payload to be parsed + * functioncode: Function code + * registeraddress: Register address for error checking + * value: Value in request, for error checking + * number_of_decimals: Number of decimals + * number_of_registers: Number of registers + * number_of_bits: Number of bits + * signed: Signed + * byteorder: Byte order + * payloadformat: Payload format + + Returns: + The parsed payload. + """ + _check_response_payload( + payload, + functioncode, + registeraddress, + value, + number_of_decimals, + number_of_registers, + number_of_bits, + signed, + byteorder, + payloadformat, + ) + + if functioncode in [1, 2]: + registerdata = payload[_NUMBER_OF_BYTES_BEFORE_REGISTERDATA:] + if payloadformat == _Payloadformat.BIT: + return _bytes_to_bits(registerdata, number_of_bits)[0] + if payloadformat == _Payloadformat.BITS: + return _bytes_to_bits(registerdata, number_of_bits) + + if functioncode in [3, 4]: + registerdata = payload[_NUMBER_OF_BYTES_BEFORE_REGISTERDATA:] + if payloadformat == _Payloadformat.STRING: + return _bytes_to_textstring(registerdata, number_of_registers) + + if payloadformat == _Payloadformat.LONG: + return _bytes_to_long(registerdata, signed, number_of_registers, byteorder) + + if payloadformat == _Payloadformat.FLOAT: + return _bytes_to_float(registerdata, number_of_registers, byteorder) + + if payloadformat == _Payloadformat.REGISTERS: + return _bytes_to_valuelist(registerdata, number_of_registers) + + if payloadformat == _Payloadformat.REGISTER: + return _two_bytes_to_num(registerdata, number_of_decimals, signed=signed) + + if functioncode in [5, 6, 15, 16]: + # Response to write + return None + + raise ValueError( + f"Wrong function code {functioncode} and payloadformat {payloadformat!r}" + + " combination" + ) + + +def _embed_payload( + slaveaddress: int, mode: str, functioncode: int, payloaddata: bytes +) -> bytes: + """Build a request from the slaveaddress, the function code and the payload data. + + Args: + * slaveaddress: The address of the slave. + * mode: The modbus protcol mode (MODE_RTU or MODE_ASCII) + * functioncode: The function code for the command to be performed. + Can for example be 16 (Write register). + * payloaddata: The bytes to be sent to the slave. + + Returns: + The built (raw) request for sending to the slave (including CRC etc). + + Raises: + ValueError, TypeError. + + The resulting request has the format: + * RTU Mode: slaveaddress byte + functioncode byte + payloaddata + CRC (two bytes). + * ASCII Mode: header (``:``) + slaveaddress (2 characters) + functioncode + (2 characters) + payloaddata + LRC (which is two characters) + footer (CR+LF) + + The LRC or CRC is calculated from the bytes made up of slaveaddress + + functioncode + payloaddata. + The header, LRC/CRC, and footer are excluded from the calculation. + """ + _check_slaveaddress(slaveaddress) + _check_mode(mode) + _check_functioncode(functioncode, None) + _check_bytes(payloaddata, description="payload") + + first_part = ( + _num_to_one_byte(slaveaddress) + _num_to_one_byte(functioncode) + payloaddata + ) + + if mode == MODE_ASCII: + request = ( + _ASCII_HEADER + + _hexencode(first_part) + + _hexencode(_calculate_lrc(first_part)) + + _ASCII_FOOTER + ) + else: + request = first_part + _calculate_crc(first_part) + + return request + + +def _extract_payload( + response: bytes, slaveaddress: int, mode: str, functioncode: int +) -> bytes: + """Extract the payload data part from the slave's response. + + Args: + * response: The raw response bytes from the slave. + This is different for RTU and ASCII. + * slaveaddress: The adress of the slave. Used here for error checking only. + * mode: The modbus protocol mode (MODE_RTU or MODE_ASCII) + * functioncode: Used here for error checking only. + + Returns: + The payload part of the *response*. Conversion from Modbus ASCII + has been done if applicable. + + Raises: + ValueError, TypeError, ModbusException (or subclasses). + + Raises an exception if there is any problem with the received address, + the functioncode or the CRC. + + The received response should have the format: + + * RTU Mode: slaveaddress byte + functioncode byte + payloaddata + CRC (two bytes) + * ASCII Mode: header (``:``) + slaveaddress byte + functioncode byte + + payloaddata + LRC (which is two characters) + footer (CR+LF) + + For development purposes, this function can also be used to extract the payload + from the request sent **to** the slave. + """ + # Number of bytes before the response payload (in stripped response) + NUMBER_OF_RESPONSE_STARTBYTES = 2 + + NUMBER_OF_CRC_BYTES = 2 + NUMBER_OF_LRC_BYTES = 1 + MINIMAL_RESPONSE_LENGTH_RTU = NUMBER_OF_RESPONSE_STARTBYTES + NUMBER_OF_CRC_BYTES + MINIMAL_RESPONSE_LENGTH_ASCII = 9 + + # Argument validity testing (ValueError/TypeError at lib programming error) + _check_bytes(response, description="response") + _check_slaveaddress(slaveaddress) + _check_mode(mode) + _check_functioncode(functioncode, None) + + plainresponse = response + + # Validate response length + if mode == MODE_ASCII: + if len(response) < MINIMAL_RESPONSE_LENGTH_ASCII: + raise InvalidResponseError( + "Too short Modbus ASCII response (minimum " + + "length {} bytes). Response: {!r}".format( + MINIMAL_RESPONSE_LENGTH_ASCII, response + ) + ) + elif len(response) < MINIMAL_RESPONSE_LENGTH_RTU: + raise InvalidResponseError( + "Too short Modbus RTU response (minimum " + + "length {} bytes). Response: {!r}".format( + MINIMAL_RESPONSE_LENGTH_RTU, response + ) + ) + + if mode == MODE_ASCII: + # Validate the ASCII header and footer. + if response[_BYTEPOSITION_FOR_ASCII_HEADER].to_bytes(1, "big") != _ASCII_HEADER: + raise InvalidResponseError( + "Did not find header ({!r}) as start ".format(_ASCII_HEADER) + + "of ASCII response. The plain response is: {!r}".format(response) + ) + if response[-len(_ASCII_FOOTER) :] != _ASCII_FOOTER: + raise InvalidResponseError( + "Did not find footer " + + "({!r}) as end of ASCII response. The plain response is: {!r}".format( + _ASCII_FOOTER, response + ) + ) + + # Strip ASCII header and footer + response = response[1:-2] + + if len(response) % 2 != 0: + template = ( + "Stripped ASCII frames should have an even " + + "number of bytes, but is {} bytes. " + + "The stripped response is: {!r} (plain response: {!r})" + ) + raise InvalidResponseError( + template.format(len(response), response, plainresponse) + ) + + # Convert the ASCII (stripped) response string to RTU-like response string + response = _hexdecode(response) + + # Validate response checksum + if mode == MODE_ASCII: + calculate_checksum = _calculate_lrc + number_of_checksum_bytes = NUMBER_OF_LRC_BYTES + else: + calculate_checksum = _calculate_crc + number_of_checksum_bytes = NUMBER_OF_CRC_BYTES + + received_checksum = response[-number_of_checksum_bytes:] + response_without_checksum = response[0 : (len(response) - number_of_checksum_bytes)] + calculated_checksum = calculate_checksum(response_without_checksum) + + if received_checksum != calculated_checksum: + template = ( + "Checksum error in {} mode: {!r} instead of {!r} . The response " + + "is: {!r} (plain response: {!r})" + ) + text = template.format( + mode, received_checksum, calculated_checksum, response, plainresponse + ) + raise InvalidResponseError(text) + + # Check slave address + responseaddress = response[_BYTEPOSITION_FOR_SLAVEADDRESS] + + if responseaddress != slaveaddress: + raise InvalidResponseError( + "Wrong return slave " + + "address: {} instead of {}. The response is: {!r}".format( + responseaddress, slaveaddress, response + ) + ) + + # Check if slave indicates error + _check_response_slaveerrorcode(response) + + # Check function code + received_functioncode = response[_BYTEPOSITION_FOR_FUNCTIONCODE] + if received_functioncode != functioncode: + raise InvalidResponseError( + "Wrong functioncode: {} instead of {}. The response is: {!r}".format( + received_functioncode, functioncode, response + ) + ) + + # Read data payload + first_databyte_number = NUMBER_OF_RESPONSE_STARTBYTES + + if mode == MODE_ASCII: + last_databyte_number = len(response) - NUMBER_OF_LRC_BYTES + else: + last_databyte_number = len(response) - NUMBER_OF_CRC_BYTES + + payload = response[first_databyte_number:last_databyte_number] + return payload + + +# ###################################### # +# Serial communication utility functions # +# ###################################### # + + +def _predict_response_size( + mode: str, functioncode: int, payload_to_slave: bytes +) -> int: + """Calculate the number of bytes that should be received from the slave. + + Args: + * mode: The modbus protcol mode (MODE_RTU or MODE_ASCII) + * functioncode: Modbus function code. + * payload_to_slave: The raw request that is to be sent to the slave + (not hex encoded) + + Returns: + The predicted number of bytes in the response. + + Raises: + ValueError, TypeError. + """ + MIN_PAYLOAD_LENGTH = 4 # For the functioncodes implemented here + BYTERANGE_FOR_GIVEN_SIZE = slice(2, 4) # Within the payload + + NUMBER_OF_PAYLOAD_BYTES_IN_WRITE_CONFIRMATION = 4 + NUMBER_OF_PAYLOAD_BYTES_FOR_BYTECOUNTFIELD = 1 + + RTU_TO_ASCII_PAYLOAD_FACTOR = 2 + + NUMBER_OF_RTU_RESPONSE_STARTBYTES = 2 + NUMBER_OF_RTU_RESPONSE_ENDBYTES = 2 + NUMBER_OF_ASCII_RESPONSE_STARTBYTES = 5 + NUMBER_OF_ASCII_RESPONSE_ENDBYTES = 4 + + # Argument validity testing + _check_mode(mode) + _check_functioncode(functioncode, None) + _check_bytes(payload_to_slave, description="payload", minlength=MIN_PAYLOAD_LENGTH) + + # Calculate payload size + if functioncode in [5, 6, 15, 16]: + response_payload_size = NUMBER_OF_PAYLOAD_BYTES_IN_WRITE_CONFIRMATION + + elif functioncode in [1, 2, 3, 4]: + given_size = int(_two_bytes_to_num(payload_to_slave[BYTERANGE_FOR_GIVEN_SIZE])) + if functioncode in [1, 2]: + # Algorithm from MODBUS APPLICATION PROTOCOL SPECIFICATION V1.1b + number_of_inputs = given_size + response_payload_size = ( + NUMBER_OF_PAYLOAD_BYTES_FOR_BYTECOUNTFIELD + + number_of_inputs // 8 + + (1 if number_of_inputs % 8 else 0) + ) + + else: + number_of_registers = given_size + response_payload_size = ( + NUMBER_OF_PAYLOAD_BYTES_FOR_BYTECOUNTFIELD + + number_of_registers * _NUMBER_OF_BYTES_PER_REGISTER + ) + + else: + raise ValueError( + "Wrong functioncode: {}. The payload is: {!r}".format( + functioncode, payload_to_slave + ) + ) + + # Calculate number of bytes to read + if mode == MODE_ASCII: + return ( + NUMBER_OF_ASCII_RESPONSE_STARTBYTES + + response_payload_size * RTU_TO_ASCII_PAYLOAD_FACTOR + + NUMBER_OF_ASCII_RESPONSE_ENDBYTES + ) + return ( + NUMBER_OF_RTU_RESPONSE_STARTBYTES + + response_payload_size + + NUMBER_OF_RTU_RESPONSE_ENDBYTES + ) + + +def _calculate_minimum_silent_period(baudrate: Union[int, float]) -> float: + """Calculate the silent period length between messages. + + It should correspond to the time to send 3.5 characters. + + Args: + baudrate: The baudrate for the serial port + + Returns: + The number of seconds that should pass between each message on the bus. + + Raises: + ValueError, TypeError. + """ + # Avoid division by zero + _check_numerical(baudrate, minvalue=1, description="baudrate") + + BITTIMES_PER_CHARACTERTIME = 11 + MINIMUM_SILENT_CHARACTERTIMES = 3.5 + MINIMUM_SILENT_TIME_SECONDS = 0.00175 # See Modbus standard + + bittime = 1 / float(baudrate) + return max( + bittime * BITTIMES_PER_CHARACTERTIME * MINIMUM_SILENT_CHARACTERTIMES, + MINIMUM_SILENT_TIME_SECONDS, + ) + + +# ########################## # +# String and num conversions # +# ########################## # + + +def _num_to_one_byte(inputvalue: int) -> bytes: + """Convert a numerical value to one byte. + + Args: + inputvalue: The value to be converted. Should be >=0 and <=255. + + Returns: + One byte representing the inputvalue. + + Raises: + TypeError, ValueError + """ + _check_int(inputvalue, minvalue=0, maxvalue=0xFF) + + return inputvalue.to_bytes(1, "big") + + +def _num_to_two_bytes( + value: Union[int, float], + number_of_decimals: int = 0, + lsb_first: bool = False, + signed: bool = False, +) -> bytes: + r"""Convert a numerical value to two bytes, possibly scaling it. + + Args: + * value: The numerical value to be converted. + * number_of_decimals: Number of decimals, 0 or more, for scaling. + * lsb_first: Whether the least significant byte should be first in + the resulting string. + * signed: Whether negative values should be accepted. + + Returns: + Two bytes representing the inputvalue. + + Raises: + TypeError, ValueError. + + Use ``number_of_decimals=1`` to multiply ``value`` by 10 before sending it to + the slave register. Similarly ``number_of_decimals=2`` will multiply ``value`` + by 100 before sending it to the slave register. + + Use the parameter ``signed=True`` if making a bytes object that can hold + negative values. Then negative input will be automatically converted into + upper range data (two's complement). + + The byte order is controlled by the ``lsb_first`` parameter, as seen here: + + ======================= ============= ==================================== + ``lsb_first`` parameter Endianness Description + ======================= ============= ==================================== + False (default) Big-endian Most significant byte is sent first + True Little-endian Least significant byte is sent first + ======================= ============= ==================================== + + For example: + To store for example value=77.0, use ``number_of_decimals = 1`` if the + register will hold it as 770 internally. The value 770 (dec) is 0302 (hex), + where the most significant byte is 03 (hex) and the least significant byte + is 02 (hex). With ``lsb_first = False``, the most significant byte is + given first why the resulting bytes are ``\x03\x02``, which has the length 2. + """ + _check_numerical(value, description="inputvalue") + _check_int( + number_of_decimals, + minvalue=0, + maxvalue=_MAX_NUMBER_OF_DECIMALS, + description="number of decimals", + ) + _check_bool(lsb_first, description="lsb_first") + _check_bool(signed, description="signed parameter") + + multiplier = 10**number_of_decimals + integer = int(float(value) * multiplier) + + if lsb_first: + formatcode = "<" # Little-endian + else: + formatcode = ">" # Big-endian + if signed: + formatcode += "h" # (Signed) short (2 bytes) + else: + formatcode += "H" # Unsigned short (2 bytes) + + outbytes = _pack_bytes(formatcode, integer) + assert len(outbytes) == 2 + return outbytes + + +def _two_bytes_to_num( + inputbytes: bytes, number_of_decimals: int = 0, signed: bool = False +) -> Union[int, float]: + r"""Convert two bytes to a numerical value, possibly scaling it. + + Args: + * inputbytes: Bytes of length 2. + * number_of_decimals: The number of decimals. Defaults to 0. + * signed: Whether large positive values should be interpreted as + negative values. + + Returns: + The numerical value (int or float) calculated from the ``inputbytes``. + + Raises: + TypeError, ValueError + + Use the parameter ``signed=True`` if converting bytes that can hold + negative values. Then upper range data will be automatically converted into + negative return values (two's complement). + + Use ``number_of_decimals=1`` to divide the received data by 10 before returning + the value. Similarly ``number_of_decimals=2`` will divide the received data by + 100 before returning the value. + + The byte order is big-endian, meaning that the most significant byte is sent first. + + For example: + The bytes ``\x03\x02`` (which has the length 2) corresponds to 0302 (hex) = + 770 (dec). If ``number_of_decimals = 1``, then this is converted + to 77.0 (float). + """ + _check_bytes(inputbytes, minlength=2, maxlength=2, description="inputbytes") + _check_int( + number_of_decimals, + minvalue=0, + maxvalue=_MAX_NUMBER_OF_DECIMALS, + description="number of decimals", + ) + _check_bool(signed, description="signed parameter") + + formatcode = ">" # Big-endian + if signed: + formatcode += "h" # (Signed) short (2 bytes) + else: + formatcode += "H" # Unsigned short (2 bytes) + + fullregister: int = _unpack_bytes(formatcode, inputbytes) + + if number_of_decimals == 0: + return fullregister + divisor = 10**number_of_decimals + return fullregister / float(divisor) + + +def _long_to_bytes( + value: int, + signed: bool = False, + number_of_registers: int = 2, + byteorder: int = BYTEORDER_BIG, +) -> bytes: + """Convert a long integer to bytes. + + Long integers (32 bits = 4 bytes or 64 bite = 8 bytes) are stored in two + or four consecutive 16-bit registers in the slave respectively. + + Args: + * value: The numerical value to be converted. + * signed: Whether large positive values should be interpreted as + negative values. + * number_of_registers: Should be 2 or 4. + * byteorder: How multi-register data should be interpreted. + + Returns: + Four or eight bytes. + + Raises: + TypeError, ValueError + """ + _check_int(value, description="inputvalue") + _check_bool(signed, description="signed parameter") + _check_int( + number_of_registers, minvalue=2, maxvalue=4, description="number of registers" + ) + _check_int( + byteorder, minvalue=0, maxvalue=_MAX_BYTEORDER_VALUE, description="byteorder" + ) + + if byteorder in [BYTEORDER_BIG, BYTEORDER_BIG_SWAP]: + formatcode = ">" + else: + formatcode = "<" + if number_of_registers == 2 and signed: + formatcode += "l" # (Signed) long (4 bytes) + lengthtarget = 4 + elif number_of_registers == 2: + formatcode += "L" # Unsigned long (4 bytes) + lengthtarget = 4 + elif number_of_registers == 4 and signed: + formatcode += "q" # (Signed) long long (8 bytes) + lengthtarget = 8 + elif number_of_registers == 4: + formatcode += "Q" # Unsigned long long (8 bytes) + lengthtarget = 8 + else: + raise ValueError( + "Wrong number of registers! Given value is {0!r}".format( + number_of_registers + ) + ) + outputbytes = _pack_bytes(formatcode, value) + if byteorder in [BYTEORDER_BIG_SWAP, BYTEORDER_LITTLE_SWAP]: + outputbytes = _swap(outputbytes) + + assert len(outputbytes) == lengthtarget + return outputbytes + + +def _bytes_to_long( + inputbytes: bytes, + signed: bool = False, + number_of_registers: int = 2, + byteorder: int = BYTEORDER_BIG, +) -> int: + """Convert bytes to a long integer. + + Long integers (32 bits = 4 bytes or 64 bite = 8 bytes) are stored in two + or four consecutive 16-bit registers in the slave respectively. + + Args: + * inputbytes: Length 4 or 8 bytes. + * signed: Whether large positive values should be interpreted as + negative values. + * number_of_registers: Should be 2 or 4. + * byteorder: How multi-register data should be interpreted. + + Returns: + The numerical value. + + Raises: + ValueError, TypeError + """ + _check_bool(signed, description="signed parameter") + _check_int( + number_of_registers, minvalue=2, maxvalue=4, description="number of registers" + ) + _check_int( + byteorder, minvalue=0, maxvalue=_MAX_BYTEORDER_VALUE, description="byteorder" + ) + + if byteorder in [BYTEORDER_BIG, BYTEORDER_BIG_SWAP]: + formatcode = ">" + else: + formatcode = "<" + if number_of_registers == 2 and signed: + formatcode += "l" # (Signed) long (4 bytes) + lengthtarget = 4 + elif number_of_registers == 2: + formatcode += "L" # Unsigned long (4 bytes) + lengthtarget = 4 + elif number_of_registers == 4 and signed: + formatcode += "q" # (Signed) long long (8 bytes) + lengthtarget = 8 + elif number_of_registers == 4: + formatcode += "Q" # Unsigned long long (8 bytes) + lengthtarget = 8 + else: + raise ValueError( + "Wrong number of registers! Given value is {0!r}".format( + number_of_registers + ) + ) + _check_bytes( + inputbytes, "input bytes", minlength=lengthtarget, maxlength=lengthtarget + ) + + if byteorder in [BYTEORDER_BIG_SWAP, BYTEORDER_LITTLE_SWAP]: + inputbytes = _swap(inputbytes) + + return int(_unpack_bytes(formatcode, inputbytes)) + + +def _float_to_bytes( + value: Union[int, float], + number_of_registers: int = 2, + byteorder: int = BYTEORDER_BIG, +) -> bytes: + r"""Convert a numerical value to bytes. + + Floats are stored in two or more consecutive 16-bit registers in the slave. The + encoding is according to the standard IEEE 754. + + =============================== ================= =========== ================= + Type of floating point in slave Size Registers Range + =============================== ================= =========== ================= + Single precision (binary32) 32 bits (4 bytes) 2 registers 1.4E-45 to 3.4E38 + Double precision (binary64) 64 bits (8 bytes) 4 registers 5E-324 to 1.8E308 + =============================== ================= =========== ================= + + A floating point value of 1.0 is encoded (in single precision) as 3f800000 (hex). + This will give the bytes ``'\x3f\x80\x00\x00'`` (big endian). + + Args: + * value (float or int): The numerical value to be converted. + * number_of_registers: Can be 2 or 4. + * byteorder: How multi-register data should be interpreted. + + Returns: + 4 or 8 bytes. + + Raises: + TypeError, ValueError + """ + _check_numerical(value, description="inputvalue") + _check_int( + number_of_registers, minvalue=2, maxvalue=4, description="number of registers" + ) + _check_int( + byteorder, minvalue=0, maxvalue=_MAX_BYTEORDER_VALUE, description="byteorder" + ) + + if byteorder in [BYTEORDER_BIG, BYTEORDER_BIG_SWAP]: + formatcode = ">" + else: + formatcode = "<" + if number_of_registers == 2: + formatcode += "f" # Float (4 bytes) + lengthtarget = 4 + elif number_of_registers == 4: + formatcode += "d" # Double (8 bytes) + lengthtarget = 8 + else: + raise ValueError( + "Wrong number of registers! Given value is {0!r}".format( + number_of_registers + ) + ) + + outputbytes = _pack_bytes(formatcode, value) + if byteorder in [BYTEORDER_BIG_SWAP, BYTEORDER_LITTLE_SWAP]: + outputbytes = _swap(outputbytes) + assert len(outputbytes) == lengthtarget + return outputbytes + + +def _bytes_to_float( + inputbytes: bytes, number_of_registers: int = 2, byteorder: int = BYTEORDER_BIG +) -> float: + """Convert four bytes to a float. + + Floats are stored in two or more consecutive 16-bit registers in the slave. + + For discussion on precision, number of bits, number of registers, the range, + byte order and on alternative names, see :func:`minimalmodbus._float_to_bytes`. + + Args: + * inputbytes: Four or eight bytes + * number_of_registers: Can be 2 or 4. + * byteorder: How multi-register data should be interpreted. + + Returns: + A float. + + Raises: + TypeError, ValueError + """ + _check_bytes(inputbytes, minlength=4, maxlength=8, description="input bytes") + _check_int( + number_of_registers, minvalue=2, maxvalue=4, description="number of registers" + ) + _check_int( + byteorder, minvalue=0, maxvalue=_MAX_BYTEORDER_VALUE, description="byteorder" + ) + number_of_bytes = _NUMBER_OF_BYTES_PER_REGISTER * number_of_registers + + if byteorder in [BYTEORDER_BIG, BYTEORDER_BIG_SWAP]: + formatcode = ">" + else: + formatcode = "<" + if number_of_registers == 2: + formatcode += "f" # Float (4 bytes) + elif number_of_registers == 4: + formatcode += "d" # Double (8 bytes) + else: + raise ValueError( + "Wrong number of registers! Given value is {0!r}".format( + number_of_registers + ) + ) + + if len(inputbytes) != number_of_bytes: + raise ValueError( + "Wrong length of the input bytes! Given value is " + + "{0!r}, and number_of_registers is {1!r}.".format( + inputbytes, number_of_registers + ) + ) + + if byteorder in [BYTEORDER_BIG_SWAP, BYTEORDER_LITTLE_SWAP]: + inputbytes = _swap(inputbytes) + return float(_unpack_bytes(formatcode, inputbytes)) + + +def _textstring_to_bytes(inputstring: str, number_of_registers: int = 16) -> bytes: + """Convert a text string to bytes. + + Each 16-bit register in the slave are interpreted as two characters (1 byte = + 8 bits). For example 16 consecutive registers can hold 32 characters (32 bytes). + + Not much of conversion is done, mostly error checking and string padding. + If the *inputstring* is shorter that the allocated space, it is padded with + spaces in the end. + + Args: + * inputstring: The string to be stored in the slave. + Max 2 * *number_of_registers* characters. + * number_of_registers: The number of registers allocated for the string. + + Returns: + Bytes. + + Raises: + TypeError, ValueError + """ + _check_int( + number_of_registers, + minvalue=1, + maxvalue=_MAX_NUMBER_OF_REGISTERS_TO_WRITE, + description="number of registers", + ) + max_characters = _NUMBER_OF_BYTES_PER_REGISTER * number_of_registers + _check_string(inputstring, "input string", minlength=1, maxlength=max_characters) + + padded = inputstring.ljust(max_characters) # Pad with space + outputbytes = bytes(padded, encoding="ascii") + assert len(outputbytes) == max_characters + return outputbytes + + +def _bytes_to_textstring(inputbytes: bytes, number_of_registers: int = 16) -> str: + """Convert bytes to a text string. + + Each 16-bit register in the slave are interpreted as two characters (1 byte = + 8 bits). For example 16 consecutive registers can hold 32 characters (32 bytes). + + Not much of conversion is done, mostly error checking. + + Args: + * inputbytes: The bytes from the slave. Length = 2 * *number_of_registers* + * number_of_registers (int): The number of registers allocated for the string. + Should be >0. + + Returns: + A the text string. + + Raises: + TypeError, ValueError + """ + _check_int( + number_of_registers, + minvalue=1, + maxvalue=_MAX_NUMBER_OF_REGISTERS_TO_READ, + description="number of registers", + ) + max_characters = _NUMBER_OF_BYTES_PER_REGISTER * number_of_registers + _check_bytes( + inputbytes, "input bytes", minlength=max_characters, maxlength=max_characters + ) + + return inputbytes.decode(encoding="ascii") + + +def _valuelist_to_bytes(valuelist: List[int], number_of_registers: int) -> bytes: + """Convert a list of numerical values to bytes. + + Each element is 'unsigned INT16'. + + Args: + * valuelist: The input list. The elements should be in the + range 0 to 65535. + * number_of_registers: The number of registers. For error checking. + Should equal the number of elements in *valuelist*. + + Returns: + Bytes Length = 2 * *number_of_registers* + + Raises: + TypeError, ValueError + """ + MINVALUE = 0 + MAXVALUE = 0xFFFF + + _check_int(number_of_registers, minvalue=1, description="number of registers") + + if not isinstance(valuelist, list): + raise TypeError( + "The valuelist parameter must be a list. Given {0!r}.".format(valuelist) + ) + + for value in valuelist: + _check_int( + value, + minvalue=MINVALUE, + maxvalue=MAXVALUE, + description="elements in the input value list", + ) + + _check_int( + len(valuelist), + minvalue=number_of_registers, + maxvalue=number_of_registers, + description="length of the list", + ) + + number_of_bytes = _NUMBER_OF_BYTES_PER_REGISTER * number_of_registers + + outputbytes = b"" + for value in valuelist: + outputbytes += _num_to_two_bytes(value, signed=False) + + assert len(outputbytes) == number_of_bytes + return outputbytes + + +def _bytes_to_valuelist(inputbytes: bytes, number_of_registers: int) -> List[int]: + """Convert bytes to a list of numerical values. + + The bytes are interpreted as 'unsigned INT16'. + + Args: + * inputbytes: The bytes from the slave. Length = 2 * *number_of_registers* + * number_of_registers: The number of registers. For error checking. + + Returns: + A list of integers. + + Raises: + TypeError, ValueError + """ + _check_int(number_of_registers, minvalue=1, description="number of registers") + number_of_bytes = _NUMBER_OF_BYTES_PER_REGISTER * number_of_registers + _check_bytes( + inputbytes, "input bytes", minlength=number_of_bytes, maxlength=number_of_bytes + ) + + values = [] + for i in range(number_of_registers): + offset = _NUMBER_OF_BYTES_PER_REGISTER * i + sub_bytes = inputbytes[offset : (offset + _NUMBER_OF_BYTES_PER_REGISTER)] + values.append(int(_two_bytes_to_num(sub_bytes))) + + return values + + +def _pack_bytes(formatstring: str, value: Any) -> bytes: + """Pack a value into bytes. + + Uses the built-in :mod:`struct` Python module, and adds relevant error messages. + + Args: + * formatstring: String for the packing. See the :mod:`struct` module + for details. + * value (depends on formatstring): The value to be packed + + Returns: + The packed bytes + + Raises: + ValueError + """ + _check_string(formatstring, description="formatstring", minlength=1) + + try: + result = struct.pack(formatstring, value) + except Exception as exc: + errortext = "The value to send is probably out of range, as the num-to-bytes " + errortext += "conversion failed. Value: {0!r} Struct format code is: {1}" + raise ValueError(errortext.format(value, formatstring)) from exc + + return result + + +def _unpack_bytes(formatstring: str, packed_bytes: bytes) -> Any: + """Unpack bytes into a value. + + Uses the built-in :mod:`struct` Python module, and adds relevant error messages. + + Args: + * formatstring: String for the packing. See the :mod:`struct` module + for details. + * packed_bytes: The bytes to be unpacked. + + Returns: + A value. The type depends on the formatstring. + + Raises: + ValueError + """ + _check_string(formatstring, description="formatstring", minlength=1) + _check_bytes(packed_bytes, description="packed bytes", minlength=1) + + try: + value = struct.unpack(formatstring, packed_bytes)[0] + except Exception: + errortext = "The received bytes is probably wrong, as the bytes-to-num " + errortext += "conversion failed. Bytes: {0!r} Struct format code is: {1}" + raise InvalidResponseError(errortext.format(packed_bytes, formatstring)) + + return value + + +def _swap(inputbytes: bytes) -> bytes: + """Swap bytes pairwise. + + This corresponds to a "byte swap". + + Args: + * inputbytes: input. The length should be an even number. + + Return the bytes swapped. + """ + length = len(inputbytes) + if length % 2: + raise ValueError( + "The length of the inputbytes should be even. Given {!r}.".format( + inputbytes + ) + ) + templist = list(inputbytes) + templist[1:length:2], templist[:length:2] = ( + templist[:length:2], + templist[1:length:2], + ) + return bytes(templist) + + +def _hexencode(inputbytes: bytes, insert_spaces: bool = False) -> bytes: + r"""Convert bytes to a hex encoded bytes. + + For example ``b'J'`` will return ``b'4A'``, and ``b'\x04'`` will return ``b'04'``. + + Args: + * inputbytes: Can be for example ``b'A\x01B\x45'``. + * insert_spaces: Insert space characters between pair of characters + to increase readability. + + Returns: + Bytes of twice the length, with characters in the range '0' to '9' and + 'A' to 'F'. It will be longer if spaces are inserted. + + Raises: + TypeError, ValueError + """ + _check_bytes(inputbytes, description="input bytes") + + if insert_spaces: + return binascii.hexlify(inputbytes, sep=" ").upper() + return binascii.hexlify(inputbytes).upper() + + +def _hexdecode(hexbytes: bytes) -> bytes: + r"""Convert hex encoded bytes to bytes. + + For example ``b'4A'`` will return ``b'J'``, and ``b'04'`` will + return ``b'\x04'`` (which has length 1). + + Args: + * hexbytes: Can be for example ``b'A3'`` or ``b'A3B4'``. Must be of even length. + Allowed bytes are ``b'0'`` to ``b'9'``, ``b'a'`` to ``b'f'`` + and ``b'A'`` to ``b'F'`` (not space). + + Returns: + Bytes of half the length, with bytes corresponding to all 0-255 values. + + Raises: + TypeError, ValueError + """ + # TODO Note: For Python3 the appropriate would be: + # raise TypeError(new_error_message) from err + # but the Python2 interpreter will indicate SyntaxError. + # Thus we need to live with this warning in Python3: + # 'During handling of the above exception, another exception occurred' + + _check_bytes(hexbytes, description="hex bytes") + + if len(hexbytes) % 2 != 0: + raise ValueError( + "The input hex bytes must be of even length. Given: {!r}".format(hexbytes) + ) + + try: + return binascii.unhexlify(hexbytes) + except binascii.Error as err: + new_error_message = ( + "Hexdecode reported an error: {!s}. Input hexstring: {!r}".format( + err.args[0], hexbytes + ) + ) + raise TypeError(new_error_message) + + +def _describe_bytes(inputbytes: bytes) -> str: + r"""Describe bytes in a human friendly way. + + Args: + * inputbytes: Bytes to describe + + Returns a space separated descriptive string. + For example ``b'\x01\x02\x03'`` gives: ``01 02 03 (3 bytes)`` + """ + return " ".join([f"{x:02X}" for x in inputbytes]) + " ({} bytes)".format( + len(inputbytes) + ) + + +def _calculate_number_of_bytes_for_bits(number_of_bits: int) -> int: + """Calculate number of full bytes required to house a number of bits. + + Args: + * number_of_bits: Number of bits + + Error checking should have been done before. + + For example 9 bits requires 2 bytes. + + Algorithm from MODBUS APPLICATION PROTOCOL SPECIFICATION V1.1b + """ + result = number_of_bits // _BITS_PER_BYTE # Integer division in Python2 and 3 + if number_of_bits % _BITS_PER_BYTE: + result += 1 + return result + + +def _bit_to_bytes(value: int) -> bytes: + """Create the bit pattern that is used for writing single bits. + + Used for functioncode 5. The same value is sent back in the response + from the slave. + + This is basically a storage of numerical constants. + + Args: + * value: Can be 0 or 1 + + Returns: + The bit pattern. + + Raises: + TypeError, ValueError + """ + _check_int(value, minvalue=0, maxvalue=1, description="inputvalue") + + if value == 0: + return b"\x00\x00" + return b"\xff\x00" + + +def _bits_to_bytes(valuelist: List[int]) -> bytes: + """Build bytes from a list of bits. + + This is used for functioncode 15. + + Args: + * valuelist: List of int (0 or 1) + + Returns bytes. + """ + if not isinstance(valuelist, list): + raise TypeError( + "The input should be a list. " + "Given: {!r}".format(valuelist) + ) + for value in valuelist: + if value not in [0, 1, False, True]: + raise ValueError( + "Wrong value in list of bits. " + "Given: {!r}".format(value) + ) + + list_position = 0 + outputbytes = b"" + while list_position < len(valuelist): + sublist = valuelist[list_position : (list_position + _BITS_PER_BYTE)] + + bytevalue = 0 + for bitposition, value in enumerate(sublist): + bytevalue |= value << bitposition + outputbytes += bytevalue.to_bytes(1, "big") + + list_position += _BITS_PER_BYTE + return outputbytes + + +def _bytes_to_bits(inputbytes: bytes, number_of_bits: int) -> List[int]: + """Parse bits from bytes. + + This is used for parsing the bits in response messages for functioncode 1 and 2. + + The first byte in the *inputbytes* contains info on the addressed bit + (in LSB in that byte). Second bit from right contains info on the bit + on the next address. + + Next byte in the *inputbytes* contains data on next 8 bits. Might be padded with + zeros toward MSB. + + Args: + * inputbytes: Input bytes + * number_of_bits: Number of bits to extract + + Returns a list of values (0 or 1). The length of the list is equal to + *number_of_bits*. + """ + expected_length = _calculate_number_of_bytes_for_bits(number_of_bits) + if len(inputbytes) != expected_length: + raise ValueError( + "Wrong length of input bytes. Expected is " + + "{} bytes (for {} bits), actual is {} bytes.".format( + expected_length, number_of_bits, len(inputbytes) + ) + ) + total_list = [] + for bytevalue in inputbytes: # Gives individual bytes as int + for bitposition in range(_BITS_PER_BYTE): + bitvalue = (bytevalue & (1 << bitposition)) > 0 + total_list.append(int(bitvalue)) + return total_list[:number_of_bits] + + +# ################### # +# Number manipulation # +# ################### # + + +def _twos_complement(x: int, bits: int = 16) -> int: + """Calculate the two's complement of an integer. + + Then also negative values can be represented by an upper range of positive values. + See https://en.wikipedia.org/wiki/Two%27s_complement + + Args: + * x: Input integer. + * bits: Number of bits, must be > 0. + + Returns: + The two's complement of the input. + + Example for *bits* = 8: + + ==== ======= + x returns + ==== ======= + 0 0 + 1 1 + 127 127 + -128 128 + -127 129 + -1 255 + ==== ======= + """ + _check_int(bits, minvalue=0, description="number of bits") + _check_int(x, description="input") + upperlimit: int = 2 ** (bits - 1) - 1 + lowerlimit: int = -(2 ** (bits - 1)) + if x > upperlimit or x < lowerlimit: + raise ValueError( + "The input value is out of range. Given value is " + + "{0}, but allowed range is {1} to {2} when using {3} bits.".format( + x, lowerlimit, upperlimit, bits + ) + ) + + # Calculate two'2 complement + if x >= 0: + return x + return int(x + 2**bits) + + +def _from_twos_complement(x: int, bits: int = 16) -> int: + """Calculate the inverse(?) of a two's complement of an integer. + + Args: + * x: Input integer. + * bits: Number of bits, must be > 0. + + Returns: + The inverse(?) of two's complement of the input. + + Example for *bits* = 8: + + === ======= + x returns + === ======= + 0 0 + 1 1 + 127 127 + 128 -128 + 129 -127 + 255 -1 + === ======= + """ + _check_int(bits, minvalue=0, description="number of bits") + + _check_int(x, description="input") + upperlimit = 2 ** (bits) - 1 + lowerlimit = 0 + if x > upperlimit or x < lowerlimit: + raise ValueError( + "The input value is out of range. Given value is " + + "{0}, but allowed range is {1} to {2} when using {3} bits.".format( + x, lowerlimit, upperlimit, bits + ) + ) + + # Calculate inverse(?) of two'2 complement + limit = 2 ** (bits - 1) - 1 + if x <= limit: + return x + return int(x - 2**bits) + + +# ################ # +# Bit manipulation # +# ################ # + + +def _set_bit_on(x: int, bit_num: int) -> int: + """Set bit *bit_num* to True. + + Args: + * x: The value before. + * bit_num: The bit number that should be set to True. + + Returns: + The value after setting the bit. + + For example: + For x = 4 (dec) = 0100 (bin), setting bit number 0 results + in 0101 (bin) = 5 (dec). + """ + _check_int(x, minvalue=0, description="input value") + _check_int(bit_num, minvalue=0, description="bitnumber") + + return x | (1 << bit_num) + + +def _check_bit(x: int, bit_num: int) -> bool: + """Check if bit *bit_num* is set the input integer. + + Args: + * x: The input value. + * bit_num: The bit number to be checked + + Returns: + True or False + + For example: + For x = 4 (dec) = 0100 (bin), checking bit number 2 results in True, and + checking bit number 3 results in False. + """ + _check_int(x, minvalue=0, description="input value") + _check_int(bit_num, minvalue=0, description="bitnumber") + + return (x & (1 << bit_num)) > 0 + + +# ######################## # +# Error checking functions # +# ######################## # + + +_CRC16TABLE = ( + 0, + 49345, + 49537, + 320, + 49921, + 960, + 640, + 49729, + 50689, + 1728, + 1920, + 51009, + 1280, + 50625, + 50305, + 1088, + 52225, + 3264, + 3456, + 52545, + 3840, + 53185, + 52865, + 3648, + 2560, + 51905, + 52097, + 2880, + 51457, + 2496, + 2176, + 51265, + 55297, + 6336, + 6528, + 55617, + 6912, + 56257, + 55937, + 6720, + 7680, + 57025, + 57217, + 8000, + 56577, + 7616, + 7296, + 56385, + 5120, + 54465, + 54657, + 5440, + 55041, + 6080, + 5760, + 54849, + 53761, + 4800, + 4992, + 54081, + 4352, + 53697, + 53377, + 4160, + 61441, + 12480, + 12672, + 61761, + 13056, + 62401, + 62081, + 12864, + 13824, + 63169, + 63361, + 14144, + 62721, + 13760, + 13440, + 62529, + 15360, + 64705, + 64897, + 15680, + 65281, + 16320, + 16000, + 65089, + 64001, + 15040, + 15232, + 64321, + 14592, + 63937, + 63617, + 14400, + 10240, + 59585, + 59777, + 10560, + 60161, + 11200, + 10880, + 59969, + 60929, + 11968, + 12160, + 61249, + 11520, + 60865, + 60545, + 11328, + 58369, + 9408, + 9600, + 58689, + 9984, + 59329, + 59009, + 9792, + 8704, + 58049, + 58241, + 9024, + 57601, + 8640, + 8320, + 57409, + 40961, + 24768, + 24960, + 41281, + 25344, + 41921, + 41601, + 25152, + 26112, + 42689, + 42881, + 26432, + 42241, + 26048, + 25728, + 42049, + 27648, + 44225, + 44417, + 27968, + 44801, + 28608, + 28288, + 44609, + 43521, + 27328, + 27520, + 43841, + 26880, + 43457, + 43137, + 26688, + 30720, + 47297, + 47489, + 31040, + 47873, + 31680, + 31360, + 47681, + 48641, + 32448, + 32640, + 48961, + 32000, + 48577, + 48257, + 31808, + 46081, + 29888, + 30080, + 46401, + 30464, + 47041, + 46721, + 30272, + 29184, + 45761, + 45953, + 29504, + 45313, + 29120, + 28800, + 45121, + 20480, + 37057, + 37249, + 20800, + 37633, + 21440, + 21120, + 37441, + 38401, + 22208, + 22400, + 38721, + 21760, + 38337, + 38017, + 21568, + 39937, + 23744, + 23936, + 40257, + 24320, + 40897, + 40577, + 24128, + 23040, + 39617, + 39809, + 23360, + 39169, + 22976, + 22656, + 38977, + 34817, + 18624, + 18816, + 35137, + 19200, + 35777, + 35457, + 19008, + 19968, + 36545, + 36737, + 20288, + 36097, + 19904, + 19584, + 35905, + 17408, + 33985, + 34177, + 17728, + 34561, + 18368, + 18048, + 34369, + 33281, + 17088, + 17280, + 33601, + 16640, + 33217, + 32897, + 16448, +) +r"""CRC-16 lookup table with 256 elements. + +Built with this code:: + + poly=0xA001 + table = [] + for index in range(256): + data = index << 1 + crc = 0 + for _ in range(8, 0, -1): + data >>= 1 + if (data ^ crc) & 0x0001: + crc = (crc >> 1) ^ poly + else: + crc >>= 1 + table.append(crc) + output = '' + for i, m in enumerate(table): + if not i%11: + output += "\n" + output += "{:5.0f}, ".format(m) + print output +""" + + +def _is_serial_object(obj: Any) -> bool: + """Check if an object is serialport-like.""" + KNOWN_ATTRIBUTES = ["open", "close", "read", "write", "is_open"] + + for attribute_name in KNOWN_ATTRIBUTES: + if not hasattr(obj, attribute_name): + return False + return True + + +def _calculate_crc(inputbytes: bytes) -> bytes: + """Calculate CRC-16 for Modbus RTU. + + Args: + inputbytes: An arbitrary-length message (without the CRC). + + Returns: + A two-byte CRC, where the least significant byte is first. + """ + _check_bytes(inputbytes, description="CRC input bytes") + + # Preload a 16-bit register with ones + register = 0xFFFF + + for current_byte in inputbytes: + register = (register >> 8) ^ _CRC16TABLE[(register ^ current_byte) & 0xFF] + + return _num_to_two_bytes(register, lsb_first=True) + + +def _calculate_lrc(inputbytes: bytes) -> bytes: + """Calculate LRC for Modbus ASCII. + + Args: + inputbytes: An arbitrary-length message (without the beginning + colon and terminating CRLF). It should already be decoded from hex-string. + + Returns: + A one-byte LRC (not encoded to hex-string) + + Algorithm from the document 'MODBUS over serial line specification and + implementation guide V1.02'. + + The LRC is calculated as 8 bits (one byte). + + For example a resulting LRC 0110 0001 (bin) = 61 (hex) = 97 (dec) = ``b'a'``. + This function will then return ``b'a'``. + + In Modbus ASCII mode, this should be transmitted using two characters. This + example should be transmitted as ``b'61'``, which is a bytes object of length two. + This function does not handle that conversion for transmission. + """ + _check_bytes(inputbytes, description="LRC input bytes") + + register = 0 + for bytevalue in inputbytes: + register += bytevalue + + lrc = ((register ^ 0xFF) + 1) & 0xFF + + return _num_to_one_byte(lrc) + + +def _check_mode(mode: str) -> None: + """Check that the Modbus mode is valid. + + Args: + mode: The Modbus mode (MODE_RTU or MODE_ASCII) + + Raises: + TypeError, ValueError + """ + if not isinstance(mode, str): + raise TypeError("The {0} should be a string. Given: {1!r}".format("mode", mode)) + + if mode not in [MODE_RTU, MODE_ASCII]: + raise ValueError( + "Unreconized Modbus mode given. Must " + + "be 'rtu' or 'ascii' but {0!r} was given.".format(mode) + ) + + +def _check_functioncode( + functioncode: int, list_of_allowed_values: Optional[List[int]] = None +) -> None: + """Check that the given functioncode is in the *list_of_allowed_values*. + + Also verifies that 1 <= function code <= 127. + + Args: + * functioncode: The function code + * list_of_allowed_values: Allowed values. Use *None* to bypass + this part of the checking. + + Raises: + TypeError, ValueError + """ + FUNCTIONCODE_MIN = 1 + FUNCTIONCODE_MAX = 127 + + _check_int( + functioncode, FUNCTIONCODE_MIN, FUNCTIONCODE_MAX, description="functioncode" + ) + + if list_of_allowed_values is None: + return + + if not isinstance(list_of_allowed_values, list): + raise TypeError( + "The list_of_allowed_values should be a list. Given: {0!r}".format( + list_of_allowed_values + ) + ) + + for value in list_of_allowed_values: + _check_int( + value, + FUNCTIONCODE_MIN, + FUNCTIONCODE_MAX, + description="functioncode inside list_of_allowed_values", + ) + + if functioncode not in list_of_allowed_values: + raise ValueError( + "Wrong function code: {0}, allowed values are {1!r}".format( + functioncode, list_of_allowed_values + ) + ) + + +def _check_slaveaddress(slaveaddress: int) -> None: + """Check that the given *slaveaddress* is valid. + + Args: + slaveaddress: The slave address + + Raises: + TypeError, ValueError + """ + SLAVEADDRESS_MAX = 255 # Allows usage also of reserved addresses + SLAVEADDRESS_MIN = 0 + + _check_int( + slaveaddress, SLAVEADDRESS_MIN, SLAVEADDRESS_MAX, description="slaveaddress" + ) + + +def _check_registeraddress(registeraddress: int) -> None: + """Check that the given *registeraddress* is valid. + + Args: + registeraddress: The register address + + Raises: + TypeError, ValueError + """ + REGISTERADDRESS_MAX = 0xFFFF + REGISTERADDRESS_MIN = 0 + + _check_int( + registeraddress, + REGISTERADDRESS_MIN, + REGISTERADDRESS_MAX, + description="registeraddress", + ) + + +def _check_response_payload( + payload: bytes, + functioncode: int, + registeraddress: int, + value: Any, + number_of_decimals: int, + number_of_registers: int, + number_of_bits: int, + signed: bool, + byteorder: int, # Not used. For same signature as _parse_payload() + payloadformat: _Payloadformat, # Not used. For same signature as _parse_payload() +) -> None: + """Check the response payload. + + Args: + * payload: Payload to be checked + * functioncode: Function code + * registeraddress: Register address + * value: Value in request + * number_of_decimals: Number of decimals + * number_of_registers: Number of registers + * number_of_bits: Number of bits + * signed: Signed + * byteorder: Byte order + * payloadformat: Payload format + + Raises: + ValueError, TypeError + """ + if functioncode in [1, 2, 3, 4]: + _check_response_bytecount(payload) + + if functioncode in [5, 6, 15, 16]: + _check_response_registeraddress(payload, registeraddress) + + if functioncode == 5: + _check_response_writedata(payload, _bit_to_bytes(value)) + elif functioncode == 6: + _check_response_writedata( + payload, _num_to_two_bytes(value, number_of_decimals, signed=signed) + ) + elif functioncode == 15: + # response number of bits + _check_response_number_of_registers(payload, number_of_bits) + + elif functioncode == 16: + _check_response_number_of_registers(payload, number_of_registers) + + # Response for read bits + if functioncode in [1, 2]: + registerdata = payload[_NUMBER_OF_BYTES_BEFORE_REGISTERDATA:] + expected_number_of_bytes = _calculate_number_of_bytes_for_bits(number_of_bits) + if len(registerdata) != expected_number_of_bytes: + raise InvalidResponseError( + "The data length is wrong for payloadformat BIT/BITS." + + " Expected: {} Actual: {}.".format( + expected_number_of_bytes, len(registerdata) + ) + ) + + # Response for read registers + if functioncode in [3, 4]: + registerdata = payload[_NUMBER_OF_BYTES_BEFORE_REGISTERDATA:] + number_of_register_bytes = number_of_registers * _NUMBER_OF_BYTES_PER_REGISTER + if len(registerdata) != number_of_register_bytes: + raise InvalidResponseError( + "The register data length is wrong. " + + "Registerdata: {!r} bytes. Expected: {!r}.".format( + len(registerdata), number_of_register_bytes + ) + ) + + +def _check_response_slaveerrorcode(response: bytes) -> None: + """Check if the slave indicates an error. + + Args: + * response: Response from the slave + + The response is in RTU format, but the checksum might be one or two bytes + depending on whether it was sent in RTU or ASCII mode. + + Checking of type and length of the response should be done before calling + this functions. + + Raises: + SlaveReportedException or subclass + """ + NON_ERRORS = [5] + SLAVE_ERRORS = { + 1: IllegalRequestError("Slave reported illegal function"), + 2: IllegalRequestError("Slave reported illegal data address"), + 3: IllegalRequestError("Slave reported illegal data value"), + 4: SlaveReportedException("Slave reported device failure"), + 6: SlaveDeviceBusyError("Slave reported device busy"), + 7: NegativeAcknowledgeError("Slave reported negative acknowledge"), + 8: SlaveReportedException("Slave reported memory parity error"), + 10: SlaveReportedException("Slave reported gateway path unavailable"), + 11: SlaveReportedException( + "Slave reported gateway target device failed to respond" + ), + } + + if len(response) < _BYTEPOSITION_FOR_SLAVE_ERROR_CODE + 1: + return # This check is also done before calling, do not raise exception here. + + received_functioncode = response[_BYTEPOSITION_FOR_FUNCTIONCODE] + + if _check_bit(received_functioncode, _BITNUMBER_FUNCTIONCODE_ERRORINDICATION): + slave_error_code = response[_BYTEPOSITION_FOR_SLAVE_ERROR_CODE] + + if slave_error_code in NON_ERRORS: + return + + error = SLAVE_ERRORS.get( + slave_error_code, + SlaveReportedException( + "Slave reported error code " + str(slave_error_code) + ), + ) + raise error + + +def _check_response_bytecount(payload: bytes) -> None: + """Check that the number of bytes as given in the response is correct. + + The first byte in the payload indicates the length of the payload (first + byte not counted). + + Args: + payload: The payload + + Raises: + TypeError, ValueError, InvalidResponseError + """ + POSITION_FOR_GIVEN_NUMBER = 0 + NUMBER_OF_BYTES_TO_SKIP = 1 + + _check_bytes( + payload, minlength=1, description="payload", exception_type=InvalidResponseError + ) + + given_number_of_databytes = payload[POSITION_FOR_GIVEN_NUMBER] + counted_number_of_databytes = len(payload) - NUMBER_OF_BYTES_TO_SKIP + + if given_number_of_databytes != counted_number_of_databytes: + errortemplate = ( + "Wrong given number of bytes in the response: " + + "{0}, but counted is {1} as data payload length is {2}." + + " The data payload is: {3!r}" + ) + errortext = errortemplate.format( + given_number_of_databytes, + counted_number_of_databytes, + len(payload), + payload, + ) + raise InvalidResponseError(errortext) + + +def _check_response_registeraddress(payload: bytes, registeraddress: int) -> None: + """Check that the start adress as given in the response is correct. + + The first two bytes in the payload holds the address value. + + Args: + * payload: The payload + * registeraddress: What the register address actually shoud be. + + Raises: + TypeError, ValueError, InvalidResponseError + """ + _check_bytes( + payload, minlength=2, description="payload", exception_type=InvalidResponseError + ) + _check_registeraddress(registeraddress) + + BYTERANGE_FOR_STARTADDRESS = slice(0, 2) + + bytes_for_startaddress = payload[BYTERANGE_FOR_STARTADDRESS] + received_startaddress = _two_bytes_to_num(bytes_for_startaddress) + + if received_startaddress != registeraddress: + raise InvalidResponseError( + "Wrong given write start adress: " + + "{0}, but commanded is {1}. The data payload is: {2!r}".format( + received_startaddress, registeraddress, payload + ) + ) + + +def _check_response_number_of_registers( + payload: bytes, number_of_registers: int +) -> None: + """Check that the number of written registers as given in the response is correct. + + The bytes 2 and 3 (zero based counting) in the payload holds the value. + + Args: + * payload: The payload + * number_of_registers: Number of registers that have been written + + Raises: + TypeError, ValueError, InvalidResponseError + """ + _check_bytes( + payload, minlength=4, description="payload", exception_type=InvalidResponseError + ) + _check_int( + number_of_registers, + minvalue=1, + maxvalue=max( + _MAX_NUMBER_OF_REGISTERS_TO_READ, _MAX_NUMBER_OF_REGISTERS_TO_WRITE + ), + description="number of registers", + ) + + BYTERANGE_FOR_NUMBER_OF_REGISTERS = slice(2, 4) + + bytes_for_mumber_of_registers = payload[BYTERANGE_FOR_NUMBER_OF_REGISTERS] + received_number_of_written_registers = _two_bytes_to_num( + bytes_for_mumber_of_registers + ) + + if received_number_of_written_registers != number_of_registers: + raise InvalidResponseError( + "Wrong number of registers to write in the response: " + + "{0}, but commanded is {1}. The data payload is: {2!r}".format( + received_number_of_written_registers, number_of_registers, payload + ) + ) + + +def _check_response_writedata(payload: bytes, writedata: bytes) -> None: + """Check that the write data as given in the response is correct. + + The bytes 2 and 3 (zero based counting) in the payload holds the write data. + + Args: + * payload: The payload + * writedata: The data that should have been written. + Length should be 2 bytes. + + Raises: + TypeError, ValueError, InvalidResponseError + """ + _check_bytes( + payload, minlength=4, description="payload", exception_type=InvalidResponseError + ) + _check_bytes(writedata, minlength=2, maxlength=2, description="writedata") + + BYTERANGE_FOR_WRITEDATA = slice(2, 4) + + received_writedata = payload[BYTERANGE_FOR_WRITEDATA] + + if received_writedata != writedata: + raise InvalidResponseError( + "Wrong write data in the response: " + + "{0!r}, but commanded is {1!r}. The data payload is: {2!r}".format( + received_writedata, writedata, payload + ) + ) + + +def _check_bytes( + inputbytes: bytes, + description: str, + minlength: int = 0, + maxlength: Optional[int] = None, + exception_type: Type[Exception] = ValueError, +) -> None: + """Check that the bytes are valid. + + Args: + * inputbytes: The bytes to be checked + * description: Used in error messages for the checked inputbytes + * minlength: Minimum length of the inputbytes + * maxlength: Maximum length of the inputbytes + * exception_type: The type of exception to raise for length errors + """ + # Type checking + if not isinstance(description, str): + raise TypeError( + "The description should be a string. Given: {0!r}".format(description) + ) + + if not isinstance(inputbytes, bytes): + raise TypeError( + "The {0} should be bytes. Given: {1!r}".format(description, inputbytes) + ) + + if not isinstance(maxlength, (int, type(None))): + raise TypeError( + "The maxlength must be an integer or None. Given: {0!r}".format(maxlength) + ) + + # Check values + _check_int(minlength, minvalue=0, maxvalue=None, description="minlength") + + if len(inputbytes) < minlength: + raise exception_type( + "The {0} is too short: {1}, but minimum value is {2}. Given: {3!r}".format( + description, len(inputbytes), minlength, inputbytes + ) + ) + + if maxlength is not None: + if maxlength < 0: + raise ValueError( + "The maxlength must be positive. Given: {0}".format(maxlength) + ) + + if maxlength < minlength: + raise ValueError( + "The maxlength must not be smaller than " + + "minlength. Given: {0} and {1}".format(maxlength, minlength) + ) + + if len(inputbytes) > maxlength: + raise exception_type( + "The " + + "{0} is too long: {1}, but maximum value is {2}. Given: {3!r}".format( + description, len(inputbytes), maxlength, inputbytes + ) + ) + + +def _check_string( + inputstring: str, + description: str, + minlength: int = 0, + maxlength: Optional[int] = None, + force_ascii: bool = False, + exception_type: Type[Exception] = ValueError, +) -> None: + """Check that the given string is valid. + + Args: + * inputstring: The string to be checked + * description: Used in error messages for the checked *inputstring* + * minlength: Minimum length of the string + * maxlength: Maximum length of the string + * force_ascii: Enforce that the string is ASCII + * exception_type: The type of exception to raise for length errors + + Raises: + TypeError, ValueError or the one given by exception_type + + Uses the function :func:`_check_int` internally. + """ + # Type checking + if not isinstance(description, str): + raise TypeError( + "The description should be a string. Given: {0!r}".format(description) + ) + + if not isinstance(inputstring, str): + raise TypeError( + "The {0} should be a string. Given: {1!r}".format(description, inputstring) + ) + + if not isinstance(maxlength, (int, type(None))): + raise TypeError( + "The maxlength must be an integer or None. Given: {0!r}".format(maxlength) + ) + try: + issubclass(exception_type, Exception) + except TypeError: + raise TypeError( + "The exception_type must be an exception class. " + + "It not even a class. Given: {0!r}".format(type(exception_type)) + ) + if not issubclass(exception_type, Exception): + raise TypeError( + "The exception_type must be an exception class. Given: {0!r}".format( + type(exception_type) + ) + ) + + # Check values + _check_int(minlength, minvalue=0, maxvalue=None, description="minlength") + + if len(inputstring) < minlength: + raise exception_type( + "The {0} is too short: {1}, but minimum value is {2}. Given: {3!r}".format( + description, len(inputstring), minlength, inputstring + ) + ) + + if maxlength is not None: + if maxlength < 0: + raise ValueError( + "The maxlength must be positive. Given: {0}".format(maxlength) + ) + + if maxlength < minlength: + raise ValueError( + "The maxlength must " + + "not be smaller than minlength. Given: {0} and {1}".format( + maxlength, minlength + ) + ) + + if len(inputstring) > maxlength: + raise exception_type( + "The " + + "{0} is too long: {1}, but maximum value is {2}. Given: {3!r}".format( + description, len(inputstring), maxlength, inputstring + ) + ) + + if force_ascii and sys.version > "3": + try: + inputstring.encode("ascii") + except UnicodeEncodeError: + raise ValueError( + "The {0} must be ASCII. Given: {1!r}".format(description, inputstring) + ) + + +def _check_int( + inputvalue: int, + minvalue: Optional[int] = None, + maxvalue: Optional[int] = None, + description: str = "inputvalue", +) -> None: + """Check that the given integer is valid. + + Args: + * inputvalue: The integer to be checked + * minvalue: Minimum value of the integer + * maxvalue: Maximum value of the integer + * description: Used in error messages for the checked inputvalue + + Raises: + TypeError, ValueError + + Note: Can not use the function :func:`_check_string`, as that function uses this + function internally. + """ + if not isinstance(description, str): + raise TypeError( + "The description should be a string. Given: {0!r}".format(description) + ) + + if not isinstance(inputvalue, (int)): + raise TypeError( + "The {0} must be an integer. Given: {1!r}".format(description, inputvalue) + ) + + if not isinstance(minvalue, (int, type(None))): + raise TypeError( + "The minvalue must be an integer or None. Given: {0!r}".format(minvalue) + ) + + if not isinstance(maxvalue, (int, type(None))): + raise TypeError( + "The maxvalue must be an integer or None. Given: {0!r}".format(maxvalue) + ) + + _check_numerical(inputvalue, minvalue, maxvalue, description) + + +def _check_numerical( + inputvalue: Union[int, float], + minvalue: Union[None, int, float] = None, + maxvalue: Union[None, int, float] = None, + description: str = "inputvalue", +) -> None: + """Check that the given numerical value is valid. + + Args: + * inputvalue: The value to be checked. + * minvalue: Minimum value. Use None to skip this part of the test. + * maxvalue: Maximum value. Use None to skip this part of the test. + * description: Used in error messages for the checked inputvalue + + Raises: + TypeError, ValueError + + Note: Can not use the function :func:`_check_string`, as it uses this function + internally. + """ + # Type checking + if not isinstance(description, str): + raise TypeError( + "The description should be a string. Given: {0!r}".format(description) + ) + + if not isinstance(inputvalue, (int, float)): + raise TypeError( + "The {0} must be numerical. Given: {1!r}".format(description, inputvalue) + ) + + if not isinstance(minvalue, (int, float, type(None))): + raise TypeError( + "The minvalue must be numeric or None. Given: {0!r}".format(minvalue) + ) + + if not isinstance(maxvalue, (int, float, type(None))): + raise TypeError( + "The maxvalue must be numeric or None. Given: {0!r}".format(maxvalue) + ) + + # Consistency checking + if (minvalue is not None) and (maxvalue is not None): + if maxvalue < minvalue: + raise ValueError( + "The maxvalue must not be smaller than minvalue. " + + "Given: {0} and {1}, respectively.".format(maxvalue, minvalue) + ) + + # Value checking + if minvalue is not None: + if inputvalue < minvalue: + raise ValueError( + "The {0} is too small: {1}, but minimum value is {2}.".format( + description, inputvalue, minvalue + ) + ) + + if maxvalue is not None: + if inputvalue > maxvalue: + raise ValueError( + "The {0} is too large: {1}, but maximum value is {2}.".format( + description, inputvalue, maxvalue + ) + ) + + +def _check_bool(inputvalue: bool, description: str = "inputvalue") -> None: + """Check that the given *inputvalue* is a boolean. + + Args: + * inputvalue: The value to be checked. + * description: Used in error messages for the checked inputvalue. + + Raises: + TypeError, ValueError + """ + _check_string(description, minlength=1, description="description string") + if not isinstance(inputvalue, bool): + raise TypeError( + "The {0} must be boolean. Given: {1!r}".format(description, inputvalue) + ) + + +##################### +# Development tools # +##################### + + +def _get_diagnostic_string() -> str: + """Generate a diagnostic string, showing the module version, the platform etc. + + Returns: + A descriptive string. + """ + text = "\n## Diagnostic output from minimalmodbus ## \n\n" + text += "Minimalmodbus version: " + __version__ + "\n" + text += "File name (with relative path): " + __file__ + "\n" + text += "Full file path: " + os.path.abspath(__file__) + "\n\n" + text += "pySerial version: " + serial.VERSION + "\n" + text += "pySerial full file path: " + os.path.abspath(serial.__file__) + "\n\n" + text += "Platform: " + sys.platform + "\n" + text += "Filesystem encoding: " + repr(sys.getfilesystemencoding()) + "\n" + text += "Byteorder: " + sys.byteorder + "\n" + text += "Python version: " + sys.version + "\n" + text += "Python version info: " + repr(sys.version_info) + "\n" + text += "Python flags: " + repr(sys.flags) + "\n" + text += "Python argv: " + repr(sys.argv) + "\n" + text += "Python prefix: " + repr(sys.prefix) + "\n" + text += "Python exec prefix: " + repr(sys.exec_prefix) + "\n" + text += "Python executable: " + repr(sys.executable) + "\n" + text += "Float repr style: " + repr(sys.float_repr_style) + "\n\n" + text += "Variable __name__: " + __name__ + "\n" + text += "Current directory: " + os.getcwd() + "\n\n" + text += "Python path: \n" + text += "\n".join(sys.path) + "\n" + text += "\n## End of diagnostic output ## \n" + return text + + +# For backward compatibility +_getDiagnosticString = _get_diagnostic_string