Java采集传感器数据,亲测有效!

背景

先说背景

最近公司项目需要用到传感器,采集设备温湿度,倾斜角,电流…,公司采购采购了一个温湿度传感器给我们开发测试使用,如下图:

image-20231027213450647

看着还挺精致有没有。

进入正题

有了这个温湿度传感器,我们如何读取其采集到的数据呢。需要一个RS485转串口工具,下面这个蓝色的东东:

image-20231027213752928

把它接到传感器上,然后插到电脑上

image-20231027213858771

通过电脑设备管理器-端口,可以看到该设备串口号是COM3,这个参数记住下面采集数据需要。

接下来,先用工具TH11S-B Tool_V105,直接读取温湿度。

工具长这样image-20231027214139239

打开工具,

image-20231027214357841

除了串口号,其他参数基本都是固定的,也看到页面上串口号也确实是COM3,然后点击连接直接连接串口。

此时点击读取就能读到当时的温湿度值,可以看到通过串口与传感器交互的协议报文。

image-20231027214545607

读取报文01 03 00 00 00 02 C4 0B,经过搜索得知这个是ModBus-RTU协议(传感器常用协议)的报文,具体含义如下:

ChatGPT回答:

这个报文 01 03 00 00 00 02 C4 0B 是一个 Modbus RTU 协议的请求报文,它的各部分含义如下:

  1. 01:从站地址,表示要操作的 Modbus 从站的地址。在这个例子中,从站地址为 1。
  2. 03:功能码,表示请求的操作类型。在 Modbus 中,功能码 03 表示读取保持寄存器。这个功能码用于读取传感器的数据。
  3. 00 00:起始寄存器地址,指示要读取的寄存器的起始地址。在这个例子中,起始寄存器地址为 0x0000(通常是一个 16 位的寄存器地址)。
  4. 00 02:寄存器数量,表示要读取的连续寄存器的数量。在这个例子中,要读取 2 个寄存器。
  5. C4 0B:CRC 校验,用于确保报文的完整性。

这个请求报文的目的是要求 Modbus 从站(通常是传感器或其他设备)返回起始寄存器地址为 0x0000 的 2 个寄存器的数据。这些数据通常包括传感器的温度和湿度值,具体含义取决于传感器的规格和协议。所以,你需要根据你的传感器的规格和协议来解析这些数据。

具体协议不做研究,主要看看响应报文01 03 04 00 FE 02 50 9A 9F,具体含义如下:

ChatGPT回答:

这个响应报文 01 03 04 00 FE 02 50 9A 9F 是 Modbus RTU 协议的响应报文,其各部分含义如下:

  1. 01:从站地址,表示响应来自 Modbus 从站的地址。在这个例子中,从站地址为 1,与请求报文相同。

  2. 03:功能码,表示响应的操作类型。在 Modbus 中,功能码 03 表示读取保持寄存器。这个功能码用于读取传感器的数据,与请求报文相同。

  3. 04:字节数,表示响应数据的字节数。在这个例子中,有 4 个字节的数据。

  4. 00 FE:数据,表示读取到的保持寄存器数据。这里的数据是 2 个 16 位寄存器的值,以大端模式表示(高位在前,低位在后)。在这个例子中,它的十六进制值为 00 FE,对应的十进制值是 254。

  5. 02:CRC 校验,用于确保报文的完整性。

根据响应报文中的数据部分,这个特定传感器的温度值为 254。要了解确切的温度单位和规范,请参考传感器的文档或规格表。通常,温度值需要进一步处理和解释,以转换为实际的温度单位(例如摄氏度或华氏度)。

其他无需关注只需知道**00 FE(第四五字节)表示温度值,02 50(第六七字节)表示湿度值**即可,十六进制转为十进制然后直接除以十就是真实温湿度值。

00 FE:254 / 10.0 = 25.4度(温度)

02 50:592 / 10.0 = 59.2%(湿度)

代码实战

经过一些调研,要使用Java读取传感器数据,jSerialComm依赖用的比较多。

添加依赖

项目中添加依赖

       <dependency>
            <groupId>com.fazecast</groupId>
            <artifactId>jSerialComm</artifactId>
            <version>2.9.2</version>
        </dependency>

封装构建请求报文工具类

接下来构建请求报文,创建工具类与请求报文格式对应如下:

public class ModbusRTURequestBuilder {

    /**
     * @param slaveAddress 从站地址
     * @param functionCode 功能码
     * @param startAddress 起始寄存器地址
     * @param registerCount 寄存器数量
     * @return Modbus-RTU 协议请求报文
     */
    public static byte[] buildModbusRTURequest(int slaveAddress, int functionCode, int startAddress, int registerCount) {
        // 创建一个字节数组用于存储报文
        byte[] request = new byte[8];

        // 设置从机地址
        request[0] = (byte) slaveAddress;

        // 设置功能码
        request[1] = (byte) functionCode;

        // 设置起始寄存器地址(高位和低位)
        request[2] = (byte) (startAddress >> 8);
        request[3] = (byte) (startAddress & 0xFF);

        // 设置寄存器数量(高位和低位)
        request[4] = (byte) (registerCount >> 8);
        request[5] = (byte) (registerCount & 0xFF);

        // 计算CRC校验并设置到报文中
        int crc = calculateCRC(request, 6);
        request[6] = (byte) (crc & 0xFF); // 低位
        request[7] = (byte) (crc >> 8); // 高位

        return request;
    }

