第九章:编程使用Modbus

2020, Nov 14    

这篇文章是介器开源十一章节PlayBook的一部分,欢迎来给我们的提PR,我们的git地址是:https://github.com/Jieqiio/BaseJay/wiki


第九章:编程使用Modbus

1. Modbus 协议的介绍

1.1 简单介绍

Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电气 Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。Modbus已经成为工业领域通信协议事实上的业界标准,并且现在是工业电子设备之间常用的连接方式。 Modbus比其他通信协议使用的更广泛的主要原因有:

  • 公开发表并且无著作权要求
  • 易于部署和维护 = 对供应商来说,修改移动本地的比特或字节没有很多限制 Modbus允许多个 (大约240个) 设备连接在同一个网络上进行通信。

1.2 Modbus通信协议的类型

串行端口和以太网存在多种版本的Modbus协议,最常见的是:

  • Modbus RTU
  • Modbus ASCII
  • Modbus TCP
  • Modbus Plus

JayBox的开发只有网络端口,所以使用的是Modbus TCP/UDP的模式,通讯端口一般是502,MBAP是ModbusTCP帧前7个字节。 详细的技术细节推荐下载Modbus基金会的技术规格书,目前版本是1.1b3.下载modbus 技术规格书: https://modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf

1.3 Modbus的限制及安全性问题

Modbus是在1970年末为可编程逻辑控制器通信开发的,这些有限的数据类型在那个时代是可以被PLC理解的,大型二进制对象数据是不支持的。 对节点而言,没有一个标准的方法找到数据对象的描述信息,举个例子,确定一个寄存器数据是否表示一个介于30-175度之间的温度。 由于Modbus是一个主/从协议,没有办法要求设备“报告异常”(构建在以太网的TCP/IP协议之上,被称为open-mbus除外)- 主节点必须循环的询问每个节点设备,并查找数据中的变化。在带宽可能比较宝贵的应用中,这种方式在应用中消耗带宽和网络时间,例如在低速率的无线链路上。 Modbus协议针对未经授权的命令或截取数据并无安全性。

在Jaybox工业应用方案中,modbus的通讯安全由多层端到端的安全通道实现,增加了授权管理,提高了安全性。

2. 支持Modbus协议的工业控制器

基本上主流的工业控制系统都会支持Modbus协议,笔者最早使用的是来自瑞士的Staubli机器人的自Modbus接口,以及WAGO的ModBus IO模块。 你也可以在这个页面找到支持modbus协议的设备: https://modbus.org/companies.php

3. 编译软件包

如果你需要开发modbus的产品,建议仔细阅读我们的参考资料。在这里,我们使用的modbus软件包是libmodubs,新的软件包我们建议以子模块的方式加入到这个git里面,使用命令git submodule,这里我们使用的包是libModbus:

3.1 将包加于软件包

git submodule add https://github.com/stephane/libmodbus.git packages/libmodubs

3.2 编译docker用编译脚本

接下来我们需要来完成编译脚本,首先将helloworld的docker脚本例子拷贝一份用来编译libmodubs:

cp docker_scripts/build-hellworld.sh docker_scripts/build-libmodubs.sh

我们需要按照libmodubs软件包里面的编译要求,结合BaseJay的编译要求,做一下调整,

cat build-libmodubs.sh

 # COPYRIGHT (C) 2019. JIEQI EdgeComputing Ltd.
 # SPDX-License-Identifier: GPL 3.0
 # Change Logs:
 # Date           Author       Notes
 # 2020-08-07     Yong      the first version

#!/bin/bash
cd /libmodbus \
    && sh autogen.sh \
    && source /environment-setup-armv7a-vfp-neon-oe-linux-gnueabi \
    && autoreconf -i \
    && ./configure --host=arm \
    && make clean && make

3.3 编译宿主机用脚本

cp scripts/deploy-hello.sh scripts/deploy-libmodubs.sh

我们需要修改一下:

cat deploy-libmodubs.sh

 # COPYRIGHT (C) 2019. JIEQI EdgeComputing Ltd.
 # SPDX-License-Identifier: GPL 3.0
 # Change Logs:
 # Date           Author       Notes
 # 2020-08-07     Yong      the first version
#!/bin/sh
docker cp packages/libmodbus $1:/libmodbus \
    && docker cp ./docker_scripts/build-libmodbus.sh $1:/ \
    && docker exec $1 bash -c "/build-libmodbus.sh" \
    && rm -rf build/libmodbus && mkdir build/libmodbus \
    && docker cp $1:/libmodbus/tests/bandwidth-client build/libmodbus/ \
    && docker cp $1:/libmodbus/tests/bandwidth-server-one build/libmodbus/ 

3.4 编译libmodubs

3.4.1 编辑测试服务端bandwidth-server-one

