前言
1.项目简介
本项目的目的就是解放双手,让购物车跟着人走,
为此需要实现购物车的自动跟随、智能避障、重量显示和自动归位等功能。
2.研究内容
(1) 在购物车上安装蓝牙设备,使用手机蓝牙与该设备建立连接
(2) 使用tof传感器感知障碍物,判断距离并返回数据至STM32
(3) 使用STM32操控和手机驱动和刹车、转向模块,驱动购物车前进、减速和避让。
(4) 使用K210进行停放区域识别,完成购物车的归位。
(5) 使用重量传感器和显示屏完成物品重量显示。
硬件部分
主控介绍
使用 STM32F03C8T6最小系统板
模块介绍
电源模块
电源
使用11.1v航模电池
设计3.3v降压电路
设计5v降压电路
蓝牙模块
使用HC-05,或者HC-06蓝牙模块
如果只是使用手机控制小车,推荐使用大夏龙雀BT-04从机。
Tof10120测距模块
工作电压:3.3V~5V都可以。
最佳距离测量范围:10cm~180cm非常准确。
通讯协议:这个模块支持串口协议和IIC协议。
引脚:
绿色 | SCL |
蓝色 | SDA |
白色 | TX |
黄色 | RX |
红色 | VCC |
黑色 | GND |
软件部分
代码
stm32主控部分
#include "stm32f10x.h" //stm32头文件
#include "usart.h"
#include "uart2.h"
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "OLED.h"
#include "vl53l0x.h"
#include "vl53l0x_gen.h"
#include "X.h"
#include "pid.h"
void CarZ(int16_t PWM);
void CarY(int16_t PWM);
void FangXiang(void);
void Bluetooth(void);
/******************************************************************************/
extern VL53L0X_Dev_t vl53l0x_dev;//设备I2C数据参数
extern uint8_t Serial_RxData3;
float PPP,PWM,i;
float MINPWM=-1000,MAXPWM=1000,PC=350;//PC=350
int32_t error,x,z,BX=120;
int16_t PWMZ=0;
int16_t PWMY=0;
vu16 DS=0;
/******************************************************************************/
PID SpeedPID = {0};
int main(void)
{
static char buf[VL53L0X_MAX_STRING_LENGTH];//测试模式字符串字符缓冲区
VL53L0X_Error Status=VL53L0X_ERROR_NONE;//工作状态
u8 mode=2; //0:默认;1:高精度;2:长距离;3:高速度
// uint16_t a;
/******************************************************************************/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//分组2
uart_init(115200); //串口1
Serial_Init();
delay_init();
LED_Init();
OLED_Init();
PWMX_Init();
IncPIDInit(&SpeedPID);
/******************************************************************************/
delay_ms(200);
if(vl53l0x_init(&vl53l0x_dev)) //vl53l0x初始化
{
// OLED_ShowString(uint8_t Line, uint8_t Column, char *String)
// printf("VL53L0X_Init Error!!!\r\n");
delay_ms(200);
}
else
{
OLED_ShowString(1, 1,"OK");//VL53L0X_Init
}
if(vl53l0x_set_mode(&vl53l0x_dev,mode)) //配置测量模式
{
printf("Mode Set Error!!!\r\n");
}
else
printf("Mode Set OK!!!\r\n");
PWMZ_SetCompare1(PWMZ);
PWMY_SetCompare2(PWMY);
while(1)
{
OLED_ShowNum(1,10,Serial_RxData3-48,2); //显示蓝牙串口3的数据
Bluetooth();//蓝牙控制
if((Serial_RxData3-48)==9)
{OLED_ShowString(4, 1,"DisT:");
OLED_ShowNum(4,7,250,5);}
else
OLED_ShowNum(4,7,500,5);
Status = vl53l0x_start_single_test(&vl53l0x_dev,&vl53l0x_data,buf);//执行一次测量
if(Status==VL53L0X_ERROR_NONE)
{
OLED_ShowString(4, 1,"DisT:") ;
OLED_ShowNum(4,7,Distance_data-60,5);}
else
;
// OLED_ShowString(4, 1,"Measurement is Error!!!") ;
// OLED_ShowString(4, 1,"distance");
DS=Distance_data-200;
if(DS<20)
DS=0;
x=(Get_x()-50)*2.4;//获取x,Get_x()
z = Get_z();
if(x==0)//处理x
{x=120;}
OLED_ShowString(2, 1,"x:") ;
OLED_ShowSignedNum(2, 4,x,3);
OLED_ShowString(3, 1,"z:") ;
OLED_ShowSignedNum(3, 4,(z-1)*100,5);
error=x-BX;//本次误差
OLED_ShowSignedNum(1,4,error,5);
if(error<=+70 && error>=-70)
{if(((z-1)*100)>500)
{
CarZ((z-1)*70);
CarY((z-1)*70);}
else
{
CarZ(0);
CarY(0);}
}
else
FangXiang();
}
}
/***************************************************************************/
/***************************************************************************/
void FangXiang(void)
{
PWMZ=0;
PWMY=0;
SpeedPID.LLastError=SpeedPID.LastError;//上上次误差
SpeedPID.LastError=error;//上次误差
SpeedPID.SumError+=error;
PPP=LocP_DCalc(&SpeedPID,x,BX);
PWM=PPP/0.12;
// OLED_ShowSignedNum(2, 5,PWM,3);
if(PWM<0)//数据处理,让PC和PWM同号
{if(PC>0)
{
PC*=-1;
}
}
if(PWM>0)//数据处理,让PC和PWM同号
{if(PC<0)
{
PC*=-1;
}
}
PWMY=PWM+PC;//同号相加得到最终pwm
PWMZ=-(PWM+PC);
if(PWMY>MAXPWM)
{PWMY=MAXPWM;
}
else if(PWMY<MINPWM)
{PWMY=MINPWM;
}
if(PWMZ>MAXPWM)
{PWMZ=MAXPWM;
}
else if(PWMZ<MINPWM)
{PWMZ=MINPWM;
}
CarZ(PWMZ);
CarY(PWMY);
}
void CarZ(int16_t PWM)
{
if(PWM>0)
{
GPIO_SetBits(GPIOB,GPIO_Pin_12);
GPIO_ResetBits(GPIOB,GPIO_Pin_13);
PWMZ_SetCompare1(PWM);
}
else if(PWM<0)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_12);
GPIO_SetBits(GPIOB,GPIO_Pin_13);
PWMZ_SetCompare1(-PWM);
}
else if(PWM==0)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_12);
GPIO_ResetBits(GPIOB,GPIO_Pin_13);
PWMZ_SetCompare1(0);
}
}
void CarY(int16_t PWM)
{
if(PWM>0)
{
GPIO_SetBits(GPIOB,GPIO_Pin_14);
GPIO_ResetBits(GPIOB,GPIO_Pin_15);
PWMY_SetCompare2(PWM);
}
else if(PWM<0)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_14);
GPIO_SetBits(GPIOB,GPIO_Pin_15);
PWMY_SetCompare2(-PWM);
}
else if(PWM==0)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_14);
GPIO_ResetBits(GPIOB,GPIO_Pin_15);
PWMY_SetCompare2(0);
}
}
void Bluetooth(void)
{
if((Serial_RxData3-48)==1)
{ CarZ(400);
CarY(400);
}
if((Serial_RxData3-48)==2)
{ CarZ(-400);
CarY(-400);
}
if((Serial_RxData3-48)==3)
{ CarZ(-400);
CarY(400);
}
if((Serial_RxData3-48)==4)
{ CarZ(400);
CarY(-400);
}
if((Serial_RxData3-48)==9)
{ CarZ(0);
CarY(0);
}
}
注意
本篇文章并不完整,内容还在完善中!!!