在ROS中获取并发布UBS式传感器的温湿度

哈喽大家好,我是钢板兽!

今天更新一篇和ROS相关的文章,有个项目需求是在ROS中获取并发布UBS式传感器的温湿度,我使用的温湿度传感器简介如下:

DL11- MC-S1 温湿度传感器通过USB 接口采用标准MODBUS RTU 协议通信,采用高精度的SHT40测量单元。

一开始尝试通过pymodbus通信,但是在安装好对应的依赖后依然不成功,于是使用字节级Modbus报文构造,通过 Python 的 pyserial 库以字节流形式与设备通信。

1.Modbus RTU 协议原理

Modbus RTU 是一种工业标准的串行通信协议,采用主从架构,每帧通信格式如下:

字段长度说明
地址1B从设备地址,通常为 1
功能码1B0x03 表示读保持寄存器
起始地址2B要读取的寄存器起始地址
寄存器数量2B要读取的寄存器个数
CRC 校验2B帧末尾附带的错误校验值

请求帧解析:

01 03 00 00 00 02 C4 0B
  • 01:设备地址(从站地址 1)
  • 03:功能码,表示“读取保持寄存器”
  • 00 00:寄存器起始地址 = 0x0000,即温度寄存器
  • 00 02:读取 2 个寄存器(温度 + 湿度)
  • C4 0B:CRC 校验(低位在前,高位在后)

响应帧解析:

01 03 04 01 19 02 11 EB 64
  • 01:从站地址
  • 03:功能码
  • 04:后续数据字节数(4 字节)
  • 01 19:寄存器 0x0000 的值 → 281(温度 28.1°C)
  • 02 11:寄存器 0x0001 的值 → 529(湿度 52.9%RH)
  • EB 64:CRC 校验

2.调试串口

  1. 查看串口是否被识别:

    ls /dev/ttyUSB*
    
  2. 串口权限设置:

    sudo usermod -aG dialout $USER
    # 重启系统后生效
    

3.Ros节点

  1. 脚本路径

    ~/catkin_ws/src/temperature_sensor/scripts/modbus_raw_node.py
    
  2. 节点代码

    节点要实现的功能:

    • 每秒向串口写入 Modbus 请求报文
    • 读取 9 字节返回帧,并解析温湿度原始值
    • 构造 ROS 消息并发布到 /sensor/temperature/sensor/humidity
    #!/usr/bin/env python3  
    import rospy             
    import serial            
    from sensor_msgs.msg import Temperature  # 引入标准温度消息类型
    from std_msgs.msg import Float32         # 引入标准浮点数消息类型# 解析 Modbus 响应帧,提取温湿度
    def parse_modbus_response(data):if len(data) != 9 or data[0] != 0x01 or data[1] != 0x03:return None, None  # 帧长度或地址/功能码错误则返回空值temp_raw = data[3] << 8 | data[4]  # 拼接为温度原始值hum_raw = data[5] << 8 | data[6]   # 拼接为湿度原始值temp = temp_raw / 10.0  # 转换为实际温度值hum = hum_raw / 10.0    # 转换为实际湿度值return temp, hum# 主函数def main():rospy.init_node("modbus_raw_temperature_node")  # 初始化 ROS 节点# 获取串口参数port = rospy.get_param("~port", "/dev/ttyUSB0")  # 默认串口设备baudrate = rospy.get_param("~baudrate", 9600)     # 默认波特率# 初始化两个 ROS 发布器temp_pub = rospy.Publisher("/sensor/temperature", Temperature, queue_size=10)hum_pub = rospy.Publisher("/sensor/humidity", Float32, queue_size=10)try:# 尝试打开串口ser = serial.Serial(port=port, baudrate=baudrate, bytesize=8, parity='N', stopbits=1, timeout=1)rospy.loginfo("串口连接成功")except Exception as e:rospy.logerr(f"串口打开失败: {e}")returnrate = rospy.Rate(1)  # 循环频率:1Hzwhile not rospy.is_shutdown():request = bytes.fromhex("01 03 00 00 00 02 C4 0B")  # 构造 Modbus 请求帧ser.write(request)  # 向串口写入请求response = ser.read(9)  # 读取9字节响应temp, hum = parse_modbus_response(response)  # 解析响应数据now = rospy.Time.now()  # 获取当前时间戳if temp is not None:msg = Temperature()msg.header.stamp = nowmsg.temperature = tempmsg.variance = 0.0temp_pub.publish(msg)  # 发布温度消息rospy.loginfo(f"温度: {temp} ℃")if hum is not None:hum_pub.publish(Float32(data=hum))  # 发布湿度消息rospy.loginfo(f"湿度: {hum} %RH")rate.sleep()  # 等待下一次循环ser.close()  # 程序退出时关闭串口if __name__ == "__main__":main()  # 调用主函数启动节点
    
  3. 添加执行权限

    chmod +x modbus_raw_node.py
    
  4. 运行

    rosrun temperature_sensor modbus_raw_node.py _port:=/dev/ttyUSB0
    
  5. 话题发布

    rostopic echo /sensor/temperature
    rostopic echo /sensor/humidit
    

