【平衡小车制作】(八)蓝牙遥控及平衡成果展示(超详解)

  大家好,我是小政。本篇文章我将针对蓝牙遥控平衡小车进行详细的讲解,让每位小伙伴能够通过手机APP和蓝牙模块实现对平衡小车的控制。

一、蓝牙初始化

1.串口3初始化函数——usart3.c
  这一串代码很容易理解,就是通过串口3与蓝牙连接,手机连接蓝牙将信息发送给蓝牙模块,再传至STM32获取控制信息。

#include "usart3.h"	 

void uart3_init(u32 bound)
{
	//GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);   // 时钟GPIOB,USART3
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
  
  //USART3_TX   PB.10
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	//USART3_RX	  PB.11
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB, &GPIO_InitStructure);  
	//USART 初始化设置
	USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	
  USART_Init(USART3, &USART_InitStructure);
	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启中断
	USART_Cmd(USART3, ENABLE);                    //使能串口 
}

/*
0x00:刹车
0x01:前进
0x02:后退
0x03:左转
0x07:右转
*/
u8 Fore,Back,Left,Right;
void USART3_IRQHandler(void)                	    // 串口1中断服务程序
{
  int Bluetooth_data;
  if(USART_GetITStatus(USART3,USART_IT_RXNE)!=0)  // 接收中断标志位拉高
  {
    Bluetooth_data=USART_ReceiveData(USART3);     // 保存接收到的指令
    if(Bluetooth_data==0x00)Fore=0,Back=0,Left=0,Right=0; // 刹车
    else if(Bluetooth_data==0x01)Fore=1,Back=0,Left=0,Right=0; // 前进
    else if(Bluetooth_data==0x05)Fore=0,Back=1,Left=0,Right=0; // 后退
    else if(Bluetooth_data==0x03)Fore=0,Back=0,Left=1,Right=0; // 左转
    else if(Bluetooth_data==0x07)Fore=0,Back=0,Left=0,Right=1; // 右转
    else                    Fore=0,Back=0,Left=0,Right=0;
  }
}

// 发送一个
void USART3_Send_Data(char data)
{
  USART_SendData(USART3,data);
  while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==0);  // 除非发送完成  
}

// 发送一串
void USART3_Send_String(char *String)
{
  u16 len,j;
  len=strlen(String);
  for(j=0;j<len;j++)
  {
    USART3_Send_Data(*String++);
  }
}

2.串口3头文件——usart3.h

#ifndef __USART_H
#define __USART_H
#include "sys.h" 

void uart3_init(u32 bound);
void USART3_IRQHandler(void);  
void USART_Send_Data(char data);
void USART_Send_String(char *String);
#endif

二、转向环控制

  转向环约束控制,引入RC,不是严格的PD控制器,Kd针对的是转向环的约束,但Kp针对的是遥控的转向。

float 
  Turn_Kd=-0.6,
  Turn_Kp=-20;
  
/*****************  
转向环:系数*Z轴角速度+系数*遥控数据
******************/
int Turn(int gyro_Z,int RC)
{
  int PWM_out;
  
  // 不是严格的PD控制器,Kd针对的是转向环的约束,但Kp针对的是遥控的转向
  PWM_out = Turn_Kd*gyro_Z+Turn_Kp*RC;
  
  return PWM_out;
}

三、修改控制函数

1.二次开发接口引入

float Target_Speed=0;     // 期望速度。---二次开发接口,用于控制小车前进后退及其速度。
float Turn_Speed=0;       // 左右遥控数据

  19行至37行是控制函数编写,这一块应该比较容易理解。当对应标志位置1时,进行对应的操作,同时还需进行限幅,防止超过PWM规定范围。

