本网页已闲置超过3分钟,按键盘任意键或点击空白处,即可回到网页

基于Arduino的遥控汽车
发布时间:2021-06-03
分享到:
基于Arduino的遥控汽车
发布时间:2021-06-03
分享到:

本文将向你介绍如何自制基于arduino的遥控汽车,该汽车通过使用具有自动制动功能的蓝牙应用程序进行控制,且汽车遇到障碍物时会停下来,避免撞车。

该汽车使用安装在伺服器上的超声波传感器来检测前方是否存在物体,而汽车向后行驶时将面向后方。该汽车通过l293d电动机驱动器来驱动齿轮电动机。且该车没有任何转向机构,因此它通过摩擦进行左右转弯,即右轮向前旋转而左轮向后旋转(反之亦然)来完成转弯。这样,汽车就也可以当场转弯而无需前进或后退。

硬件部件:

  • 四轮驱动智能汽车底盘
  • Arduino UNO
  • L293D电机驱动器护罩
  • SG90微型伺服电机
  • 超声波传感器-HC-SR04
  • HC-05蓝牙模块
  • 电池座
  • 电池

设计步骤:

1、焊接

 齿轮电动机:

l293d电机护罩

板未使用引脚2和13,因此在该引脚上焊接了超声波传感器的引脚;蓝牙模块的发送和接收也需要针脚0和1,将引脚焊接到了屏蔽底部的电源引脚上。

2、组装:

使用了2个电动机

用双面胶带将尼龙轮粘在前面

使用尼龙扎带将arduino固定在汽车上,并用双面胶带将电池座粘在arduino的前面。

在电池座的电线上增加了一个开关

18650电池每个只有3.7V,功率不足以为汽车供电,所以又连接了一个4x AA电池座(每个1.5V),所以总电压为8.9V

超声波传感器将安装在伺服器的顶部,使用纸板和胶带为超声波传感器创建了一个支架

使用双面胶带将伺服器安装在电池的侧面

超声波传感器将使用双面胶带安装在伺服器的顶部

最终设计

细节:

  • 将电动机护罩安装到arduino
  • 将电机拧入端子对中
  • 将伺服器连接到电动机屏蔽罩上的伺服1排针,此处的棕色线应连接到负极端子
  • 将电缆从电池座插入电源端子。(确保电池的正极连接到正极,负极连接到地面)。
  • 将超声传感器连接到电缆,并将Vcc和接地线连接到5V和接地引脚。将回波引脚连接到引脚13,将触发引脚连接到引脚2。
  • 将hc05蓝牙模块连接至电缆,并将txd和rxd连接至引脚0和1,然后将其连接。将vcc和gnd连接到电机屏蔽罩上的伺服2引脚的+和-。

3、编程: 

程序需要两个库,AFMotor.h用于控制电机罩,Servo.h用于控制电机

按下按钮时,Arduino蓝牙应用发送命令/字符作为输入

将使用switch语句为何时按下Arduino蓝牙应用程序中的按钮分配做具体说明。

通过HC-SR04超声波传感器进行物体感测。传感器通过空气发出超声波,如果有物体,它将反弹回模块。为了产生超声波,需将触发引脚设置为高电平,持续10微秒,将以40kHz发射一个8周期的声波。当传感器检测到已反射的超声波时,回波针将变高。

使用pulseIn(echo, HIGH)函数使等待回波引脚变高,还添加了超时作为pulseIn函数的参数,并设置为等待返回信号的最长时间。这样,就可以得到超声波传感器发送和接收信号所需的时间。由于超声波以音速传播,可以通过将信号返回所需的时间除以2并乘以空气中的声速来计算从传感器到物体的距离。

创建了一个名为getDistance的函数,该函数返回超声波传感器与物体之间的距离。每当汽车向前或向后移动时,都会使用此功能,当该函数返回的距离小于我设置的最大距离时,它将自动使汽车停止。当汽车向前行驶时,该传感器将面向前方;而当汽车向后行驶时,该传感器将向后面向。传感器面对的方向将由伺服器控制,因为传感器将安装在伺服器的顶部。

代码:

//Christopher Sutjiono

#include <AFMotor.h>                              //导入库以控制电机屏蔽
#include <Servo.h>                                //导入库控制伺服

AF_DCMotor leftBack(1);
AF_DCMotor rightBack(4);
Servo servoLook;                                  //创建一个对象来控制伺服

char command;                                     //用于存储BT应用程序输入的全局变量
int motorspeed = 100;                                  //速度变量(0-255)
byte trig = 2;                                    //分配超声波传感器引脚
byte echo = 13;
byte stopDist = 50;                               //从物体到停止的距离(厘米)
float timeOut = 2 * (maxDist + 10) / 100 / 340 * 1000000; //等待返回信号的最长时间


void setup() {
  Serial.begin(9600);                             //设置蓝牙模块的波特率
  StopMove();                                     //确保所有电机停止运行
  servoLook.attach(10);                           //分配伺服销
  servoLook.write(180);
  pinMode(trig, OUTPUT);                          //指定超声波传感器引脚模式
  pinMode(echo, INPUT);
}


