基于stm32f4的蓝牙控制小车

news2024/10/2 8:22:33

1.    引言


蓝牙的创始人是瑞典爱立信公司,蓝牙技术是一种无限数据与语音通信的开放性全球规范,它以低成本的近距离无线连接为基础,为固定与移动设备通信环境建立一个特别连接。手机之间通过蓝牙实现数据共享成为常理,将手机变为遥控器为人们的生活带来无限方便。遥控小车在工业、国防、科研等领域应用越来越广泛,例如说:消防遥控小车、探测小车等。本文详细阐述了使用蓝牙通信的手机遥控小车前行、倒退、左转、右转和停止等功能的软硬件设计过程。


2.    系统方案 


该系统分为电机驱动模块、电源管理模块、主控板、蓝牙通信模块、android控制端等5个模块
 

3、系统硬件设计

3.1 电机驱动模块

3.1.1 L298N的封装

H 桥电路虽然有着诸多的优点,但是在实际制作过程中,由于元件较多,电路的搭建也较为麻烦,增加了硬件设计的复杂度。

由于H 桥电路有诸多的优点,但是在实际制作过程中电路又比较麻烦,因此在本设计中我们采用H 桥集成电机驱动芯片L298。L298N 的工作原理和以上介绍的H 桥相同,引脚图如图:

3.1.2 L298N的原理图设计

L298N 是ST 公司生产的一种高电压、大电流电机驱动芯片。该芯片采用15 脚封装。主要特点是:工作电压高,最高工作电压可达46V;输出电流大,瞬间 峰值电流可达3A,持续工作电流为2A;额定功率25W。内含两个H 桥的高电压大电流全桥式驱动器,可以用来驱动直流电动机和步进电动机、继电器线圈等感性负载;采用标准逻辑电平信号控制;具有两个使能控制端,在不受输入信号影响的情况下允许或禁止器件工作有一个逻辑电源输入端,使内部逻辑电路部分在低电 压下工作;可以外接检测电阻,将变化量反馈给控制电路。使用L298N 芯片驱动电机,该芯片可以驱动一台两相步进电机或四相步进电机,也可以驱动两台直流电机。L298 的参考电路图如图 

3.1.3 电机驱动模块实物 

1、控制板内部带5V逻辑电平转换芯片,不需要额外的5V供电。

2、如果EN1、EN2、EN3、EN4不接PWM调速信号,次脚需要和对应的管教短接。

3、GND和12V接电机电源,其中12V可以接7V--24V电平,板子上的电源开关只是控制逻辑5V电平的开关,L298的12V电源不受此开关控制.

4、输出端和输入端一一对应,当输入端为5V时,输出端也为高电平,输入端为低电平时输出亦为低电平。

电源管理模块

3.2.1 智能车电源设计要点

电源是整个系统稳定工作的前提,因此必须有一个合理的电源设计,对于小车来说电源设计应

注意两点:

1. 与一般的稳压电源不同,小车的电池电压一般在6-8V 左右,还要考虑在电池损耗的情况下电压的降低,因此常用的78 系列稳压芯片不再能够满足要求,因此必须采用低压差的稳压芯片,在本文中以较为常见的LM2940-5.0 为例。

2. 单片机必须与大电流器件分开供电,避免大电流器件对单片机造成干扰,影响单片机的稳定运行。

现在各种新型的电源芯片层出不穷,各位读者可以根据自己的需求自行选择电源芯片,对于本设计应该主要注意稳压压差和最大输出电流两个指标能否满足设计要求。

3.2.2 低压差稳压芯片LM2940 简介

LM2940 系列是输出电压固定的低压差三端端稳压器;输出电压有5V、8V、10V 多种;最大输出电流1A;输出电流1A 时,最小输入输出电压差小于0.8V;最大输入电压26V;工作温度-40~+125℃;

内含静态电流降低电路、电流限制、过热保护、电池反接和反插入保护电路。同时LM2940 价格适中而且较容易购买,非常适合在本设计中使用。LM2940-5.0 封装和实物如图3.4所示。

 如图3.5所示,采用两路供电,这样可以使用其中一路单独为STM32F4discovery电路板供电,指示灯等供电。另外一路提供L298N、舵机、蓝牙的工作电压,L298N 的驱动电压由电池不经任何处理直接给出。舵机可以用6V 供电,也可以直接用5V 供电。

 

 PCB图

图3.7 是运用腐蚀液自制的电源管理模块,具有12v\5v的供电模块,可同时给电机模块和主控板(STM32DISCOVERY)供电: 

4、系统软件设计

4.1 主控板程序设计

