stm32与openmv通讯实现识别颜色并读取座标值[hal库]

由于之前接触openmv的时候是用库函数写的代码,在网上发现用hal库写接收代码的例子并不多,于是就想重新用cubemx写一次openmv与stm32通讯的代码,把之前写好的颜色识别返回座标的Python代码运用一次。

openmv

所需要的元器件

  • stm32单片机
  • usb-ttl模块
  • stlink
  • openmv
  • 导线若干

整体思路

  1. 先编写openmv的代码,实现特定颜色识别,并把座标值通过串口发送出去;
  2. 之后在cube上配置相关stm32的初始化设置,并生成代码;
  3. 在keil里编写串口中断接收函数,将串口1用于接收openmv发送来的数据,并通过串口2将接收到的数据通过串口发送给电脑;
  4. 烧录程序实现效果,并改进出现的问题。

接线方式

  • stm32通过uart1与openmv连接
  • stm32通过sw与stlink连接
  • stm32通过uart2与usb-ttl连接

完成效果

openmv识别特定颜色的物体,并把其座标发送给stm32,单片机读取后通过ttl在pc上显示。

在这里插入图片描述

Cube配置

cube配置

代码解析

  • openmv颜色识别及座标发送

import sensor, image, time
from pyb import UART
import json

threshold = [(6, 16, 19, 63, 4, 25)]

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000 )
sensor.set_auto_whitebal(False)

clock = time.clock()

uart = UART(3, 115200)

uart.init(115200, bits=8, parity=None, stop=1)  #8位数据位,无校验位,1位停止位、

while(True):
    clock.tick()
    img = sensor.snapshot()
    blob = img.find_blobs(threshold, area_threshold=300)
    if blob: #如果找到了目标颜色
        FH = bytearray([0xb3,0xb4])
        uart.write(FH)
        for b in blob:
        #迭代找到的目标颜色区域
            img.draw_cross(b[5], b[6]) # cx, cy
            img.draw_edges(b.min_corners(), color=(0,255,0))
            x = b.cx()
            y = b.cy()

            data = bytearray([x,y])
            uart.write(data)

            end = bytearray([0x01,0x01,0xb5,0xb6])
            uart.write(end)



  • stm32串口中断接收

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)     //opmv-receive
{
	if(huart==&huart1)
	{	
		HAL_UART_Receive_IT(&huart1,&my_re_buf1[++pt_w1],1);  		
		trans(my_re_buf1[pt_w1]);		
	}
}

  • stm32接收数据处理
	while(pt_r1<pt_w1 )
	{
		while(pt_r1<pt_w1)
		{				
				pt_r1++;		
		}				
	}
		
		if(pt_r1>=pt_w1)
		{
			pt_w1=pt_r1=0;
		HAL_UART_AbortReceive_IT(&huart1);
	  	HAL_UART_Receive_IT(&huart1,my_re_buf1,1);
			
		}


  • 发送数据函数

void measure(void)
{
	  int x,y;
	
	  x=opmvdata[2];
	  y=opmvdata[3];
	  
	printf("x:  %d \r ,",x);
	printf("y:  %d \r\n",y);
	
}


  • 数据判断部分

static int state = 0;
	
	if(state==0&&data==0xb3)
	{
		state=1;
		opmvdata[0]=data;

	}
	else if(state==1&&data==0xb4)
	{
		state=2;
		opmvdata[1]=data;
	}

  • 数据不符清除部分


        else if(data != 0xb6)
        {
            state = 0;
            for(i=0;i<8;i++)
            {
                opmvdata[i]=0x00;
            }           
        }

遇到的问题

刚开始的时候openmv的发送数据总是会在stm32上漏掉一些,或者多出来一些,后来发现数据不能发送\r\n这样的数据,会打乱数据的结构。并且发送的时候一定要开启16进制显示,这样调试的时候才能看到数据是否满足需求。
其次,stm32的接收函数一定要判断发送的数据串的帧头是否为openmv上设置的预设值,满足后方可把数据存入数组。
在数据处理中,记得把16进制的数据转化为10进制,否则数据格式会不容易读懂。

总结

写代码是个有趣的过程,遇到问题多在csdn上找答案。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章