void loop()
{
  if (Serial.available() > 0)
  {
    command = Serial.read();                                 //将输入存储到变量
    switch (command) {                                       //将输入用作switch语句的case
      case 'F':
        servoLook.write(180);                                //将伺服设置为向前看
        if (getDistance() >= stopDist)                       //I如果停车距离内没有物体,向前移动
        {
          Drive();
        }
        else StopMove();                                     //如果停车距离内有物体,停车
        break;
      case 'B':
        servoLook.write(0);                                  //设置伺服向后看
        if (getDistance() >= stopDist)                       //如果停车距离内没有物体,向后移动
        {
          Reverse();                                         //如果停车距离内有物体,停车
        }
        else StopMove();
        break;
      case 'L': TurnLeft(); break;
      case 'R': TurnRight(); break;
      case 'G': DriveLeft(); break;
      case 'I': DriveRight(); break;
      case 'H': ReverseLeft(); break;
      case 'J': ReverseRight(); break;
      case 'S': StopMove(); break;
      case '0': motorspeed = 0; break;
      case '1': motorspeed = 25; break;
      case '2': motorspeed = 50; break;
      case '3': motorspeed = 75; break;
      case '4': motorspeed = 100; break;
      case '5': motorspeed = 125; break;
      case '6': motorspeed = 150; break;
      case '7': motorspeed = 175; break;
      case '8': motorspeed = 200; break;
      case '9': motorspeed = 225; break;
      case 'q': motorspeed = 250; break;
    }

  }
}


void Drive()
{
  leftBack.setSpeed(motorspeed); //定义最大速度
  leftBack.run(FORWARD); //顺时针旋转电机
  rightBack.setSpeed(motorspeed);//定义最大速度
  rightBack.run(FORWARD); //顺时针旋转电机
}

void Reverse()
{
  leftBack.setSpeed(motorspeed); //定义最大速度
  leftBack.run(BACKWARD); //逆时针旋转电机
  rightBack.setSpeed(motorspeed); //定义最大速度
  rightBack.run(BACKWARD); //逆时针旋转电机
}


void TurnLeft()
{
  leftBack.setSpeed(motorspeed); //定义最大速度
  leftBack.run(BACKWARD); //逆时针旋转电机
  rightBack.setSpeed(motorspeed); //定义最大速度
  rightBack.run(FORWARD);  //顺时针旋转电机
}

void TurnRight()
{
  leftBack.setSpeed(motorspeed); //定义最大速度
  leftBack.run(FORWARD); //顺时针旋转电机
  rightBack.setSpeed(motorspeed); //定义最大速度
  rightBack.run(BACKWARD); //逆时针旋转电机
}

void DriveRight()
{
  leftBack.setSpeed(motorspeed); //定义最大速度
  leftBack.run(FORWARD); //顺时针旋转电机
  rightBack.setSpeed(motorspeed / 4); //定义最大速度
  rightBack.run(FORWARD); //顺时针旋转电机
}
void ReverseRight()
{
  leftBack.setSpeed(motorspeed / 4); //定义最大速度
  leftBack.run(BACKWARD); //逆时针旋转电机
  rightBack.setSpeed(motorspeed); //定义最大速度
  rightBack.run(BACKWARD); //逆时针旋转电机
}
void DriveLeft()
{
  leftBack.setSpeed(motorspeed / 4); //定义最大速度
  leftBack.run(FORWARD); //顺时针旋转电机
  rightBack.setSpeed(motorspeed); //定义最大速度
  rightBack.run(FORWARD); //顺时针旋转电机
}
void ReverseLeft()
{
  leftBack.setSpeed(motorspeed); //定义最大速度
  leftBack.run(BACKWARD); //顺时针旋转电机
  rightBack.setSpeed(motorspeed / 4); //定义最大速度
  rightBack.run(BACKWARD); //逆时针旋转电机
}

void StopMove()                                   //设置所有电机停止
{
  leftBack.setSpeed(0); //定义最小速度
  leftBack.run(RELEASE); //顺时针旋转电机
  rightBack.setSpeed(0); //定义最小速度
  rightBack.run(RELEASE); //松开按钮时停止电机
}


int getDistance()                                   //获取超声波传感器与物体之间的距离
{
  unsigned long pulseTime;                          //创建一个变量来存储脉冲行程时间
  int distance;                                     //创建变量以存储计算的距离
  digitalWrite(trig, HIGH);                         //产生10微秒的脉冲
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  pulseTime = pulseIn(echo, HIGH, timeOut);         //测量脉冲返回的时间
  distance = (float)pulseTime * 340 / 2 / 10000;    //根据脉冲时间计算目标距离
  return distance;
}

加入微信技术交流群

技术交流,职业进阶

关注与非网服务号

获取电子工程师福利

加入电路城 QQ 交流群

与技术大牛交朋友

讨论