目录
1.赛题及硬件方案分析:
刚得到消息,我们队被推荐为国奖,国一国二还没定,大概率是国二,因为测评时发挥部分的小车二在转弯时因为电池原因急转弯失败,发挥部分就没有成功验收。刚收到消息就更新了一下,本方案的成本可以说是此赛题方案中成本最低的。
通过题目可以很容易的看出来,这道题有最难的两个点:巡线+数字识别。
此题的巡线又不同于以往电赛题目的黑白巡线,此题是巡红白线。这样就会带来一个问题,以往巡黑白线我们最常用的是红外传感器,但是此题中的红线和白色背景两者间的吸光能力差别很小,一般的红外传感器根本难以分辨,这就需要用到较为不常用的灰度传感器或者是颜色传感器。据我所知,开赛前就已经准备好这两种传感器的小组还是较少的,包括我们组就没有准备,只能用摄像头代替,用对应的算法进行巡线。
数字识别用到的硬件就没什么好说的了,肯定用到摄像头,我们组用的是赛前已经准备好的OpenMV,OpenMV上手还是很快的,但是需要有一定的Python基础 。在比赛过程中也有很多大佬认为OpenMV同时进行巡线和数字识别的话,其帧率会很低,我们组当然也遇到了以上问题,具体的解决方法在后面会讲到。
另外,题目中要求检测到200g药品的装载和卸载,一般的话可以用压力传感器,但为了方便我们直接用的红外对管,以检测障碍物的方式判断药品是否装载。
2.用到的主要器件清单:
STM32F407ZGT6单片机
OpenMV4智能处理摄像头
舵机转向四驱车
锂电池、5V、12V降压模块
L298N电机驱动模块
红外传感器
蓝牙模块HC-05
LED指示灯
以上器件都是一辆小车用到的,如果要做发挥部分的话就需要两辆车了,不过小车2用到的器件基本不变。我们采取的方案是一辆小车用一个摄像头,我看网上有的大佬一辆小车左右两边各有一个摄像头,这样的话写代码就会较为简便,不过一般的OpenMV价格在300到500之间,除非你的经费充足且赛前已经准备好,否则还是老老实实用一个摄像头肝吧.....就像我们组,当时只有一个OpenMV,第二个还是临时找关系借的。
3.各部分思路及代码实现
(1).小车舵机、马达驱动
这一部分的代码就不贴上了,都是基本的PWM输出,可以参照正点原子的相关例程,并且两辆小车的代码都一样,只不过舵机让车轮保持直行时的PWM脉宽不同,到时候自己找到并在代码中改数字即可。
(2).蓝牙通信
蓝牙通信的代码说白了就是串口通信,代码如下:
#include "stm32f4xx.h"#include "bluetooth.h"/*蓝牙通信:USART3,所用引脚为PC10,PC11*/void bluetooth_U3_Init(){GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //使能GPIOA时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //使能USART2时钟//串口1对应引脚复用映射GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3); //GPIOA9复用为USART1GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_USART3); //GPIOA10复用为USART1//USART1端口配置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; //GPIOA9与GPIOA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //上拉GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化PA9,PA10//USART1 初始化设置USART_InitStructure.USART_BaudRate = 9600;//波特率设置USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式USART_Init(USART3, &USART_InitStructure);//初始化串口1USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //开启相关中断//Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //串口1中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、USART_Cmd(USART3, ENABLE); //使能串口1}/* 蓝牙使能引脚:PA9 */void bluetooth_IO_Init(){GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //??GPIOA??GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //??50MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_OD; //??????GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //??GPIO_Init(GPIOC, &GPIO_InitStructure); //???PA9,PA10}
注意:以上代码中蓝牙使能引脚PA9可以不进行初始化,这样就会一直使能。
(3).单片机与OpenMV的串口通信
此代码