如果这篇文章对你有帮助,欢迎点赞、转发、留言!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/95152.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/95152.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【图论】 Graph.jl 操作汇总

文章目录图论的集合类操作Base.getindexBase.intersectBase.joinBase.reverseBase.reverse!Base.sizeBase.sumBase.sumBase.union图生成与转换Graphs.cartesian_productGraphs.complementGraphs.compute_shiftsGraphs.crosspathGraphs.differenceGraphs.egonetGraphs.induced_s…

【链表 - LeetCode】146. LRU 缓存

146. LRU 缓存 题解&#xff1a; class LRUCache {list<pair<int,int>>v;unordered_map<int,list<pair<int,int>>::iterator>idx;int capacity; public:LRUCache(int capacity):capacity(capacity){}int get(int key) {if(idx.count(key) 0) …

Elasticsearch vs Solr vs OpenSearch:搜索引擎方案对比与索引设计最佳实践

Elasticsearch vs Solr vs OpenSearch&#xff1a;搜索引擎方案对比与索引设计最佳实践 随着大数据和实时分析需求的爆发&#xff0c;搜索引擎已成为许多业务系统中的核心组件。本篇文章将从“技术方案对比分析型”角度切入&#xff0c;重点比较三大主流搜索引擎&#xff1a;El…

光颉科技)Viking)的CS25FTFR009 1225 0.009R/9mR 3W电阻介绍-华年商城

“**华年商城”**小编为您介绍&#xff1a;光颉科技&#xff08;Viking&#xff09;的CS25FTFR009 1225 0.009R/9mR 3W电阻 光颉CS25FTFR009合金电阻&#xff1a;0.009Ω/9mΩ 3W 1%精密采样电阻 光颉科技&#xff08;Viking&#xff09;的CS25FTFR009是一款高性能的电流检测电…

港科大开放世界长时域具身导航!LOVON:足式机器人开放词汇目标导航

作者&#xff1a;Daojie Peng1^{1}1, Jiahang Cao1,2^{1,2}1,2, Qiang Zhang1,2^{1,2}1,2, Jun Ma1,3^{1,3}1,3单位&#xff1a;1^{1}1香港科技大学&#xff08;广州&#xff09;&#xff0c;2^{2}2北京人形机器人创新中心&#xff0c;3^{3}3香港科技大学论文标题&#xff1a;L…

【前端教程】JavaScript 数组对象遍历与数据展示实战

在前端开发中&#xff0c;处理数组和对象是日常工作的基础。无论是篇文章将通过一个具体案例&#xff0c;详细讲解如何使用JavaScript遍历包含对象的数组&#xff0c;并将数据以清晰的格式展示在页面上。我们会从基础语法开始&#xff0c;逐步优化代码&#xff0c;最终实现一个…

无重复字符的最长子串,leetCode热题100,C++实现

题目来源&#xff1a;leetCode 3. 无重复字符的最长子串 - 力扣&#xff08;LeetCode&#xff09; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子串 的长度。 解法 class Solution { public:int lengthOfLongestSubstring(string s) {unordered_set<…

卷积神经网络中1×1卷积的作用

part I &#xff1a;来源part II &#xff1a;应用part III &#xff1a;作用&#xff08;降维、升维、跨通道交互、增加非线性&#xff09;part IV &#xff1a;从fully-connected layers的角度理解一、来源&#xff1a;[1312.4400] Network In Network &#xff08;如果11…

VMware设置Ubuntu虚拟机桥接模式完整教程

VMware 设置 Ubuntu 虚拟机桥接模式完整教程 下面是一个详细的、避免出错的 VMware Ubuntu 桥接模式设置教程&#xff0c;包含常见问题的解决方案。 准备工作 确保宿主机&#xff08;Windows 11&#xff09;已连接到网络&#xff08;有线或无线&#xff09;确认您有管理员权限关…

