0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Modbus RTU客户端及服务器端的编程与实验

瑞萨MCU小百科 来源:瑞萨MCU小百科 2024-12-31 16:38 次阅读

11.5 Modbus RTU客户端编程与实验

瑞米派开发板作为client(主设备),去访问Modbus传感器(作为Server)。

本节源码位于如下目录:

3652ef10-c72d-11ef-9310-92fbcf53809c.png

11.5.1 硬件连接

硬件连接原理图如下:

3671307e-c72d-11ef-9310-92fbcf53809c.png

实物连接图如下:

367d2532-c72d-11ef-9310-92fbcf53809c.png

11.5.2 传感器点表

对于Modbus设备,怎么访问它们?它们的寄存器分别有什么功能?这在“点表”里描述,每个寄存器被称为一个“点”。

百问网的温湿度传感器的点表如下:

设备
地址
寄存器
地址
寄存器
类别
用途 描述
03H 0000H DO 控制器蜂鸣1 1-响
0001H DO 控制器蜂鸣2 1-响
0002H DO 控制LED1 1-亮
0003H DO 控制LED2 1-亮
0004H DO 控制LED3 1-亮
0000H AI 读取温度 单位0.1摄氏度
16位有符号整数
0001H AI 读取湿度 单位0.1%RH
16位有符合整数

11.5.3 程序解析

代码在如下目录里:

36eb6e20-c72d-11ef-9310-92fbcf53809c.png

假设执行如下命令:

左右滑动查看完整内容

./modbus_client /dev/ttySC4 read

程序运行的情景分析如下

1. 初始化与连接

代码如下:

左右滑动查看完整内容