4.1.1 main程序设计

主函数主要分为延迟时间初始化、串口接收模块程序、电机初始化三部分。主函数的流程图如图4.1所示:

主函数程序代码如下:

int main(void)

{  

    delay_init(168);//延迟时间初始化

    uart_init(9600);//串口初始化

    Direction(1);//电机初始化

    delay_ms(10);//延迟10ms

    printf(" welcome to control the smart car!:\n\r");//输入语句

    while(1);

}

4.1.2 串口接收模块程序

主控板接收到蓝牙从串口传来的数据后存入Res变量,然后通过分支程序来选择执行前进、后退、左转、右转和停止等功能。该模块的程序流程图如图2所示:

4.1.3 修改PWM输出值程序

该程序是基于“4_PWM的实现”中的程序改编的。代码如下:
void Change_PWM(int duty1,int duty2,int duty3,int duty4)
{
	SCB->AIRCR=0x05AF00;// 中断优先级分组 抢占:响应=3:1  
  RCC->AHB1ENR|=(1<<2);// 打开GPIOC时钟
  GPIOC->MODER|=0x000AA000;// pc6789第二功能,推挽输出
  GPIOC->OSPEEDR|=0x000FF000;//输出速度为100m
  GPIOC->PUPDR|=0x00055000;//上拉
  
  GPIOC->AFR[0]|=0x22000000;//pc6789的第二功能为AF2
  GPIOC->AFR[1]|=0x00000022;
  
  RCC->APB1ENR|=(1<<1);//打开TIM3时钟
  TIM3->PSC=83;//对84M时钟进行84分频,使得计数频率为1M
  TIM3->ARR=10000;//周期为10ms
  TIM3->EGR|=1;//产生一次更新时间
  
  TIM3->CCMR1|=0x6060;//PWM模式1
  TIM3->CCMR2|=0x6060;//PWM模式2
  
  TIM3->CCR1=duty1;//1路PWM
  TIM3->CCR2=duty2;//2路PWM
  TIM3->CCR3=duty3;//3路PWM
  TIM3->CCR4=duty4;//4路PWM
  
  TIM3->CCER|=0x1111;//使能比较输出
  
  TIM3->CCMR1|=0x0808;//启动预装载
  TIM3->CCMR2|=0x8080;
  
  TIM3->CR1|=1;//开始计时
}

4.1.4 设置电机转向程序

改程序将电机驱动模块的8个输入端口接到了主控板的8个GPIO口,通过推挽输出,从而控制电机的转向,代码如下:

void Direction(int direction)
{
SysTick_Config(SystemCoreClock / 1000); //时钟中断设为1ms
 	RCC->AHB1ENR |= 0x00000005; //使能GPIOA和GPIOD时钟
    RCC->APB2ENR |= (1<<14);  //使能syscfg时钟
if(direction==0)
{
   GPIOA->MODER &= 0xffff0000; //设置PA0,1,2,3为输出
   GPIOA->MODER |= 0x00005555; 
   GPIOA->OTYPER &= 0xFFFFff00; //设置PA0,1,2,3为推挽输出
   GPIOA->OSPEEDR &= 0xffff0000; //设置PA0,1,2,3的输出速度为100M
   GPIOA->OSPEEDR |= 0x0000ffff;
   SYSCFG->CMPCR = 0x00000001; //使用IO补偿单元
   GPIOA->PUPDR &= 0xffffff00;  //设置PA0,1,2,3无上拉,无下拉
   GPIOA->BSRRH = 0x00ff;  //复位GPIOA_BSRRH寄存器
   GPIOA->BSRRL = 0x0055;		
	 }
	else
	{
GPIOA->MODER &= 0xffff0000; //设置PA0,1,2,3为输出
   GPIOA->MODER |= 0x0000005555; 
   GPIOA->OTYPER &= 0xFFFFff00; //设置PA0,1,2,3为推挽输出
   GPIOA->OSPEEDR &= 0xffff0000; //设置PA0,1,2,3的输出速度为100M
   GPIOA->OSPEEDR |= 0x0000ffff;
   SYSCFG->CMPCR = 0x00000001; //使用IO补偿单元
   GPIOA->PUPDR &= 0xffffff00;  //设置PA0,1,2,3无上拉,无下拉
   GPIOA->BSRRH = 0x00ff;  //复位GPIOA_BSRRH寄存器
   GPIOA->BSRRL = 0x00AA;
}
}

4.2 android客户端程序设计

4.2.1 控制界面的布局

控制界面主要运用了线性布局、相对布局和表格布局。整体采用线性布局,局部采用相对布局,而控制按钮采用了表格布局。控制界面的布局如图4.1所示:

4.2.2 布局的代码如下: 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
<RelativeLayout 
   android:id = "@+id/container"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <RelativeLayout
	  android:layout_width="fill_parent"
	  android:layout_height="wrap_content"
	  android:id= "@+id/edit_bottombar"
	  android:layout_alignParentBottom = "true">
     <Button android:id="@+id/btn_disconnect"
			android:layout_width="65dp" 
			android:layout_height="wrap_content"  
			android:layout_alignParentLeft ="true"
			android:text="断开"/> 
		<Button android:id="@+id/btn_msg_send"
			android:layout_width="65dp" 
			android:layout_height="wrap_content"  
			android:layout_alignParentRight ="true"
			android:text="发送"/> 
		
		<EditText
		    android:id="@+id/MessageText"
		    android:layout_width="98dp"
		    android:layout_height="wrap_content"
		    android:layout_toRightOf="@+id/btn_disconnect"
		    android:hint="说点什么呢?"
		    android:textSize="15dip"
		      />
	</RelativeLayout>  
	 <ListView
	     android:id="@+id/list"
	     android:layout_width="wrap_content"
	     android:layout_height="wrap_content"
	     android:layout_above="@id/edit_bottombar"
	     android:layout_below="@id/container"
	     android:layout_weight="1.0"
	     android:divider="#ffc6c6c6"
	     android:scrollingCache="false"
	     android:visibility="visible" />

	 <TableLayout
	     android:layout_width="match_parent"
	     android:layout_height="wrap_content" >

	     <TableRow
	         android:id="@+id/tableRow1"
	         android:layout_width="wrap_content"
	         android:layout_height="wrap_content" >

	         <Button
	             android:id="@+id/button1"
	             android:layout_width="wrap_content"
	             android:layout_height="wrap_content"
	             android:text="Button"
	             android:visibility="invisible" />

	         <Button
	             android:id="@+id/start"
	             android:layout_width="wrap_content"
	             android:layout_height="wrap_content"
	             android:layout_marginRight="0dp"
	             android:text="start"
	             android:width="120px" />
	     </TableRow>

	     <TableRow
	         android:id="@+id/tableRow2"
	         android:layout_width="wrap_content"
	         android:layout_height="0dp"
	         android:layout_weight="1" >

	         <Button
	             android:id="@+id/left"
	             android:layout_width="wrap_content"
	             android:layout_height="wrap_content"
	             android:layout_marginRight="0dp"
	             android:text="left"
	             android:width="120px" />

	         <Button
	             android:id="@+id/stop"
	             android:layout_width="wrap_content"
	             android:layout_height="wrap_content"
	             android:text="stop"
	             android:width="120px" />

	         <Button
	             android:id="@+id/right"
	             android:layout_width="wrap_content"
	             android:layout_height="wrap_content"
	             android:text="right"
	             android:width="120px" />
	     </TableRow>

	     <TableRow
	         android:id="@+id/tableRow3"
	         android:layout_width="wrap_content"
	         android:layout_height="wrap_content" >

	         <Button
	             android:id="@+id/button2"
	             android:layout_width="wrap_content"
	             android:layout_height="wrap_content"
	             android:text="Button"
	             android:visibility="invisible" />

	         <Button
	             android:id="@+id/back"
	             android:layout_width="wrap_content"
	             android:layout_height="wrap_content"
	             android:text="Back" />
	     </TableRow>
	 </TableLayout>
</RelativeLayout>
</LinearLayout>

 4.2.3 android客户端的界面如图4.2所示:

4.2.4 发送按钮的代码 

sendButton= (Button)findViewById(R.id.btn_msg_send);
sendButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
String msgText =editMsgView.getText().toString();//获取编辑框内的内容
if (msgText.length()>0) {
	sendMessageHandle(msgText);//发送编辑框的内容给串口	
	editMsgView.setText("");//清空编辑框
	editMsgView.clearFocus();
//close InputMethodManager
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
			imm.hideSoftInputFromWindow(editMsgView.getWindowToken(), 0);
}
else
Toast.makeText(mContext, "发送内容不能为空!", Toast.LENGTH_SHORT).show();
}
});

4.2.5 控制按钮的代码 

以左转按钮为例:
sendButton= (Button)findViewById(R.id.left);
sendButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
String msgText ="1"; // 发送左转命令“l”
if (msgText.length()>0) {
sendMessageHandle(msgText);//发送“l”给串口	
editMsgView.setText("");//清空编辑框
editMsgView.clearFocus();
//close InputMethodManager
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
imm.hideSoftInputFromWindow(editMsgView.getWindowToken(), 0);
}
else
Toast.makeText(mContext, "发送内容不能为空!", Toast.LENGTH_SHORT).show();
}
});

 5、系统创新

