基于STM32的传感器数据采集系统设计:Qt、RS485、Modbus Rtu协议(代码示例)

一、项目概述

项目目标与用途

本项目旨在设计并实现一个基于STM32F103RCT6微控制器的传感器数据采集系统。该系统通过多个传感器实时监测环境参数,并将采集到的数据传输至上位机进行处理和分析。系统的主要应用领域包括环境监测、工业控制、智能家居等。通过该系统,用户能够实时获取传感器数据,进行数据存储和分析,并具备限位报警、状态判断、故障监测等功能,以提高监测的及时性和有效性。

技术栈关键词

  • 硬件: STM32F103RCT6微控制器、RS485、RS232接口、传感器模块

  • 通信协议: Modbus RTU

  • 软件: Qt开发环境

  • 编程语言: C/C++、Qt

二、系统架构

系统架构设计

本系统由三个主要部分组成:传感器、数据采集模块和上位机。系统架构的设计如下图所示:

数据采集
RS485
数据处理
限位报警
状态判断
故障监测
传感器
数据采集模块
上位机
用户界面
报警模块
状态监测模块
故障检测模块

系统组件选择

  1. 单片机: 选用STM32F103RCT6微控制器,具有高性能和丰富的外设接口,适合复杂的数据采集任务。

  2. 通信协议: 采用RS485接口,以Modbus RTU协议进行数据通信,适合长距离和多点通信,确保数据的完整性和可靠性。

  3. 传感器: 选择温度、湿度、气体等多种传感器,能够满足不同环境监测需求。

  4. 上位机软件: 使用Qt开发环境,提供直观的用户交互界面,支持实时数据显示和历史数据分析。

三、环境搭建和注意事项

环境搭建

  1. 硬件环境:

    • STM32开发板(如STM32F103RCT6)

    • RS485转USB模块

    • 各类传感器(如DHT11、MQ系列气体传感器等)

  2. 软件环境:

    • 安装STM32CubeIDE或Keil进行固件开发。

    • 安装Qt Creator,配置Qt环境以进行上位机软件开发。

注意事项

  • 电源管理: 确保电源电压稳定,避免对微控制器和传感器造成损害。

  • RS485通信: 在RS485通信中,确保信号的正确连接和终端电阻的匹配,以防止信号反射和干扰。

  • 数据传输稳定性: 在长距离通信时,注意数据线的屏蔽和布线,以提高抗干扰能力。

四、代码实现过程

为了实现基于STM32的传感器数据采集系统,我们需要按照系统架构设计逐步实现各个功能模块。以下将详细介绍数据采集模块和上位机模块的代码实现过程,包括系统初始化、数据采集、数据传输、界面设计等方面。

4.1 数据采集模块实现

4.1.1 系统初始化

在STM32F103RCT6微控制器中,首先需要进行系统的初始化,包括时钟配置、GPIO初始化和UART配置。以下是系统初始化的代码示例:

#include "stm32f10x.h"void SystemClock_Config(void);
void GPIO_Config(void);
void UART_Config(void);int main(void) {HAL_Init();                // 初始化HAL库SystemClock_Config();      // 配置系统时钟GPIO_Config();             // 初始化GPIOUART_Config();             // 配置UARTwhile (1) {CollectSensorData();    // 采集传感器数据HAL_Delay(1000);        // 每秒采集一次}
}

4.1.2 GPIO配置

在数据采集模块中,GPIO配置用于控制RS485的发送和接收模式。以下是GPIO配置的代码示例:

