当前位置:   article > 正文

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

stm32f4与openmv串口通信

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

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

一:颜色阈值

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

二:openmv代码

  1. import sensor, image, time #引入三个库
  2. from pyb import UART
  3. red = (21, 61, 9, 127, -2, 127) ###
  4. green = (9, 87, -67, -11, -18, 66) ## 定义三个颜色的lab值范围格式为(Lmax,Lmin,Amax,Amin,Bmax,Bmin)
  5. blue = (25, 85, 101, -104, -14, -41) # 以及一个颜色组colour
  6. colour = [red,green,blue] ### 对应颜色的lab阈值信息,可以通过IDE中的工具→机器视觉→阈值编辑器自行调整和获取
  7. red_blob = None ## 定义三个空的变量,用来盛放下面寻找到的色块的信息
  8. green_blob = None ## 定义三个空的变量,用来盛放下面寻找到的色块的信息
  9. blue_blob = None # 以及定义一个色块组blobs_group
  10. blobs_group = [red_blob,green_blob,blue_blob] ###
  11. sensor.reset() #初始化相机传感器
  12. sensor.set_pixformat(sensor.RGB565) #设置相机模块的像素模式,16 bits/像素
  13. sensor.set_framesize(sensor.QVGA) #设置相机模块的帧大小 320x240
  14. sensor.skip_frames(time = 2000) #
  15. sensor.set_auto_gain(False) #打开(True)或关闭(False)自动增益
  16. sensor.set_auto_whitebal(False) #打开(True)或关闭(False)自动白平衡,追踪颜色,则需关闭白平衡
  17. clock = time.clock() ###
  18. uart = UART(3,9600) #定义串口3变量
  19. uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters
  20. def sending_data(cx,cy,cw,ch): #定义发送数据的串口函数
  21. global uart;
  22. #frame=[0x2C,18,cx%0xff,int(cx/0xff),cy%0xff,int(cy/0xff),0x5B];
  23. #data = bytearray(frame)
  24. data = ustruct.pack("<bbhhhhb", #格式为俩个字符俩个短整型(2字节)
  25. 0x2C, #帧头1
  26. 0x12, #帧头2
  27. int(cx), # up sample by 4 #数据1
  28. int(cy), # up sample by 4 #数据2
  29. int(cw), # up sample by 4 #数据1
  30. int(ch), # up sample by 4 #数据2
  31. 0x5B)
  32. uart.write(data); #必须要传入一个字节数组
  33. def Find_group(): ###定义寻找色块的函数
  34. t = 0 ## 这里是重点,定义一个发现色块组的函数
  35. while t < 3: # find_blobs函数会寻找对应阈值内颜色的色块,例如t=0时寻找的是红色,并将
  36. blobs_group[t] = img.find_blobs([colour[t]]) # 它找的信息赋值给blobs_group中的red_blobl
  37. if len(blobs_group[t]) > 0: # 判断是否找到色块,找到色块会对色块进行一系列操作
  38. for b in blobs_group[t]: # 先判断色块的b[4],即像素数,对应的b几代表什么可以在星瞳科技的'10分钟快速上手'里找到
  39. if 12000 > b[4] > 3000: # 利用画图函数,根据寻找到的色块的信息,分别画出外边框,中心十字,在左上角写对应色块的名称
  40. img.draw_rectangle(b[0:4]) # 然后将b[5]追加到tool中储存起来。最后会让t+1,就会对绿色的色块进行这一系列操作
  41. img.draw_cross(b[5], b[6]) # 这个函数的目的就是依次寻找红绿蓝色块
  42. #img.draw_string(b[0], b[1])
  43. print(colour[t]) #找到之后打印出来色块的阈值
  44. print(t+1) #打印出色块的数字
  45. #串口的程序
  46. Num = t + 1
  47. FH = bytearray([0x2C,0x12,Num,0, 0, 0,0x5B])
  48. uart.write(FH)
  49. t+=1
  50. while (True): ###
  51. clock.tick() ## 这是一个大的循环,可以说前面的都是准备工作,主要是为这个循环
  52. img = sensor.snapshot() # 逻辑是,抓取画面,然后用前面定义的好的Find_group函数抓取出画面中的色块
  53. Find_group() #调用寻找色块的函数
  54. #blob.x() 返回色块的外框的x坐标(int),也可以通过blob[0]来获取。
  55. #blob.y() 返回色块的外框的y坐标(int),也可以通过blob[1]来获取。
  56. #blob.w() 返回色块的外框的宽度w(int),也可以通过blob[2]来获取。
  57. #blob.h() 返回色块的外框的高度h(int),也可以通过blob[3]来获取。
  58. #blob.pixels() 返回色块的像素数量(int),也可以通过blob[4]来获取。
  59. #blob.cx() 返回色块的外框的中心x坐标(int),也可以通过blob[5]来获取。
  60. #blob.cy() 返回色块的外框的中心y坐标(int),也可以通过blob[6]来获取。

