蓝牙超声波循迹小车制作

蓝牙超声波循迹小车制作

材料准备:

  1. stm32F103C8t6主控板

  2. 超声波传感器模块

  3. 小车底盘

  4. 直流电机驱动模块tb6612一个

  5. 直流电机四个(买小车会送)

  6. 杜邦线

  7. 电池盒及电池

  8. 蓝牙HC-04模块

  9. 面包板洞洞板

  10. 反射式红外模块

  11. 热熔胶

步骤:

1.搭建小车底盘和电机:

将四个直流电机安装在小车底盘上,并连接到直流电机驱动模块。

单片机输出一个pwm信号,提供给电机驱动的两个端口,AIN BIN 控制一侧电机的转向;

PWM代码如下:

#include "stm32f10x.h"                  // Device header
void PWM1_Init(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    TIM_InternalClockConfig(TIM2);
    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;     //ARR
    TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;       //PSC
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
    
    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_OCStructInit(&TIM_OCInitStructure);
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 0;      //CCR
    TIM_OC3Init(TIM2, &TIM_OCInitStructure);
    
    TIM_Cmd(TIM2, ENABLE);
}
​
void PWM_SetCompare3(uint16_t Compare)
{
    TIM_SetCompare3(TIM2, Compare);
}

2.电机转向模块 Motor

在Motor_Init函数中,首先使能了GPIOA外设的时钟,并配置了GPIOA的几个引脚为推挽输出模式,最大输出频率为50MHz。然后调用了PWM1_Init函数进行PWM模块的初始化。

接下来的Motor_SetLeftSpeed函数和Motor_SetRightSpeed函数分别用于设置左电机和右电机的速度。这两个函数接受一个表示速度的参数Speed。

如果Speed大于0,表示正向转动,则相关GPIO引脚设置为相应状态,同时通过PWM_SetCompare3函数设置PWM的占空比为Speed。

如果Speed等于0,表示停止转动,那么GPIO引脚都设置为高电平,同时通过PWM_SetCompare3函数设置PWM的占空比为Speed。

如果Speed小于0,表示反向转动,相关GPIO引脚设置为相应状态,然后通过PWM_SetCompare3函数设置PWM的占空比为-Speed。

#include "stm32f10x.h"                  // Device header
#include "PWM1.h"
void Motor_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    PWM1_Init();
    
}
void Motor_SetLeftSpeed(int8_t Speed)
{
    if (Speed >0)
    {
        GPIO_SetBits(GPIOA, GPIO_Pin_4);
        GPIO_ResetBits(GPIOA, GPIO_Pin_5);
        PWM_SetCompare3(Speed);
    }
    else if(Speed==0){
        GPIO_SetBits(GPIOA, GPIO_Pin_4);
        GPIO_SetBits(GPIOA, GPIO_Pin_5);
        PWM_SetCompare3(Speed);
    }else{
        GPIO_ResetBits(GPIOA, GPIO_Pin_4);
        GPIO_SetBits(GPIOA, GPIO_Pin_5);
        PWM_SetCompare3(-Speed);
    }
}
void Motor_SetRightSpeed(int8_t Speed)
{
    if (Speed >0)
    {
        GPIO_SetBits(GPIOA, GPIO_Pin_6);
        GPIO_ResetBits(GPIOA, GPIO_Pin_7);
        PWM_SetCompare3(Speed);
    }
    else if(Speed==0){
        GPIO_SetBits(GPIOA, GPIO_Pin_6);
        GPIO_SetBits(GPIOA, GPIO_Pin_7);
        PWM_SetCompare3(Speed);
    }else{
        GPIO_ResetBits(GPIOA, GPIO_Pin_6);
        GPIO_SetBits(GPIOA, GPIO_Pin_7);
        PWM_SetCompare3(-Speed);
    }
}

3.小车运行状态模块 Car

Car_Init() 函数用于初始化电机,它调用了 Motor_Init() 函数。

Go_Ahead() 函数用于让车辆前进,通过调用 Motor_SetLeftSpeed() 和 Motor_SetRightSpeed() 函数将左右电机速度都设置为 Speed(75)。

Go_Back() 函数用于让车辆后退,与 Go_Ahead() 函数类似,只不过将左右电机速度设置为 -Speed(负的 Speed)。