void GPIO_Config(void) {__HAL_RCC_GPIOA_CLK_ENABLE();  // 使能GPIOA时钟GPIO_InitTypeDef GPIO_InitStruct = {0};// 配置RS485 DE引脚为输出GPIO_InitStruct.Pin = GPIO_PIN_1; // 假设DE连接在PA1GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

4.1.3 UART配置

UART配置用于RS485通信,设置波特率和数据格式。以下是UART配置的代码示例:

void UART_Config(void) {__HAL_RCC_USART1_CLK_ENABLE();  // 使能USART1时钟UART_HandleTypeDef huart1;huart1.Instance = USART1;huart1.Init.BaudRate = 9600;huart1.Init.WordLength = UART_WORDLENGTH_8B;huart1.Init.StopBits = UART_STOPBITS_1;huart1.Init.Parity = UART_PARITY_NONE;huart1.Init.Mode = UART_MODE_TX_RX;huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart1.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart1) != HAL_OK) {// 初始化失败,处理错误Error_Handler();}
}

4.1.4 传感器数据采集

在数据采集模块中,我们需要实现从传感器读取数据的功能。以下是读取温度和湿度传感器数据的示例代码:

void ReadTemperature(uint8_t *data) {// 假设使用某种传感器读取温度// 这里应实现具体的传感器读取逻辑data[0] = 25; // 示例:读取到的温度值
}void ReadHumidity(uint8_t *data) {// 假设使用某种传感器读取湿度// 这里应实现具体的传感器读取逻辑data[1] = 60; // 示例:读取到的湿度值
}void CollectSensorData() {uint8_t sensorData[10];ReadTemperature(sensorData);ReadHumidity(sensorData + 1);// 发送数据到上位机RS485_SendData(sensorData, sizeof(sensorData));
}

4.1.5 RS485数据发送

RS485通信需要在发送数据前控制DE引脚的状态。以下是数据发送的代码示例:

void RS485_SendData(uint8_t *data, uint16_t length) {// 控制DE引脚为高电平,设置为发送模式HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);// 发送数据到上位机HAL_UART_Transmit(&huart1, data, length, HAL_MAX_DELAY);// 控制DE引脚为低电平,设置为接收模式HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
}

4.2 上位机模块实现

上位机模块负责接收来自数据采集模块的数据,并在用户界面上实时显示这些数据。以下将详细介绍上位机模块的关键实现步骤,包括Qt界面的设计、数据接收与解析、数据展示等。

4.2.1 Qt环境配置

首先,需要在计算机上安装Qt SDK,并创建一个新的Qt Widgets应用程序项目。确保在项目设置中选择适当的Qt版本,并配置好编译环境。

4.2.2 界面设计

在Qt Creator中,可以使用Qt Designer工具设计用户界面。以下是一个简单的界面设计步骤:

  1. 创建主窗口: 在Qt Designer中创建一个QMainWindow,命名为MainWindow

  2. 添加控件: 在主窗口中添加以下控件:

  • QLabel: 显示温度和湿度信息。

  • QPushButton: 用于开始和停止数据接收。

  • QTableWidget: 显示历史数据。

  • QTextEdit: 用于显示日志信息。

设计完成后,将界面保存。

4.2.3 代码实现

MainWindow类中,编写数据接收和显示的逻辑。以下是关键代码部分的实现:

#include <QMainWindow>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QTimer>class MainWindow : public QMainWindow {Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void readSerialData(); // 读取串口数据void startReceiving();  // 开始接收数据void stopReceiving();   // 停止接收数据private:QSerialPort *serial;    // 串口对象QLabel *temperatureLabel; // 温度标签QLabel *humidityLabel;    // 湿度标签QTableWidget *dataTable;  // 数据表格
};MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), serial(new QSerialPort(this)) {// 界面初始化setupUi(this);// 配置串口serial->setPortName("COM3"); // 设置串口名称serial->setBaudRate(QSerialPort::Baud9600);// 连接信号和槽connect(serial, &QSerialPort::readyRead, this, &MainWindow::readSerialData);
}MainWindow::~MainWindow() {if (serial->isOpen()) {serial->close();}
}void MainWindow::startReceiving() {if (serial->open(QIODevice::ReadOnly)) {// 启动接收数据qDebug() << "串口已打开";} else {qDebug() << "无法打开串口";}
}void MainWindow::stopReceiving() {if (serial->isOpen()) {serial->close();qDebug() << "串口已关闭";}
}void MainWindow::readSerialData() {while (serial->canReadLine()) {QString line = serial->readLine();QStringList sensorData = line.split(',');if (sensorData.size() >= 2) {// 更新温度和湿度标签temperatureLabel->setText("温度: " + sensorData[0] + " °C");humidityLabel->setText("湿度: " + sensorData[1] + " %");// 在数据表格中记录历史数据int rowCount = dataTable->rowCount();dataTable->insertRow(rowCount);dataTable->setItem(rowCount, 0, new QTableWidgetItem(sensorData[0]));dataTable->setItem(rowCount, 1, new QTableWidgetItem(sensorData[1]));}}
}

4.2.5 故障监测与报警功能

在上位机中,我们可以实现一个简单的故障监测机制,以便在传感器数据超过设定阈值时发出警报。以下是监测函数的完整实现代码。

void MainWindow::checkForAlerts(double temperature, double humidity) {QString alertMessage;// 检查温度是否超过警戒线if (temperature > 30.0) {alertMessage += "警报:温度超过30°C!\n";}// 检查湿度是否超过警戒线if (humidity > 80.0) {alertMessage += "警报:湿度超过80%!\n";}// 如果有警报信息,显示在文本框中if (!alertMessage.isEmpty()) {QTextEdit *logTextEdit = findChild<QTextEdit *>("logTextEdit");if (logTextEdit) {logTextEdit->append(alertMessage);}}
}

readSerialData函数中调用checkForAlerts,以便在接收到数据后立即检查是否存在报警情况:

void MainWindow::readSerialData() {while (serial->canReadLine()) {QString line = serial->readLine();QStringList sensorData = line.split(',');if (sensorData.size() >= 2) {// 更新温度和湿度标签double temperature = sensorData[0].toDouble();double humidity = sensorData[1].toDouble();temperatureLabel->setText("温度: " + QString::number(temperature, 'f', 2) + " °C");humidityLabel->setText("湿度: " + QString::number(humidity, 'f', 2) + " %");// 调用报警检查函数checkForAlerts(temperature, humidity);// 在数据表格中记录历史数据int rowCount = dataTable->rowCount();dataTable->insertRow(rowCount);dataTable->setItem(rowCount, 0, new QTableWidgetItem(QString::number(temperature)));dataTable->setItem(rowCount, 1, new QTableWidgetItem(QString::number(humidity)));}}
}

在适当的时机(例如在关闭程序时)调用saveDataToFile函数,以确保数据被保存。

4.2.7 主函数

最后,确保在主函数中创建并显示主窗口,同时设置接收数据的启动和停止事件。

int main(int argc, char *argv[]) {QApplication app(argc, argv);MainWindow window;// 开始接收数据window.startReceiving();window.show();return app.exec();
}

4.3 整体系统流程

4.3.1 数据采集流程

  1. 系统启动: STM32微控制器初始化,配置时钟、GPIO和UART。

  2. 传感器数据采集: 定时采集传感器数据,读取温度和湿度信息。

  3. 数据传输: 通过RS485接口将采集到的数据发送给上位机,采用Modbus RTU协议格式化数据。

  4. 数据发送: 控制RS485的发送和接收模式,确保数据的完整性。

4.3.2 上位机数据处理流程

  1. 串口配置: 打开指定的串口,设置波特率和数据格式。

  2. 数据接收: 接收来自STM32的数据并解析。

  3. 数据展示: 实时更新界面上的数据标签,显示温度和湿度值。同时,将历史数据保存到数据表格中,以供后续查询与分析。

  4. 故障监测与报警: 在每次接收数据时,调用监测函数检查温度和湿度是否超出设定阈值。如果超出,则在日志框中打印警报信息,提示用户注意。

  5. 数据持久化: 在适当的时机(例如用户点击“保存”按钮或关闭软件时),将历史数据写入CSV文件,便于后续查看和分析。

4.3.3 整体系统工作流程图

用户 上位机 STM32微控制器 传感器 启动上位机软件 打开串口 确认串口打开 采集传感器数据 返回温度、湿度数据 发送数据(温度, 湿度) loop [数据采集与发送] 解析数据 更新界面显示 检查限位 触发报警 显示警报信息 记录正常数据 alt [超出限位] [正常状态] 保存数据 将数据写入文件 关闭串口 用户 上位机 STM32微控制器 传感器

五、项目总结

5.1 项目主要功能

本项目实现了一个基于STM32F103RCT6微控制器的传感器数据采集系统,主要功能包括:

  1. 传感器数据采集: 通过多个传感器(如温度、湿度传感器)实时采集环境数据。

  2. 数据传输: 采用RS485接口与Modbus RTU协议,将采集到的数据实时传送至上位机。

  3. 上位机数据处理: 使用Qt开发环境实现用户界面,实时显示温度、湿度数据,并支持历史数据记录和展示。

  4. 故障监测与报警: 实现对传感器数据的阈值监测,超出设定范围时发出警报,并在界面中记录相关信息。

  5. 数据持久化: 支持将历史数据保存为CSV文件,便于后续分析与查看。

5.2 实现过程总结

该系统的实现过程经历了以下几个阶段:

  • 需求分析与设计: 针对项目需求,设计了系统架构和数据流,并选择了合适的硬件组件和通信协议。

  • 硬件开发: 在STM32开发板上实现了数据采集模块,配置了GPIO、UART和RS485接口,编写了数据采集和发送的代码。

  • 上位机开发: 使用Qt进行上位机软件的开发,设计了用户界面,编写了数据接收、解析及显示的逻辑代码。

  • 系统集成与测试: 将硬件和上位机软件进行集成,进行了系统测试,确保数据的准确性和系统的稳定性。

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

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

相关文章

搭建AD域服务器

搭建AD域服务器 使用深信服HCI搭建AD域服务器 1、新建虚拟机 2、填写参数 3、省略安装过程 4、进入服务器管理器 5、 6、 7、 8、 9、 10、 11、 12、 13、 14、 15、 16、 17、 18、 19、 20、 21、 22、 23、

MOH: MULTI-HEAD ATTENTION AS MIXTURE-OFHEAD ATTENTION

当前的问题 多头注意力使用多个头部可以提高模型的精度。然而&#xff0c;并不是所有的注意力头都具有同样的重要性。一些研究表明&#xff0c;许多注意力头可以被修剪而不影响准确性。 此外&#xff0c;在多头注意中&#xff0c;每个注意头并行操作&#xff0c;最终输出是所…

Spring boot之BeanDefinition介绍

在spring框架中IOC容器进行bean的创建和管理。Bean的创建是一个比较复杂的过程&#xff0c;它并不像我们创建对象一样只是直接new一下就行&#xff0c;虽然有些bean确实就是New一下。但在Spring中可以通过一些途径对bean进行增强扩展。在这个过程中&#xff0c;BeanDefinition作…

Ubuntu 服务器部署 Tomcat 并配置 SSL/TLS 证书

本文目录 准备登陆云服务器安装 Java下载 tomcat 包配置防火墙浏览器访问 Tomcat 默认页面以服务的形式运行 Tomcat创建 Tomcat 用户和组创建 systemd 服务文件启动 tomcat 服务 Tomcat webapps 文件目录部署一个静态网站tomcat 的配置文件 将域名解析到服务器Tomcat 配置 SSL/…

C++小问题

怎么分辨const修饰的是谁 是限定谁不能被改变的&#xff1f; 在C中&#xff0c;const关键字的用途和位置非常关键&#xff0c;它决定了谁不能被修改。const可以修饰变量、指针、引用等不同的对象&#xff0c;并且具体的作用取决于const的修饰位置。理解const的规则能够帮助我们…

PPT不能编辑,按钮都是灰色,怎么办?

PPT文件打开之后&#xff0c;发现无法编辑&#xff0c;再仔细查看发现工具栏中的功能按钮都是灰色的&#xff0c;无法使用&#xff0c;这是什么原因&#xff1f;该如何解决&#xff1f; 原因&#xff1a;无法编辑PPT文件&#xff0c;并且功能按钮都是灰色&#xff0c;这是因为…

相交链表和环形链表

&#xff08;一&#xff09;相交链表 相交链表 思路&#xff1a;先分别计算出A列表和B列表的长度&#xff0c;判断它们的尾节点是否相等&#xff0c;如果不相等就不相交&#xff0c;直接返回空。然后让两个列表中的长的列表先走它们的差距步&#xff0c;然后再一起走&#xff…

ARM架构下安装新版docker及docker-compose

一、常见CPU 架构&#xff1a; 二、环境信息 CPU架构操作系统配置HUAWEI Kunpeng 920 5220 aarch64openEuler 22.03 (LTS-SP3)64C128g15T 三、安装docker 3.1 二进制包下载 docker-ce 社区下载地址&#xff1a; wget https://mirrors.nju.edu.cn/docker-ce/linux/static/s…

LeetCode-315. Count of Smaller Numbers After Self

目录 题目描述 解题思路 【C】 【Java】 复杂度分析 LeetCode-315. Count of Smaller Numbers After Selfhttps://leetcode.com/problems/count-of-smaller-numbers-after-self/description/ 题目描述 Given an integer array nums, return an integer array counts whe…

【NLP 4、数学基础】

此去经年&#xff0c;应是良辰美景虚设 —— 24.11.28 一、线性代数 1.标量和向量 ① 标量 Scalar 一个标量就是一个单独的数 ② 向量 Vector 一个向量是一列数 可以把向量看作空间中的点&#xff0c;每个元素是不同坐标轴上的坐标 向量中有几个数&#xff0c;就叫作几维…

VideoBooth: Diffusion-based Video Generation with Image Prompts

VideoBooth: Diffusion-based Video Generation with Image Prompts 概括 文章提出了一个视频生成模型VideoBooth&#xff0c;输入一张图片和一个文本提示词&#xff0c;即可输出保持图片中物体且符合文本提示词要求的视频。 方法 粗-细两阶段设计&#xff1a;1&#xff09;…

Graphy 是一款终极、易于使用、功能齐全的 FPS 计数器、统计监视器和调试器,适用于您的 Unity 项目。

主要特点&#xff1a; Graph & Text: 图文&#xff1a; FPSMemory 记忆Audio 声音的Advanced device information 高级设备信息Debugging tools 调试工具 GitHub - Tayx94/graphy:Graphy 是适用于 Unity 项目的终极、易于使用、功能丰富的 FPS 计数器、统计监视器和调试…

ASP.NET Core 负载/压力测试

文章目录 一、第三方工具二、使用发布版本进行负载测试和压力测试 负载测试和压力测试对于确保 web 应用的性能和可缩放性非常重要。 尽管负载测试和压力测试的某些测试相似&#xff0c;但它们的目标不同。 负载测试&#xff1a;测试应用是否可以在特定情况下处理指定的用户负…

008静态路由-特定主机路由

按照如上配置&#xff0c;用192.168.0.1 电脑ping 192.168.1.1 发现能够ping通 用192.168.0.1 电脑ping 192.168.2.1 发现不能ping通 这是因为192.168.0.1 和 192.168.1.1 使用的是同一个路由器R1。 192.168.0.1 和 192.168.2.1 通信需要先经过R1&#xff0c;再经过R2 &#xf…

基于yolov4深度学习网络的排队人数统计系统matlab仿真,带GUI界面

目录 1.算法仿真效果 2.算法涉及理论知识概要 3.MATLAB核心程序 4.完整算法代码文件获得 1.算法仿真效果 matlab2022a仿真结果如下&#xff08;完整代码运行后无水印&#xff09;&#xff1a; 仿真操作步骤可参考程序配套的操作视频。 2.算法涉及理论知识概要 在现代社会…

周鸿祎再次“创业”,盯上百度

周鸿祎特地拍了部短剧来推广的新产品&#xff0c;终于上线了。 11月27日晚间&#xff0c;360正式发布多模态内容创作引擎“纳米搜索”。 作为当前AI应用最红的赛道之一&#xff0c;AI搜索已经有腾讯、秘塔、商汤、抖音等公司入局。传统搜索老大百度也在发力。竞争不妨碍有搜索…

pytorch中一个tensor经过多次softmax会有什么变化?

在 PyTorch 中&#xff0c;一个 Tensor 经过多次 softmax 操作时&#xff0c;其值会逐渐趋向于某种分布&#xff0c;但并不会无限变化。以下是具体的行为与原因分析&#xff1a; 1. Softmax 的作用&#xff1a; Softmax 将输入张量的值转换为一个概率分布&#xff0c;满足以下…

汽车轮毂结构分析有哪些?国产3D仿真分析实现静力学+模态分析

本文为CAD芯智库原创&#xff0c;未经允许请勿复制、转载&#xff01; 之前分享了如何通过国产三维CAD软件如何实现「汽车/汽配行业产品设计」&#xff0c;兼容NX&#xff08;UG&#xff09;、Creo&#xff08;Proe&#xff09;&#xff0c;轻松降低企业上下游图纸交互成本等。…

深度学习中的生成对抗网络(GAN)原理与应用

引言 生成对抗网络&#xff08;Generative Adversarial Network&#xff0c;简称GAN&#xff09;是由Ian Goodfellow等人在2014年提出的一种深度学习模型&#xff0c;它通过对抗训练的方式生成与真实数据分布相似的假数据。GAN的出现极大地推动了深度学习和生成模型的研究&…

前端学习笔记之FileReader

概念 FileReader接口允许网页应用程序异步读取用户计算机上存储的文件&#xff08;或原始数据缓冲区&#xff09;的内容&#xff0c;使用File或Blob对象来制定要读取的文件或数据。 File对象可以通过用户使用<input>元素选择文件后返回的FileList对象获得&#xff0c;或…