openmv与stm32串口通信——————不同颜色追踪

感谢@AD1617681854的博客代码及@海喂喂喂的帮助

参考代码(29条消息) 基于openmv的多色块识别并返回色块顺序_Ding_YF的博客-CSDN博客

一:颜色阈值

打开示例helloworld.py文件,运行openmv,在帧缓冲区放置需要颜色的物品,打开机器视觉,打开阈值编辑器,选择帧缓冲区,将目标颜色调白,其他调黑。复制LAB阈值

二:openmv代码

import sensor, image, time    #引入三个库
from pyb import UART

red = (21, 61, 9, 127, -2, 127)         ###
green = (9, 87, -67, -11, -18, 66)          ## 定义三个颜色的lab值范围格式为(Lmax,Lmin,Amax,Amin,Bmax,Bmin)
blue = (25, 85, 101, -104, -14, -41)       #  以及一个颜色组colour
colour = [red,green,blue]                 ###  对应颜色的lab阈值信息,可以通过IDE中的工具→机器视觉→阈值编辑器自行调整和获取

red_blob = None                                   ## 定义三个空的变量,用来盛放下面寻找到的色块的信息
green_blob = None                                 ## 定义三个空的变量,用来盛放下面寻找到的色块的信息
blue_blob = None                                  #  以及定义一个色块组blobs_group
blobs_group = [red_blob,green_blob,blue_blob]   ###


sensor.reset()                                #初始化相机传感器
sensor.set_pixformat(sensor.RGB565)           #设置相机模块的像素模式,16 bits/像素
sensor.set_framesize(sensor.QVGA)             #设置相机模块的帧大小 320x240
sensor.skip_frames(time = 2000)               #
sensor.set_auto_gain(False)                   #打开(True)或关闭(False)自动增益
sensor.set_auto_whitebal(False)               #打开(True)或关闭(False)自动白平衡,追踪颜色,则需关闭白平衡
clock = time.clock()                        ###

uart = UART(3,9600)   #定义串口3变量
uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters

def sending_data(cx,cy,cw,ch):                #定义发送数据的串口函数
    global uart;
    #frame=[0x2C,18,cx%0xff,int(cx/0xff),cy%0xff,int(cy/0xff),0x5B];
    #data = bytearray(frame)
    data = ustruct.pack("<bbhhhhb",      #格式为俩个字符俩个短整型(2字节)
                   0x2C,                      #帧头1
                   0x12,                      #帧头2
                   int(cx), # up sample by 4   #数据1
                   int(cy), # up sample by 4    #数据2
                   int(cw), # up sample by 4    #数据1
                   int(ch), # up sample by 4    #数据2
                   0x5B)
    uart.write(data);   #必须要传入一个字节数组

def Find_group():                                                       ###定义寻找色块的函数
    t = 0                                                                 ## 这里是重点,定义一个发现色块组的函数
    while t < 3:                                                          #  find_blobs函数会寻找对应阈值内颜色的色块,例如t=0时寻找的是红色,并将
        blobs_group[t] = img.find_blobs([colour[t]])                      #  它找的信息赋值给blobs_group中的red_blobl
        if len(blobs_group[t]) > 0:                                       #  判断是否找到色块,找到色块会对色块进行一系列操作
            for b in blobs_group[t]:                                      #  先判断色块的b[4],即像素数,对应的b几代表什么可以在星瞳科技的'10分钟快速上手'里找到
                if  12000 > b[4] > 3000:                                  #  利用画图函数,根据寻找到的色块的信息,分别画出外边框,中心十字,在左上角写对应色块的名称
                    img.draw_rectangle(b[0:4])                            #  然后将b[5]追加到tool中储存起来。最后会让t+1,就会对绿色的色块进行这一系列操作
                    img.draw_cross(b[5], b[6])                            #  这个函数的目的就是依次寻找红绿蓝色块
                    #img.draw_string(b[0], b[1])
                    print(colour[t]) #找到之后打印出来色块的阈值
                    print(t+1)    #打印出色块的数字
                    #串口的程序
                    Num = t + 1
                    FH = bytearray([0x2C,0x12,Num,0, 0, 0,0x5B])
                    uart.write(FH)

        t+=1

while (True):                                                                ###
    clock.tick()                                                               ## 这是一个大的循环,可以说前面的都是准备工作,主要是为这个循环
    img = sensor.snapshot()                                                    #  逻辑是,抓取画面,然后用前面定义的好的Find_group函数抓取出画面中的色块

    Find_group()   #调用寻找色块的函数


