python -- struct模块

struct模块中基本的pack和unpack函数:
pack(fmt,v1,v2…) 返回string 按照给定的格式(fmt),把数据转换成字符串(字节流),并将该字符串返回.

unpack(fmt,v1,v2…..) 返回tuple 按照给定的格式(fmt)解析字节流,并返回解析结果

格式化字符串:
当打包或者解包的时,需要按照特定的方式来打包或者解包.该方式就是格式化字符串,它指定了数据类型,除此之外,还有用于控制字节顺序、大小和对齐方式的特殊字符.

对齐方式:
为了同c中的结构体交换数据,还要考虑c或c++编译器使用了字节对齐,通常是以4个字节为单位的32位系统,故而struct根据本地机器字节顺序转换.可以用格式中的第一个字符来改变对齐方式.定义如下:
这里写图片描述

格式符:
这里写图片描述

最后在此呈上阿凯的二进制Binary_PC发送给ESP32接收的代码
【在此请尊重出品:1Z实验室 (1ZLAB: Make Things Easy) 1Z实验室 Make Things Easy . 致力于在机器人+计算机视觉+人工智能的重叠区域, 制作小白友好的教程.】
让大家再糊涂下思维(注意阿凯的是自定义二进制通信协议哦(坏笑,假装我看出来,你没看出来):

PC端 : binary_publisher_pc_pyserial.py

# -*- coding:utf-8 -*-
'''
## 功能描述
# 串口解析信息 二进制数据
## 接线:
# ESP32,TDX,D13 ->ESP32,RXD,D12
'''
from machine import UART,Pin
import struct
import utime
# 初始化串口 UART
# 波特率 115200
# rx -> Pin 13
# tx -> Pin 12

uart = UART(2, baudrate=115200, rx=13,tx=12,timeout=10)

def pack_bin_data(x,y,value):
    '''
    h: unsigned short bit=2
    b: unsigned char (byte): bit =1
    i: integer bit=4
    f: float bit=4

    b*2 + i*2 + f*1
    = 1*2 + 4*2 + 4*1 = 14byte

    '''
    bin_data = struct.pack(">BBiifB",
        0xAA,
        0xAE,
        int(x * 100), # x坐标,精确到小数点后两位
        int(y * 100 ), # y坐标,精确到小数点后两位
        float(value), # 传感器读入的值,float类型
        0x0A) # 结束符 \n = 0x0A
    print(bin_data)
    return bin_data

x = 100.123
y = -23.398
value = 1.2912312352

while True:
    print('Send Data')
    print(pack_bin_data(x, y, value))
    uart.write(pack_bin_data(x, y, value))
    utime.sleep_ms(1000)
    print("Recv Data")
    # byte_raw = uart.readline()
    byte_raw = uart.read()
    print(len(byte_raw))
    print(byte_raw)
    # 讲接收的字节流转换成容易读取的样式
    # byte_str = ':'.join(["{:02x}".format(char_byte) for char_byte in byte_raw])
    # print(byte_str)
    # print(byte_raw)
    utime.sleep_ms(1000)

顺带也把下位机ESP32要download进去的的代码:
ESP32端 :binary_listener_esp32_uart.py

# -*- coding:utf-8 -*-
'''
## 功能描述
# 串口解析信息 二进制数据
## 接线:
# ESP32,TDX,D12 -> RXD,CP2102 (USB转TTL)
# ESP32,RXD,D13 -> TXD,CP2102 (USB转TTL)

# TODO 数据解析
# 运行过程中遭遇跳过 ? ESP32的问题
'''
from machine import UART,Pin
import struct
import utime

uart = UART(2, baudrate=115200, rx=16,tx=17,timeout=10)


def depack_bin_data(byte_raw):
    '''
    将数据解包
        根据通信协议,解析数据, 并校验帧头
    '''
    FRAME_BYTE_LEN = 15

    if len(byte_raw) != FRAME_BYTE_LEN:
        # 检查数据帧长度是否满足条件
        raise ValueError("ERROR: 长度不满足条件")
    
    (verify_byte1, verify_byte2, x, y, value, _) = struct.unpack('>BBiifB', byte_raw)
    if verify_byte1 == 0xAA and verify_byte2 == 0xAE:
        x /= 100 # 恢复为实际数值范围
        y /= 100 # 恢复为实际数值范围
        return (x, y, value)
    else:
        raise ValueError("ERROR: 数据帧头校验失败")



while True:
    if uart.any():
        print("Recv Raw Data")
        byte_raw = uart.readline()
        print(byte_raw)
        print(len(byte_raw))
        # 讲接收的字节流转换成容易读取的样式
        # byte_str = ':'.join(['{:02x}'.format(char_byte) for char_byte in byte_raw])
        try:
            (x, y,value) = depack_bin_data(byte_raw)
            print("x= %.2f y=%.2f value=%f"%(x, y, value))
        except ValueError as e:
            print(e)
        # print(byte_raw)
    # print('.')
    utime.sleep_ms(1000)

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值