Turn_Left() 函数用于让车辆向左转弯。它将左电机速度设置为 0,以停止旋转,然后将右电机速度设置为 Speed,使其正向旋转。

Turn_Right() 函数用于让车辆向右转弯。与 Turn_Left() 函数类似,只不过将右电机速度设置为 0,然后将左电机速度设置为 Speed。

Self_Left() 函数与之前提到的不同,它用于车辆自旋向左转。它将左电机速度设置为 -Speed,使其反向旋转,而右电机速度仍然设置为 Speed,使其正向旋转。

Self_Right() 函数用于车辆自旋向右转,它将左电机速度设置为 Speed,右电机速度设置为 -Speed,与 Self_Left() 函数相反。

Car_Stop() 函数用于使车辆停止,将左右电机速度都设置为 0。

#include "stm32f10x.h"                  // Device header
#include "Motor.h"
#include "Delay.h"
#define Speed 75
void Car_Init(){
    Motor_Init();
}
void Go_Ahead(){ 
    Motor_SetLeftSpeed(Speed);
    Motor_SetRightSpeed(Speed);
}
void Go_Back(){
    Motor_SetLeftSpeed(-Speed);
    Motor_SetRightSpeed(-Speed);
}
void Turn_Left(){
    Motor_SetLeftSpeed(0);
    Motor_SetRightSpeed(Speed);
}
void Turn_Right(){
    Motor_SetRightSpeed(0);
    Motor_SetLeftSpeed(Speed);
    
}
void Self_Left(){
    Motor_SetLeftSpeed(-Speed);
    Motor_SetRightSpeed(Speed);
}
void Self_Right(){
    Motor_SetLeftSpeed(Speed);
    Motor_SetRightSpeed(-Speed);
}
void Car_Stop(){
    Motor_SetLeftSpeed(0);
    Motor_SetRightSpeed(0);
}

3.蓝牙模块就利用串口和单片机通信

本代码由B站UP江科大提供

#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>
uint8_t Serial_RxFlag;
uint8_t Serial_RxData;
void Serial_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9 ;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10 ;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b; 
    USART_Init(USART1,&USART_InitStructure);
    
    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // 选择中断
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  // 选择 开启
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //
    
    NVIC_Init(&NVIC_InitStructure);
    
    USART_Cmd(USART1,ENABLE);
}
​
void Serial_SendByte(uint8_t Byte)
{
    USART_SendData(USART1,Byte); 
    while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
    
}
​
void Serial_SendArry(uint8_t *Arry, uint16_t Lenth)
{
    uint16_t i;
    for(i = 0; i < Lenth; i++)
    {
        Serial_SendByte(Arry[i]);
    }
}
​
void Serial_SendString(char *String)
{
    uint16_t i;
    for(i = 0; String[i] != '\0'; i++)
    {
        Serial_SendByte(String[i]);
    }
}
uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{
    uint32_t Result = 1;
    while (Y --)
    {
        Result *= X;
    }
    return Result;
}
​
void Serial_SendNumber(uint32_t Number, uint8_t Length)
{
    uint8_t i;
    for (i = 0; i < Length; i ++)
    {
        Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');
    }
}
int fputc(int ch,FILE *f)
{
    Serial_SendByte(ch);
    return ch;
}
void Serial_Printf(char *format,...)
{
    char String[100];
    va_list arg;
    va_start(arg,format);
    vsprintf(String,format,arg);
    va_end(arg);
    Serial_SendString(String);
}
uint8_t Get_Serial_RxData(void)
{
    return Serial_RxData;
}
uint8_t Get_Serial_RxFlag(void)
{
    uint8_t temp = Serial_RxFlag;
    Serial_RxFlag = 0;
    return temp;
}
void USART1_IRQHandler(void)
{
    if(USART_GetFlagStatus(USART1,USART_IT_RXNE) == SET)
    {
        Serial_RxData = USART_ReceiveData(USART1);
        Serial_RxFlag = 1;
        USART_ClearITPendingBit(USART1,USART_IT_RXNE);
    }
}

蓝牙模块的 TX和RX分别对应连接 PA10 和 PA9

手机上通过APP给蓝牙发送指令,控制小车运动状态

main.c中蓝牙控制部分