#blob.x() 返回色块的外框的x坐标(int),也可以通过blob[0]来获取。

#blob.y() 返回色块的外框的y坐标(int),也可以通过blob[1]来获取。

#blob.w() 返回色块的外框的宽度w(int),也可以通过blob[2]来获取。

#blob.h() 返回色块的外框的高度h(int),也可以通过blob[3]来获取。

#blob.pixels() 返回色块的像素数量(int),也可以通过blob[4]来获取。

#blob.cx() 返回色块的外框的中心x坐标(int),也可以通过blob[5]来获取。

#blob.cy() 返回色块的外框的中心y坐标(int),也可以通过blob[6]来获取。




三:stm32代码

1.设置CubeMx

我使用的是串口三,也可以设置其他的。

2.在main函数添加接收串口中断函数

 HAL_UART_Receive_IT(&huart3,&uart3_rxbuff,1);//openmv通信串口

3.openmv代码及接收中断回调函数

#include "openmv.h"
#include "usart.h"
#include "gpio.h"
#include "stm32f1xx.h"

int GetOpenmvDataCount  = 0;

uint8_t uart3_rxbuff;
uint8_t  Num=0, LoR =0, Finded_flag = 0, FindTask = 0;     //()


 
void Openmv_Receive_Data(uint8_t com_data)
{
		uint8_t i;
		static uint8_t RxCounter1=0;//计数
		static uint16_t RxBuffer1[10]={0};
		static uint8_t RxState = 0;	
    	static uint8_t RxFlag1 ;

		if(RxState==0&&com_data==0x2C)  //0x2c帧头
		{
			
			RxState=1;
			RxBuffer1[RxCounter1++]=com_data;  
		}

		else if(RxState==1&&com_data==0x12)  //0x12帧头
		{
			RxState=2;
			RxBuffer1[RxCounter1++]=com_data;
		}
		
		else if(RxState==2)
		{
			 
			RxBuffer1[RxCounter1++]=com_data;
			if(RxCounter1>=10||com_data == 0x5B)       //RxBuffer1接受满了,接收数据结束
			{
				RxState=3;
				RxFlag1=1;
				
				 //正常情况下,运行到这RxCounter1 == 7?  7-5 = 2    openmv发送过来的一个数据包有8个
				Num =          RxBuffer1[RxCounter1-5]; //2
				LoR =          RxBuffer1[RxCounter1-4]; //3    //-1是左, 1是右,0表示还没有识别到任何数字
				Finded_flag =  RxBuffer1[RxCounter1-3]; //4
				FindTask =      RxBuffer1[RxCounter1-2];//5
				
				//RxCounter1-1是帧尾
				
				//greenLED_Toggle;    //用来看是否接收数据的,电平翻转一次则成功接收一个数据,跟下面的一个意思
		  	GetOpenmvDataCount++;      
				//用来看1秒内成功解码多少个数据包的 需要在1s钟的延时中清除,帧率越高越准确,个位数的话偏差就大了
				//不如改一下解码代码,将openmv那里的帧率直接传过来
				
			}
		}

		else if(RxState==3)		//检测是否接受到结束标志
		{
				if(RxBuffer1[RxCounter1-1] == 0x5B)
				{
							
							RxFlag1 = 0;
							RxCounter1 = 0;
							RxState = 0;
						
				}
				else   //接收错误
				{
							RxState = 0;
							RxCounter1=0;
							for(i=0;i<10;i++)
							{
									RxBuffer1[i]=0x00;      //将存放数据数组清零
							}
				}
		} 

		else   //接收异常
		{
				RxState = 0;
				RxCounter1=0;
				for(i=0;i<10;i++)
				{
						RxBuffer1[i]=0x00;      //将存放数据数组清零
				}
		}
}


void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{


   uint8_t tem;// 这里的是无符号的
	
	//RedSignal_Toggle;   //用来看是否接收数据的, 这里要随时都没效果的话就代表连串口3的中断都没进来
  if(huart->Instance== USART3)     //这里只能这样大写USART3
  {
		   
		//RedSignal_Toggle;   //用来看是否接收数据的, 这里要随时都没效果的话就代表连串口3的中断都没进来
		
    tem=uart3_rxbuff;
    Openmv_Receive_Data(tem);
		
  }	
   HAL_UART_Receive_IT(&huart3,&uart3_rxbuff,1); 

}

四:成果展示

stm32部分用oled显示数字

 有什么错误的地方,望指正。

谢谢大家!!!!

  • 7
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值