python——适用于基于python或Micropython开发的上下位机间通信的协议

因为博主最喜欢使用的单片机是基于micropython开发的,均使用python编程,可以兼容python间的数据格式。同时,在已经实现了PYB和树莓派进行串口通信的基础上,我们需要对通信数据的格式加以规范化。而元组作为python中内存占用最小的多数据存储格式,可以说是比列表、字典等更好的选择,所以本篇博客基于元组作为通信的主要数据格式进行讲解。

本地转换格式模拟通信过程

在这里我们需要将PYB中的数据打包成元组,再转换为加了换行符的字符串格式,再进行编码转换,通过UART串口通信,将其发送至上位机接收端。
在上位机中,首先需要将接收到的整行数据进行解码操作,再将

# 源数据
tp = (1, (2,3), 5)
# 测试eval()函数,python内置的eval函数可以将列表、元组格式的字符串转换回原格式。
n = eval(str(tp))
print(n, type(n))
# 编码
n1 = str(n) +"/n"
a = n1.encode("utf-8")

# 上位机端接收到编码后的数据,进行解码操作
a.decode("utf-8")
print(a, type(a))
# 转换回元组格式
a = str(a)[2:-3]
print(a, type(a))
b = eval(a)
print(b, type(b))

# 判断最终的格式是否为元组,且和原来相同
if type(b) == tuple:
    print("is tuple")

运行结果展示

在这里插入图片描述

说明我们的代码操作是没有问题的,好,接下来进行实机通信过程。

PYB和树莓派通信实现元组数据互传

如果还没有实现PYB和树莓派通信的小伙伴先看博客:Micropython——基于树莓派的GPIO实现UART串口通信,跑通这个demo后,接下来我们进入元组数据的互传步骤。

直接上代码,大家看最后的效果图即可,直接copy代码即可运行。

上位机端(树莓派)

# -*- coding:utf-8 -*-
import serial
import time
ser = serial.Serial("/dev/ttyAMA0", 115200)
ser.flushInput()  
ser.write("begin".encode("utf-8")) 

tp = (12,34, (56,78), 910)

def main():
    while True:
        count = ser.inWaiting() 
        if count != 0:
            recv = ser.read(count) 
            #ser.write("I'm raspberry pi!".encode("utf-8")) 
            ser.write(str(tp).encode("utf-8"))   
            ser.write("\n".encode("utf-8"))  
            try:
                print(ser.readline())
            except:
                pass
            ser.flushInput()

 
if __name__ == '__main__':
    main()

下位机端(这里使用的是PYB)

import utime
import serial
from pyb import UART


class Serial:
    def __init__(self, uart):
        self.uart = uart

    def data_check(self):
        '''
        函数功能:返回串口接收状态
        '''
        return self.rev_data()

    def send_data(self, data="hi i'm pyboard!\n"):
        '''
        函数功能:串口发送数据
        入口参数:需要发送的打包好的数据(字符串格式)
        '''
        if type(data) != str:
            data = str(data)
        data.encode("utf-8")
        self.uart.write(data)

    def rev_data(self):
        '''
        函数功能:读取上位机发送的运动控制指令
        入口参数:
        返回值  :接收到的数据
        '''
        start = utime.ticks_ms()
        data = self.uart.readline()
        if data != None:
            # print("get data!!!!!")
            try:
                data = self.analysis_data(data)
            except:
                pass
            end = utime.ticks_ms()
            print("running time:", end - start)
            print(data)    
            return True
        else:
            return False
    
    def format_data(self, motion=0, angle=0, encoders=(0,0), imu=(0,0,0)):
        '''
        函数功能:将需要发送的所有数据封装起来
        入口参数:
        返回值  :封装后的数据元组
        '''
        data = (motion, angle, encoders, imu)
        return str(data + "\n")
    
    def analysis_data(self, data):
        data.decode("utf-8")
        data = str(data)[2:-3] # 将 “\n” 和 b'' 去除
        data = eval(data) # 转化回元组形式
        print(type(data))
        return data
        
uart = UART(2, 115200)
ser = serial.Serial(uart)
while True:
	ser.rev_data()

PYB端接收

在这里插入图片描述

参考文章:

猜你喜欢

转载自blog.csdn.net/qq_45779334/article/details/112797226