自从有了智能手机,机器人的应用也就多了一个新的方向:手机控制机器人。2005年日本第二大电信运营商KDDI和机械制造商I Bee KK联合推出了第一款手机控制机器人。当然了,想要操纵这种机器人,你首先需要使用KDDI网络,并且用户的手机上,本身还需要带有蓝牙功能,然后再通过KDDI提供BREW方式下载机器人的驱动程式和控制系统。不过这种机器人的价格却相对高昂,预售市价约合人民币15000元。随着Android系统技术的普及,可以做个基于Android的客户端,在小车上装个接收蓝牙信号的FBT蓝牙接收模块,然后就可以通过客户端发送蓝牙信号,来对蓝牙小车进行控制控制,其接收可达15米,完全能适应对小车的要求。其中这个FBT蓝牙接收模块是低耗能,这样就把更多的能量用在小车的驱动上。

小车需要很大的马力和很好的灵活性以应对不同的地形。这辆车的车轮使用四驱的直流电机来驱动的,用PWM波来控制小车的速度,可以很方便的更改其速度,有主控板通过推挽输出来控制电机的翻转以让车子进行后退的速度。这样就可以胜任对小车的要求。

6、评测与结论

        首先,给电源模块上12v的电源,然后打开电机驱动模块开关,同时将主控板的供电端连接到电源管理模块。然后,在android手机上安装“蓝牙通信”应用程序后,打开该APP,然后选择“允许打开蓝牙”。点击设备列表中的“开始搜索按钮”,在设备列表中选择蓝牙模块的名字进行连接。

       完成上述工作以后,就可以在手机上通过按下“start”、“left”、“stop”、“right”、“back”通过蓝牙给小车发送“前进”、“左转”、“停止”、“右转”、“后退”5个命令。小车可以解析命令轻松进行前进、后退、左转、右转和停止。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1378143.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

500mA High Voltage Linear Charger with OVP/OCP

一、General Description YHM2810 is a highly integrated, single-cell Li-ion battery charger with system power path management for space-limited portable applications. The full charger function features Trickle-charge, constant current fast charge and const…

php 的数学常用函数

目录 1.常用列表 2.代码示例 1.常用列表 函数名描述输入输出abs()求绝对值数字绝对值数字ceil()进一法取整浮点数进一取整floor()舍去法求整浮点数直接舍去小数部分fmod()浮点数取余 两个浮点 数,x>y 浮点余数 pow()返回数的n次方基础数n次方乘方值round()浮点数四舍五入…