修改server的绑定IP为0.0.0.0:

#bandwidth-server-one.c
...
ctx = modbus_new_tcp("0.0.0.0", 502);
...

3.4.2 编辑测试客户端 bandwidth-client

#bandwidth-client.c
...
if (use_backend == TCP) {
        ctx = modbus_new_tcp("10.100.1.63", 502);
    } else {
        ctx = modbus_new_rtu("/dev/ttyUSB1", 115200, 'N', 8, 1);
        modbus_set_slave(ctx, 1);
    }
...

3.4.3 编译bandwidth-client和bandwidth-server-one

执行以下命令就可以:

./scripts/deploy-libmodbus.sh basejay
libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, 'build-aux'.
libtoolize: linking file 'build-aux/ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
libtoolize: linking file 'm4/libtool.m4'
libtoolize: linking file 'm4/ltoptions.m4'
libtoolize: linking file 'm4/ltsugar.m4'
libtoolize: linking file 'm4/ltversion.m4'
libtoolize: linking file 'm4/lt~obsolete.m4'
configure.ac:33: installing 'build-aux/compile'
configure.ac:56: installing 'build-aux/config.guess'
configure.ac:56: installing 'build-aux/config.sub'
configure.ac:32: installing 'build-aux/install-sh'
configure.ac:32: installing 'build-aux/missing'
src/Makefile.am: installing 'build-aux/depcomp'
parallel-tests: installing 'build-aux/test-driver'

------------------------------------------------------
Initialized build system. You can now run ./configure
------------------------------------------------------

