当前位置: 代码网 > 科技>人工智能 > 【STM32+OPENMV】二维云台颜色识别及追踪

【STM32+OPENMV】二维云台颜色识别及追踪

2024年08月01日 人工智能 我要评论
一、准备工作有关OPENMV最大色块追踪及与STM32通信内容,详情见【STM32+HAL】与OpenMV通信有关七针OLED屏显示内容,详情见【STM32+HAL】七针OLED(SSD1306)配置(SPI版)二、所用工具1、芯片:STM32F407ZGT62、CUBEMX配置软件3、KEIL54、OPENMV三、实现功能二维云台追踪最大色块,并显示中心x,y坐标至OLED

一、准备工作

有关openmv最大色块追踪及与stm32通信内容,详情见【stm32+hal】与openmv通信

有关七针oled屏显示内容,详情见【stm32+hal】七针oled(ssd1306)配置(spi版)

二、所用工具

1、芯片:stm32f407zgt6

2、cubemx配置软件

3、keil5

4、openmv

三、实现功能

二维云台追踪最大色块,并显示中心x,y坐标至oled

四、hal配置步骤

1、生成两路pwm波控制舵机

周期为20ms

2、中断配置

五、keil填写代码

1、ptz.c
#include "ptz.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "main.h"
#include "tim.h"
#include "usart.h"

#define rxbuffersize	256
#define ccr_ud 			tim2->ccr2   	//up and down....		range:420-2000		
#define ccr_lr 			tim2->ccr3   	//left and right....	range:420-2500  	
#define cen_x  			160		//x轴中心坐标值
#define cen_y  			120		//y轴中心坐标值

#define sp1				7       //x轴速度
#define sp2				6       //y轴速度
#define range			40      //识别范围



char rxbuffer[rxbuffersize],rx_buf[rxbuffersize];
uint8_t arxbuffer;
uint8_t uart1_rx_cnt = 0;

int cnt_rx=0,cnt_dt=0;
int cx=0,cy=0;




void tilt(void)
{
	if(cx < (cen_x-range)) ccr_lr = (ccr_lr>2450)?2450:ccr_lr+sp1;
	else if (cx > (cen_x+range))	ccr_lr = (ccr_lr<450)?450:ccr_lr -sp1;
	else ccr_lr= ccr_lr;

	if(cy < (cen_y-range)) ccr_ud = (ccr_ud<420)?420:ccr_ud -sp2;
	else if (cy > (cen_y+range))	ccr_ud = (ccr_ud>1800)?1800:ccr_ud+sp2;
	else ccr_ud= ccr_ud;
}





void hal_uart_rxcpltcallback(uart_handletypedef *huart)
{
    unused(huart);
	if(huart==&huart2){
		rxbuffer[uart1_rx_cnt] = arxbuffer;
		uart1_rx_cnt++;
		if((rxbuffer[uart1_rx_cnt-1] == 0xb3)&&(rxbuffer[uart1_rx_cnt-2] == 0xb3)) cnt_rx=1;		//帧头判定
		else if((rxbuffer[uart1_rx_cnt-2] == 0x0d)&&(rxbuffer[uart1_rx_cnt-1] == 0x0a)) cnt_rx=2;	//帧尾判定
		else cnt_rx=0;

		switch (cnt_rx)
        {
        	case 1:
				uart1_rx_cnt = 0;
				memset(rxbuffer,0x00,sizeof(rxbuffer));
        		break;
        	case 2:
				rxbuffer[uart1_rx_cnt-1] = '\0';
				rxbuffer[uart1_rx_cnt-2] = '\0';
				strcpy(rx_buf,rxbuffer);

				int st=0;						//有效数值开始位置
				cnt_dt=0;						//空格数
				for(int i=0;rx_buf[i];i++){
					if(cnt_dt==4) break;
					if(rx_buf[i]==' ') {
						cnt_dt++;
						int temp=0;
						for(int j=st;j<i;j++)
							temp=temp*10+(rx_buf[j]-'0');
						switch (cnt_dt){
                        	case 1:cx=temp;break;
                        	case 2:cy=temp;break;
                        }
						st=i+1;
					}
				}

				while(hal_uart_getstate(&huart2) == hal_uart_state_busy_tx);
				uart1_rx_cnt = 0;
				memset(rxbuffer,0x00,sizeof(rxbuffer));
        		break;
			default:break;
        }
	hal_uart_receive_it(&huart2, (uint8_t *)&arxbuffer, 1);
	}
}

2、main.c
  /* user code begin 2 */
	oled_init();

	hal_uart_receive_it(&huart2, (uint8_t *)&arxbuffer, 1);

	tim2->ccr2 = 420-1;
	tim2->ccr3 = 1400-1;
	hal_tim_pwm_start (&htim2, tim_channel_2);
	hal_tim_pwm_start (&htim2, tim_channel_3);
  /* user code end 2 */

  /* infinite loop */
  /* user code begin while */
  while (1)
  {
	  oled_shownum(30,20,cx,3,16);
	  oled_shownum(30,40,cy,3,16);
	  oled_refresh();
    /* user code end while */

    /* user code begin 3 */
	  if(flag) tilt();
  }
  /* user code end 3 */
}