    private static int calculateCRC(byte[] message, int length) {
        int crc = 0xFFFF;
        for (int i = 0; i < length; i++) {
            crc ^= (message[i] & 0xFF);
            for (int j = 0; j < 8; j++) {
                if ((crc & 1) == 1) {
                    crc = (crc >> 1) ^ 0xA001;
                } else {
                    crc = crc >> 1;
                }
            }
        }
        return crc;
    }
}

与传感器交互,解析响应报文

接下来与传感器交互,解析响应报文温湿度值

简单测试一下:

public class SerialSensorReader {
    public static void main(String[] args) {
        // 设置串口一些参数,除了串口号其他基本固定 COM3就是开头要大家记住的串口号
        SerialPort serialPort = SerialPort.getCommPort("COM3"); // 串口设备名称
        serialPort.setBaudRate(9600); // 波特率
        serialPort.setNumDataBits(8); // 数据位
        serialPort.setParity(SerialPort.NO_PARITY); // 校验位
        serialPort.setNumStopBits(1); // 停止位

        if (serialPort.openPort()) {
            // 借助工具类,构建请求报文
            byte[] requestMessage = ModbusRTURequestBuilder.buildModbusRTURequest(1, 3, 0, 2);
            // 读取温湿度
            serialPort.writeBytes(requestMessage, requestMessage.length);

            try {
                Thread.sleep(100); // 等待足够的时间以确保传感器响应
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
			// 响应数据的长度根据传感器规格进行配置(该传感器响应报文长度为9,不同传感器自行调整)
            byte[] responseData = new byte[9]; 

            // 获取响应 	
            int bytesRead = serialPort.readBytes(responseData, responseData.length);
            if (bytesRead == responseData.length) {
                // 解析温湿度数据
                int temperature = ((responseData[3] << 8) | (responseData[4] & 0xFF));
                int humidity = ((responseData[5] << 8) | (responseData[6] & 0xFF));

                System.out.println("温度: " + temperature / 10.0);
                System.out.println("湿度: " + humidity / 10.0);
            } else {
                System.out.println("未收到完整的响应数据");
            }

            serialPort.closePort();
        } else {
            System.out.println("无法打开串口");
        }
    }
}

经测试,数据没有问题:

image-20231027221424840

文章不长,也是博主一点一点搜出来、ChatGPT出来的,其中也是踩了不少坑,创作不易,请一键三连啊!(如果文章对您有用的话,不妨给我一个大大的赞,您的赞是我创作的动力。)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于ChatGPT实现AI软件研发 | 神经网络 | 数据

计算机技术的发展和互联网的普及&#xff0c;使信息处理和传输变得更加高效&#xff0c;极大地改变了金融、商业、教育、娱乐等领域的运作方式。数据分析、人工智能和云计算等新兴技术&#xff0c;也在不断地影响和改变着各个行业。 如今&#xff0c;我们正在见证人工智能技术…

Redis(04)| 数据结构-压缩列表

压缩列表的最大特点&#xff0c;就是它被设计成一种内存紧凑型的数据结构&#xff0c;占用一块连续的内存空间&#xff0c;不仅可以利用 CPU 缓存&#xff0c;而且会针对不同长度的数据&#xff0c;进行相应编码&#xff0c;这种方法可以有效地节省内存开销。 但是&#xff0c;…

RK3568-pcie接口

pcie接口与sata接口 pcie总线pcie总线pcie控制器sata控制器nvme设备sata设备nvme协议ahci协议m-key接口b-key接口RC模式和EP模式 RC和EP分别对应主模式和从模式,普通的PCI RC主模式可以用于连接PCI-E以太网芯片或PCI-E的硬盘等外设。 RC模式使用外设一般都有LINUX驱动程序,安…

计算机操作系统重点概念整理-第四章 内存管理【期末复习|考研复习】

第四章 内存管理 【期末复习|考研复习】 计算机操作系统系列文章传送门&#xff1a; 第一章 计算机系统概述 第二章 进程管理 第三章 进程同步 第四章 内存管理 第五章 文件管理 第六章 输出输出I/O管理 文章目录 第四章 内存管理 【期末复习|考研复习】前言四、内存管理4.1 内…

企业安全—DevSecOps概述详情

0x00 前言 SDL存在的问题在于体量过于庞大&#xff0c;不利于快速进行适配和进行&#xff0c;所以就有了DevSecOps&#xff0c;实际上是因为敏捷开发也就是DevOps的推进&#xff0c;并且坐上了云服务模式的火车&#xff0c;所以这一系列的东西都开始普及。DevSecOps作为DevOps…

PTE-写作 学习(一)

目录 PTE写作 写作技能 词汇积累 熟悉机经 pte写作考的就是态度 写作技能 看一段写一句 蓝色框里的单词是不可以使用的 &#xff0c;他们是副词&#xff0c;要添加新的句子 PTE写作 写作技能 词汇积累 熟悉机经 题库太窄 pte写作考的就是态度 写作技能 极有模板可…

【数据结构】选择排序

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;浅谈数据结构 &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 直接选择、堆排序 1. 直接选择排序2…

泛微OA之获取每月固定日期

文章目录 1.需求及效果1.1需求1.2效果 2. 思路3. 实现 1.需求及效果 1.1需求 需要获取每个月的7号作为需发布日期&#xff0c;需要自动填充1.2效果 自动获取每个月的七号2. 思路 1.功能并不复杂&#xff0c;可以用泛微前端自带的插入代码块的功能来实现。 2.将这需要赋值的…

Redis -- 基础知识2

1.Redis客户端介绍 1.基础介绍 Redis是一种客户端-服务器结构的程序&#xff0c;通过网络进行互动 客户端的多种形态 1.自带了命令行客户端&#xff1a;redis-cil 2.图形化界面的客户端&#xff1a;依赖windows系统&#xff0c;连接服务器有诸多限制&#xff0c;不建议使用 3.基…

模拟算法及其优化

第一题 替换所有问号 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 class Solution { public:string modifyString(string s) {string ret;for(int i0;i<s.size();i){if(i0){if(s[i]?&&i1<s.size()){for(char aa;a<z;a){if(a!s…

J2EE项目部署与发布(Windows版本)

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《Spring与Mybatis集成整合》《Vue.js使用》 ⛺️ 越努力 &#xff0c;越幸运。 1.单机项目的部署 1.1们需要将要进行部署的项目共享到虚拟机中 在部署项目之前&#xff0c;我们先要检查一下…

基于情感词典的情感分析方法

计算用户情绪强弱性&#xff0c;对于每一个文本都可以得到一个情感分值&#xff0c;以情感分值的正负性表示情感极性&#xff0c;大于0为积极情绪&#xff0c;小于0反之&#xff0c;绝对值越大情绪越强烈。 基于情感词典的情感分析方法主要思路&#xff1a; 1、对文本进行分词…

数据结构与算法基础(青岛大学-王卓)(9)

终于迎来了最后一部分(排序)了&#xff0c;整个王卓老师的数据结构就算是一刷完成了&#xff0c;但是也才是数据结构的开始而已&#xff0c;以后继续与诸位共勉 &#x1f603; (PS.记得继续守护家人们的健康当然还有你自己的)。用三根美味的烤香肠开始吧。。。 文章目录 排序基…

CSS 基础知识-02

CSS 基础知识-01 1. flex布局2.定位3.CSS精灵4.CSS修饰属性 1. flex布局 2.定位 3.CSS精灵 4.CSS修饰属性

NEWCC:新时代的区块链生态新币私募造势平台

在当今区块链领域&#xff0c;这项技术已经为金融资产注入了全新的生机&#xff0c;同时也为初创企业提供了新的商业模式和融资机会。通过代币的金融属性&#xff0c;企业和项目方得以实现资本的初期积累&#xff0c;同时在区块链空间以更低成本和更高效率进行交易和服务创新。…

【Oracle】[INS-30131]执行安装程序验证所需的初始设置失败。

这里写目录标题 一、问题描述1 报错内容1.1 无法从节点“kotin”检索 exectask 的版本1.2 工作目录"xxx"无法在节点"kotin"上使用 2 相关环境2.1 安装软件2.2 安装系统 3 解决思路分析 二、解决方案1 方案一、 满足验证条件 - 不换系统1.1 第一步、检查文件…

如何 通过使用优先级提示,来控制所有网页资源加载顺序

当你打开浏览器的网络标签时&#xff0c;你会看到大量的活动。资源正在下载&#xff0c;信息正在提交&#xff0c;事件正在记录&#xff0c;等等。 由于有太多的活动&#xff0c;有效地管理这些流量的优先级变得至关重要。带宽争用是真实存在的&#xff0c;当所有请求同时触发时…

three.js第一课

官网 1.创建场景 2.创建几何体 3.创建材质 4.创建网格模型 5.将几何体、材质加入网格模型&#xff0c;设置网格模型的位置&#xff0c;将网格模型加入场景中 6.创建相机&#xff0c;构造函数中设置角度、最后面视椎体的长宽比&#xff0c;相机离视椎体近端面的距离、视椎体的远…

Fabric.js 图案笔刷

本文简介 带尬猴&#xff0c;我是德育处主任 Fabric.js 有图案画笔功能&#xff0c;这个功能可以简单理解成“刮刮卡”效果。 如果只是看 Fabric.js 文档可能还不太明白 图案画笔 PatternBrush 是如何使用。 本文将讲解如何配置这款画笔的基础属性。 图案画笔&#xff08;笔…

Linux ——目录结构

&#xff08;一&#xff09;文件与目录操作 Linux可支持长达256个字符的文件名称&#xff0c;且文件名称是区分大小写的&#xff0c;“abc”与“ABC”表示的是不同的文件。 聪明的你请猜猜下面文件的类型是啥呀&#xff1f; 答&#xff1a;管道文件、普通文件、链接文件、设备文…