IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 2021电赛F题智能送药小车方案分析(k210数字识别openMV循迹小车自动返回) -> 正文阅读

[嵌入式]2021电赛F题智能送药小车方案分析(k210数字识别openMV循迹小车自动返回)

2021全国大学生电子设计竞赛F题智能送药小车

前提:本篇文章重在分享自己的心得与感悟,反思自己的不足,我们把最重要的部分,摄像头循迹,摄像头数字识别问题都解决了,数字识别准确率可达98.7%,最后却运动控制上出现了一点失误。

人们常常希望向成功者获取经验,可是生活中哪有那么多成功者,我想只有失败者才最有发言权,最有经验可以分享吧。但我不甘是失败者,我们为此付出了多少,坚持了多少,只有我们自己知道,只要全力以赴就无所谓失败,也许多年后再回过头来看,想起来这些热血我依然能够热泪盈眶,那就无悔了。

目录:
一、题目分析
二、分工以及小车的搭建
三、摄像头部分
四、控制部分
五、联调
六、随谈
七、工程代码

备注:
只需要工程代码的同学(如下是此次电赛过程中所有的代码),建议先看完正文
openmv巡线代码:
https://download.csdn.net/download/cubejava/41873305
k210数字识别代码:
https://download.csdn.net/download/cubejava/41861166
stm32HAL库keil工程(配置freeRTOS,巡线,自动返回,定点停车):
https://download.csdn.net/download/cubejava/41871669
巡线和数字识别的融合代码(K210):
https://download.csdn.net/download/cubejava/41862039
本次电赛所有工程代码汇总(K210数字识别,openmv循迹,stm32f411运动控制):
https://download.csdn.net/download/cubejava/41884388
(可私聊提供技术支持,代码中不懂的可手把手教学)

正文

一、题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们是做测控方向的,当时在4号早上7:30左右题目就出来了,随即就有人发在了群里。在这里插入图片描述
看了一下测控方向除了无人机能选的也就D题和F题了,D题是基于互联网的摄像测量系统(D题),我们对这方面的了解不多,没有什么把握,就没敢选,后来听说选D题的在GitHub上能够找到源码,做到后面车调不动时倒有点小后悔,哈哈。

F题经典小车题目,但与往年不同的是今年识别和控制都是重点,必须要先能做到识别,你才能谈接下来的循迹和运动控制。
谈到识别就需要用到摄像头,但之前我们对于摄像头并没有太重视,循迹一般用的都是红外对管,灰度传感器,或者线性CCD就足够了,但是这次的赛到元素存在十字,黑白色块,还要求能自动返回,使用普通的循迹模块就比较吃力了。

二、分工以及小车的搭建

我们组三人都没有玩过摄像头,要立马开始现学,我们一开始准备使用openmv进行循迹和数字识别,后来发现我们的openmv的版本不能训练神经网络,必须要openmvplus(可是没有,买又来不急送到),就很难受,于是我们采用openmv循迹,使用k210识别数字。
其中一位学长写openmv循迹的代码,其中一位学长完成k210数字识别,我则负责stm32f4的工程创建小车的底层代码和运动控制。
由于之前备赛准备的东西比较充分,所以当天上午就把车给搭建好了,使用平衡小车,加了一个万向轮,转弯差速控制。
在这里插入图片描述
小车硬件:
STM32F411CEU6,TB6612,车模(自带霍尔编码器减速电机),LM2596,MPU6050,航模电池,openMV,K210
小车软件:
使用的HAL库建立工程,在cubeMX中配置freeRTOS操作系统,
在这里插入图片描述
KEIL工程程序代码:
在这里插入图片描述

串口重定向printf

/*串口重定向printf*/
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart6, (uint8_t *)&ch, 1, 1000);
  return ch;
}

编码器模式取值

/*编码器模式取值*/
int Read_Encoder(uint8_t TIMX)           
{
   int Encoder_TIM;    
   switch(TIMX)
	 {
	   case 1:  Encoder_TIM= (short)TIM1 -> CNT;  TIM1 -> CNT=0;break;
		 case 2:  Encoder_TIM= (short)TIM2 -> CNT;  TIM2 -> CNT=0;break;	
		 
		 default:  Encoder_TIM=0;
	 }
		return Encoder_TIM;
}

判断mpu6050初始化是否成功

void Mpu6050_Init()
{
	while(w_mpu_init() != mpu_ok)           
	{
		printf("0x%x (ID_ERROR)\r\n", w_mpu_init());
		HAL_Delay(10);
	}
	/*DMP初始化*/
	dmp_init();     
}

初始化程序

int main(void)
{
	/*开启编码器计数*/
	HAL_TIM_Encoder_Start(&htim1, TIM_CHANNEL_ALL);
	HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);
	/*开启电机PWM输出*/
	HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
	HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
	/*开启舵机的PWM输出*/
	HAL_TIM_PWM_Start(&htim5,TIM_CHANNEL_3);
	HAL_TIM_PWM_Start(&htim5,TIM_CHANNEL_4);
	/*Enable the USART1 Interrupt*/
	HAL_UART_Receive_IT(&huart1,(uint8_t *)&usart6_rxbuff,1);
	/*临时*/
	Temporary();
	Mpu6050_Init();
	/*使能定时器4中断*/
	HAL_TIM_Base_Start_IT(&htim4);
	HAL_UART_Transmit(&huart6, (uint8_t *)&cc, 1,0xFFF);
//	TIM3 ->CCR1 = 400;
//		TIM3 ->CCR2 = 400;
  /* USER CODE END 2 */

  /* Call init function for freertos objects (in freertos.c) */
    MX_FREERTOS_Init();
	HAL_UART_Transmit(&huart6, (uint8_t *)&cc, 1,0xFFF);
  /* Start scheduler */
    osKernelStart();
   while (1)
  {
    /* USER CODE END WHILE */
//		printf("-------------\r\n");
//		HAL_Delay(500);
    /* USER CODE BEGIN 3 */
		
		
  }
  /* USER CODE END 3 */
}

