此項目是基于STM32F103ZET6來開發的物流循迹小車
-
- 項目緣由
- 項目選型
- 場地地圖及比賽任務簡述
- 硬體設計
- 設計思路
- 部分代碼
- 目前存在的問題
- 還可以提升的點
- 作者的話
項目緣由
這個項目是在大三上學期自己專業主辦的“機甲大師”物流搬運校級比賽來制作的,由我和三位大四的學長合作完成。
項目選型
僅供參考
-
車身 ,使用平衡小車之家的一款自帶車體和4個麥克納姆輪的套餐。
連結: link.
(不需要PS2搖桿,巡線配置都不需要,麥輪直徑60mm)
-
主要 ,STM32F103ZET6最小系統闆,不是很推薦我使用的這塊,顔值不高。
連結如下: link.
(不加SRAM)
-
電機驅動 ,WINGXINE阿裡風斯的一款H橋雙驅,電機驅動超級好用。
連結如下link.
-
無順序列槽 ,選擇的逐飛科技的無順序列槽,半雙工。主要是喜歡即插即用。
連結如下: link.
(整套套件各一個)
-
機械臂 ,這個爪子真的超級不推薦,放出連接配接就是給大家避坑。
連結如下: link.
(黑色B款爪子)
場地地圖及比賽任務簡述

比賽任務需要從啟動區出發,前往資源區拿取乒乓球,再去資源整合區将不同顔色的乒乓球分類放置,然後小車停在目标區。
硬體設計
值得一談的就是電源部分的設計,其餘主要和電機驅動部分的設計,本質上隻是進行相應的線路連接配接,僅此而已。
下面我好好聊一下這次的電源設計。
1、一開始的方案是,使用一塊實驗室就有的航模電池(權盛電子,5200毫安時,11.1V電壓輸出,白嫖實驗室的,沒有産品連接配接),使用LM2940-5.0穩壓到5V給電機驅動供電,再由5.0V使用LM1117-3.3穩壓為3.3V給單片機供電。
遇到的問題是,當電機占空比給到50%,長時間的運作會導緻LM2940過熱自動保護。
2、改進的方法,使用以前的一塊電池直接替換,做過智能車的都懂(香山紅葉,輸出7.2V,2000毫安時鎳鉻電池)
連結如下: link.
設計思路
使用紅外子產品循迹,(紅外子產品是實驗室白嫖的,上面沒有任何型号的标注,沒有連結;注:五路紅外,無電位器調節門檻值),使用實驗室的舵機和自己買的機械爪搭接一個機械臂來執行乒乓球的抓取,使用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=%d\n",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=%d\n",status,Resources);
}
目前存在的問題
1、電池容量太小,調試時候,調試一會供電電壓就大幅下降,導緻參數的變化,十分不便。
2、整車品質太重、在過坡的時候十分吃力。
3、紅外子產品受光照影響很大,整體系統不夠穩定。
還可以提升的點
1、并沒有把電機的編碼器這個子產品使用上,電機沒有閉環。
2、如果可以使用攝像頭來巡線,那麼整個系統會更加穩定。
作者的話
第一次寫部落格,格式和内容的輸出上可能會有一些問題,希望大家多多包容。
最近經曆電賽校賽和省賽再加上這次的機甲大師後,内心十分的“窩囊”。
現在迫切想做一個項目來證明自己。
GitHub項目位址
簡單上傳了最終版,沒有下載下傳測試。