configure: loading site script /usr/local/oecore-x86_64/site-config-armv7a-vfp-neon-oe-linux-gnueabi
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for arm-strip... arm-oe-linux-gnueabi-strip
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking how to create a pax tar archive... gnutar
checking for style of include used by make... GNU
checking for arm-gcc... arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi accepts -g... yes
checking for arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi option to accept ISO C89... none needed
checking whether arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi understands -c and -o together... yes
checking dependency style of arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi... gcc3
checking for arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi option to accept ISO C99... -std=gnu99
checking for arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi -std=gnu99 option to accept ISO Standard C... (cached) -std=gnu99
checking how to run the C preprocessor... arm-oe-linux-gnueabi-gcc -E  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... (cached) yes
checking for sys/types.h... (cached) yes
checking for sys/stat.h... (cached) yes
checking for stdlib.h... (cached) yes
checking for string.h... (cached) yes
checking for memory.h... (cached) yes
checking for strings.h... (cached) yes
checking for inttypes.h... (cached) yes
checking for stdint.h... (cached) yes
checking for unistd.h... (cached) yes
checking minix/config.h usability... no
checking minix/config.h presence... no
checking for minix/config.h... no
checking whether it is safe to define __EXTENSIONS__... yes
checking for special C compiler options needed for large files... no
checking for _FILE_OFFSET_BITS value needed for large files... 64
checking whether make supports nested variables... (cached) yes
checking build system type... x86_64-pc-linux-gnu
checking host system type... arm-unknown-none
checking how to print strings... printf
checking for a sed that does not truncate output... (cached) sed
checking for fgrep... /bin/grep -F
checking for ld used by arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi -std=gnu99... arm-oe-linux-gnueabi-ld  --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi
checking if the linker (arm-oe-linux-gnueabi-ld  --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... arm-oe-linux-gnueabi-nm
checking the name lister (arm-oe-linux-gnueabi-nm) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking how to convert x86_64-pc-linux-gnu file names to arm-unknown-none format... func_convert_file_noop
checking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noop
checking for arm-oe-linux-gnueabi-ld  --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi option to reload object files... -r
checking for arm-objdump... arm-oe-linux-gnueabi-objdump
checking how to recognize dependent libraries... unknown
checking for arm-dlltool... no
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for arm-ar... arm-oe-linux-gnueabi-ar
checking for archiver @FILE support... @
checking for arm-strip... (cached) arm-oe-linux-gnueabi-strip
checking for arm-ranlib... arm-oe-linux-gnueabi-ranlib
checking command to parse arm-oe-linux-gnueabi-nm output from arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi -std=gnu99 object... ok
checking for sysroot... no
checking for a working dd... /bin/dd
checking how to truncate binary pipes... /bin/dd bs=4096 count=1
checking for arm-mt... no
checking for mt... mt
checking if mt is a manifest tool... no
checking for dlfcn.h... (cached) yes
checking for objdir... .libs
checking if arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi -std=gnu99 supports -fno-rtti -fno-exceptions... no
checking for arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi -std=gnu99 option to produce PIC... -fPIC -DPIC
checking if arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi -std=gnu99 PIC flag -fPIC -DPIC works... yes
checking if arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi -std=gnu99 static flag -static works... no
checking if arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi -std=gnu99 supports -c -o file.o... yes
checking if arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi -std=gnu99 supports -c -o file.o... (cached) yes
checking whether the arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi -std=gnu99 linker (arm-oe-linux-gnueabi-ld  --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... no
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... no
checking whether to build shared libraries... no
checking whether to build static libraries... yes
checking for arpa/inet.h... (cached) yes
checking for byteswap.h... (cached) yes
checking for errno.h... (cached) yes
checking for fcntl.h... (cached) yes
checking for limits.h... (cached) yes
checking for linux/serial.h... (cached) yes
checking for netdb.h... (cached) yes
checking for netinet/in.h... (cached) yes
checking for netinet/tcp.h... (cached) yes
checking for sys/ioctl.h... (cached) yes
checking sys/params.h usability... no
checking sys/params.h presence... no
checking for sys/params.h... no
checking for sys/socket.h... (cached) yes
checking for sys/time.h... (cached) yes
checking for sys/types.h... (cached) yes
checking for termios.h... (cached) yes
checking for time.h... (cached) yes
checking for unistd.h... (cached) yes
checking for asciidoc... no
checking for xmlto... no
checking whether to build documentation... no
configure: WARNING: The tools to build the documentation aren't installed
checking whether __CYGWIN__ is declared... no
checking for accept4... yes
checking for getaddrinfo... (cached) yes
checking for gettimeofday... (cached) yes
checking for inet_ntoa... (cached) yes
checking for select... (cached) yes
checking for socket... (cached) yes
checking for strerror... (cached) yes
checking for strlcpy... no
checking for inline... inline
checking whether we are using the GNU C++ compiler... yes
checking whether arm-oe-linux-gnueabi-g++  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi accepts -g... yes
checking dependency style of arm-oe-linux-gnueabi-g++  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi... gcc3
checking how to run the C++ preprocessor... arm-oe-linux-gnueabi-g++  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi -E
checking for ld used by arm-oe-linux-gnueabi-g++  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi... arm-oe-linux-gnueabi-ld  --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi
checking if the linker (arm-oe-linux-gnueabi-ld  --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi) is GNU ld... yes
checking whether the arm-oe-linux-gnueabi-g++  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi linker (arm-oe-linux-gnueabi-ld  --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi) supports shared libraries... no
checking for arm-oe-linux-gnueabi-g++  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi option to produce PIC... -fPIC -DPIC
checking if arm-oe-linux-gnueabi-g++  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi PIC flag -fPIC -DPIC works... yes
checking if arm-oe-linux-gnueabi-g++  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi static flag -static works... no
checking if arm-oe-linux-gnueabi-g++  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi supports -c -o file.o... yes
checking if arm-oe-linux-gnueabi-g++  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi supports -c -o file.o... (cached) yes
checking whether the arm-oe-linux-gnueabi-g++  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi linker (arm-oe-linux-gnueabi-ld  --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi) supports shared libraries... no
checking dynamic linker characteristics... no
checking how to hardcode library paths into programs... immediate
checking for int64_t... yes
checking for size_t... yes
checking for ssize_t... yes
checking for uint16_t... yes
checking for uint32_t... yes
checking for uint8_t... yes
checking winsock2.h usability... no
checking winsock2.h presence... no
checking for winsock2.h... no
checking whether TIOCSRS485 is declared... yes
checking whether TIOCM_RTS is declared... yes
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating src/modbus-version.h
config.status: creating src/win32/modbus.dll.manifest
config.status: creating tests/Makefile
config.status: creating doc/Makefile
config.status: creating libmodbus.pc
config.status: creating config.h
config.status: creating tests/unit-test.h
config.status: tests/unit-test.h is unchanged
config.status: executing depfiles commands
config.status: executing libtool commands

        libmodbus 3.1.6
        ===============

        prefix:                 /usr/local
        sysconfdir:             ${prefix}/etc
        libdir:                 ${exec_prefix}/lib
        includedir:             ${prefix}/include

        compiler:               arm-oe-linux-gnueabi-gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/usr/local/oecore-x86_64/sysroots/armv7a-vfp-neon-oe-linux-gnueabi -std=gnu99
        cflags:                  -O2 -fexpensive-optimizations -frename-registers -fomit-frame-pointer
        ldflags:                -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed

        documentation:          no
        tests:                  yes

Making clean in src
test -z "*~" || rm -f *~
test -z "libmodbus.la" || rm -f libmodbus.la
rm -f ./so_locations
rm -rf .libs _libs
rm -f *.o
rm -f *.lo
Making clean in doc
test -z "*.3 *.7 *.html" || rm -f *.3 *.7 *.html
rm -rf .libs _libs
rm -f *.lo
Making clean in tests
test -z "*~ *.log" || rm -f *~ *.log
rm -rf .libs _libs
 rm -f bandwidth-server-one bandwidth-server-many-up bandwidth-client random-test-server random-test-client unit-test-server unit-test-client version
rm -f *.o
test -z "./unit-tests.sh.log" || rm -f ./unit-tests.sh.log
test -z "./unit-tests.sh.trs" || rm -f ./unit-tests.sh.trs
test -z "test-suite.log" || rm -f test-suite.log
rm -f *.lo
test -z "libmodbus.pc" || rm -f libmodbus.pc
rm -rf .libs _libs
rm -f *.lo
make --no-print-directory all-recursive
Making all in src
  CC       modbus.lo
  CC       modbus-data.lo
  CC       modbus-rtu.lo
  CC       modbus-tcp.lo
  CCLD     libmodbus.la
Making all in doc
make[2]: Nothing to be done for 'all'.
Making all in tests
make  all-am
  CC       bandwidth-server-one.o
  CCLD     bandwidth-server-one
  CC       bandwidth-server-many-up.o
  CCLD     bandwidth-server-many-up
  CC       bandwidth-client.o
  CCLD     bandwidth-client
  CC       random-test-server.o
  CCLD     random-test-server
  CC       random-test-client.o
  CCLD     random-test-client
  CC       unit-test-server.o
  CCLD     unit-test-server
  CC       unit-test-client.o
  CCLD     unit-test-client
  CC       version.o
  CCLD     version
cd . && /bin/bash ./config.status libmodbus.pc
config.status: creating libmodbus.pc

在我们的脚本里面是把libmodbus编译后的tests文件夹拷贝出来,ls显示一下可以看到:

ls build/libmodbus/
bandwidth-client bandwidth-server-one

里面两个程序我们是需要用的bandwidth-clientbandwidth-server-one.

3.5 测试modbus编译好的程序

JayBox可以同里用做Modbus的Server。也可以作为Client来测试,使用scp命令将这些编译好的程序拷贝到Jaybox,这里只用bandwidth-clientbandwidth-server-one来测试:

scp bandwidth-client xguard@10.100.1.254:/tmp/
scp bandwidth-server-one xguard@10.100.1.254:/tmp/

登录JayBox终端:

ssh root@10.100.1.254

你可以使用你的电脑作为Server或者client测试也可以,这里我们使用盒子同时作为server和client来测试。

运行bandwidth-server-one

root@jieqi:/var/volatile/tmp# ./bandwidth-server-one &
root@jieqi:/var/volatile/tmp# ./bandwidth-client
READ BITS

Transfert rate in points/seconds:
* 112930 points/s

Values:
* 100000 x 2000 values
* 21531.000 ms for 25000000 bytes
* 1133 KiB/s

Values and TCP Modbus overhead:
* 100000 x 271 bytes
* 21531.000 ms for 27100000 bytes
* 1229 KiB/s


READ REGISTERS

Transfert rate in points/seconds:
* 218219 registers/s

Values:
* 100000 x 125 values
* 17918.000 ms for 25000000 bytes
* 1362 KiB/s

Values and TCP Modbus overhead:
* 100000 x 271 bytes
* 17918.000 ms for 27100000 bytes
* 1476 KiB/s


WRITE AND READ REGISTERS

Transfert rate in points/seconds:
* 175371 registers/s

Values:
* 100000 x 121 values
* 20015.000 ms for 24200000 bytes
* 1180 KiB/s

Values and TCP Modbus overhead:
* 100000 x 263 bytes
* 20015.000 ms for 26300000 bytes
* 1283 KiB/s

Quit the loop: Connection reset by peer
[1]+  Done                       ./bandwidth-server-one

Refer:


以上为第九章内容,我们陆续会推出以下新章节:

如何使用您的工业边缘计算单元

内容

第一章:了解您的JayBox 主板

第二章:开始使用您的JayBox 主板(仅需连接以太网电缆,24V电源)

第三章:使用你的JayBox 主板

第四章:使用易于编译的BaseJay开始编写程序

第五章:使用用Python编程

第六章:使用用C语言编程

第七章:使用BaseJay并编译你的应用

第八章:使用GPIO引脚进行物理计算

第九章:编程使用Modbus

第十章:编程使用OPC-UA

第十一章:使用MQTT的编程。

附录

附录A:命令行界面

附录B:JayBox 主板规格

附录C:JayBox主板4G及以太网带宽测试


联系我们

复杂的交给我们,简单的带给你们

hello@jieqi.io +86 (571) 8618 5263

地址

中国(杭州)人工智能小镇
文一西路1818-2号,杭州市
浙江,中国

申请试用