三:stm32代码

1.设置CubeMx

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

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

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

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

  1. #include "openmv.h"
  2. #include "usart.h"
  3. #include "gpio.h"
  4. #include "stm32f1xx.h"
  5. int GetOpenmvDataCount = 0;
  6. uint8_t uart3_rxbuff;
  7. uint8_t Num=0, LoR =0, Finded_flag = 0, FindTask = 0; //()
  8. void Openmv_Receive_Data(uint8_t com_data)
  9. {
  10. uint8_t i;
  11. static uint8_t RxCounter1=0;//计数
  12. static uint16_t RxBuffer1[10]={0};
  13. static uint8_t RxState = 0;
  14. static uint8_t RxFlag1 ;
  15. if(RxState==0&&com_data==0x2C) //0x2c帧头
  16. {
  17. RxState=1;
  18. RxBuffer1[RxCounter1++]=com_data;
  19. }
  20. else if(RxState==1&&com_data==0x12) //0x12帧头
  21. {
  22. RxState=2;
  23. RxBuffer1[RxCounter1++]=com_data;
  24. }
  25. else if(RxState==2)
  26. {
  27. RxBuffer1[RxCounter1++]=com_data;
  28. if(RxCounter1>=10||com_data == 0x5B) //RxBuffer1接受满了,接收数据结束
  29. {
  30. RxState=3;
  31. RxFlag1=1;
  32. //正常情况下,运行到这RxCounter1 == 7? 7-5 = 2 openmv发送过来的一个数据包有8个
  33. Num = RxBuffer1[RxCounter1-5]; //2
  34. LoR = RxBuffer1[RxCounter1-4]; //3 //-1是左, 1是右,0表示还没有识别到任何数字
  35. Finded_flag = RxBuffer1[RxCounter1-3]; //4
  36. FindTask = RxBuffer1[RxCounter1-2];//5
  37. //RxCounter1-1是帧尾
  38. //greenLED_Toggle; //用来看是否接收数据的,电平翻转一次则成功接收一个数据,跟下面的一个意思
  39. GetOpenmvDataCount++;
  40. //用来看1秒内成功解码多少个数据包的 需要在1s钟的延时中清除,帧率越高越准确,个位数的话偏差就大了
  41. //不如改一下解码代码,将openmv那里的帧率直接传过来
  42. }
  43. }
  44. else if(RxState==3) //检测是否接受到结束标志
  45. {
  46. if(RxBuffer1[RxCounter1-1] == 0x5B)
  47. {
  48. RxFlag1 = 0;
  49. RxCounter1 = 0;
  50. RxState = 0;
  51. }
  52. else //接收错误
  53. {
  54. RxState = 0;
  55. RxCounter1=0;
  56. for(i=0;i<10;i++)
  57. {
  58. RxBuffer1[i]=0x00; //将存放数据数组清零
  59. }
  60. }
  61. }
  62. else //接收异常
  63. {
  64. RxState = 0;
  65. RxCounter1=0;
  66. for(i=0;i<10;i++)
  67. {
  68. RxBuffer1[i]=0x00; //将存放数据数组清零
  69. }
  70. }
  71. }
  72. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  73. {
  74. uint8_t tem;// 这里的是无符号的
  75. //RedSignal_Toggle; //用来看是否接收数据的, 这里要随时都没效果的话就代表连串口3的中断都没进来
  76. if(huart->Instance== USART3) //这里只能这样大写USART3
  77. {
  78. //RedSignal_Toggle; //用来看是否接收数据的, 这里要随时都没效果的话就代表连串口3的中断都没进来
  79. tem=uart3_rxbuff;
  80. Openmv_Receive_Data(tem);
  81. }
  82. HAL_UART_Receive_IT(&huart3,&uart3_rxbuff,1);
  83. }

四:成果展示

stm32部分用oled显示数字

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

谢谢大家!!!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/474132?site
推荐阅读
相关标签
  

闽ICP备14008679号