精华内容
下载资源
问答
  • 基于STM32的智能循迹小车设计(基础版) 想看IF-WHILE代码块直接拉到底,在最下面 硬件准备 1、小车底盘+四直流电机(带轮) 2、STM32F103C8T6核心板 3、12V 8700mAh锂电池(可以用几节18650锂电池) 4、循迹...

    基于STM32的智能循迹小车设计(IF-WHILE)

    可实现的的功能:虚线转弯,直角弯,弧形弯,冲坡,十字路口,八字,八字不连续弯,不连续直角弯,终点停车。
    实测完成赛道
    在这里插入图片描述

    想看IF-WHILE代码块直接拉到底,在最下面
    

    硬件准备

    1、小车底盘+四直流电机(带轮)

    在这里插入图片描述

    2、STM32F103C8T6核心板

    在这里插入图片描述

    3、12V 8700mAh锂电池(可以用几节18650锂电池)

    在这里插入图片描述

    4、循迹模块

    选择的是TCRT500L,五路集成在一起,集成度比较高,但是可能不如五个单独的循迹模块好用
    在这里插入图片描述
    5、L298N电机驱动模块
    四驱车为啥用L298N电机驱动模块?
    可以把左边的两个电机并联,用输出A控制。把右边的两个电机并联,用输出B控制。
    在这里插入图片描述
    12V供电接电源正极,供电GND接电源负极和核心板GND,5V供电接核心板5V和循迹模块5V,然后循迹模块GND接核心板GND,所有设备就都可以上电了。(最好设置几个开关,安全且方便调试)
    另外,接线最好先试触,避免短路。

    6、杜邦线、开关若干

    软件设计

    1、电机调速

    通过输出PWM控制电机转速

    PWM初始化(以A1为例)

    void TIM2_CH2_PWM_Init(void)
    {
    	GPIO_InitTypeDef GPIO_InitStructure;
    	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;  
    	TIM_OCInitTypeDef  TIM_OCInitStructure;//定义三个结构体
    	
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);  
    //开启相关时钟
    
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; 
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOA, &GPIO_InitStructure);
     //A1 GPIO初始化
    	TIM_TimeBaseStructure.TIM_Period = 199; 
    	TIM_TimeBaseStructure.TIM_Prescaler =7199; 
    	TIM_TimeBaseStructure.TIM_ClockDivision = 0; 
    	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
    	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); 
    	// 定时器初始化
    	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 
     	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
    	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; 
    	TIM_OC2Init(TIM2, &TIM_OCInitStructure);  
    	//定时器通道初始化
    	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); 
     	//预装值初始化
    	TIM_Cmd(TIM2, ENABLE);  	
    	//打开定时器
    }
    

    初始化完后,输出PWM控制电机转速,注意,TIM_SetCompare2(TIM2,n);n越小占空比越大,点假转速越快,一下代码就是A1输出PWM占空比更大,它所对应的电机转速就越快。 具体的数据是多少,需要自己根据不同的场地去摸索,不停地调试。

    void left()
    {
    		TIM_SetCompare2(TIM2,200); 
    		TIM_SetCompare3(TIM2,165);
    }
    
    

    2、循迹模块检测

    GPIOB初始化,同时将B4 B5 B6 B7 B8设置为上拉输入

    void GPIOB_Init()	
    {
      GPIO_InitTypeDef GPIO_InitStructure;	
      RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); 
    	
      GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4 | GPIO_Pin_5  | GPIO_Pin_6 | GPIO_Pin_7| GPIO_Pin_8;	
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;;//浮空输入
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOB, &GPIO_InitStructure); 
    }
    
    

    宏定义,少打字,B4 B5 B6 B7 B8 分别对应L1 L2 M R2 R1

    #define L1 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_4)
    #define L2 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)
    #define M GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)
    #define R2 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)
    #define R1 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8) // L1 L2 M R2 R1 
    
    

    读取函数

    void Read_Date(void)
    {
     	L1;
    	L2;
    	M;
    	R2;
    	R1;
    }
    

    3、主函数(IF-WHILE思路)

    
    if(L1==0&&R1==1)
    	{
    		delay_ms(1);//消抖
    		if(L1==0&&R1==1)
    		{
    	while(M==1&&R1==1)//直到转正,R1是防止转出赛道的
    		{
    			bigleft();
    		}
    		}
    	}
    

    工程文件压缩包现已上传,进入我的主页可以查看、下载。

    展开全文
  • 本文主要对车模整体设计思路、硬件与软件设计及车模的装配调试过程作简要的说明。  1 整体设计  系统按照功能划分为:电源模块、单片机控制系统模块、运行调试模块、路径识别模块、直流电机驱动模块、舵机转向...
  • 一、设计思路分析前置的数据采集装置(眼睛)采集道路信息并送到单片机(大脑)进行分析,根据小车相对黑线的不同位置做出控制策略,再将处理信号后发出的命令输出给小车电机,分别控制小车的两个电机转向和转速,实现...

    一、设计思路分析

    前置的数据采集装置(眼睛)采集道路信息并送到单片机(大脑)进行分析,根据小车相对黑线的不同位置做出控制策略,再将处理信号后发出的命令输出给小车电机,分别控制小车的两个电机转向和转速,实现根据道路情况而直走、转弯、停车。

    采用MSP430F148单片机作为数据采集、处理、控制,系统的总体设计如图1所示,MSP430的开发平台为IAR Embedded Workbench EW430,它界面操作易上手。芯片内部JTAG对外的端口称为JIAG端口,该端口是一个双向串行端口。通过它可以控制MSP430进行在线仿真调试。因此,将JTAG电路集成到CPU内就相当于将仿真器集成到了CPU内部,只需要一个接口电路,将JTAG信号传送到调试终端(PC机)就可以实现在线调试了。

    二、硬件设计

    系统的组成主要有小车、信号采集模块、控制模块、供电模块和驱动模块,以下将分别介绍。

    1. 基础小车

    市面上小车多种多样,如有两个电机的四驱小车:适合爬坡、走沙石路等,但是过弯容易卡死;后轮有两个电机的三轮小车,过弯灵活但是重心不稳;两个电机的四轮后驱小车,过弯灵活且稳定。

    结合了前面两种车的优势,被我选用。

    2. 信号采集模块

    选择ST168光电对管来制作路面检测的传感器模块,见图2,当光电对管下方是深色的时候,由于深色吸收光线,接收管不受光照,因此不导通,A端输出电压为3.5V左右,被单片机识别为逻辑“1”,同理,白色的时候接收管导通,输出电压为0V左右,单片机识别为逻辑“0”。也可在信号输出前连接一个比较器以便获得更灵敏的输出。R1限制发射二极管的电流,发射管的电流和发射功率成正比,但受其极限输入正向电流50mA的影响,用R1=150Ω的电阻作为限流电阻,电源电压为5V,测试发现发射功率完满足检测需要。可变电阻R2可限制接收电路的电流,一方面保护光电对管;另一方面可调节检测电路的灵敏度。

    3. 控制模块

    为了使系统更容易设计和增加系统的稳定性,我们使用在电子器件市场上很方便购买的MSP430系列的最小系统板(见图3)。

    4. 各模块供电方案

    供电单元是9V直流电池组,根据各个模块对电压的不同需求通过稳压模块分别为其供电。单片机系统、各模块系统以及电机的工作电压不同,我们需要使电压满足各自的要求。

    除单片机外其他模块的工作电压均为5V,可用REG1117-5(输入3.8~12V,输出5V)将9V电压降为5V为这些模块供电,MSP430系列单片机具有超低功耗特性,工作电压仅为3.3V,故需要一块REG1117-3.3(输入5V,输出3.3V)为其供电。两个稳压模块电路相同,只是稳压芯片不同,再参见REG1117典型电路便可确定如图4所示的稳压电路。

    5. 电机驱动模块

    采用常用的H 桥电机驱动芯片L 2 9 8 N 驱动小车电机, L 2 9 8 N 第9 脚为逻辑控制部分的电源(4.5~7V),第4脚为电机驱动电源(此系统中为9V,为46V),第5、7、10、12脚输入标准TTL逻辑电平,用来控制内部H桥的开和关,第6、11脚为使能控制端(我们将两个使能端都接高电平,直接通过PWM波控制电机。若为低电平,驱动桥路上的4个晶体管全部截止,电动机自由停止),第1、15脚用来连接电流检测电阻(见图5)。

    通过单片机产生PWM波来调整直流电机电枢绕组两端的电压控制转速。脉冲宽度调制波由一列占空比不同的矩形脉冲构成, PWM波的占空比越大,输出电压越高,利用占空比的变化调整加在电机电枢绕组上的电压,改变电压随即改变电机电流,从而改变电机的转速。图中C1与C2,C3与C4分别并联后接地起滤波作用,防止在开机的时候产生的冲击电流损坏L298N。D1~D8是常用1N4007二极管,可防止电机中电感产生的反电势击穿L298N。根据L298N的输入输出关系,通过输入PWM信号可以控制电机的正反转,输入端IN1为PWM信号,输入端IN2为低电平,电机正转;输入端IN2为PWM信号,输入端IN1为低电平,电机反转。同理,IN3和IN4能共同控制另外一个电机。

    三、软件设计

    为便于描述,此处将四只光电对管左到右分别编号为1、2、3、4。分为两组置于车前,将黑色引导线“夹”在中间,内侧两个光电对管起主要的定位作用,优势在于外侧的两支管可以有效地解决小车由于惯性略微冲出轨道导致内侧的两支管子检测到白色而冲出去的危险。相比于其他用更多管子的方案,此方案简单有效,避免了很多复杂情况的产生(见图6)。

    当小车入弯前(以右转为例),四支光电对管均检测到白色(直走),入弯时,3、4号管将检测到黑色,此时便调用“右转”函数,当四支管子重新检测到白色信号时,调用“直走”函数;当四支对管同时检测到黑色信号时,调用“停车”函数。

    在此过程中,使用一个while(1)的死循环使单片机不停地对道路信息进行判断,并时刻纠正小车的前进方向。

    转弯策略

    变量定义:temp1~temp4为1~4号光电对管采集到的路面逻辑信息,见图7。

    为了更好的实现转弯,防止小车在过急弯时冲出路径,设计了强弱不同的两重转弯策略,同样以右转为例:车刚入弯时,必然是3号管先检测到黑色,而其他三个管均检测到白色时,启动重转弯程序;当车转急弯或由于小车略微冲出轨迹使3号管检测到白色时,4号管会检测到黑色,此时将启动第二重转弯程序,此程序能将小车拉回到执行一重转弯程序的位置上。

    直线行驶:用PWM对两个电机输出相同的占空比(350/512),使两轮速度相同。

    重转弯策略(以右转为例):调整PWM使右轮停止转动,左轮全速(占空比512/512)转动。

    第二重转弯策略:调整PWM使右轮反转(占空比300/512),左轮全速转动。

    四、制作与调试

    具体制作时,条件有限的读者可以根据前面给出的各模块电路图在面包板上分别进行焊接,将芯片的管脚和与其他模块的接口用排针引出。对各模块进行调试时可在各管脚上加需要的电压,测试其输出端的波形。有条件的读者可以将各个模块制作在一块PCB板上,可以大大简化小车的结构。

    1.用万用表检查板的焊接情况,确保管脚的引出情况良好,无虚焊、短路。

    2.调试供电模块,在输入端加上额定电压,测量输出端的电压是否合格。

    3.调试电机驱动模块时,在5、7脚上加5V直流电压,电机能够正向转动,交换两极后能反转(在10、12脚上进行同样的操作)即调试通过。

    4.调试信号采集模块,加上5V的直流电压,测试每一个光电对管在面对黑色(3V以上)和白色(0V)时A端的输出电压。ST168的检测距离很小,一般为8~15mm,因为8mm以下是它的检测盲区,而大于15mm则很容易受干扰。

    笔者经过多次测试比较,发现把传感器安装在距离检测物表面10mm时,检测效果。将地面监测模块放置在离前轮5cm处效果比较理想。

    5.用杜邦线将各模块的输入输出连接起来,形成一个完整的系统。

    6.编写、下载程序。首先编写直走程序使小车能动起来,在此基础上再加入转弯功能,进行参数的调整。

    7.小车的底盘一定要调平,保证小车始终都是“四脚着地”。电池组的位置将直接影响小车的重心位置,会对小车的转弯性能产生影响,放在靠后的位置效果较佳。检查车轮轴与轮胎的连接严实,以免小车打滑或意外转弯。

    8.不同等级的电压一定要共地,注意5V或者9V电压千万不能给单片机供电,会直接将单片机烧坏!

    直线行驶的时候占空比为350/512,这样可以避免速度过快小车由于惯性冲出了可识别路径,也可以使小车在转弯时有足够的速度不至于转不过去。当弯道比较平缓的时候重转弯策略能够满足过弯的需求,此时将一边车轮停转一边全速转动(占空比为1),使两边的车轮差生一个比较大的差速使小车转弯。当弯道比较急,仅仅依靠上述的策略小车可能转不过去而卡住,甚至冲出路径。此时使原本停转的那边车轮反转(占空比300/512,经实验得到的优化数据),就能够获得更大的差速,小车产生一个瞬间的摆动。如果小车的路径识别足够灵敏、转弯能力够好,读者可自行取消第二重转弯策略。

    展开全文
  • 本文主要对车模整体设计思路、硬件与软件设计及车模的装配调试过程作简要的说明。  1 整体设计  系统按照功能划分为:电源模块、单片机控制系统模块、运行调试模块、路径识别模块、直流电机驱动模块、舵机转向...
  • 小车循迹硬件设计

    2013-01-18 10:29:01
    小车循迹基本思想 适合没有思路的同学 也适合没有时间做的同学
  • 本程序参加过电子设计比赛,适用于四路红外收发传感器循迹小车。此程序的思路与网上我搜到的思路完全不同,是我自创的独特的,比那些程序更稳定精确并且我的小车行进速度要快得多,非常适合大一大二学生参考学习。
  • 智能小车稳定快速循迹一直是学者们研究的热门话题,能在直径0.8 mm左右的铁丝形成的轨迹...实验结果表明,设计的智能小车可以稳定快速循迹,在遇到硬币后能发出声光报警信号,并且小车能实时显示行驶速度、里程与时间。
  • 1、控制小车运动:通过STM32输出PWM波给驱动模块进行小车运动状态的控制。 2、与OpenMV4串口通信:实现与OpenMV4的串口收发字符类型数据功能。 3、与树莓派串口通信:实现与树莓派的串口收发字符类型数据功能。 4、...

    主要使用:

    1、单片机STM32F407
    2、树莓派3B+
    3、OpenMV4摄像头
    4、L298N四路电机驱动模块
    5、OLED屏幕

    总IO口接线:

    在这里插入图片描述

    各部分功能:

    STM32:

    作为主控,完成的功能为:
    1、控制小车运动:通过STM32输出PWM波给驱动模块进行小车运动状态的控制。
    2、与OpenMV4串口通信:实现与OpenMV4的串口收发字符类型数据功能。
    3、与树莓派串口通信:实现与树莓派的串口收发字符类型数据功能。
    4、OLED屏的显示:让OLED屏能显示表示当前状态的字符。

    在这里插入图片描述

    OpenMV4:

    主要完成循迹部分图像数据采集:
    1、寻线:OpenMV4摄像头将获得的轨迹进行处理,得到轨迹的一个偏离角度,然后通过偏转角判断给STM32发送左转或右转的信号。
    2、停止:MV4通过模板匹配和识别圆双重判断是否目标为圆,如果是则给STM32发出信号来停止小车运动并开始树莓派识别。
    在这里插入图片描述

    树莓派3B+:

    通过树莓派上的摄像头模块(Pi Cam)进行目标识别:
    树莓派通过颜色识别和形状判断,如果发现绿色的圆,即发现目标,则显示发现目标。
    在这里插入图片描述

    电机驱动和OLED屏:

    电机驱动主要通过STM3给的PWM波对小车运动进行控制。
    OLED屏主要显示表示当前状态的字符,主要为了能更加清楚当前状态,并进行调试。

    在这里插入图片描述

    资源链接:

    总项目文件:下载链接

    下一篇文章:循迹识别小车:(二)STM32部分

    展开全文
  • 简单循迹小车的制作

    2021-01-20 07:20:33
    一、设计思路分析  前置的数据采集装置(眼睛)采集道路信息并送到单片机(大脑)进行分析,根据小车相对黑线的不同位置做出控制策略,再将处理信号后发出的命令输出给小车电机,分别控制小车的两个电机转向和转速...
  • STM32循迹小车/Android蓝牙控制小车(三) 循迹蓝牙小车的第三篇终于来了,这篇开篇先来介绍一下整个开发过程中得构思思路。本来这应该放在第一篇,但是实际思路会因为开发过程中遇到的问题而改变,到今天为止小车的...

    STM32循迹小车/Android蓝牙控制小车(三)

    循迹蓝牙小车的第三篇终于来了,这篇开篇先来介绍一下整个开发过程中得构思思路。本来这应该放在第一篇,但是实际思路会因为开发过程中遇到的问题而改变,到今天为止小车的三个目标功能都已经实现。所以在介绍app控制小车之前先来理清一下思路。

    整个设计软件方面分为两大块:

    一、STM32作为主控制器,有三种工作模式,三种模式通过开发板上的物理按键或者App虚拟按键来进行切换:

    1、红外遥控——通过接受解码红外头接收到的遥控信息来控制小车
    2、循线跟踪——通过循环扫描光电循迹模块检测黑线并且跟踪黑线行驶
    3、手机蓝牙控制——HC-05蓝牙模块接收App通过蓝牙发送的信息控制小车行驶
    

    二、Android端APP:
    App功能分为两大块:蓝牙连接、控制小车,两大功能模块通过两个Activity来实现。

     蓝牙连接包括:
     1、判断当前设备是否支持蓝牙
     2、判断当前设备蓝牙功能是否打开
     3、读取已经配对的蓝牙信息
     4、扫描周围蓝牙信息
     5、与指定蓝牙发起配对
     6、与指定蓝牙发起连接
     7、断开连接、取消配对
    
    控制小车:
    控制小车其实就是和小车通讯,只需要通过已经连接蓝牙的Socket通道,向小车端发送约定的信息,
    小车端STM32接收到信息,解码之后根据约定的含义控制小车。
    

    先从App开始:

    App开发软件平台AndroidStudio2.2.2
    硬件平台:Android手机,目标API 28,最低API 24。检测平台OPPO A7X
    

    APP工程文件构架:

    下图详解说明了每个文件的具体作用:
    在这里插入图片描述

    蓝牙连接过程详细说明请访问Android 官服档,有详细说明:
    Android 官服文档 ——蓝牙概览

    APP UI界面:
    在这里插入图片描述

    循迹蓝牙小车.mp4

    STM32蓝牙接收端源码:

    	因为TC-05蓝牙模块数据通过串口输出,所以使用的时候不需要涉及到任何蓝牙协议。直接把模块当成串口来使用就行,代码相对简单:
    

    串口初始化程序:

    void LanYa_Init(void){
    	
    	GPIO_InitTypeDef GPIO_InitStrue;
    	USART_InitTypeDef USART_InitStrue;
    	NVIC_InitTypeDef NVIC_InitStrue;
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//① 使能GPIOA时钟
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//① 使能USART2时钟
    	
    	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;
    	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_2;
    	GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
      GPIO_Init(GPIOA,&GPIO_InitStrue);//②设置发送端IO
    	
    	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;
    	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_3;
    	GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
      GPIO_Init(GPIOA,&GPIO_InitStrue);//②设置接收端IO
    	
    	USART_InitStrue.USART_BaudRate=9600;
    	USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
    	USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;
    	USART_InitStrue.USART_Parity=USART_Parity_No;
    	USART_InitStrue.USART_StopBits=USART_StopBits_1;
    	USART_InitStrue.USART_WordLength=USART_WordLength_8b;	
    	USART_Init(USART2,&USART_InitStrue);//③设置串口参数,波特率9600,发送接收双工模式,无奇偶校验,数据位8位,停止位1位,无流控制
    	USART_Cmd(USART2,ENABLE);//使能串口1
    	USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);//开启接收中断
    	
    	NVIC_InitStrue.NVIC_IRQChannel=USART2_IRQn;
    	NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;
    	NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;
    	NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;//中断优先级设置
    	NVIC_Init(&NVIC_InitStrue);
    }
    
    //串口2中断服务程序
    void USART2_IRQHandler(void)
    {
    
    	if(USART_GetITStatus(USART2,USART_IT_RXNE))
     {
        LanYaRes = USART_ReceiveData(USART2); 	//蓝牙接收到的数据
    		LCD_ShowNum(30+8*16,70,1,5,16);
    		flag = 0;
      }
    }
    
    int GetLanYaRes(void){
    	if(flag == 0){
    		flag = 1;
    		return LanYaRes;
    	}else return -1;
    }
    

    数据接收处理代码:

    		LCD_Clear(WHITE);
    		LanYa_Init();		//蓝牙接收初始化
    //		USART_Cmd(USART2,ENABLE);//使能串口2
    //		USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);//开启串口2接收中断
    		pwm_sudu = 10000;	
    		flagSudu = 0;
    		while(mode1 == 2){ //模式3,App蓝牙模式
    			mode1 = GetMode();
    			if(flagSudu == 0){
    				PGout(13) = 0;
    				PGout(14) = 0;
    				flagSudu = 1;
    			}
    			Show_Str(30,30,200,16,"循迹小车蓝牙调试界面",16,0);	
    			POINT_COLOR=RED;
    			LanYaRes1 = GetLanYaRes();
    			Show_Str(30,70,200,16,"蓝牙接收数据:",16,0);
    
    			switch(LanYaRes1){
    				case 48:{
    						TIM_SetCompare4(TIM3,pwm_sudu);	//前进
    						PGout(13) = 1;
    						PGout(14) = 0;
    						LanYaRes1 = -1;
    				}break;
    				case 50:{
    						TIM_SetCompare4(TIM3,pwm_sudu);	//后退
    						PGout(13) = 0;
    						PGout(14) = 1;
    						LanYaRes1 = -1;					
    				}break;
    				case 49:{
    						TIM_SetCompare4(TIM3,0);				//停止
    						PGout(13) = 0;
    						PGout(14) = 0;
    						LanYaRes1 = -1;					
    				}break;
    				case 51:{														//加速
    						if(pwm_sudu <= 14000)pwm_sudu+=500;
    						else pwm_sudu=8000;	
    						TIM_SetCompare4(TIM3,pwm_sudu);
    						LanYaRes1 = -1;					
    				}break;	
    				case 52:{														//减速
    						if(pwm_sudu >=1000)pwm_sudu-=500;
    						else pwm_sudu=0;
    						TIM_SetCompare4(TIM3,pwm_sudu);
    						LanYaRes1 = -1;					
    				}break;
    				case 54:{														//左转
    						TIM_SetCompare2(TIM3,MIN_zou);
    						LanYaRes1 = -1;					
    				}break;					
    				case 53:{														//右转
    						TIM_SetCompare2(TIM3,MAX_you);
    						LanYaRes1 = -1;					
    				}break;	
    				case 56:{														//右转
    						TIM_SetCompare2(TIM3,Z_qian);
    						LanYaRes1 = -1;					
    				}break;
    				default:break;
    			}
    		}
    

    代码中设计一条LanYaRes1 = -1; 的代码,为什么要在每次数据处理之后将LanYaRes1 = -1置为-1?
    因为蓝牙接收到的信息不是按键,如果不在每使用一次数据信息之后将数据清理,那么同一条数据就会重复直行很多次,就像按键处理里面的连续按键一样。可以看到,在上面一个程序片段中,也有相似的代码:flag = 0; return -1; 如下,也是同样的原因。

    if(USART_GetITStatus(USART2,USART_IT_RXNE))
     {
        LanYaRes = USART_ReceiveData(USART2); 	//蓝牙接收到的数据
    		LCD_ShowNum(30+8*16,70,1,5,16);
    		flag = 0;
      }
    }
    
    int GetLanYaRes(void){
    	if(flag == 0){
    		flag = 1;
    		return LanYaRes;
    	}else return -1;
    }
    

    App端源码:

    public void onClick(View v) {
            switch (v.getId()){
                case R.id.BluetoothConnectivity:{   //连接蓝牙
                    startActivityForResult(new Intent(MainActivity.this,Main2Activity.class),1);
    //                Toast.makeText(MainActivity.this,"按“搜索”开始扫描附近蓝牙设备",Toast.LENGTH_LONG).show();
                }break;
                case R.id.Forward_Button:{          //前进
                    if(writeTask != null)
                        writeTask.doInBackground(""+0);
                }break;
                case R.id.Stop_Button:{          //停止
                    if(writeTask != null)
                        writeTask.doInBackground(""+1);
                }break;
                case R.id.Back_Button:{          //后退
                    if(writeTask != null)
                        writeTask.doInBackground(""+2);
                }break;
                case R.id.Accelerate_Button:{          //加速
                    if(writeTask != null)
                        writeTask.doInBackground(""+3);
                }break;
                case R.id.SlowDown_Button:{          //减速
                    if(writeTask != null)
                        writeTask.doInBackground(""+4);
                }break;
                case R.id.Right_Button:{          //右转
                    if(writeTask != null)
                        writeTask.doInBackground(""+5);
                }break;
                case R.id.Left_Button:{          //左转
                    if(writeTask != null)
                        writeTask.doInBackground(""+6);
                }break;
                case R.id.Mode_Button:{          //模式切换
                    if(writeTask != null)
                        writeTask.doInBackground(""+7);
                }break;
                case R.id.StraightTravel_Button:{          //直行
                    if(writeTask != null)
                        writeTask.doInBackground(""+8);
                }break;
                default:writeTask.cancel(); //关闭蓝牙通道
            }
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    //        super.onActivityResult(requestCode, resultCode, data);
            switch (requestCode){
                case 1:{
                    if(resultCode == RESULT_OK){
                        if(data.getParcelableExtra("connectBluetooth") != null)
                            currentBluetoothDevice = data.getParcelableExtra("connectBluetooth"); //接收反馈回来的当前连接蓝牙设备
                        LanYa_TextView.setText("蓝牙“" + currentBluetoothDevice.getName() + "”已连接");
                        if(((GlobalBlueSocket)getApplication()).getGlobalBlueSocket() != null)
                            mBluetoothSocket = ((GlobalBlueSocket)getApplication()).getGlobalBlueSocket();  //通过全局变量获取蓝牙套接字
                        writeTask =  new WriteTask(mBluetoothSocket);
                   }
                }break;
                default:break;
            }
        }
    

    关于蓝牙连接以及相关的逻辑代码,因为涉及功能多逻辑复杂,将在下篇进行介绍。

    STM32循迹小车/Android蓝牙控制小车(一)
    STM32循迹小车/Android蓝牙控制小车(二)
    STM32循迹小车/Android蓝牙控制小车(三)
    STM32循迹小车/Android蓝牙控制小车(四)完结篇——Android经典蓝牙开发

    展开全文
  • 对于飞思卡尔的同学,尤其是初学者,大有用处,具体介绍了智能车个模块的实现,和设计思路
  • 物流机器人竞赛。包含电路设计,电机模块应用,循迹模块应用,PID算法等。
  • 在(一)中买齐备了东西之后就可以进行动手制作了,分为三个部分,三个部分一个一个搭建,先讲思路。 控制思路 模块的使用这里就不说了,使用的模块都很常见,对照着下面的控制思路涉及到的模块一个一个看看,后期...
  • 循迹的光电搬运小车含PID(硬件+源代码+3D文件)

    千次阅读 多人点赞 2019-11-17 12:06:18
    循迹的光电搬运小车(硬件+源代码+3D文件)一. 设计思路1.比赛规则2. 设计思路二. 硬件需求三. 算法设计四. 所有文件 第一次写博客,可能显得比较杂乱。 本人为非985/211的大二男一枚,所以技术水平你懂的,程序中...
  • 硬件篇:教你做STM32蓝牙+循迹+避障+pwm调速小车

    多人点赞 热门讨论 2021-03-27 17:36:48
    设计思路 材料准备 以下材料为新增材料,全部材料参照上一篇博客的介绍!! TCRT5000循迹模块 HC-SR04超声波模块 SG90舵机(180度) 超声波支架 程序设计 pwm调速 这里我们直接用上一次用于驱动
  • 此项目是基于STM32F103ZET6来开发的物流循迹小车项目缘由项目选型场地地图及比赛任务简述硬件设计设计思路部分代码目前存在的问题作者的话 项目缘由 这个项目是在大三上学期自己专业主办的“机架大师”物流搬运校级...
  • 基于19年电赛A题的一些思考

    千次阅读 2020-07-31 11:56:53
    19年的A题是设计一个能够自启动的无线充电小车小车实现基本的循迹功能即可。自启动条件:小车充电完成。 解题思路: 整个充电的系统由发射端,接收端,输出端组成。 1.1发射端 在发射端,组成部分有PWM波...
  • 51单片机自学笔记

    2016-07-27 22:24:19
    如自己动手制作一个数字电子钟、智能孵化器、循迹小车等,在制作的过程中学得最扎实。, 条件允许的话,可以参加培训班或购买现成的实验板。这样可以加速学习的进程,快速掌握别人已有的经验。在这个信息爆炸的社会,...

空空如也

空空如也

1 2
收藏数 26
精华内容 10
关键字:

循迹小车设计思路