提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
一年前的这个时候,研0提前进组,作为一个本科机械的学生,老师给我的第一个任务:把一个带机械臂的小车动起来,没有电路板,只有机械部分。要自己做软硬件。OpenMV和stm32串口通讯是这个里面比较关键的一部分,在这里分享一下。

一、OpenMV和stm32信息
OpenMV STM32
定位 专用机器视觉模块 通用微控制器系列
核心功能 集成摄像头 + 视觉算法库 基础计算与外设控制
开发语言 Python(MicroPython) C/C++(支持 HAL 库)
处理能力 专注图像处理(H7 支持 400MHz) 全场景覆盖(M0 至 M7 多层级)
典型应用 人脸检测、二维码扫描、目标跟踪 电机控制、通信网关、传感器采集
二、串口通讯
1.原理
在这个项目里,OpenMV和stm32的通讯需求源于OpenMV要把检测到的物体的坐标发送给STM32,然后STM32驱动机械臂抓取。因为OpenMV本质上也是一个单片机,所以这里就是两块单片机之间的通讯,我使用的是串口通讯。
串口通讯(Serial Communication)是一种最基本、最古老但也极其重要和广泛使用的数据传输方式。其核心特点是:简单、低成本、点对点(通常用于两个设备之间的直接通讯)、异步通信(发送方和接收方没有共享的时钟信号来同步每一位的传输,通信双方必须事先约定好相同的通讯参数,如波特率、数据位、停止位等)、全双工(使用两根独立的线(TX 和 RX),允许数据同时双向传输)
2.代码
先是OpenMV发送代码,这里的功能是:在图像里找到最大的红色块,定位其中心坐标(x,y)。然后以数据包的形式通过串口发送出去。
import sensor, image, time,pyb
from pyb import UART,LED
import json
import ustruct
red_threshold_01 = (17, 57, 26, 73, 3, 63) #红色阈值
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # must be turned off for color tracking
sensor.set_auto_whitebal(False) # must be turned off for color tracking
clock = time.clock()
uart = UART(3,9600) #定义串口3变量
uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters
def find_max(blobs): #定义寻找色块面积最大的函数
max_size=0
for blob in blobs:
if blob.pixels() > max_size:
max_blob=blob
max_size = blob.pixels()
return max_blob
def send_data_packet(x,y):
temp = ustruct.pack("<bhhb", #格式为俩个字符俩个整型
0xFF, #帧头1
int(x), # up sample by 2 #数据1
int(y), # up sample by 2 #数据2
0xFE)
uart.write(temp); #串口发送
while(True):
img = sensor.snapshot()
blobs = img.find_blobs([red_threshold_01]);
cx=0;cy=0;
if blobs:
#如果找到了目标颜色
max_b = find_max(blobs);
# Draw a rect around the blob.
img.draw_rectangle(max_b[0:4]) # rect
#用矩形标记出目标颜色区域
img.draw_cross(max_b[5], max_b[6]) # cx, cy
#img.draw_cross(160, 120) # 在中心点画标记
#在目标颜色区域的中心画十字形标记
cx=max_b[5];
cy=max_b[6];
send_data_packet(cx,cy)
# print(cx,cy)
然后是STM32单片机的接收代码,这部分用的是STM32标准库。主要参考的B站江协科技的视频:https://www.bilibili.com/video/BV1th411z7sn?spm_id_from=333.788.videopod.episodes&p=25
这里代码只截取了主函数的一部分。
if (Serial_GetRxFlag() == 1) //如果接收到数据包
{
num_x = hextoDec(Serial_RxPacket[0])+Serial_RxPacket[1]*16*16; //将接收的十六进制数转换为十进制数
num_y = hextoDec(Serial_RxPacket[2])+Serial_RxPacket[3]*16*16;
OLED_ShowNum(1, 7, num_x, 3); //显示屏显示X坐标
OLED_ShowNum(2, 7, num_y, 3); //显示屏显示Y坐标
总结
主要分享了一个OpenMV和STM32串口通讯的实现方式。
2882

被折叠的 条评论
为什么被折叠?