freeRTOS.C文件中的代码

```c![在这里插入代码片](https://img-blog.csdnimg.cn/900085698de24363b9b8bb58cad34e06.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5Lmf5peg6aOO6Zuo5Lmf5peg5oOFV1k=,size_20,color_FFFFFF,t_70,g_se,x_16)

巡线和功能实现代码均放在freeRTOS.C中

在这里插入图片描述

三、摄像头部分

有关摄像头部分,学长在第一天就把openmv的巡线代码给写好了
在openmv中处理好数据,可以寻红线,识别十字,识别黑白色块,
传回来的数据:
左右线传回为模拟量,传入单片机,进行pid控制
在这里插入图片描述
K210数字识别:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

四、控制部分

控制部分,巡线使用的PD控制

首先速度闭环,PI控制,让小车保持在一个稳定的速度
在这里插入图片描述
在速度环上叠加一层方向环,PD控制,巡线
在这里插入图片描述

int track_control(float collect_openmv)
{
	static float last_bias,Bias,kp=0.75,Kd=0.25;//0.5的效果还行
	float Turn;     	  
	Bias=-(collect_openmv-60);
	Turn=-Bias*kp-Kd*(Bias-last_bias);
	last_bias = Bias;
	//printf("\r\nt:%.1f\r\n",Turn);
	return Turn;
}

小车的自动返回,和判定十字转弯,黑白色块停车使用了标志位,定义数组,根据出栈入栈原理,记录去回的方向。
在这里插入图片描述

五、联调

openmv和k210的数据传入单片机
打开串口中断,注意需要写好摄像头和单片机之间的通信协议,如下:
在这里插入图片描述

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)    //串口中断,遥控部分。
{
	uint16_t tem;
	if(huart->Instance == USART1)	// 判断是由哪个串口触发的中断
	{

		//printf("ok");
		tem = usart6_rxbuff;
		printf("%x\r\n",tem);
		if(RxState==0&&tem==0x79)
		{
			RxState=1;
			RxBuffer1[RxCounter1++]=tem;
		}
		else if(RxState==1)
		{
			RxBuffer1[RxCounter1++]=tem;
			if(RxCounter1>=10||tem == 0x85)       //RxBuffer1接受满了,接收数据结束
			{
				RxState=2;
			}
		 }
		 else if(RxState==2)		//检测是否接受到结束标志
		 {
				if(RxBuffer1[RxCounter1-1] == 0x85)
				{
						if(RxBuffer1[1] == 0xaa)//识别
						{
							Flag = Flag + 1;
		
							JG=RxBuffer1[RxCounter1-2];
							Turn = RxBuffer1[RxCounter1-3];
							if(Flag>3)
							{
								if(JG>0&&FS==0) {FS = JG;}
								printf("\r\n Turn:%d FS:%d  \r\n",Turn,FS);
							}

						}
						if(RxBuffer1[1] == 0xbb)//搜线
						{
							printf("\r\n___sou xian___\r\n");
							printf("\r\n Cx:%d, STOP:%d \r\n",Cx,STOP);
							Cx=RxBuffer1[RxCounter1-2];

							STOP=RxBuffer1[RxCounter1-3];
						}
						


							RxCounter1 = 0;
							RxState = 0;
						
				}
				else   //接收错误
				{
							RxState = 0;
							RxCounter1=0;
							for(i=0;i<10;i++)
							{
									RxBuffer1[i]=0x00;      //将存放数据数组清零
							}
							printf("接收错误\r\n");
				}
			}
		 if(state==2)
		 {
			 if(STOP == 0)
			 {
				 state = 0;
			 }
		 }
		 if(state==4)
		 {
			 if(STOP == 0)
			 {
				 state = 0;
			 }
		 }
	}
	HAL_UART_Receive_IT(&huart1, (uint8_t *)&usart6_rxbuff, 1); 
}

六、随谈

在这里插入图片描述
在这里插入图片描述
我们是在结束的前一天晚上完成好的数字识别,离调车整个程序的逻辑就只有一天的时间,说真的,程序写少了,这个程序逻辑真的很难想出来,尤其是在当时已经连续三天每天只睡2个小时左右,头脑非常混沌,呆滞。
还是要多写程序,练习自己写程序的逻辑思维。

结尾:第一次参加国赛,也是第一次参加电赛,本来应该是大一结束就开始了的,电赛延期拖到了大二开学后的一段时间,自己需要学的内容还有很多,好好学习,提升自己的技术,明年省赛继续冲!

七、 工程代码:

openmv巡线代码:
https://download.csdn.net/download/cubejava/41873305
k210数字识别代码:
https://download.csdn.net/download/cubejava/41861166
stm32HAL库keil工程(配置freeRTOS,巡线,自动返回,定点停车):
https://download.csdn.net/download/cubejava/41871669
巡线和数字识别的融合代码(K210):
https://download.csdn.net/download/cubejava/41862039
本次电赛所有工程代码汇总(K210数字识别,openmv循迹,stm32f411运动控制):
https://download.csdn.net/download/cubejava/41884388
备注:这些都是我们没日没夜熬出来的程序代码,花费了很多精力,所以没有免费开源(望理解),设置了付费,不过在博客里也写了相关的思路,可以参考借鉴一些经验,来年省赛加油!!!
现在电赛越来越趋向于视觉和人工智能了,一定要好好学习摄像头,视觉,神经网络。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-11-14 21:52:49  更:2021-11-14 21:54:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:39:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码