- 车身 ,使用平衡小车之家的一款自带车体和4个麦克纳姆轮的套餐。
(不需要PS2手柄,巡线配置都不需要,麦轮直径60mm)
- 主控 ,STM32F103ZET6最小系统板,不是很推荐我使用的这块,颜值不高。
电机驱动 ,WINGXINE阿里风斯的一款H桥双驱,电机驱动超级好用。
- 无线串口 ,选择的逐飞科技的无线串口,半双工。主要是喜欢即插即用。
(整套套件各一个)
- 机械臂 ,这个爪子真的超级不推荐,放出连接就是给大家避坑。
(黑色B款爪子)
场地地图及比赛任务简述
比赛任务需要从启动区出发,前往资源区拿取乒乓球,再去资源整合区将不同颜色的乒乓球分类放置,然后小车停在目标区。
硬件设计
值得一谈的就是电源部分的设计,其余主控和电机驱动部分的设计,本质上只是进行相应的线路连接,仅此而已。
下面我好好聊一下这次的电源设计。
1、一开始的方案是,使用一块实验室就有的航模电池(权盛电子,5200毫安时,11.1V电压输出,白嫖实验室的,没有产品连接),使用LM2940-5.0稳压到5V给电机驱动供电,再由5.0V使用LM1117-3.3稳压为3.3V给单片机供电。
遇到的问题是,当电机占空比给到50%,长时间的运行会导致LM2940过热自动保护。
2、改进的方法,使用以前的一块电池直接替换,做过智能车的都懂(香山红叶,输出7.2V,2000毫安时镍铬电池)
设计思路
使用红外模块循迹,(红外模块是实验室白嫖的,上面没有任何型号的标注,没有链接;注:五路红外,无电位器调节阈值),使用实验室的舵机和自己买的机械爪搭接一个机械臂来执行乒乓球的抓取,使用32进行整体控制,用串口无线回传给电脑上位机来实时查看小车状况。
可能有人要问了,你们乒乓球不是在资源整合区需要按照颜色进行分类的嘛,你上面说的这些硬件如何完成这个任务呢?
使用星瞳科技的openmv(这个懂的人都懂,就不放链接了)来识别小球位置并控制舵机来进行抓取,在资源整合区来进行颜色识别分类归放。
openmv和主控stm32通过串口通信。
部分代码
红外.c
#include "bsp_Find_Num.h"
void Find_Nun_Init()
{
GPIO_InitTypeDef GPIO_InitStruct; //定义一个 GPIO_InitTypeDef 类型的结构体
RCC_APB2PeriphClockCmd(LED_1_GPIO_CLK|LED_2_GPIO_CLK|LED_3_GPIO_CLK|LED_4_GPIO_CLK|LED_5_GPIO_CLK, ENABLE);//开启led对应GPIO的时钟
GPIO_InitStruct.GPIO_Pin = LED_1_GPIO_PIN|LED_2_GPIO_PIN|LED_3_GPIO_PIN|LED_4_GPIO_PIN|LED_5_GPIO_PIN;//设置需要控制的GPIO引脚
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD; //设置为下拉电阻输入
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //设置GPIO速率
GPIO_StructInit(&GPIO_InitStruct);
}
红外.H
#ifndef _BSP_FIND_NUM_H
#define _BSP_FIND_NUM_H
#include "stm32f10x.h"
//********************红外循迹模块IO配置(数字量)*****************//
// led 1
#define LED_1_GPIO_PORT GPIOB
#define LED_1_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED_1_GPIO_PIN GPIO_Pin_2
// led 2
#define LED_2_GPIO_PORT GPIOB
#define LED_2_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED_2_GPIO_PIN GPIO_Pin_7
// led 3
#define LED_3_GPIO_PORT GPIOB
#define LED_3_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED_3_GPIO_PIN GPIO_Pin_4
// led 4
#define LED_4_GPIO_PORT GPIOB
#define LED_4_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED_4_GPIO_PIN GPIO_Pin_5
// led 5
#define LED_5_GPIO_PORT GPIOB
#define LED_5_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED_5_GPIO_PIN GPIO_Pin_6
//分别检测各路输入
#define LED_1_out GPIO_ReadInputDataBit( LED_1_GPIO_PORT, LED_1_GPIO_PIN);
#define LED_2_out GPIO_ReadInputDataBit( LED_2_GPIO_PORT, LED_2_GPIO_PIN);
#define LED_3_out GPIO_ReadInputDataBit( LED_3_GPIO_PORT, LED_3_GPIO_PIN);
#define LED_4_out GPIO_ReadInputDataBit( LED_4_GPIO_PORT, LED_4_GPIO_PIN);
#define LED_5_out GPIO_ReadInputDataBit( LED_5_GPIO_PORT, LED_5_GPIO_PIN);
void Find_Nun_Init(void); //初始化红外循迹模块
#endif
控制.c
#include "bsp_Car_Oper.h"
#include "bsp_em_gpio.h"
#include "bsp_Find_Num.h"
#include "bsp_usart.h"
#include "bsp_SysTick.h"
int LED_1=1,LED_2=1,LED_3=1,LED_4=1,LED_5=1,i=0,status=0;
static int Resources=1;
void Follow_line()//巡线
{
//车上红灯亮为1,灭为0;
//不踩黑线红(1),踩黑线灭(0);
LED_1=LED_1_out;//A
LED_2=LED_2_out;//A
LED_3=LED_3_out;//B
LED_4=LED_4_out;//A
LED_5=LED_5_out;//B
if((LED_1==1)&(LED_5==1))//2、3、4全部压线
{
Car_Fore(Car_Speed_Str);//直行
status=1;
}
if((LED_1==1)&(LED_3==0)&(LED_5==0))//2丢线了,向左转一下
{
Car_CLOCKWISE(Car_Speed_Turn+20);//向左转
status=2;
}
if((LED_1==0)&(LED_3==0)&(LED_5==1))//4丢线了,向右转一下
{
Car_ANTICLOCKWISE(Car_Speed_Turn);//向右转
status=3;
}
//printf("LED_1=%d LED_2=%d LED_3=%d LED_4=%d LED_5=%dn",LED_1,LED_2,LED_3,LED_4,LED_5);
}
void Identify()//模式识别
{
// if((LED_1==0)&(LED_2==0)&(LED_3==0)&(LED_4==0)&(LED_5==0)&(Resources==6))//上坡
// {
// status=6;
// Car_Fore(80);//直行通过
// SysTick_Delay_Ms(4000);
// Resources=7;
// }
if((LED_1==0)&(LED_2==0)&(LED_3==0)&(LED_4==0)&(LED_5==0)&(Resources==5))//第三个重生点
{
status=6;
Car_Fore(30);//直行通过
SysTick_Delay_Ms(1500);
Resources=6;
}
if((LED_1==0)&(LED_2==0)&(LED_3==0)&(LED_4==0)&(LED_5==0)&(Resources==4))//Z_2
{
status=6;
Car_Fore(30);
SysTick_Delay_Ms(300);
Car_ANTICLOCKWISE(Car_Speed_Turn);//右转
SysTick_Delay_Ms(650);
Resources=5;
}
if((LED_1==0)&(LED_2==0)&(LED_3==0)&(LED_4==0)&(LED_5==0)&(Resources==3))//Z_1
{
status=6;
Car_CLOCKWISE(Car_Speed_Turn);//左转
SysTick_Delay_Ms(1700);
Resources=4;
}
if((LED_1==0)&(LED_2==0)&(LED_3==0)&(LED_4==0)&(LED_5==0)&(Resources==2))//第二个重生点
{
status=6;
Car_Fore(30);//直行通过
SysTick_Delay_Ms(1500);
Resources=3;
}
if((LED_1==0)&(LED_2==0)&(LED_3==0)&(LED_4==0)&(LED_5==0)&(Resources==1))//第一个重生点
{
status=5;
Car_Fore(30);//直行通过
SysTick_Delay_Ms(1700);
Resources=2;
}
if((LED_1==0)&(LED_2==0)&(LED_3==0)&(LED_4==0)&(LED_5==0)&(Resources==0))//丁字路口
{
status=4;
Car_Fore(30);//直行一会
SysTick_Delay_Ms(400);
Car_ANTICLOCKWISE(50);//左转一会
SysTick_Delay_Ms(900);
Car_Fore(30);//再直行一会
SysTick_Delay_Ms(1000);
Resources=1;
}
printf("status=%d Resources=%dn",status,Resources);
}
目前存在的问题
1、电池容量太小,调试时候,调试一会供电电压就大幅下降,导致参数的变化,十分不便。
2、整车质量太重、在过坡的时候十分吃力。
3、红外模块受光照影响很大,整体系统不够稳定。
还可以提升的点
1、并没有把电机的编码器这个模块使用上,电机没有闭环。
2、如果可以使用摄像头来巡线,那么整个系统会更加稳定。
- 车身 ,使用平衡小车之家的一款自带车体和4个麦克纳姆轮的套餐。
(不需要PS2手柄,巡线配置都不需要,麦轮直径60mm)
- 主控 ,STM32F103ZET6最小系统板,不是很推荐我使用的这块,颜值不高。
电机驱动 ,WINGXINE阿里风斯的一款H桥双驱,电机驱动超级好用。
- 无线串口 ,选择的逐飞科技的无线串口,半双工。主要是喜欢即插即用。
(整套套件各一个)
- 机械臂 ,这个爪子真的超级不推荐,放出连接就是给大家避坑。
(黑色B款爪子)
场地地图及比赛任务简述
比赛任务需要从启动区出发,前往资源区拿取乒乓球,再去资源整合区将不同颜色的乒乓球分类放置,然后小车停在目标区。
硬件设计
值得一谈的就是电源部分的设计,其余主控和电机驱动部分的设计,本质上只是进行相应的线路连接,仅此而已。
下面我好好聊一下这次的电源设计。
1、一开始的方案是,使用一块实验室就有的航模电池(权盛电子,5200毫安时,11.1V电压输出,白嫖实验室的,没有产品连接),使用LM2940-5.0稳压到5V给电机驱动供电,再由5.0V使用LM1117-3.3稳压为3.3V给单片机供电。
遇到的问题是,当电机占空比给到50%,长时间的运行会导致LM2940过热自动保护。
2、改进的方法,使用以前的一块电池直接替换,做过智能车的都懂(香山红叶,输出7.2V,2000毫安时镍铬电池)
设计思路
使用红外模块循迹,(红外模块是实验室白嫖的,上面没有任何型号的标注,没有链接;注:五路红外,无电位器调节阈值),使用实验室的舵机和自己买的机械爪搭接一个机械臂来执行乒乓球的抓取,使用32进行整体控制,用串口无线回传给电脑上位机来实时查看小车状况。
可能有人要问了,你们乒乓球不是在资源整合区需要按照颜色进行分类的嘛,你上面说的这些硬件如何完成这个任务呢?
使用星瞳科技的openmv(这个懂的人都懂,就不放链接了)来识别小球位置并控制舵机来进行抓取,在资源整合区来进行颜色识别分类归放。
openmv和主控stm32通过串口通信。
部分代码
红外.c
#include "bsp_Find_Num.h"
void Find_Nun_Init()
{
GPIO_InitTypeDef GPIO_InitStruct; //定义一个 GPIO_InitTypeDef 类型的结构体
RCC_APB2PeriphClockCmd(LED_1_GPIO_CLK|LED_2_GPIO_CLK|LED_3_GPIO_CLK|LED_4_GPIO_CLK|LED_5_GPIO_CLK, ENABLE);//开启led对应GPIO的时钟
GPIO_InitStruct.GPIO_Pin = LED_1_GPIO_PIN|LED_2_GPIO_PIN|LED_3_GPIO_PIN|LED_4_GPIO_PIN|LED_5_GPIO_PIN;//设置需要控制的GPIO引脚
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD; //设置为下拉电阻输入
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //设置GPIO速率
GPIO_StructInit(&GPIO_InitStruct);
}
红外.H
#ifndef _BSP_FIND_NUM_H
#define _BSP_FIND_NUM_H
#include "stm32f10x.h"
//********************红外循迹模块IO配置(数字量)*****************//
// led 1
#define LED_1_GPIO_PORT GPIOB
#define LED_1_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED_1_GPIO_PIN GPIO_Pin_2
// led 2
#define LED_2_GPIO_PORT GPIOB
#define LED_2_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED_2_GPIO_PIN GPIO_Pin_7
// led 3
#define LED_3_GPIO_PORT GPIOB
#define LED_3_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED_3_GPIO_PIN GPIO_Pin_4
// led 4
#define LED_4_GPIO_PORT GPIOB
#define LED_4_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED_4_GPIO_PIN GPIO_Pin_5
// led 5
#define LED_5_GPIO_PORT GPIOB
#define LED_5_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED_5_GPIO_PIN GPIO_Pin_6
//分别检测各路输入
#define LED_1_out GPIO_ReadInputDataBit( LED_1_GPIO_PORT, LED_1_GPIO_PIN);
#define LED_2_out GPIO_ReadInputDataBit( LED_2_GPIO_PORT, LED_2_GPIO_PIN);
#define LED_3_out GPIO_ReadInputDataBit( LED_3_GPIO_PORT, LED_3_GPIO_PIN);
#define LED_4_out GPIO_ReadInputDataBit( LED_4_GPIO_PORT, LED_4_GPIO_PIN);
#define LED_5_out GPIO_ReadInputDataBit( LED_5_GPIO_PORT, LED_5_GPIO_PIN);
void Find_Nun_Init(void); //初始化红外循迹模块
#endif
控制.c
#include "bsp_Car_Oper.h"
#include "bsp_em_gpio.h"
#include "bsp_Find_Num.h"
#include "bsp_usart.h"
#include "bsp_SysTick.h"
int LED_1=1,LED_2=1,LED_3=1,LED_4=1,LED_5=1,i=0,status=0;
static int Resources=1;
void Follow_line()//巡线
{
//车上红灯亮为1,灭为0;
//不踩黑线红(1),踩黑线灭(0);
LED_1=LED_1_out;//A
LED_2=LED_2_out;//A
LED_3=LED_3_out;//B
LED_4=LED_4_out;//A
LED_5=LED_5_out;//B
if((LED_1==1)&(LED_5==1))//2、3、4全部压线
{
Car_Fore(Car_Speed_Str);//直行
status=1;
}
if((LED_1==1)&(LED_3==0)&(LED_5==0))//2丢线了,向左转一下
{
Car_CLOCKWISE(Car_Speed_Turn+20);//向左转
status=2;
}
if((LED_1==0)&(LED_3==0)&(LED_5==1))//4丢线了,向右转一下
{
Car_ANTICLOCKWISE(Car_Speed_Turn);//向右转
status=3;
}
//printf("LED_1=%d LED_2=%d LED_3=%d LED_4=%d LED_5=%dn",LED_1,LED_2,LED_3,LED_4,LED_5);
}
void Identify()//模式识别
{
// if((LED_1==0)&(LED_2==0)&(LED_3==0)&(LED_4==0)&(LED_5==0)&(Resources==6))//上坡
// {
// status=6;
// Car_Fore(80);//直行通过
// SysTick_Delay_Ms(4000);
// Resources=7;
// }
if((LED_1==0)&(LED_2==0)&(LED_3==0)&(LED_4==0)&(LED_5==0)&(Resources==5))//第三个重生点
{
status=6;
Car_Fore(30);//直行通过
SysTick_Delay_Ms(1500);
Resources=6;
}
if((LED_1==0)&(LED_2==0)&(LED_3==0)&(LED_4==0)&(LED_5==0)&(Resources==4))//Z_2
{
status=6;
Car_Fore(30);
SysTick_Delay_Ms(300);
Car_ANTICLOCKWISE(Car_Speed_Turn);//右转
SysTick_Delay_Ms(650);
Resources=5;
}
if((LED_1==0)&(LED_2==0)&(LED_3==0)&(LED_4==0)&(LED_5==0)&(Resources==3))//Z_1
{
status=6;
Car_CLOCKWISE(Car_Speed_Turn);//左转
SysTick_Delay_Ms(1700);
Resources=4;
}
if((LED_1==0)&(LED_2==0)&(LED_3==0)&(LED_4==0)&(LED_5==0)&(Resources==2))//第二个重生点
{
status=6;
Car_Fore(30);//直行通过
SysTick_Delay_Ms(1500);
Resources=3;
}
if((LED_1==0)&(LED_2==0)&(LED_3==0)&(LED_4==0)&(LED_5==0)&(Resources==1))//第一个重生点
{
status=5;
Car_Fore(30);//直行通过
SysTick_Delay_Ms(1700);
Resources=2;
}
if((LED_1==0)&(LED_2==0)&(LED_3==0)&(LED_4==0)&(LED_5==0)&(Resources==0))//丁字路口
{
status=4;
Car_Fore(30);//直行一会
SysTick_Delay_Ms(400);
Car_ANTICLOCKWISE(50);//左转一会
SysTick_Delay_Ms(900);
Car_Fore(30);//再直行一会
SysTick_Delay_Ms(1000);
Resources=1;
}
printf("status=%d Resources=%dn",status,Resources);
}
目前存在的问题
1、电池容量太小,调试时候,调试一会供电电压就大幅下降,导致参数的变化,十分不便。
2、整车质量太重、在过坡的时候十分吃力。
3、红外模块受光照影响很大,整体系统不够稳定。
还可以提升的点
1、并没有把电机的编码器这个模块使用上,电机没有闭环。
2、如果可以使用摄像头来巡线,那么整个系统会更加稳定。
举报