【STM32+OPENMV】二维云台颜色识别及追踪
创始人
2024-12-18 17:05:38
0

一、准备工作

有关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

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

源码

STM32+OPENMV二维云台颜色识别及追踪PID版

相关内容

热门资讯

第2分钟发现!四川家园游戏辅助... 第2分钟发现!四川家园游戏辅助软件,多乐跑辅助,2026新版技巧(有挂解密)-哔哩哔哩;四川家园游戏...
第8分钟带你讲解!新九哥开挂,... 第8分钟带你讲解!新九哥开挂,欢乐达人正版脚本,存在挂教程(有挂方式)-哔哩哔哩;无需打开直接搜索微...
第六分钟指导!手机挂机软件,反... 第六分钟指导!手机挂机软件,反杀新大厅辅助,教你攻略(有挂方略)-哔哩哔哩;1、让任何用户在无需AI...
第一分钟带你透视!悟空大厅辅助... 第一分钟带你透视!悟空大厅辅助器下载,榆林打锅子辅助器,曝光教程(有挂秘诀)-哔哩哔哩;无需打开直接...
第7分钟普及!wejoker开... 第7分钟普及!wejoker开挂,pokermaster破解版,黑科技教程(真是有挂)-哔哩哔哩;A...
7分钟带你开挂!蜀山四川辅助脚... 蜀山四川辅助脚本视频教学开挂教程视频分享装挂详细步骤在当今的网络游戏中,蜀山四川辅助脚本视频教学作为...
2分钟普及!wepoker轻量... 2分钟普及!wepoker轻量版有透视吗,pokemmo辅助器,介绍教程(证实有挂)-哔哩哔哩相信很...
7分钟带你发现!多乐辅助下载够... 【亲,逸趣鄱阳翻精辅助 这款游戏可以开挂的,确实是有挂的,很多玩家在这款逸趣鄱阳翻精辅助中打牌都会发...
第8分钟领会!wejoker辅... 第8分钟领会!wejoker辅助机器人,pokemmo辅助脚本,科技教程(新版有挂)-哔哩哔哩;小薇...
三分钟带你辅助!小程序微乐游戏... 三分钟带你辅助!小程序微乐游戏辅助器,反杀大厅辅助,辅助教程(有挂分析)-哔哩哔哩 了解更多开挂安装...