33 ctx = modbus_new_rtu(argv[1], 115200, 'N', 8, 1);
34 if (ctx == NULL) {
35 fprintf(stderr, "Unable to allocate libmodbus context
");
36 return -1;
37 }
38
39 modbus_set_slave(ctx, SERVER_ID);
40
41 if (modbus_connect(ctx) == -1) {
42 fprintf(stderr, "Connection failed: %s
", modbus_strerror(errno));
43 modbus_free(ctx);
44 return -1;
45 }

第33行:分配一个modbus_t结构体。

第39行:设置要访问的Modbus传感器地址。

第41行:打开串口设备。

2. 读取传感器数据

代码如下:

左右滑动查看完整内容

47 if (!strcmp(argv[2], "read"))
48 {
49 while (1)
50 {
51 rc = modbus_read_input_registers(ctx, 0, 2, vals);
52 if (rc == 2)
53 {
54 printf("Temprature = %d.%dC, Humity = %d.%d%%
", vals[0]/10, val
s[0]%10, vals[1]/10, vals[1]%10);
55 }
56 else
57 {
58 printf("modbus_read_input_registers err: %d, %s
", rc, strerror
(errno));
59 }
60 sleep(2);
61 }
62 }

第51行:读取2个AI寄存器。

第54行:打印温湿度值。

11.5.4 上机实验

注意:假设你在“/home/ubuntu/apps/libmodbus-3.1.10”目录下编译了Libmodbus,并且在“/home/ubuntu/apps/libmodbus-3.1.10/tmp”目录下安装了Libmodbus。如果你的路径不一样,需要修改后续程序的Makefile。

把代码上传到Ubuntu。

然后,在Ubuntu下执行如下命令进行编译:

左右滑动查看完整内容

$ source /opt/remi-sdk/environment-setup-aarch64-poky-linux
$ make
$ scp modbus_client root@192.168.5.9:/mnt

最后,在开发板上执行如下命令:

左右滑动查看完整内容

# cd /mnt
# ./modbus_client /dev/ttySC4 beep1 on
modbus_write_bit ok
# ./modbus_client /dev/ttySC4 beep1 off
modbus_write_bit ok
# ./modbus_client /dev/ttySC4 led1 on
modbus_write_bit ok
# ./modbus_client /dev/ttySC4 led1 off
modbus_write_bit ok
# ./modbus_client /dev/ttySC4 read
Temprature = 32.0C, Humity = 39.2%
Temprature = 31.9C, Humity = 39.2%

11.6 Modbus RTU服务器端编程与实验

要把瑞米派当做一个Modbus服务器(传感器)来使用,需要有另一个开发板作为客户端。为了方便实验,本课程使用同一个瑞米派开发板,它运行2个程序:一个模拟服务器,另一个模拟客户端。

本节源码位于如下目录:

3723757c-c72d-11ef-9310-92fbcf53809c.png

硬件框图与连接如下所示。

11.6.1 硬件连接

硬件连接原理图如下:

3746beb0-c72d-11ef-9310-92fbcf53809c.png

实物连接图如下:

376a0730-c72d-11ef-9310-92fbcf53809c.png

11.6.2 程序解析

代码在如下目录里:

37a37934-c72d-11ef-9310-92fbcf53809c.png

“modbus_server.c”代码解析如下。

1. 初始化与连接

代码如下:

左右滑动查看完整内容

40 ctx = modbus_new_rtu(argv[1], 115200, 'N', 8, 1);
41 if (ctx == NULL) {
42 fprintf(stderr, "Unable to allocate libmodbus context
");
43 return -1;
44 }
45
46 modbus_set_slave(ctx, SERVER_ID);
47
48 mb_mapping = modbus_mapping_new_start_address(0,
49 NB_BITS, /* 5 个 DO 寄存器,对应 beep1,beep2,led1,led2,led3 */
50 0,
51 NB_INPUT_BITS,
52 0,
53 NB_REGISTERS,
54 0,
55 NB_INPUT_REGISTERS); /* 2 个 AI 寄存器,对应温度和湿度 */
56 memset(mb_mapping->tab_bits, 0, NB_BITS);
57 memset(mb_mapping->tab_input_registers, 0, NB_INPUT_REGISTERS*2);
58
59 memset(old_bits, 0, NB_BITS);
60 memset(old_regs, 0, NB_INPUT_REGISTERS*2);
61
62 if (modbus_connect(ctx) == -1) {
63 fprintf(stderr, "Connection failed: %s
", modbus_strerror(errno));
64 modbus_free(ctx);
65 return -1;
66 }

第40行:分配一个modbus_t结构体。

第46行:设置自己的传感器地址。

第48~55行:分配Modbus寄存器。

第56~57行:设置DO、AI寄存器初始值为0。

第59~60行:设置2个数组的值为0,这2个数组将用来跟Modbus寄存器进行比较,这样才能知道Client程序有没有修改这些值。

第62行:打开串口设备。

2. 等待Client程序发来请求

代码如下:

左右滑动查看完整内容

68 while (1)
69 {
70 do {
71 rc = modbus_receive(ctx, query);
72 /* Filtered queries return 0 */
73 } while (rc == 0);

第71行:读取请求。

3. 模拟温湿度传感器

代码如下:

左右滑动查看完整内容

82 /* 使用随机数模拟温度、湿度 */
83 mb_mapping->tab_input_registers[0] = rand() % 1000; /* 温度,单位:0.1C */
84 mb_mapping->tab_input_registers[1] = rand() % 1000; /* 湿度,单位:0.1% */

4. 回复数据给Client

代码如下:

左右滑动查看完整内容

86 rc = modbus_reply(ctx, query, rc, mb_mapping);
87 if (rc == -1) {
88 //break;
89 }

如果Client发来的请求是读取温湿度值的话,那么第86行就会回复数据给它。

5. 模拟蜂鸣器和LED操作

代码如下:

左右滑动查看完整内容

91 /* 根据 client 设置的数值,假装操作蜂鸣器和 LED */
92 if (mb_mapping->tab_bits[0] != old_bits[0])
93 {
94 printf("set beep1 %s
", mb_mapping->tab_bits[0] ? "on" : "off");
95 old_bits[0] = mb_mapping->tab_bits[0];
96 }
97
98 if (mb_mapping->tab_bits[1] != old_bits[1])
99 {
100 printf("set beep2 %s
", mb_mapping->tab_bits[1] ? "on" : "off");
101 old_bits[1] = mb_mapping->tab_bits[1];
102 }
103
104 if (mb_mapping->tab_bits[2] != old_bits[2])
105 {
106 printf("set led1 %s
", mb_mapping->tab_bits[2] ? "on" : "off");
107 old_bits[2] = mb_mapping->tab_bits[2];
108 }
109
110 if (mb_mapping->tab_bits[3] != old_bits[4])
111 {
112 printf("set led2 %s
", mb_mapping->tab_bits[4] ? "on" : "off");
113 old_bits[3] = mb_mapping->tab_bits[4];
114 }
115
116 if (mb_mapping->tab_bits[4] != old_bits[4])
117 {
118 printf("set led3 %s
", mb_mapping->tab_bits[4] ? "on" : "off");
119 old_bits[4] = mb_mapping->tab_bits[4];
120 }

代码比较简单,不再赘述。

11.6.3 上机实验

把代码上传到Ubuntu。

然后,在Ubuntu下执行如下命令进行编译:

左右滑动查看完整内容

$ source /opt/remi-sdk/environment-setup-aarch64-poky-linux
$ make
$ scp modbus_client root@192.168.5.9:/home/root
$ scp modbus_server root@192.168.5.9:/home/root

最后,在开发板上执行如下命令(先执行 modbus_server):

左右滑动查看完整内容

# cd /home/root
# ./modbus_server /dev/ttySC2 &
# ./modbus_client /dev/ttySC4 beep1 on
modbus_write_bit ok
# ./modbus_client /dev/ttySC4 beep1 off
modbus_write_bit ok
# ./modbus_client /dev/ttySC4 led1 on
modbus_write_bit ok
# ./modbus_client /dev/ttySC4 led1 off
modbus_write_bit ok
# ./modbus_client /dev/ttySC4 read
Temprature = 64.9C, Humity = 42.1%
Temprature = 36.2C, Humity = 2.7%
Temprature = 69.0C, Humity = 5.9%

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 传感器
    +关注

    关注

    2554

    文章

    51638

    浏览量

    758049
  • MODBUS
    +关注

    关注

    28

    文章

    1838

    浏览量

    77557
  • 服务器
    +关注

    关注

    12

    文章

    9384

    浏览量

    86366
  • RTU
    RTU
    +关注

    关注

    0

    文章

    422

    浏览量

    28832

原文标题:Modbus RTU客户端及服务器端的编程与实验 - RZ MPU工业控制教程连载(43)

文章出处:【微信号:瑞萨MCU小百科,微信公众号:瑞萨MCU小百科】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    相关推荐

    服务器端模式下的TCP通信

    我是谁——ESP8266,连接家里路由成功之后,会自动获得一个IP,这是服务器端IP 谁要和我连接——因为是在我电脑上使用网络调试助手模拟TCP客户端,所以客户端
    的头像 发表于 12-30 09:15 4642次阅读
    <b class='flag-5'>服务器端</b>模式下的TCP通信

    用队列实现的1对N的TCP服务器端,自动回复信息总发错客户端

    本帖最后由 kaneiqi1210 于 2014-7-17 12:43 编辑 如题,我仿照教材用队列做的TCP一对多的服务器端,在1对1时,没问题,而在1对多时,就出现,自动回复信息至不正确的客户端(即非发送信息的客户端
    发表于 07-17 09:31

    TCP视频服务器&客户端 - 版本LabVIEW 2012

    客户端功能:显示服务器采集到的视频,实时调整服务器采集视频的分辨率。客户端需要输入服务器端的ip地址和端口号。以这两个程序为基础,可以加个
    发表于 01-22 14:22

    qt tcp程序在服务器端发送数据之前能接收客户端发送的数据吗?

    写了一个tcp的客户端服务器端,是服务器端客户端发送文件,但是我想在服务器端发送之前先让客户端
    发表于 04-22 20:06

    一个服务器,多个客户端,怎么向指定的客户端发数据

    我用labview做服务器,单片机做客户端客户端几百个,怎么区分客户端,给指定的客户发发数据
    发表于 06-01 09:26

    labview怎么实现服务器端一直等待客户端发送数据啊

    我现在在做labview的服务器端,但是当客户端发送数据结束后,我的服务器端会报错。报错的意思就是说客户端关闭,我想知道怎么实现才可以让客户端
    发表于 08-12 14:34

    为什么LWIP的TCP客户端服务器端断开后继续发送数据就无法检测到连接状态?

    发现LWIP的TCP客户端有个BUG,当服务器端开之后,如果还继续发送数据,那就不能检测到连接状态。求助求助
    发表于 10-29 20:26

    4412开发板Qt网络编程-TCP实现服务器客户端

    更改组件名称注释,完成后如图 : 步骤三:服务器端编程:1.创建 QTcpServer 对象2.创建监听端口,使得客户端可以使用这个端口访问服务器,使用 listen 函数。bool
    发表于 04-28 15:33

    监控系统客户端服务端设计

    项目开发报告1 项目简介1.1 概述1.2 开发环境1.3 其他支持1.4 应用界面1.4.1 服务器端1.4.2 客户端1.5 程序使用2 项目开发2.1 搭建基于实验平台数据库2.1.1 数据库
    发表于 12-21 07:02

    客户端服务器和网络技术

    基于服务器的计算代表着一种应用程序部署方法。 对以下基于服务器的计算环境而言,瘦客户端是理想的客户端设备: 借助 Windows 2000 或 Windows Server 2003
    发表于 07-02 16:46 17次下载
    瘦<b class='flag-5'>客户端</b>的<b class='flag-5'>服务器</b>和网络技术

    网络调试和串口调试集合UDP TCP客户端和TCP服务器端应用程序免费下载

    本文档的主要内容详细介绍的是网络调试和串口调试集合UDP TCP客户端和TCP服务器端应用程序免费下载。
    发表于 08-30 08:00 16次下载
    网络调试和串口调试集合UDP TCP<b class='flag-5'>客户端</b>和TCP<b class='flag-5'>服务器端</b>应用程序免费下载

    TCP通信服务器端客户端同机互传的简单示例程序免费下载

    本文档的主要内容详细介绍的是TCP通信服务器端客户端同机互传的简单示例程序免费下载初学者学习。本例子是本计算机labview程序之间的通信,如果要想实现计算机与计算机之间的通信,需要设置例子里面的IP。
    发表于 10-25 08:00 9次下载
    TCP通信<b class='flag-5'>服务器端</b>和<b class='flag-5'>客户端</b>同机互传的简单示例程序免费下载

    数据是怎么样保证准确的从客户端发送到服务器端

    你有想过吗,在计算机网络当中,数据是怎么样保证准确的从客户端发送到服务器端的?中间涉及到了哪些理论?
    的头像 发表于 07-01 10:09 2192次阅读

    Linux下TCP网络编程-创建服务器客户端

    这篇文章介绍在Linux下的socket编程,完成TCP服务器客户端的创建,实现数据通信。
    的头像 发表于 08-14 09:26 2581次阅读
    Linux下TCP网络<b class='flag-5'>编程</b>-创建<b class='flag-5'>服务器</b>与<b class='flag-5'>客户端</b>

    服务端测试和客户端测试区别在哪

    服务端测试和客户端测试是软件开发过程中的两个重要环节,它们分别针对服务器端客户端的软件进行测试。本文将详细介绍服务端测试和
    的头像 发表于 05-30 15:27 3606次阅读