openmv與stm32通訊實現控制舵機跟隨顏色塊轉動[hal庫]

由於之前寫了一篇openmv與stm32串口通訊的博客,恰巧最近又突發奇想,想做一個用openmv視覺控制舵機轉動的程序,於是便花了一個下午寫成了這個代碼,嘗試用hal庫完成代碼的編寫

openmv

所需要的元器件

  • stm32單片機
  • stlink
  • openmv
  • 舵機
  • 導線若干
    在這裏插入圖片描述

整體思路

  1. 先編寫openmv的代碼,實現特定顏色識別,並把座標值通過串口發送出去;
  2. 之後在cube上配置相關stm32的初始化設置,並生成代碼;
  3. 在keil裏編寫串口中斷接收函數,將串口1用於接收openmv發送來的數據,並編寫舵機控制程序;
  4. 燒錄程序實現效果,並改進出現的問題。

接線方式

  • stm32通過uart1與openmv連接
  • stm32通過sw與stlink連接
  • stm32通過GND、VCC、PWM口連接舵機

完成效果

openmv識別特定顏色的物體,並把其座標發送給stm32,單片機讀取後控制舵機轉動,實現定向跟隨效果。

Cube配置

  1. 串口

串口
2. 定時器

定時器

代碼解析

  • 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]);		
	}
}

  • 舵機控制函數


void measure(void)
{
	
      if(m>6){
		
			  if(x<130&&x>10){
				
				if(servo_angle<90){
									
	     	servo_angle+=5;
	     	MG996R_Set_Angle(servo_angle); 	//SERVO
					
				}
		
      	}else if(x>170&&x<300){
					
					
					if(servo_angle>-90){
									
	     	servo_angle-=5;
	     	MG996R_Set_Angle(servo_angle); 	//SERVO
					
				}
		
	}
	m=0;
		
	}
	m++;
	

}



  • 數據幀頭判斷部分代碼

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代碼裏顏色識別容易對攝像頭內多對象進行顏色識別,傳回來的數據就會波動較大,因此改變了顏色識別的閾值,實現了較爲穩定的顏色識別舵機跟隨效果

總結

寫程序的時候要注意多方面的問題,不能僅僅考慮當下的問題,因此經驗總結很重要,不能忽視。

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