前言
由于项目中设备使用气体对容器进行充气。需要测试充气稳定性和一些管道堵塞等情况下防护措施。开发本套自动化测试方案。
一、试验器件
1、Arduino mega2560单片机 * 1
2、电磁阀 * 3
3、气体压力传感器 * 1
4、待测设备
二、试验方法
1、单片机写入程序,电脑USB串口对单片机发送串口指令分别执行电磁阀闭合以及压力传感器设备数据读取
2、对不同管路进行关闭
3、通过脚本实现每隔0.5秒读取一次压力传感器设备数值,然后记录在一个Excel列表中
4、通过程序对Excel列表中的数据进行折线图显示,分析充气稳定性
三、试验
1、搭建测试环境

四、控制和实现代码
import time
import serial
import openpyxl
from openpyxl import Workbook
import os
"""
以下是3个电磁阀控制代码
"""
"""
串口参数设置
"""
PORT = 'COM17' # 根据实际情况修改端口号
BAUDRATE = 9600 # 波特率
BYTESIZE = 8 # 数据位
PARITY = 'N' # 奇偶校验
STOPBITS = 1 # 停止位
TIMEOUT = 2 #
"""
指令参数设置
"""
END_MARKER = b"\xEF\xEF" # 结束标记
"""
压力采集控制
"""
command_barometric_pressure_sensor = b"\xFE\xFE\x02\x02\x04\xEF\xEF"
expected_barometric_pressure_sensor_response = b"\xFE\xFE\x04\x82"
LOOP_TIME = 30 # 实验持续时间(秒)
SAMPLE_INTERVAL = 0.5 # 传感器采样间隔(秒)
"""
文件参数设置
"""
EXCEL_FILENAME = "test_bunper_123_new20241016.xlsx"
# todo 电磁阀控制变量
# =============================打 开 电 磁 阀======================================
"""
电磁阀控制打开-----1号电磁阀
"""
command_open_magnetic_valve1 = b"\xFE\xFE\x04\x01\x01\x01\x07\xEF\xEF"
expected_open_magnetic_valve1_response = b"\xFE\xFE\x04\x81\x01\x01\x00"
"""
电磁阀控制打开-----2号电磁阀
"""
command_open_magnetic_valve2 = b"\xFE\xFE\x04\x01\x02\x01\x07\xEF\xEF"
expected_open_magnetic_valve2_response = b"\xFE\xFE\x04\x81\x02\x01\x00"
"""
电磁阀控制打开-----3号电磁阀
"""
command_open_magnetic_valve3 = b"\xFE\xFE\x04\x01\x03\x01\x07\xEF\xEF"
expected_open_magnetic_valve3_response = b"\xFE\xFE\x04\x81\x03\x01\x00"
"""
电磁阀控制打开-----4号电磁阀
"""
command_open_magnetic_valve4 = b"\xFE\xFE\x04\x01\x04\x01\x07\xEF\xEF"
expected_open_magnetic_valve4_response = b"\xFE\xFE\x04\x81\x04\x01\x00"
# =============================关 闭 电 磁 阀======================================
"""
电磁阀控制关闭-----1号电磁阀
"""
command_close_magnetic_valve1 = b"\xFE\xFE\x04\x01\x01\x00\x07\xEF\xEF"
expected_close_magnetic_valve1_response = b"\xFE\xFE\x04\x81\x01\x00\x00"
"""
电磁阀控制关闭-----2号电磁阀
"""
command_close_magnetic_valve2 = b"\xFE\xFE\x04\x01\x02\x00\x07\xEF\xEF"
expected_close_magnetic_valve2_response = b"\xFE\xFE\x04\x81\x02\x00\x00"
"""
电磁阀控制关闭-----3号电磁阀
"""
command_close_magnetic_valve3 = b"\xFE\xFE\x04\x01\x03\x00\x07\xEF\xEF"
expected_close_magnetic_valve3_response = b"\xFE\xFE\x04\x81\x03\x00\x00"
"""
电磁阀控制关闭-----4号电磁阀
"""
command_close_magnetic_valve4 = b"\xFE\xFE\x04\x01\x04\x00\x07\xEF\xEF"
expected_close_magnetic_valve4_response = b"\xFE\xFE\x04\x81\x04\x00\x00"
# 定义串口通信类
class SerialCommunicator:
def __init__(self, port):
"""
初始化串口设置
"""
self.ser = serial.Serial(
port=port, # 串口名称
baudrate=BAUDRATE, # 波特率
bytesize=BYTESIZE, # 数据位
parity=PARITY, # 校验位
stopbits=STOPBITS, # 停止位
timeout=TIMEOUT # 超时设置
)
self.ser.flushInput() # 清空输入缓冲区
self.ser.flushOutput() # 清空输出缓冲区
def send_data(self, data):
"""发送数据到串口"""
self.ser.write(data)
def receive_data(self):
"""从串口接收数据"""
buffer = bytearray()
start_time = time.time()
timeout = 1 # 设置超时时间
while time.time() - start_time < timeout:
count = self.ser.in_waiting
if count != 0:
recv = self.ser.read(count)
buffer.extend(recv) # 将新接收到的数据追加到缓冲区
# 检查是否包含预期的结束标记
if END_MARKER in buffer:
message, buffer = buffer.split(END_MARKER, 1)
return message
time.sleep(0.01) # 防止 CPU 占用过高
print("接收超时")
return None
# todo 电磁阀控制函数
def control_switch(self, command, expected_response):
"""
电磁阀控制
发送特定的十六进制指令,并在没有收到预期响应时重新发送指令
"""
# command_magnetic_valve = b"\xFE\xFE\x04\x01\x01\x01\x07\xEF\xEF"
# expected_magnetic_valve_response = b"\xFE\xFE\x04\x81\x01\x01\x07"
# 发送指令
self.send_data(command)
# 等待响应
start_time = time.time()
while time.time() - start_time < 1.1:
received_message = self.receive_data()
if received_message and expected_response in received_message:
print("控制成功")
return True
# 如果未收到预期响应,则重新发送指令
print("未收到预期响应,重新发送指令")
self.send_data(command)
start_time = time.time()
while time.time() - start_time < 1.1:
received_message = self.receive_data()
if received_message and expected_response in received_message:
print("控制成功")
return True
print("两次尝试均未收到预期响应")
return False
# todo 压力采集函数
def read_pressure(self):
"""发送读取压力值指令,并接收压力值数据"""
# command_barometric_pressure_sensor = b"\xFE\xFE\x02\x02\x04\xEF\xEF"
# expected_barometric_pressure_sensor_response = b"\xFE\xFE\x04\x82"
# 发送指令
self.send_data(command_barometric_pressure_sensor)
# 等待响应
start_time = time.time()
while time.time() - start_time < 1.1:
received_message = self.receive_data()
if received_message:
received_message_hex = received_message.hex()
# 检查是否包含预期的响应
if expected_barometric_pressure_sensor_response in received_message and len(received_message_hex) == 18:
# 提取整数部分和小数部分
integer_part = int.from_bytes(received_message[4:6], byteorder='big')
decimal_part = int.from_bytes(received_message[6:8], byteorder='big') / 1000.0
pressure_value = integer_part + decimal_part
print(f"压力值: {pressure_value}")
return pressure_value
print("未收到预期的压力值响应")
return None
# todo excel数据函数
def write_to_excel(self, filename, current_time, pressure_values, max_value, experiment_count):
"""将当前时间、压力值列表和最大值写入 Excel 文件"""
workbook = Workbook() if not os.path.exists(filename) else openpyxl.load_workbook(filename)
sheet = workbook.active
if sheet.title != "Pressure Data":
sheet.title = "Pressure Data"
sheet.append(["次数", "生成时间", "完整数据", "最大值"])
# 写入数据
sheet.append([experiment_count, current_time, pressure_values, max_value])
# 保存文件
workbook.save(filename)
print(f"数据已保存到 {filename}")
def open_port(self):
"""打开串口"""
if not self.ser.is_open:
self.ser.open()
def close_port(self):
"""关闭串口"""
if self.ser.is_open:
self.ser.close()
# todo 实验函数
def run_experiment(self):
"""
执行实验流程
"""
# 创建串口通信对象
self.open_port()
# 初始化压力值列表
pressure_values = []
"""
"""
# 控制 电磁阀1 关闭 ----------------------------------------------------------------------------
if not self.control_switch(command_close_magnetic_valve1, expected_close_magnetic_valve1_response):
print("电磁阀打开失败")
return
time.sleep(0.1)
if not self.control_switch(command_open_magnetic_valve2, expected_open_magnetic_valve2_response):
print("电磁阀打开失败")
return
time.sleep(0.1)
if not self.control_switch(command_open_magnetic_valve3, expected_open_magnetic_valve3_response):
print("电磁阀打开失败")
return
# 开始计时
start_time = time.time()
# 每隔 SAMPLE_INTERVAL 秒发送读取压力值指令
while time.time() - start_time < LOOP_TIME:
pressure_value = self.read_pressure()
if pressure_value is not None:
pressure_values.append(pressure_value)
print(f"添加压力值: {pressure_value}")
time.sleep(SAMPLE_INTERVAL)
pressure_values.append(-9.000000001)
# 控制 电磁阀2 关闭 ---------------------------------------------------------
if not self.control_switch(command_close_magnetic_valve2, expected_close_magnetic_valve2_response):
print("电磁阀打开失败")
return
time.sleep(0.1)
if not self.control_switch(command_open_magnetic_valve1, expected_open_magnetic_valve1_response):
print("电磁阀打开失败")
return
time.sleep(0.1)
if not self.control_switch(command_open_magnetic_valve3, expected_open_magnetic_valve3_response):
print("电磁阀打开失败")
return
# 开始计时
start_time = time.time()
# 每隔 SAMPLE_INTERVAL 秒发送读取压力值指令
while time.time() - start_time < LOOP_TIME:
pressure_value = self.read_pressure()
if pressure_value is not None:
pressure_values.append(pressure_value)
print(f"添加压力值: {pressure_value}")
time.sleep(SAMPLE_INTERVAL)
pressure_values.append(-9.000000002)
# 控制 电磁阀3 关闭 ---------------------------------------------------------
if not self.control_switch(command_close_magnetic_valve3, expected_close_magnetic_valve3_response):
print("电磁阀打开失败")
return
time.sleep(0.1)
if not self.control_switch(command_open_magnetic_valve1, expected_open_magnetic_valve1_response):
print("电磁阀打开失败")
return
time.sleep(0.1)
if not self.control_switch(command_open_magnetic_valve2, expected_open_magnetic_valve2_response):
print("电磁阀打开失败")
return
# 开始计时
start_time = time.time()
# 每隔 SAMPLE_INTERVAL 秒发送读取压力值指令
while time.time() - start_time < LOOP_TIME:
pressure_value = self.read_pressure()
if pressure_value is not None:
pressure_values.append(pressure_value)
print(f"添加压力值: {pressure_value}")
time.sleep(SAMPLE_INTERVAL)
pressure_values.append(-9.00000003)
# 控制 电磁阀123 全打开 ----------------------------------------------------------------------------
if not self.control_switch(command_open_magnetic_valve3, expected_open_magnetic_valve3_response):
print("电磁阀打开失败")
return
time.sleep(0.1)
if not self.control_switch(command_open_magnetic_valve2, expected_open_magnetic_valve2_response):
print("电磁阀打开失败")
return
time.sleep(0.1)
if not self.control_switch(command_open_magnetic_valve1, expected_open_magnetic_valve1_response):
print("电磁阀打开失败")
return
# 开始计时
start_time = time.time()
# 每隔 SAMPLE_INTERVAL 秒发送读取压力值指令
while time.time() - start_time < LOOP_TIME:
pressure_value = self.read_pressure()
if pressure_value is not None:
pressure_values.append(pressure_value)
print(f"添加压力值: {pressure_value}")
time.sleep(SAMPLE_INTERVAL)
pressure_values.append(-9.00000004)
# 控制 电磁阀 12关闭 3打开 ---------------------------------------------------------
if not self.control_switch(command_open_magnetic_valve3, expected_open_magnetic_valve3_response):
print("电磁阀打开失败")
return
time.sleep(0.1)
if not self.control_switch(command_close_magnetic_valve1, expected_close_magnetic_valve1_response):
print("电磁阀打开失败")
return
time.sleep(0.1)
if not self.control_switch(command_close_magnetic_valve2, expected_close_magnetic_valve2_response):
print("电磁阀打开失败")
return
# 开始计时
start_time = time.time()
# 每隔 SAMPLE_INTERVAL 秒发送读取压力值指令
while time.time() - start_time < LOOP_TIME:
pressure_value = self.read_pressure()
if pressure_value is not None:
pressure_values.append(pressure_value)
print(f"添加压力值: {pressure_value}")
time.sleep(SAMPLE_INTERVAL)
pressure_values.append(-9.00000005)
# 控制 电磁阀123 全打开 ----------------------------------------------------------------------------
if not self.control_switch(command_open_magnetic_valve3, expected_open_magnetic_valve3_response):
print("电磁阀打开失败")
return
time.sleep(0.1)
if not self.control_switch(command_open_magnetic_valve2, expected_open_magnetic_valve2_response):
print("电磁阀打开失败")
return
time.sleep(0.1)
if not self.control_switch(command_open_magnetic_valve1, expected_open_magnetic_valve1_response):
print("电磁阀打开失败")
return
# 开始计时
start_time = time.time()
# 每隔 SAMPLE_INTERVAL 秒发送读取压力值指令
while time.time() - start_time < LOOP_TIME:
pressure_value = self.read_pressure()
if pressure_value is not None:
pressure_values.append(pressure_value)
print(f"添加压力值: {pressure_value}")
time.sleep(SAMPLE_INTERVAL)
pressure_values.append(-9.00000006)
# 获取当前时间
current_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
# 检查压力值列表是否为空
if not pressure_values:
print("没有接收到有效的压力值数据")
return
# 计算最大值
max_value = max(pressure_values)
print(f"最大压力值: {max_value}")
# 将数据写入 Excel 文件
pressure_values_str = str(pressure_values)
# 追加写入数据
try:
workbook = openpyxl.load_workbook(EXCEL_FILENAME)
sheet = workbook["Pressure Data"]
experiment_count = len(list(sheet.rows))
except FileNotFoundError:
workbook = Workbook()
sheet = workbook.active
sheet.title = "Pressure Data"
sheet.append(["次数", "生成时间", "完整数据", "最大值"])
experiment_count = 1
self.write_to_excel(EXCEL_FILENAME, current_time, pressure_values_str, max_value, experiment_count)
print(f"当前执行次数: {experiment_count}")
print('------------------'+EXCEL_FILENAME+'------------------')
# 关闭串口
self.close_port()
# 程序主入口
if __name__ == '__main__':
communicator = SerialCommunicator(port=PORT)
while True:
communicator.run_experiment()
time.sleep(30) # 间隔 1 秒后重复执行
五、数据收集

六、数据分析
1、使用如下代码将第三列数据粘贴到运行程序中,即可
import matplotlib.pyplot as plt
import ast # 用于安全地解析字符串
while True:
# 输入数据
data_input = input("请输入数据:")
# 使用 ast.literal_eval 来解析输入的字符串
data = ast.literal_eval(data_input)
# 检查数据是否为列表
if not isinstance(data, list):
raise ValueError("输入的数据必须是一个列表格式!")
# 绘制折线图
plt.plot(data, marker='o') # 使用 'o' 标记每个数据点
plt.title('Line Plot of Data')
plt.xlabel('Index')
plt.ylabel('Value')
plt.grid() # 添加网格
plt.xticks(range(len(data))) # 设置 x 轴刻度
plt.show() # 显示图形

622

被折叠的 条评论
为什么被折叠?



