系列文章目录

一、小车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)链接---->蓝牙小车完整工程(设置了收费望理解)


总结

好了,遇到问题就及时解决,想到什么就动手去做
最后谢谢隔壁老王的好点子

欢迎大家积极交流,本文未经允许谢绝转载!!!

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