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

作者:南笺天月

物联沃分享整理
物联沃-IOTWORD物联网 » stm32通过串口通信将数据保存到PC

发表回复