void EXTI9_5_IRQHandler(void)
{
  int PWM_out;
  if(EXTI_GetITStatus(EXTI_Line5)!=0) // 一级判定
  {
    if(PBin(5)==0)    // 二级判断
    { 
      EXTI_ClearITPendingBit(EXTI_Line5); // 清除中断标志位
      // 1.采集编码器数据&MPU6050角度信息
      // 电机是相对安装,刚好相差180度,为了编码器输出极性一致,就需要对其中一个取反
      Encoder_Left  = -Read_Speed(2); 
      Encoder_Right = Read_Speed(4);
      
      mpu_dmp_get_data(&Pitch,&Roll,&Yaw);	    // 读取角度
      MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz);  // 读取角速度
      MPU_Get_Accelerometer(&aacx,&aacy,&aacz); // 读取加速度
      // 2.将数据压入闭环控制中,计算出控制输出量
			
      /*前后*/
      if((Fore==0)&&(Back==0))Target_Speed=0;   // 未接收到前进后退指令->速度清零,稳在原地
      if(Fore==1)Target_Speed++;  // 前进标志位为1->需要前进
      if(Back==1)Target_Speed--;  // 后退标志位为1->需要后退 
      Target_Speed=Target_Speed>SPEED_Y?SPEED_Y:(Target_Speed<-SPEED_Y?(-SPEED_Y):Target_Speed);  // 限幅
      
      /*左右*/
      if((Left==0)&&(Right==0))Turn_Speed=0;
      if(Left==1)Turn_Speed++;   // 左转标志位为1->需要左转
      if(Right==1)Turn_Speed--;  // 右转标志位为1->需要右转
      Turn_Speed=Turn_Speed>SPEED_Z?SPEED_Z:(Turn_Speed<-SPEED_Z?(-SPEED_Z):Turn_Speed);          // 限幅
      
      /*转向约束*/
      if((Left==0)&&(Right==0))Turn_Kd=-0.6;    // 若无左右转向指令,则开启转向约束
      else if((Left==1)||(Right==1))Turn_Kd=0;  // 若左右转向指令接收到,则去掉转向约束
      
      Velocity_out=Velocity(Target_Speed,Encoder_Left,Encoder_Right); // 速度环
      Vertical_out=Vertical(Velocity_out+Med_Angle,Roll,gyrox);			  // 直立环
	  Turn_out=Turn(gyroz,Turn_Speed);	
      
      PWM_out=Vertical_out;//最终输出
      
      // 3.把控制输出量加载到电机上,完成最终控制
      MOTO1 = PWM_out-Turn_out; // 左电机
      MOTO2 = PWM_out+Turn_out; // 右电机
      Limit(&MOTO1,&MOTO2);     // PWM限幅
      Load(MOTO1,MOTO2);        // 加载到电机上
    }
  }
}     

四、主函数

  在主函数中初始化串口3函数。

#include "stm32f10x.h"
#include "sys.h" 

int PWM_MAX=7200,PWM_MIN=-7200;	// PWM限幅变量
int MOTO1,MOTO2;

float Pitch,Roll,Yaw;	          // Pitch:俯仰角,Roll:横滚角,Yaw:偏航角
short gyrox,gyroy,gyroz;        // 角速度
short aacx,aacy,aacz;           // 加速度
int Encoder_Left,Encoder_Right; // 编码器数据(速度)

int main(void)	
{
	delay_init();
	NVIC_Config();
	uart1_init(115200);
	uart3_init(9600);
  	USART3_Send_String("AT+NAME hc_05_sxwl \r\n");
	OLED_Init();
	OLED_Clear();
	
	MPU_Init();
	mpu_dmp_init();
	MPU6050_EXTI_Init();
	
	Encoder_TIM2_Init();
	Encoder_TIM4_Init();
	Motor_Init();
	PWM_Init_TIM1(0,7199);
  	while(1)	
	{
		OLED_Float(0,0,Roll,3);
	} 	
}

五、展示

蓝牙遥控部分代码完成后实物展示如下:

平衡小车(蓝牙遥控)

六、总结

(1)硬件原理图+程序+蓝牙APP:
网址:https://pan.baidu.com/s/1EVBBazPzmtm6Gd-0m8nLGA
提取码:1234

  本篇文章是平衡小车(蓝牙遥控)系列的拓展教学,平衡小车一系列文章到这里也就告一段落了,感谢大家观看与支持,之后小政还会推出一系列嵌入式学习文章,与大家一起讨论学习进步。

