一、项目概述
1.1 项目目标与用途
在现代制造业中,电解加工机床因其高精度和高效率而广泛应用于复杂零件的加工。为了提高加工质量并降低故障率,实时监测加工过程中各项参数(如电流、电压、温度等)变得尤为重要。本项目旨在研发一套基于STM32微控制器的数据采集系统,能够实时采集多种传感器的数据,并将数据传输至上位机进行可视化处理和分析。该系统的主要目标包括:
-
实时监控:实现对加工过程中的关键参数的实时监控,提高生产效率。
-
数据分析:为后续的数据分析和加工优化提供基础数据支持。
-
报警功能:当监测到的参数超过设定的阈值时,及时发出报警通知操作人员,以减少设备损坏和生产事故的发生。
1.2 技术栈关键词
-
硬件:STM32F103RCT6微控制器、各类电流传感器、电压传感器、温度传感器、RS485通信模块、RS232通信模块。
-
软件:Qt、Modbus RTU协议、STM32 HAL库、数据可视化工具。
二、系统架构
2.1 系统架构设计
本数据采集系统主要由三个核心部分组成:传感器模块、数据采集模块和上位机。系统架构设计旨在确保数据采集的实时性、准确性和可靠性。
-
传感器模块:用于采集电解加工过程中所需的各种参数,具体包括电流、电压和温度等传感器。传感器通过RS485接口连接至数据采集模块,确保数据传输的稳定性和抗干扰能力。
-
数据采集模块:以STM32F103RCT6为核心,负责接收传感器数据、进行数据处理和通过RS232接口将数据传输至上位机。数据采集模块通过Modbus RTU协议与上位机进行通信,确保数据格式的标准化和可解析性。
-
上位机:使用Qt开发的可视化界面,实时显示传感器数据,支持数据的保存和分析,并具备报警功能,用于在传感器数据超过设定阈值时及时通知操作人员。
2.2 系统架构图
RS485 RS232 Modbus RTU 数据可视化 限位报警 传感器模块 数据采集模块 上位机 用户界面
三、环境搭建与注意事项
3.1 环境搭建
3.1.1 硬件连接
-
STM32F103RCT6微控制器与各类传感器之间采用RS485总线连接,确保数据采集的稳定性和实时性。在总线末端添加适当的终端电阻,以减少信号反射。
-
RS232模块与上位机连接,确保数据的无误传输。
3.1.2 软件开发环境
-
开发工具:使用STM32CubeIDE或Keil进行STM32的固件开发,确保代码的高效性和可维护性。
-
上位机开发:使用Qt Creator进行上位机软件的开发,采用Qt Widgets进行用户界面设计。
-
Modbus RTU库:选择开源的Modbus RTU库(如libmodbus)以支持数据通信,确保协议的标准化和兼容性。
3.2 注意事项
-
电源管理:确保所有设备的电源及接地良好,避免因电源不稳定导致的设备误操作。
-
通信稳定性:在RS485和RS232通信时,需定期检查连接线和接口,保持良好的接触,以避免数据传输中断。
四、代码实现过程
在本项目中,系统功能模块主要分为以下几个部分:传感器数据采集模块、数据处理与传输模块以及上位机显示与报警模块。以下将详细介绍每个功能模块的实现过程、代码示例及其说明。
4.1 传感器数据采集模块
4.1.1 功能描述
传感器数据采集模块的主要功能是通过RS485接口从多个传感器中实时获取数据。该模块使用STM32F103RCT6微控制器进行控制,定期读取传感器数据并进行初步处理。
4.1.2 硬件连接
-
传感器通过RS485总线连接至STM32F103RCT6的UART接口。每个传感器都有唯一的地址,以便于区分和选择。
-
RS485收发器需要连接至STM32的GPIO引脚,以控制数据的发送和接收状态。
4.1.3 代码示例
以下是传感器数据采集模块的代码示例:
c
#include "stm32f1xx_hal.h"
// 定义传感器数据结构体
typedef struct {
uint16_t current; // 电流
uint16_t voltage; // 电压
float temperature; // 温度
} SensorData;
SensorData sensorData;
// UART句柄
extern UART_HandleTypeDef huart1;
// 定义传感器地址
#define SENSOR_ADDRESS 0x01
// 读取传感器数据
void readSensorData() {
uint8_t request[8];
uint8_t response[32];
// 构建Modbus RTU请求帧
request[0] = SENSOR_ADDRESS; // 从站地址
request[1] = 0x03; // 功能码:读寄存器
request[2] = 0x00; // 起始地址高字节
request[3] = 0x00; // 起始地址低字节
request[4] = 0x00; // 读寄存器数量高字节
request[5] = 0x03; // 读寄存器数量低字节
// 计算CRC
uint16_t crc = calculateCRC(request, 6);
request[6] = crc & 0xFF; // CRC低字节
request[7] = (crc >> 8) & 0xFF; // CRC高字节
// 发送请求
HAL_UART_Transmit(&huart1, request, sizeof(request), HAL_MAX_DELAY);
// 接收响应
HAL_UART_Receive(&huart1, response, sizeof(response), HAL_MAX_DELAY);
// 解析响应数据
sensorData.current = (response[3] << 8) | response[4];
sensorData.voltage = (response[5] << 8) | response[6];
sensorData.temperature = (float)((response[7] << 8) | response[8]) / 10.0; // 假设温度数据以0.1°C为单位
}
// CRC校验函数
uint16_t calculateCRC(uint8_t* data, uint8_t length) {
uint16_t crc = 0xFFFF;
for (uint8_t pos = 0; pos < length; pos++) {
crc ^= (uint16_t)data[pos]; // XOR byte into least sig. byte of crc
for (uint8_t i = 8; i != 0; i--) { // Loop over each bit
if ((crc & 0x0001) != 0) { // If the LSB is set
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
} else { // Else just shift right
crc >>= 1;
}
}
}
return crc;
}
4.1.4 代码说明
-
数据结构:定义了一个
SensorData
结构体,用于存储传感器采集的电流、电压和温度数据。 -
UART传输:使用UART接口发送Modbus RTU请求,读取传感器的数据。请求帧中包括从站地址、功能码、起始地址和读取数量,并通过
calculateCRC
函数计算CRC校验码以确保数据的完整性。 -
响应解析:接收到的响应帧解析后将数据存储到
SensorData
结构体中。
4.2 数据处理与传输模块
4.2.1 功能描述
数据处理与传输模块的主要功能是对采集到的传感器数据进行处理,并通过RS232接口将数据传送至上位机。该模块还负责实现报警功能,当某一传感器数据超过预设阈值时,系统将触发报警。
4.2.2 代码示例
以下是数据处理与传输模块的代码示例:
c
#include "stm32f1xx_hal.h"
// 定义报警阈值
#define CURRENT_THRESHOLD 500 // 500mA
#define VOLTAGE_THRESHOLD 2200 // 220V
extern UART_HandleTypeDef huart2;
// 发送数据到上位机
void sendDataToPC() {
uint8_t modbusFrame[8];
// 构建Modbus RTU数据发送帧
modbusFrame[0] = 0x01; // 从站地址
modbusFrame[1] = 0x03; // 功能码
modbusFrame[2] = sizeof(SensorData); // 数据长度
modbusFrame[3] = (sensorData.current >> 8) & 0xFF; // 电流高字节
modbusFrame[4] = sensorData.current & 0xFF; // 电流低字节
modbusFrame[5] = (sensorData.voltage >> 8) & 0xFF; // 电压高字节
modbusFrame[6] = sensorData.voltage & 0xFF; // 电压低字节
modbusFrame[7] = calculateCRC(modbusFrame, 7); // CRC校验
// 发送数据
HAL_UART_Transmit(&huart2, modbusFrame, sizeof(modbusFrame), HAL_MAX_DELAY);
}
// 检查传感器数据并触发报警
void checkAlarm() {
if (sensorData.current > CURRENT_THRESHOLD) {
// 触发电流报警
triggerAlarm("Current exceeds threshold!");
}
if (sensorData.voltage > VOLTAGE_THRESHOLD) {
// 触发电压报警
triggerAlarm("Voltage exceeds threshold!");
}
}
// 报警处理函数
void triggerAlarm(const char* message) {
// 通过蜂鸣器或LED灯等方式发出报警
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // 假设GPIO_PIN_0为报警输出
// 发送报警信息到上位机
HAL_UART_Transmit(&huart2, (uint8_t*)message, strlen(message), HAL_MAX_DELAY);
}
4.2.3 代码说明
-
报警阈值:定义了电流和电压的报警阈值,当传感器数据超过这些值时,将触发相应的报警。
-
数据发送:使用UART接口通过Modbus RTU协议将传感器数据发送到上位机。数据帧包括从站地址、功能码和数据长度,最后计算并附加CRC校验。
-
报警功能:在
checkAlarm
函数中判断电流和电压是否超过设定的阈值,并调用triggerAlarm
函数进行报警处理。报警可以通过GPIO引脚控制蜂鸣器或LED灯实现。
4.3 上位机显示与报警模块
4.3.1 功能描述
上位机模块的主要功能是通过Qt开发一个用户界面,实时显示传感器数据,并提供数据保存和报警信息显示的功能。用户可以通过界面设置报警阈值,并接收来自数据采集模块的实时数据和报警信息。
4.3.2 开发环境
-
Qt环境:确保安装Qt Creator和Qt SDK,配置好Qt Widgets模块。
-
Modbus RTU支持:使用libmodbus库或QtModbus库来实现Modbus RTU协议的支持。
4.3.3 代码示例
下面是上位机显示与报警模块的代码示例:
c
#include <QApplication>
#include <QMainWindow>
#include <QTimer>
#include <QLabel>
#include <QMessageBox>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void readSerialData();
void checkAlarmThreshold();
private:
QLabel *currentLabel;
QLabel *voltageLabel;
QLabel *temperatureLabel;
QSerialPort *serialPort;
QTimer *timer;
const int currentThreshold = 500; // 电流阈值
const int voltageThreshold = 2200; // 电压阈值
};
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
currentLabel = new QLabel(this);
voltageLabel = new QLabel(this);
temperatureLabel = new QLabel(this);
// 设置串口
serialPort = new QSerialPort(this);
serialPort->setPortName("COM3"); // 根据实际情况修改
serialPort->setBaudRate(QSerialPort::Baud9600);
serialPort->setDataBits(QSerialPort::Data8);
serialPort->setParity(QSerialPort::NoParity);
serialPort->setStopBits(QSerialPort::OneStop);
serialPort->open(QIODevice::ReadOnly);
// 设置定时器,每500毫秒读取一次数据
timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MainWindow::readSerialData);
timer->start(500);
}
MainWindow::~MainWindow() {
serialPort->close();
}
void MainWindow::readSerialData() {
QByteArray data = serialPort->readAll();
// 解析数据并更新UI
if (data.size() >= 6) { // 假设数据总是6个字节
int current = (data[3] << 8) | data[4];
int voltage = (data[5] << 8) | data[6];
// Update labels
currentLabel->setText("Current: " + QString::number(current) + " mA");
voltageLabel->setText("Voltage: " + QString::number(voltage) + " V");
// 检查报警阈值
if (current > currentThreshold) {
QMessageBox::warning(this, "报警", "电流超出阈值!");
}
if (voltage > voltageThreshold) {
QMessageBox::warning(this, "报警", "电压超出阈值!");
}
}
}
4.3.4 代码说明
-
串口配置:使用
QSerialPort
类设置与STM32微控制器的串口通信。根据实际情况配置串口号和波特率。 -
数据读取:通过定时器定期读取串口数据,并解析数据。假设数据格式为固定长度,解析数据后更新界面上显示的电流和电压。
-
报警功能:检查电流和电压是否超过设定的阈值,如果超过,则弹出报警框提示用户。
五、项目总结
本项目成功研发了一套基于STM32的电解加工机床数据采集系统,主要功能包括:
-
数据采集:系统能够通过RS485接口从多种传感器实时采集电流、电压和温度数据。
-
数据处理与传输:采集到的数据经过处理后,通过RS232接口以Modbus RTU协议传输至上位机。
-
数据可视化:上位机界面实时显示传感器数据,并能根据设定的阈值进行报警。
-
报警功能:在电流或电压超出设定范围时,系统能够及时发出报警信号,提示操作人员。