HTTP 常见协议:选择正确的协议,提升用户体验(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

数据库创建表并插入数据练习题

一、创建表的要求 创建一个英雄表(hero) 主键 name nickname address groups email telphone 二、 操作步骤 1.登录MySQL [rootlocalhost ~]# systemctl start mysqld [rootlocalhost ~]# mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with…

共商、共建、共谋未来,国台与经销商的“双向奔赴”

执笔 | 洪大大 编辑 | 扬 灵 1月9日&#xff0c;以“共商共建同奋进 共创共享新名酒”为主题的国台2024年全国经销商大会在广州召开。大会彰显了国台对经销商的尊重&#xff0c;将经销商放在C位&#xff0c;进一步强化厂商同心的经营理念。 此次大会不仅是对国台2023年市场…

1、理解Transformer:革新自然语言处理的模型

目录 一、论文题目 二、背景与动机 三、卖点与创新 四、解决的问题 五、具体实现细节 0. Transformer 架构的主要组件 1. 注意力、自注意力&#xff08;Self-Attention&#xff09;到多头注意力&#xff08;Multi-Head Attention&#xff09; 注意力到底是做什么的&…

【开源项目】轻量元数据管理解决方案——Marquez

大家好&#xff0c;我是独孤风。 又到了本周的开源项目推荐。最近推荐的元数据管理项目很多&#xff0c;但是很多元数据管理平台的功能复杂难用。 那么有没有轻量一点的元数据管理项目呢&#xff1f; 今天为大家推荐的开源项目&#xff0c;就是一个轻量级的元数据管理工具。虽然…

ModuleNotFoundError: No module named ‘simple_knn‘

【报错】使用 AutoDL 复现 GaussianEditor 时引用 3D Gaussian Splatting 调用simple_knn 时遇到 ModuleNotFoundError: No module named ‘simple_knn‘ 报错&#xff1a; 【原因】 一开始以为是版本问题&#xff0c;于是将所有可能的版本都尝试了 (from versions: 0.1, 0.2…

C++设计模式-- 2.代理模式

文章目录 代理模式 代理模式 代理模式的定义&#xff1a;为其他对象提供一种代理以控制对这个对象的访问。在某些情况下&#xff0c;一个对象不适合 或不能直接引用另一个对象&#xff0c;而代理对象可以在客户端和目标对象之间起到中介的作用。 代理模式有以下三种角色&…

VBA_MF系列技术资料1-310

MF系列VBA技术资料 为了让广大学员在VBA编程中有切实可行的思路及有效的提高自己的编程技巧&#xff0c;我参考大量的资料&#xff0c;并结合自己的经验总结了这份MF系列VBA技术综合资料&#xff0c;而且开放源码&#xff08;MF04除外&#xff09;&#xff0c;其中MF01-04属于…

爬虫之使用代理

爬虫—使用代理 1. 为什么使用代理 1.1 让服务器以为不是同一个客户端在请求 1.2 防止我们的真实地址被泄漏&#xff0c;防止被追究 2. 理解使用代理的过程 3. 理解正向代理和反向代理的区别 通过上图可以看出&#xff1a; 正向代理&#xff1a;对于浏览器知道服务器的真实…

PostMan、LoadRunner进行并发压测流程

需求 两个记账接口在同一时间大量处理同一账户账务时&#xff0c;锁表顺序不同导致死锁&#xff0c;在修改完代码后模拟生产记账流程进行测试&#xff0c;需要对两个接口进行并发测试。 在进行压测的时候&#xff0c;需要对流水号进行递增。 PostMan处理流程 1. 新建Collection…

Postman接口测试神器从安装到精通

Postman 的优点&#xff1a; 支持各种的请求类型: get、post、put、patch、delete 等支持在线存储数据&#xff0c;通过账号就可以进行迁移数据很方便的支持请求 header 和请求参数的设置支持不同的认证机制&#xff0c;包括 Basic Auth&#xff0c;Digest Auth&#xff0c;OAu…

RTSP网络视频协议

一.RTSP网络视频协议介绍 RTSP是类似HTTP的应用层协议&#xff0c;一个典型的流媒体框架网络体系可参考下图&#xff0c;其中rtsp主要用于控制命令&#xff0c;rtcp主要用于视频质量的反馈&#xff0c;rtp用于视频、音频流从传输。 1、RTSP&#xff08;Real Time Streaming P…

装机必看:电脑Bios里的CSM兼容模块是啥?打开有啥用?

前言 最近朋友装了一台新的电脑&#xff0c;用的i5-13490f的CPU。但是由于预算有限&#xff0c;手边只有一块GTX650ti&#xff0c;没办法&#xff0c;只好先这么用着了。 谁知道出现了个大问题&#xff1a;电脑开机居然没办法显示。 由于电脑所有的配件基本上都是全新的&…

查看lucene和elasticsearch的版本对应关系

一、Maven仓库官网&#xff1a; https://mvnrepository.com/ 二、搜索elasticsearch&#xff0c;然后点击Server或者elasticsearch进入。 三、点击相应的版本号进入。 四、查看对应的lucene版本。 END

J3-DenseNet实战

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 目录 环境步骤环境设置数据准备图像信息查看 模型构建模型训练模型效果展示 总结与心得体会 环境 系统: Linux语言: Python3.8.10深度学习…

Defi安全--Zunami Protocol攻击事件分析

其它相关内容可见个人主页 1 Zunami攻击事件相关信息 2023.8.13发生在Ethereum上发生的攻击&#xff0c;存在两个攻击交易&#xff0c;具体信息如下&#xff1a; 攻击合约地址&#xff1a;Contract Address 攻击合约 攻击者地址&#xff1a;Zunami Protocol Exploiter 攻击…

一种DevOpts的实现方式:基于gitlab的CICD(二)

写在之前 前文已经搭建了基于gitlab的cicd环境&#xff0c;现在我们来更近一步&#xff0c;结合官网给出的案例来详细介绍如何一步一步实现CI的过程。 基于gitlab搭建一个前端静态页面 环境依赖&#xff1a; gitlabgitlab runner&#xff08;docker版本&#xff09; 环境达吉…

Element-ui图片懒加载

核心代码 <el-image src"https://img-blog.csdnimg.cn/direct/2236deb5c315474884599d90a85d761d.png" alt"我是图片" lazy><img slot"error" src"https://img-blog.csdnimg.cn/direct/81bf096a0dff4e5fa58e5f43fd44dcc6.png&quo…