STM32方位感知操控蓝牙小车(stm32f103c8t6/HAL库/mpu6050+双蓝牙透传)
**手柄方向感知操控**可以简单理解为向前倾--->小车前进,后倾--->小车后退,左倾--->小车左转,右倾--->小车右转,水平放置时--->小车停止。
系列文章目录
一、小车1.0——基本蓝牙小车(仅蓝牙遥控小车运动方向,本篇)
二、小车2.0——蓝牙小车PLUS(可以蓝牙控制方向+蓝牙直接调节车速)
三、小车3.0——避障小车(超声波+舵机云台)
四、小车4.0——无线手柄方向感知操控小车(mpu6050+双蓝牙透传)
五、双轮自平衡小车(HAL库版)——点此学习吧
建议:阅读这篇文章前最好先看看系列文章里的小车1.0
完整工程(CubeIDE)链接---->蓝牙小车完整工程(设置了收费望理解)
文章目录
前言
本文将介绍手柄方向感知操控小车,其实我也不知道取什么名字好 ,所谓手柄方向感知操控可以简单理解为向前倾—>小车前进,后倾—>小车后退,左倾—>小车左转,右倾—>小车右转,水平放置时—>小车停止。
提示:本文仅介绍方向感知操控手柄的相关代码以及原理,小车部分其实就是基本的蓝牙小车,关于小车部分的代码可以点击系列文章目录中的小车1.0
先放个图,视频等剪辑好了再说吧。。。
方位感知遥控蓝牙小车
一、前期准备
需要准备
STM32F103C8T6———————— 2个
12V电池 ————————————1个
9V电池 ——————-—————— 1个(这个只要能供5V或3.3V就行)
L298N电机驱动 —————————2个
小车底座———————————— 1个
稳压模块或者可调降压模块———— 2个
蓝牙模块HC-08————————— 2个
mpu6050(GY-521)————————1个
二、蓝牙配置
想要方向感知操控手柄与蓝牙小车实现通信,第一个想到的便是用蓝牙模块实现,在选择蓝牙模块的时候一定要选择一主一从,选择HC-08的原因是:它是主从一体的蓝牙,只需要设置一个HC-08为主机,另一个为从机,以及相同的波特率,即可实现蓝牙间的数据交换,而且是透传(透传即不再区分主机与从机),之后再次开启蓝牙会自动秒连。
下面讲一下设置:
因为由于HC-08蓝牙芯片默认状态为从机且波特率为9600Bits/s,所以只需要将手柄上的HC-08进行AT指令设置为主机即可,如下
具体操作:
1、将手柄上的HC-08与USB转TTL模块正确连接后接入PC;
2、通过串口调试助手完成AT指令的输入;(把串口助手的“发送新行”取消勾选)
3、先检查串口是否正常工作,串口助手发送区输入AT(ASCII码输入),若返回 OK,进入下一步,否
则,检查芯片是否损坏,连线是否正确;
4、检测到串口正常工作后,键入AT+ROLE=M,若返回OK,则表明已经成功将其设为主机。
5、再将两个HC-08的LUUID、SUUID、TUUID三个设置为相同,即可进行配对。指令为:AT+LUUID=1234、AT+SUUID=1234、AT+TUUID=1234(参数为十六进制,必须在0~F范围内)
具体的AT指令集和相关操作可以参考——>汇承HC-08蓝牙模块间配对
三、原理图
手柄原理图:
手柄实物图:
四、Cube MX中的配置
4.1. 时钟树的配置
(1)点击RCC ,开启HSE,并选择RC或晶体作为时钟源
(2)配置时钟树
4.2. USART2的设置
目的是控制手柄的蓝牙发送数据
,因为只是利用串口发送数据,所以USART2的设置不需要开启串口中断
(1)点击Connectivity–>USART2,开启异步模式(Asynchronous)
(2)Parameter Settings的参数设置
4.3. I2C1 的设置
4.4. SYS的设置
我用的是SWD模式,这个看你自己的烧录模式,如果是用串口进行烧录那就可以忽略这步设置。
最终引脚配置图:
五、代码
这里给出了main.c的代码以及部分我改动的mpu6050测试代码,关于mpu6050测量欧拉角的代码我是直接移植的官方DMP库。
官方DMP库的移植方法参考这篇博客——>MPU6050官方DMP的HAL库版移植
5.1. 整体框架
5.2. DMP中改动部分
提示:改动部分是在DMP_test.c中修改了一开头的部分和最后一个 DMP_test(void)函数,以及在DMP文件中又添加了DMP_test.h
DMP_test.c改动代码
1.修改了DMP_test.c一开始的.h文件
#include "DMP_test.h"
float pitch,roll,yaw=0; //欧拉角
2.修改了DMP_test(void)函数
void DMP_test(void)
{
unsigned char i;
HAL_Delay(500);
//由MPU6050的官方DMP库说明,初始化时,必须使得z轴与竖直方向平行
//z轴向上活着向下都可以
//mpu_dmp_init()为mpu6050,dmp初始化,返回值:0,正常;其他,失败
i = mpu_dmp_init();
while(i)
{
HAL_Delay(500);
i = mpu_dmp_init();
printf("MPU6050 init error:%d\r\n",i);
}
printf("MPU6050 init OK\r\n");
}
添加DMP_test.h
DMP_test.h代码
#ifndef DMP_DMP_TEST_H_
#define DMP_DMP_TEST_H_
#include "stm32f1xx_hal.h"
#include <stdio.h>
#include "main.h"
#include "math.h"
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"
#define q30 1073741824.0f //q30格式,long转float时的除数.
#define DEFAULT_MPU_HZ 200
extern float pitch,roll,yaw; //欧拉角
unsigned char run_self_test(void);
unsigned short inv_orientation_matrix_to_scalar(const signed char *mtx);
unsigned short inv_row_2_scale(const signed char *row);
void mget_ms(unsigned long *time);
unsigned char mpu_dmp_init(void);
unsigned char mpu_dmp_get_data(float *pitch,float *roll,float *yaw);
void DMP_test(void);
#endif /* DMP_DMP_TEST_H_ */
5.3. main.c
/* USER CODE BEGIN Includes */
#include "../../icode/DMP/DMP_test.h"
/* USER CODE END Includes */
/* USER CODE BEGIN 1 */
uint8_t USART2_TX_BUF[4]={0xA5,0x00,0xFF,0x5A};
//先定义一个数组,里面存放着数据包,数据包结构是由4个数据组成,即包头、原数据、校验码、包尾各一个字节,后续只用改变原数据和校验码发送不同数据给蓝牙小车
/* USER CODE END 1 */
/* USER CODE BEGIN 2 */
DMP_test();
/* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0)
/*pitch:俯仰角 精度:0.1° 范围:-90.0° <---> +90.0°, 向前向后倾,改变了俯仰角的值
roll:横滚角 精度:0.1° 范围:-180.0°<---> +180.0°,向左向右倾,改变了横滚角的值
yaw:航向角 精度:0.1° 范围:-180.0°<---> +180.0°,这个暂时不用
*/
{
if(pitch>30)//俯仰角大于30°,这里角度的值可以自己设定,其绝对值越小越灵敏
{
USART2_TX_BUF[1]=0x01;//小车前进
USART2_TX_BUF[2]=USART2_TX_BUF[1]%0x100;
HAL_UART_Transmit(&huart2, (uint8_t *)USART2_TX_BUF,4,0xFFFF);
}
else if(pitch<-30)//俯仰角小于-30°
{
USART2_TX_BUF[1]=0x04;//小车后退
USART2_TX_BUF[2]=USART2_TX_BUF[1]%0x100;
HAL_UART_Transmit(&huart2, (uint8_t *)USART2_TX_BUF,4,0xFFFF);
}
else if(roll<-30)//横滚角小于-30°
{
USART2_TX_BUF[1]=0x02;//小车左转
USART2_TX_BUF[2]=USART2_TX_BUF[1]%0x100;
HAL_UART_Transmit(&huart2, (uint8_t *)USART2_TX_BUF,4,0xFFFF);
}
else if(roll>30)//横滚角大于30°
{
USART2_TX_BUF[1]=0x03;//小车右转
USART2_TX_BUF[2]=USART2_TX_BUF[1]%0x100;
HAL_UART_Transmit(&huart2, (uint8_t *)USART2_TX_BUF,4,0xFFFF);
}
else
{
USART2_TX_BUF[1]=0x00;//小车停止
USART2_TX_BUF[2]=USART2_TX_BUF[1]%0x100;
HAL_UART_Transmit(&huart2, (uint8_t *)USART2_TX_BUF,4,0xFFFF);
}
}
}
/* USER CODE END 3 */
完整工程(CubeIDE)链接---->蓝牙小车完整工程(设置了收费望理解)
总结
好了,遇到问题就及时解决,想到什么就动手去做
最后谢谢隔壁老王的好点子
欢迎大家积极交流,本文未经允许谢绝转载!!!
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)