声明:该设计资料转自lb8820265网友分享,仅供学习参考,不可用于商业用途。 继电路城之前该小车资料, 手机遥控蓝牙平衡小车V1资料全部开源(https://www.cirmall.com/circuit/6201/detail?3), 现介绍该蓝牙平衡小车V1.1(BlueNRG+虚拟摇杆)开源设计(https://www.cirmall.com/circuit/6202/detail?3)。 前面介绍了基于CC2541的蓝牙模块平衡小车,之前BlueNRG由于损坏所以才采用CC2541,这次又得到了一块BlueNRG,现在集齐三块ST的模组可以召唤神龙了,之前预留了BlueNRG的6个接口,所以只需要直接将扩展板插在传感器板上就可以了,然后再增加一点高度。 这里主要是虚拟的摇杆的实现,详细“相关文件”下载 视频演示: CC2541模块厂家已经写好相关代码使其变成一个透传模块,而BlueNRG是需要自己写好代码的,不过好在ST已经有了例程,而且也是使用STM32F4来驱动,这就大大的方便了开发,BlueNRG相关工具和软件下载地址:https://www.st.com/web/en/catalog/tools/PF261442点击最下面download。 进入X-CUBE-BLE1\Projects\Multi\Applications\SampleApp,这是一个简单的使用蓝牙对话的例程,可以直接烧到STM32F411板子中查看效果,打开手机蓝牙搜索,可以搜索到BlueNRG_Chat的蓝牙,连接就后可以发送和接收数据了,查看工程中的代码也是十分简单的,有详细的注释,初始化之后,就是两个函数HCI_Process()与User_Process(),第一个函数用来处理各种事件,第二个是用户函数里面是一个监听按键并发送的函数。 数据的收取主要是在ample_service.c中case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED:和case EVT_BLUE_GATT_NOTIFICATION:两个事件中,第一个用来接收数据,第二个用来接收通知信息。 另一个重要的改进是添加了虚拟摇杆,可以在虚拟摇杆与SEEKBAR之间切换,同时简化了界面,如下图所示: 更新:修复复杂环境下搜索BLE崩溃BUG, 采用JUMA SDKAndroid源代码:https://github.com/flyloong/NUCLEO_Balance_Car_Android STM32F411源代码:https://github.com/flyloong/NUCLEO_Balance_Car_STM32
声明:该设计资料转自lb8820265网友分享,仅供学习参考,不可用于商业用途。 手机遥控蓝牙平衡小车概述: 蓝牙平衡玩具小车,具有的功能有:手机APP虚拟遥感控制模式,自动行走避障模式,碰撞自动后退,倒下自动停止,预警模式,跳舞模式,说话,语音表情,压强播报,温度播报,湿度播报,前方障碍物距离播报,PC上位机无线调参,示波器显示,3D姿态显示。是集趣味性,智能性,易操作性,可研究性于一体的蓝牙平衡小车。 视频演示: 采用的硬件如下: 处理器: Nucleo STM32F411核心板 传感器模块: Nucleo IKS01A1(包括陀螺仪,加速度计,磁力计,温度计,湿度计,压强计) 蓝牙模块: CC2541 蓝牙4.0模块 无线模块: NRF24L01+模块 电机驱动模块: BT6612模块 测距模块: 夏普2Y0A21红外测距模块 舵机: SG90模拟舵机 语音模块: SYN6658语音模块 电池: 狮子11.1V 2200mAh 电源: LM2596电源模块 电机: 诗凯支架自带,3530直流减速电机 光电编码器: 电机自带,13440线每轮转,AB相输出 手机: 魅族MX3 上位机接收端: MSP430G2553核心板 电脑: 这个随意 整个系统的硬件拆解图图下图所示: 整个系统可大致分为4个部分,分别是:小车部分,上位机接收机,PC上位机,安卓手机控制端。 4个部分的关系如下图所示: 其中以平衡小车为中心,能将信息通过无线发送给上位机接收端,上位机接收端再将数据通过串口的形式发送给PC上位机。同时上位机亦可以发送调参与控制指令给上位机接收端,上位机接收端再将信息发送给平衡小车。安卓APP也能通过蓝牙传输信息给CC2541模块,将信息通过串口的形式发送给平衡小车进行控制。 编写的软件如下: 小车: 采用IAR7.3编写 上位机接收端: 采用CCS5.1编写 上位机: 采用VC6.0 MFC编写 手机APP: 采用Android studio 1.2.2编写 手机APP 之前的帖子已经讲了,如何实现蓝牙4.0的收发,那么接下来就是通信协议的制定与界面的编辑了, 下图是手机APP的截图: PC上位机端 上位机采用VC6.0编写,PC上位机主要是用来进行参数调整、虚拟示波器显示波形、3D姿态显示。下图是上位机截图。采用MSComm串口控件进行数据的发送与接收。能够进行端口扫描,并连接串口,实现数据发送,错误显示,实现了4个整形数字与4个浮点数的调整,并且能够读取系统的原始数据,显示发送状态,且能够显示信号强弱,同时能够进行示波器显示,调节显示间隔。 由于采用的是NRF24L01+带数据的ACK模式进行数据传输,所以上位机不发送数据的时候,小车并不会发送回来,所以上位机能够掌握显示数据的间隔。示波器采用的IPlot控件,能够实现4个数据波形显示,且能够让任意一组数据显示、实现轴的缩放、在顶端显示数值。3D姿态显示采用的是OpenGL库,画出小车模型,设置为半透明,能实时清晰的显示小车的姿态。 PC上位机示波器显示紧挨着3D姿态显示亲热照! 蓝牙平衡玩具小车全家福!
评论 152
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鲁乎乎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值