3、按键控制暂停
/* user code begin 4 */

void hal_gpio_exti_callback(uint16_t gpio_pin)  
{
	if(gpio_pin == key0_pin){
		hal_delay(20); //延时消抖
		if(gpio_pin == key0_pin){
			flag=0;
		}
	}
}
/* user code end 4 */

六、巨人之肩

【毕业设计】基于stm32及openmv的云台追踪装置

电赛:二维云台控制

【毕业设计】基于stm32f103c8t6最小系统板与openmv的二维云台pid控制追踪系统

后续优化方案:pid调控

位置式pid与增量式pid区别浅析

七、源码提供

【stm32+openmv】二维云台颜色识别及追踪【无pid版】

八、成果展示

ptz

九、优化方案:pid控制

#include "ptz.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "main.h"
#include "tim.h"
#include "usart.h"

#define rxbuffersize	256
#define ccr_ud 			tim1->ccr1   	//up and down....		range:1250-7500
#define ccr_lr 			tim1->ccr2   	//left and right....	range:1250-7500
#define cen_x  			160				//x轴中心坐标值
#define cen_y  			120				//y轴中心坐标值

#define kp1 				0.45
#define kd1 				2
#define kp2 				0.35
#define kd2 				2

#define sp1				30
#define sp2				23
#define range			35



char rxbuffer[rxbuffersize],rx_buf[rxbuffersize];
uint8_t arxbuffer;
uint8_t uart1_rx_cnt = 0;

int cnt_rx=0,cnt_dt=0;
int cx=0,cy=0;




void tilt(void)
{
	if(pid1(cx,cen_x)+ccr_lr>7450) ccr_lr=7450;
	else if(ccr_lr<1250) ccr_lr=1250;
	else ccr_lr+=pid1(cx,cen_x);
	
	if(ccr_ud>4000) ccr_ud=4000;
	else if(ccr_ud<1250) ccr_ud=1250;
	else ccr_ud-=pid2(cy,cen_y);
	
}


int pid1(int current,int target)  //pid速度控制
{
	static int lasterror;					//error[-1]
	int ierror,outpid;						//当前误差

	ierror=target-current;		 			//增量计算
	outpid=(kp1 * ierror)  					//e[k]项
			+(kd1 * (ierror-lasterror));		//e[k]-e[k-1]项

	lasterror=ierror;						//存储误差,用于下次计算
	
	return outpid;
}

int pid2(int current,int target)  //pid速度控制
{
	static int lasterror;					//error[-1]
	int ierror,outpid;						//当前误差

	ierror=target-current;		 			//增量计算
	outpid=(kp2 * ierror)  					//e[k]项
			+(kd2 * (ierror-lasterror));		//e[k]-e[k-1]项

	lasterror=ierror;						//存储误差,用于下次计算
	
	return outpid;
}







void hal_uart_rxcpltcallback(uart_handletypedef *huart)
{
    unused(huart);
	if(huart==&huart2){
		rxbuffer[uart1_rx_cnt] = arxbuffer;
		uart1_rx_cnt++;
		if((rxbuffer[uart1_rx_cnt-1] == 0xb3)&&(rxbuffer[uart1_rx_cnt-2] == 0xb3)) cnt_rx=1;		//帧头判定
		else if((rxbuffer[uart1_rx_cnt-2] == 0x0d)&&(rxbuffer[uart1_rx_cnt-1] == 0x0a)) cnt_rx=2;	//帧尾判定
		else cnt_rx=0;

		switch (cnt_rx)
        {
        	case 1:
				uart1_rx_cnt = 0;
				memset(rxbuffer,0x00,sizeof(rxbuffer));
        		break;
        	case 2:
				rxbuffer[uart1_rx_cnt-1] = '\0';
				rxbuffer[uart1_rx_cnt-2] = '\0';
				strcpy(rx_buf,rxbuffer);

				int st=0;						//有效数值开始位置
				cnt_dt=0;						//空格数
				for(int i=0;rx_buf[i];i++){
					if(cnt_dt==4) break;
					if(rx_buf[i]==' ') {
						cnt_dt++;
						int temp=0;
						for(int j=st;j<i;j++)
							temp=temp*10+(rx_buf[j]-'0');
						switch (cnt_dt){
                        	case 1:cx=temp;break;
                        	case 2:cy=temp;break;
                        }
						st=i+1;
					}
				}

				while(hal_uart_getstate(&huart2) == hal_uart_state_busy_tx);
				uart1_rx_cnt = 0;
				memset(rxbuffer,0x00,sizeof(rxbuffer));
        		break;
			default:break;
        }
	hal_uart_receive_it(&huart2, (uint8_t *)&arxbuffer, 1);
	}
}

源码

stm32+openmv二维云台颜色识别及追踪pid版

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com