實驗?zāi)康?/font>:本實驗實現(xiàn)使用openMV檢測前方色塊,并傳回色塊的坐標位置給STM32,控制舵機轉(zhuǎn)動來跟蹤色塊。
openMV部分
- import sensor, image, time
- from pyb import UART
- import json
- red_threshold = (46, 80, 19, -5, 38, 103)
- sensor.reset() # Initialize the camera sensor.
- sensor.set_pixformat(sensor.RGB565) # use RGB565.
- sensor.set_framesize(sensor.QQVGA) # use QQVGA for speed.
- sensor.skip_frames(10) # Let new settings take affeOpenMV_Xct.
- sensor.set_auto_whitebal(False) # turn this off.
- clock = time.clock() # Tracks FPS.
- uart = UART(3, 115200)
- uart.init(115200, bits=8, parity=None, stop=1) #8位數(shù)據(jù)位,無校驗位,1位停止位
- def find_max(blobs):
- max_size=0
- for blob in blobs:
- if blob[2]*blob[3] > max_size:
- max_blob=blob
- max_size = blob[2]*blob[3]
- return max_blob
- def sending_data(cx_max,cy_max):
- global uart;
- data = ustruct.pack("<bbbb", #格式為倆個字符倆個短整型(2字節(jié))
- 0xff,
- 0xfe,
- int(cx_max),
- int(cy_max));
- #數(shù)據(jù)1
- # up sample by 4#數(shù)據(jù)2LCD_ShowStringLCD_ShowString
- uart.write(data); #必須要傳入一個字節(jié)數(shù)組
- while(True):
- clock.tick() # Track elapsed milliseconds between snapshots().
- img = sensor.snapshot() # Take a picture and return the image.
- blobs = img.find_blobs([red_threshold])
- if blobs:
- max_blob = find_max(blobs)
- img.draw_cross(max_blob.cx(),max_blob.cy())
- img.draw_circle(max_blob.cx(),max_blob.cy(),max_blob.cx()-max_blob.x(), color = (255, 255, 255))
- X =int(max_blob.cx()-img.width()/2)
- Y =int(max_blob.cy()-img.height()/2)
- # FH = bytearray([0xb3,0xb3])
- # uart.write(FH) #打印幀頭
- data = bytearray([0xb3,0xb3,X,Y,0x5b])
- uart.write(data) #打印XY軸的偏移坐標
- print("X軸偏移坐標 : ",X)
- print("Y軸偏移坐標 : ",Y)
- print("幀率 : ",clock.fps())
- sending_data(blob.X,blob.Y)
復(fù)制代碼
代碼介紹:此部分為openMV追蹤色塊(黃色)并且傳回色塊的橫坐標位置給STM32C8T6t,同時也可以用串口打印出來色塊距離中心坐標位置偏移值。
如圖所示
如果要利用串口顯示的話可以用一根杜杜邦線接openMV的P4和USB轉(zhuǎn)TTL的RXD接收端即可。
STM32部分
串口接收終端代碼
- void USART1_IRQHandler(void) //串口1中斷服務(wù)程序
- {
- u8 com_data;
- #if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS為真,則需要支持OS.
- OSIntEnter();
- #endif
- if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中斷(接收到的數(shù)據(jù)必須是0x0d 0x0a結(jié)尾)
- {
- USART_ClearFlag(USART1,USART_FLAG_RXNE);
- com_data = USART1->DR;
- Openmv_Receive_Data(com_data); //openmv數(shù)據(jù)處理函數(shù)
- Openmv_Data(); //openmv數(shù)據(jù)處理函數(shù)
- }
- #if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS為真,則需要支持OS.
- OSIntExit();
- #endif
- }
復(fù)制代碼
處理openMV數(shù)據(jù)代碼
- #include "openmv.h"
- int openmv[5];//stm32接收數(shù)據(jù)數(shù)組
- int8_t OpenMV_X; /*OPENMV X 軸反饋坐標*/
- int8_t OpenMV_Y; /*OPENMV X 軸反饋坐標*/
- int i=0;
- void Openmv_Receive_Data(int16_t data)//接收Openmv傳過來的數(shù)據(jù)
- {
- static u8 state = 0;
- if(state==0&&data==0xb3)
- {
- state=1;
- openmv[0]=data;
- }
- else if(state==1&&data==0xb3)
- {
- state=2;
- openmv[1]=data;
- }
- else if(state==2)
- {
- state=3;
- openmv[2]=data;
- }
- else if(state==3)
- {
- state = 4;
- openmv[3]=data;
- }
- else if(state==4) //檢測是否接受到結(jié)束標志
- {
- if(data == 0x5B)
- {
- state = 0;
- openmv[4]=data;
- Openmv_Data();
- }
- else if(data != 0x5B)
- {
- state = 0;
- for(i=0;i<5;i++)
- {
- openmv=0x00;
- }
- }
- }
- else
- {
- state = 0;
- for(i=0;i<5;i++)
- {
- openmv=0x00;
- }
- }
- }
- void Openmv_Data(void)
- {
- OpenMV_X=openmv[2];
- OpenMV_Y=openmv[3];
- }
復(fù)制代碼
其他部分的代碼就很簡單,在這里只列出關(guān)鍵部分代碼
下面就是關(guān)鍵的控制舵機轉(zhuǎn)動的代碼
- while (1)
- {
- OpenMV_X= openmv[2];
- printf ("\r\n%d\r\n",OpenMV_X);
- if(OpenMV_X>=0&&OpenMV_X<80)
- {
- s=185-OpenMV_X/16;
- TIM_SetCompare1(TIM1, s);
- }
- if(OpenMV_X>=180)
- {
- s=190-(OpenMV_X-180)/16;
- TIM_SetCompare1(TIM1, s);
- }
- }
|