if(Get_Serial_RxFlag())
{
    Data1= Get_Serial_RxData();
    Delay_us(10);
    Serial_SendByte(Data1);
    if(Data1==0x30)Car_Stop();
    if(Data1==0x31)Go_Ahead();
    if(Data1==0x33)Turn_Left();
    if(Data1==0x34)Turn_Right();
    if(Data1==0x35)Self_Left();
    if(Data1==0x36)Self_Right();
    if(Data1==0x37)Servo_SetAngle(0);
​
}

4.超声波测距模块

用热熔胶把超声波模块粘在车头

首先我们要了解超声波测距模块饿原理

工作原理

Step1:通过IO口给Trig接口周期不小于10us的脉冲信号。 Step2:HC-SR04接收到单片机发来的脉冲信号后自动发送8个频率为40KHz的方波,自动检测是否有信号返回。 Step3:若有信号返回,则通过Echo接口向单片机相连的IO口发送一个高电平,高电平持续时间就是超声波从发射到返回的总时间。 距离计算:假设高电平持续时间为T,声速为V(一般为340m/s),时间T是从发射到返回的时间,超声波测距模块到障碍物时间为T的一半。img

距离S=(T*V)/2。

所以我们先给模块一个10us以上的触发信号,再用定时器捕获回响信号的次数

注意超声波模块新版跟旧版有区别,供电3.3v-5v 和 5v

代码部分:

1.定时器部分
#include "stm32f10x.h"                  // Device header
#include "Timer.h"
​
uint16_t Time;
void Timer_Init()
{
    Time = 0;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);    //选择APB1总线下的定时器Timer2
    
    TIM_InternalClockConfig(TIM3);      //TIM2使用内部时钟
    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;     //计数模式,此处为向上计数
    TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;     //ARR 
    TIM_TimeBaseInitStructure.TIM_Prescaler = 72;       //PSC
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;        //高级计时器特有,重复计数
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure); 
    TIM_ClearFlag(TIM3, TIM_FLAG_Update);
    
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);      //使能中断
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;     //中断通道选择
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;      //优先级,同上
    
    NVIC_Init(&NVIC_InitStructure);
    
    TIM_Cmd(TIM3, ENABLE);      //打开定时器
}
void TIM3_IRQHandler()      //定时器3的中断函数,不懂直接套用 
{
    if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) // 0.0001秒就进一次中断 1秒就计数 10000
    {
​
        if (GPIO_ReadInputDataBit(Echo_Port, Echo_Pin) == 1) //捕获回响
        {
            Time ++;
        }
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);     //清空标志位
    }
}
2.超声波部分
#include "stm32f10x.h"                  // Device header
#include "HCSR04.h"
#include "Timer.h"
#include "Delay.h"
​
void HCSR04_Init()
{
    RCC_APB2PeriphClockCmd(Trig_RCC, ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStruct;
    
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Pin = Trig_Pin;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(Trig_Port, &GPIO_InitStruct);
    
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD; //下拉输出
    GPIO_InitStruct.GPIO_Pin = Echo_Pin;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(Echo_Port, &GPIO_InitStruct);
    
    GPIO_ResetBits(Trig_Port, Trig_Pin);
    
}
void HCSR04_Start()
{
    GPIO_SetBits(Trig_Port, Trig_Pin);
    Delay_us(45);
    GPIO_ResetBits(Trig_Port, Trig_Pin);
    Timer_Init();
}
​
uint16_t HCSR04_GetValue()
{
    HCSR04_Start();
    Delay_ms(100);
    return ((Time * 0.0001) * 34000) / 2;
}
​

超声波避障模式

当超声波感应到设置的距离后做出决策,这个可以根据自己的想法设计决策。

以下是我的代码部分,蓝牙发送 0x40 开启

if(Data1 == 0x40)
{
    // 如果蓝牙模块返回的数据为0x40,则执行以下操作
    Go_Ahead(); // 前进
​
    uint32_t T1 = HCSR04_GetValue(); // 获取超声波传感器的数值
​
    Serial_SendNumber(T1,3); // 将获取的数值通过串口发送出去
​
    if(T1<8)
    {
        // 如果距离小于8,则执行以下操作
        Car_Stop(); // 停止车辆
​
        Go_Back(); // 后退
        Delay_ms(1000); // 延时1秒
​
        if(Flag == 0)
        {
            // 如果Flag标志为0,则执行以下操作
            Turn_Left(); // 左转
            Flag=1;
        }
        else
        {
            // 如果Flag标志不为0,则执行以下操作
            Turn_Left(); // 左转
            Flag=0;
        }
        Delay_ms(Turning_time); // 延时一段时间
​
        Go_Ahead(); // 前进
        Serial_SendNumber(T1,3); // 将获取的数值通过串口发送出去
    }
    else if(T1<distance)
    {
        // 如果距离小于设定的distance,则执行以下操作
        Car_Stop(); // 停止车辆
        Delay_ms(500); // 延时500毫秒
​
        if(Flag == 0)
        {
            // 如果Flag标志为0,则执行以下操作
            Self_Left(); // 车辆自旋左转
            Flag=1;
        }
        else
        {
            // 如果Flag标志不为0,则执行以下操作
            Self_Right(); // 车辆自旋右转
            Flag=0;
        }
        Delay_ms(Turning_time); // 延时一段时间
​
        Go_Ahead(); // 前进
        Serial_SendNumber(T1,3); // 将获取的数值通过串口发送出去
    }
}

5.红外循迹模块

粘在车头左右分别两个

介绍:红外循迹模块是一种传感器模块,用于检测地面上的黑线或白线。它由红外发射管和红外接收管组成。发射管发出红外光照射在地面上,接收管接收地面上反射回来的红外光。当传感器位于黑线上时,反射回来的红外光较少;而当传感器位于白线上时,反射回来的红外光较多。通过检测反射回来的红外光信号强度,红外循迹模块可以判断当前位置是黑线还是白线。根据检测结果,可以控制机器人或小车的运动方向,实现自动循迹。

当碰到黑线就输出高电平

初始化代码如下:

#include "stm32f10x.h"                  // Device header
void Infrared_Init(){
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPD ;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_6| GPIO_Pin_7| GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

红外循迹模式

和超声波测距避障的决策类似

if(Data1 == 0x41)
{
    if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)==0&&
       GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)==0&&
       GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==0&&
       GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)==0)
    {
        Go_Ahead();
    }
    else if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)==1&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)==1&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==1&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)==1)
    {
        Car_Stop();
        Delay_ms(Turning_time2);
    }
    else if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)==0&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)==0&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==1&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)==1)
    {
        Self_Right();
        Delay_ms(Turning_time2);
    }
    else if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)==0&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)==0&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==1&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)==0)
    {
        Turn_Right();Delay_ms(Turning_time2);
    }
    else if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)==0&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)==0&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==0&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)==1)
    {
        Turn_Right();Delay_ms(Turning_time2);
    }
    else if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)==0&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)==1&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==0&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)==0)
    {
        Turn_Left();Delay_ms(Turning_time2);
    }
    else if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)==1&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)==1&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==0&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)==0)
    {
        Self_Left();Delay_ms(Turning_time2);
    }
    else if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)==1&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)==0&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==0&&
            GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)==0)
    {
        Turn_Left();Delay_ms(Turning_time2);
    }
}

总结:

  1. 硬件组装和连接:学会了如何正确连接电机、传感器、主控板和其他组件。这需要仔细阅读电路图并确保连接正确无误。

  2. 传感器的应用和数据处理:了解了如何使用超声波传感器和红外循迹传感器,并获取它们返回的数据。学习了如何根据传感器数据来做出决策,比如避开障碍物或跟踪线路。

  3. 编程控制:通过编写代码,能够实现小车的自动避障和循迹功能。学到了如何处理传感器数据、控制电机的运动以及与蓝牙模块进行通信。

  4. 测试和调试:在完成硬件组装和编写代码后,进行了测试和调试,以确保小车的功能正常。我发现了一些问题并进行了修复,提高了小车的性能和稳定性。

  5. 创新和改进:一旦基本功能实现,还可以进行创新和改进。例如,可以添加其他传感器或功能,探索更多有趣的应用。还可以优化代码和算法,提高小车的性能和响应速度。

代码和软件:

链接:百度网盘 请输入提取码 提取码:6666

posted @ 2026-08-04 22:23  blade13  阅读(0)  评论(0)    收藏  举报