stm32通过串口通信将数据保存到PC
stm32f103c8t6通过串口通信将数据保存到本地电脑中。
(最下文有相应的代码)
串口通信格式
stm32f103c8t6可以将数据通过串口发送,利用串口收发多个数据,参考串口收发数据包的方法:“包头+数据(+分隔符+数据)+包尾”的格式。
字符串开始符-包头为“\r\n$”、分隔符为“,”、结束符-包尾为“#”是规定好的串口数据格式
stm32核心代码如下:
串口1循环发送如同 “\r\n$22.5,72.6#”(\r\n$温度,湿度#)的字符串
if( DHT11_Read_TempAndHumidity ( & DHT11_Data ) == SUCCESS)
{
printf("\r\n$%d,%d,%d,%d.%d,%d.%d#",DHT11_Data.temp_int,DHT11_Data.temp_deci,DHT11_Data.humi_int,DHT11_Data.humi_deci);
}
PYTHON获取串口字符串
使用python读取串口数据,将数据保存到csv文件中,有利于后面转换成“txt”\“mat”等格式的数据集。
from multiprocessing import Process, Queue
import keyboard, csv, serial, os
import numpy as np
def get_numbers_from_serial(target_com, begin='\r\n', end='$', cut=','):
'''
从串口获得float类型数据列表
如果两个分隔符cut相邻或分隔符中间为无效字符串(无法转换为float的字符串),在中间位置补-32768
若起始符begin不符则返回空列表
'''
data = target_com.read_until(bytes(end, encoding='utf-8')) # 一直读取直到遇到截止符end
data = data.decode('utf-8', 'ignore')
# print('gotten:', data)
begin_len = len(begin)
if (data[0:begin_len] != begin): # 检测begin是否与字符串开头相符
return []
cut_len = len(cut)
pos = begin_len
num_list = []
label = True
while (data[pos:] != end):
num_str = ''
# 确认目标位及其后方不为cut和end
while (data[pos:] != end and data[pos:pos + cut_len] != cut):
label = True # 至少采集到了一个有效字符
num_str = num_str + data[pos]
pos = pos + 1
# 根据label和num_str向num_list中赋值
if label:
try:
num_list.append(float(num_str))
except Exception:
num_list.append(-32768) # num_str为无效字符串
else:
num_list.append(-32768) # label为负,两个cut相邻
if data[pos:] != end:
pos = pos + cut_len
label = False
return num_list
def deal_with_csv_file(file_path='save_csv.csv', csv_head=[], mode='new'):
'''
csv文件预处理
file_path:文件保存的路径
mode两种模式:
'new'删除原同名文件(如果有)并新建文件
'add'在原文件后续写
csv_head是以列表形式给出的csv文件每列标题,只有在'new'模式才有用
'''
def create_csv(csv_head=[], path='save_csv.csv'):
'''
新建csv文件
'''
with open(path, 'w', newline='') as f:
csv_write = csv.writer(f)
if csv_head != []:
csv_write.writerow(csv_head)
if mode == 'new': # 新建模式
if os.path.isfile(file_path):
os.remove(file_path)
create_csv(csv_head, file_path)
elif mode == 'add': # 续写模式
if os.path.isfile(file_path) == False:
print('源文件缺失,自动新建')
create_csv(csv_head, file_path)
def serial_to_csv(q):
'''
第一进程,从串口保存数据到csv文件
'''
# 初始设置
file_path = 'tmp_hum_day_new.csv' # 保存文件名称
csv_head = ['Temp℃', 'Hum%RH'] # 数据含义
mode = 'new' # 新建文件还是在原有文件上续写
ser = serial.Serial('COM8', baudrate=115200) # 串口信息(名称,波特率)
ser_msg = ['\r\n$', '#', ','] # 串口符号规定,若有换行则需在原有开始符前加\r\n
show = True # 是否实时展示数据
# csv文件预处理
deal_with_csv_file(file_path, csv_head, mode)
# 开始读数并保存
with open(file_path, 'a+', newline='') as f:
csv_write = csv.writer(f)
n = 0
while q.empty():
num_list = get_numbers_from_serial(ser, begin=ser_msg[0], end=ser_msg[1], cut=ser_msg[2])
csv_write.writerow(num_list)
n = n + 1
if show:
print('\r', num_list, end='')
if n > 14400:
print('\n总共保存了', n, '个数据')
break
def key_board_listen(q):
'''
第二进程,键盘监听充当中断函数
'''
keyboard.wait('esc')
q.put(1)
if __name__ == "__main__":
'''
从串口保存数据到csv文件,具体参数设置在serial_to_csv中。
按下esc停止保存,程序退出
'''
q = Queue()
p1 = Process(target=serial_to_csv, args=(q,))
p2 = Process(target=key_board_listen, args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
注:stm32f103与温湿度dht11、串口通信代码,python代码如下:
链接:https://pan.baidu.com/s/1Nm-grGLlAbz7eXJ5fTT94Q
提取码:4456
作者:南笺天月