浅析NVMe协议:DIF

文章目录概述DIF数据格式盘片支持DIFFormatPILPIMSETLBAF协议命令DIF支持PRACTPRACT0PRACT1PRCHK相关参考概述 NVMe协议将DIF信息作为元数据的一部分进行携带。 DIF数据格式 DIF的PI由多个字段组成&#xff0c;包括&#xff1a; Guard字段&#xff1a;基于逻辑块数据计算的C…

【观成科技】蔓灵花User下载者加密通信分析

概述2025年5月7日&#xff0c;蔓灵花&#xff08;BITTER&#xff09;组织针对巴基斯坦电信公司工作人员发起钓鱼邮件攻击&#xff0c;投递伪装为安全简报的恶意邮件&#xff0c;附件为IQY类型的Web查询文件。该文件在用户执行后通过HTTP协议获取远程CMD指令并执行&#xff0c;进…

Redis 保证数据不丢失

Redis 保证数据不丢失&#xff08;或最大限度减少丢失&#xff09;的核心是通过 持久化机制 结合 合理的配置策略 实现的。具体方案如下&#xff1a;一、核心&#xff1a;开启 Redis 持久化&#xff08;防止进程崩溃丢失数据&#xff09;Redis 提供两种持久化方式&#xff0c;可…

NUMA/SNC 4种组合下Stream+MLC性能对决:双路服务器BIOS调优全攻略

关于调整 BIOS NUMA 与 SNC 选项的 Stream / MLC 性能测试总结一、测试背景与目的在现代多路 Intel Xeon 服务器上&#xff0c;NUMA&#xff08;Non-Uniform Memory Access&#xff09;与 SNC&#xff08;Sub-NUMA Clustering&#xff09;是两项决定内存访问延迟与带宽的关键 B…

Java-113 深入浅出 MySQL 扩容全攻略:触发条件、迁移方案与性能优化

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; AI炼丹日志-31- 千呼万唤始出来 GPT-5 发布&#xff01;“快的…

Kafka Connect + Streams 用到极致从 CDC 到流处理的一套落地方案

关键目标&#xff1a; 零丢失&#xff1a;端到端 Exactly Once&#xff08;Source 端事务 Streams exactly_once_v2 Sink DLQ&#xff09;。低延迟&#xff1a;Producer 端批量压缩 Streams 缓存 合理 poll/commit 间隔。可恢复&#xff1a;Connect/Streams 的 rebootstrap…

# `std::basic_istream`总结

std::basic_istream总结 文章目录std::basic_istream总结概述常用类型定义全局对象核心成员函数1. 格式化输入2. 非格式化输入3. 流定位4. 其他功能继承的功能来自 std::basic_ios状态检查状态管理来自 std::ios_base格式化标志流打开模式特点说明例子std::basic_istream全面用…

人工智能——课程考核

课程考核包括平时测验&#xff08;75%&#xff09;和讨论&#xff08;25%&#xff09;两个环节&#xff0c;测验采用线上随堂考试&#xff08;2-3次&#xff0c;具体会在本课堂发布&#xff09;重点考核&#xff1a;A*算法、极大极小过程&#xff08;α-β剪枝&#xff09;、不…

机器学习-时序预测1

最近面试过程中&#xff0c;Predict-then-Optimize是运筹优化算法工程师未来的发展方向。就像我之前写过的运筹优化&#xff08;OR&#xff09;-在机器学习&#xff08;ML&#xff09;浪潮中何去何从&#xff1f;-CSDN博客&#xff0c;机器学习适合预测、运筹优化适合决策。我研…

vim-plugin AI插件

文章目录一、vim 插件管理vim-plug二、如何使用和配置 vim-plug第 1 步&#xff1a;安装 vim-plug第 2 步&#xff1a;配置你的 .vimrc / init.vim第 3 步&#xff1a;安装插件常用 vim-plug 命令三、配置vim-aivim-aivim-deepseekvim升级四、配置 AI 插件GitHub Copilot第 1 步…

Adobe Photoshop 2025 最新下载安装教程,附PS2025下载

点击获取&#xff1a;Adobe Photoshop 2025 安装教程&#xff1a; 1、安装包下载后&#xff0c;鼠标右键解压安装包 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 2、双击打开解压后的安装包文件夹 3、打开setup文件夹 添加图片注释&#xff0c;不超过…