OpenMV数据打包发送以及STM32对数据的解析(串口方式)

    今天尝试了使用Openmv用串口发送数据,32接收,遇到了一些坑,但是最后还是实现了,难住我的地方并不是关于传输的代码,而是那个板子串口3不知道因为什么原因接收到的数据是错误的,这个原因正在寻找,找到了再记录。

    Python提供了便捷的将数据打包的方法。我使用的方法就是将数据以二进制的方式打包然后通过串口逐字节发送。

    struct模块的pack(fmt, v1, v2, ...)  函数提供了按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流)的功能,关与格式,有一个表定义了所有支持的字符及数据格式,如下:

Format

C Type

Python

字节数

x

pad byte

no value

1

c

char

string of length 1

1

b

signed char

integer

1

B

unsigned char

integer

1

?

_Bool

bool

1

h

short

integer

2

H

unsigned short

integer

2

i

int

integer

4

I

unsigned int

integer or long

4

l

long

integer

4

L

unsigned long

long

4

q

long long

long

8

Q

unsigned long long

long

8

f

float

float

4

d

double

float

8

s

char[]

string

1

p

char[]

string

1

P

void *

long

    microPython的串口使用方法也是很简单的,代码如下

uart = pyb.UART(3, 115200)  #串口3,波特率115200
uart.init(115200, bits=8, parity=None, stop=1)  #8位数据位,无校验位,1位停止位

    所以我在openmv的代码中定义了一个函数,来将传入的俩个参数打包然后通过串口发送,代码如下

def send_data_packet(x, y):
    temp = struct.pack("<bbii",                #格式为俩个字符俩个整型
                   0xAA,                       #帧头1
                   0xAE,                       #帧头2
                   int(x), # up sample by 4    #数据1
                   int(y)) # up sample by 4    #数据2
    uart.write(temp)                           #串口发送

    为什么不直接通过串口发送字符串然后使用sscanf来解析呢:串口发送字符串(ASCAII编码)的方式比较简单, 用C语言的sscanf()语句解析从语法上是完全可以的, 但是在实际工程上测试,解析不是很稳定,易丢数据。 ASCAII编码易出错,缺乏纠错功能。所以我采用二进制传输的,整数直接发送,浮点数放大去除小数位,然后以C语言的int,short,char的拆分逐8位形式逐位发送。 接收以后先计算校验累加,再重组。这种方式长期使用稳定可靠。

    这样发出来的数据(int,short型)都是低位的字节在前,比如发送整型数9,得到的数据为(0x09 0x00 0x00 0x00)

    所以32端的解析函数为

void Optical_Flow_Receive_Prepare(u8 data)
{
    /* 局部静态变量:接收缓存 */
    static u8 RxBuffer[10];
    /* 数据长度 *//* 数据数组下标 */
    static u8  _data_cnt = 0;
    /* 接收状态 */
    static u8 state = 0;

    /* 帧头1 */
    if(state==0&&data==TITLE1)
    {
        state=1;
    }
    /* 帧头2 */
    else if(state==1&&data==TITLE2)
    {
        state=2;
        _data_cnt = 0;
    }
    /* 接收数据租 */
    else if(state==2)
    {
        RxBuffer[++_data_cnt]=data;
        if(_data_cnt>=8)
        {
            state = 0;
            Data_Processing(RxBuffer,_data_cnt);
        }
    }
    /* 若有错误重新等待接收帧头 */
    else
        state = 0;
}


void Data_Processing(u8 *data_buf,u8 num)
{
	int theta_org,rho_org;
    /* 读取偏移角度原始数据  */
    theta_org = (int)(*(data_buf+1)<<0) | (int)(*(data_buf+2)<<8) | (int)(*(data_buf+3)<<16) | (int)(*(data_buf+4)<<24) ;
    theta_err = theta_org;

    /* 读取偏移尺寸原始数据 */
    rho_org = (int)(*(data_buf+5)<<0) | (int)(*(data_buf+6)<<8) | (int)(*(data_buf+7)<<16) | (int)(*(data_buf+8)<<24) ;
    rho_err = rho_org;
}

    通过这样的方式就能将Openmv计算的数据通过串口发送给32,过段时间我会做一个基于openmv+32的寻线小车,单双轨的寻线算法已经弄好了,做完以后我会发博客记录。

### 关于OpenMV通过串口发送数据 #### 初始化UART接口 为了使OpenMV能够通过串口发送数据,首先需要初始化UART接口。这可以通过Python脚本完成,指定使用的串口号和波特率: ```python from pyb import UART uart = UART(3, 115200) # 使用串口3,设置波特率为115200[^3] ``` 此代码片段创建了一个名为`uart`的对象来表示UART接口,并设置了相应的参数。 #### 发送简单字符串消息 一旦配置好UART之后,可以利用`.write()`方法向连接的设备发送简单的ASCII字符序列: ```python message = "Hello from OpenMV!\r\n" uart.write(message.encode()) # 将字符串编码为字节流并发送出去 ``` 这段程序会把定义好的问候语句转换成适合传输的形式并通过选定的串行端口发出。 #### 图像压缩后的二进制文件传输 对于更复杂的应用场景比如图像处理项目中,可能还需要考虑如何高效地传递大量信息如图片帧。此时可采用JPEG格式对捕获的画面进行高压缩比编码后再经由UART输出: ```python import sensor sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) while True: img = sensor.snapshot() # 获取当前摄像头视图的一张照片 compressed_img = img.compressed(quality=80)# 压缩图像至合理大小以便更快捷上传 uart.write(compressed_img) # 实际执行写入操作以启动物理层上的位移过程[^4] ``` 上述循环结构允许持续不断地获取最新拍摄所得影像资料经过适当优化后即时分享给其他硬件单元做进一步分析或显示用途。 #### 定义特定协议用于对象检测结果报告 当涉及到机器视觉任务时,通常会有专门设计的消息体用来描述识别出来的目标特征。下面给出了一种常见做法——将轮廓区域内的颜色标记点位置封装起来传送给外部控制器: ```python blobs = img.find_blobs([red_threshold], pixels_threshold=200, area_threshold=200) for b in blobs: data_packet = struct.pack("<hh", int(b.cx()), int(b.cy()))# 创建包含中心坐标的二进制包 uart.write(data_packet) # 向外设提交打包完毕的信息[^5] ``` 这里运用到了Python内置库中的`struct`模块帮助构建固定长度的数据报文;每次发现符合条件的颜色斑块都会触发一次坐标值更新动作直至遍历结束为止。
评论 58
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值