Arduino硬件设计(一)|利用Arduino UNO R3制作手机蓝牙遥控小车---01

概述: 

      本文将主要介绍以Arduino UNO R3为核心主板开发测试一款可利用手机进行蓝牙控制的遥控小车,文章将分为两部分,第一篇将详细的介绍利用Arduino UNO R3制作蓝牙小车所需硬件和软件配置以及使用Arduino IDE编写的总代码程序,第二篇将详细的介绍代码程序中各部分代码的功能和作用以及在测试过程中遇到的问题。

一.硬件准备

      1.Arduino UNO R3(开发板主板)

90d82e6c819749eca23659359293c2a5.png

      2.HC-05(蓝牙模块)

7c1ef5d0c7fb4375812f6ea72c82ef59.png

      3.L298N(电机驱动模块)

18bd5fd7f25a40ebad88100c8b1ef098.png

二.软件准备

      1.蓝牙串口调试助手

            (1).在手机应用商店/APP Store中查找带有键盘功能的蓝牙串口软件

            (2).百度网盘地址(安卓版):   蓝牙串口.apk|百度网盘icon-default.png?t=N7T8https://pan.baidu.com/s/14FlalmvyKR2DaAD-TjB2sA?pwd=MJY6

      2. 软件截图

cf6370a35cec43b9b25524990f733648.png      f2182c30219646cd86db9f19b5babeaf.png      52ce90102da64963b512dbdccb38f2da.png

三.硬件图解

      1.Arduino UNO R3开发板图解

            参考文档:Arduino硬件介绍(一)|Arduino UNO R3开发板介绍、原理和功能-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/2301_80771046/article/details/136465812?spm=1001.2014.3001.5502

      2.HC-05/06蓝牙模块图解

26574968c40845beb1b8ea67aed5d3ad.png

      3.L298N电机驱动模块图解

122692c0d0d64fcca25a881192b06e4a.png

5b37f43a4dd546a5ac61fdd419780001.png

71ee097ef2d04412a24d1e4a8bf8d330.png

四.硬件连接

d00323f4f6b741cdb3349773327e4190.png

      1.HC-05/06蓝牙模块连接

df00de424acb4b2c9f580140c6ace0f3.png

cde1fa26a5534c4a9e401d22d79b1954.png

HC-05/06Arduino UNO R3说明
VCC5V正极
GNDGND负极
TXRX接收端,用于接收数据。
RXTX发送端,用于发送数据。

         注意: 

               1.接口是:TX -- RX,RX -- TX,注意不要接反;

               2.在写入程序时需要将RX,TX引脚拔掉或者让蓝牙模块断电,否则会出现写入失败。

       2.L298N电机驱动模块连接

aa116c6c16c1418189ffb5d6f00f78a1.png

L298NArduino UNO R3说明
5V5V正极
12V------ ------ ------接外12V接电源,必须与开发板主板处在同一个电源回路
GNDGND负极
OUT1、OUT2------ ------ ------接左侧电机
OUT3、OUT4------ ------ ------接右侧电机
ENAD9通道A使能
ENBD10通道B使能
IN1D2信号输入口1(左侧电机)
IN2D3信号输入口2(左侧电机)
IN3D4信号输入口3(右侧电机)
IN4D5信号输入口4(右侧电机)

         注意:

            1.L298N上的12V电源口必须要和Arduino UNO R3的电源处于同一回路下(可使用DC口电源为Arduino UNO R3供电并并联为L298N供电);

            2.在测试过程中若出现电机旋转方向相反,尝试调换OUT接口即可。

五.代码程序

      以下代码是基于Arduino IDE开发环境下的代码程序

// 定义左右轮脉冲计数器和时间标记
int leftCounter = 0, rightCounter = 0;
unsigned long time = 0, old_time = 0;       // 时间标记,用于计算速度
unsigned long time1 = 0;                    // 时间标记,用于其他计时功能
float lv, rv;                                // 左、右轮速度

// 定义运动控制命令
#define STOP        0
#define FORWARD     1
#define BACKWARD    2
#define TURNLEFT    3
#define TURNRIGHT   4
#define CHANGESPEED 5

// 定义电机引脚
int leftMotor1 = 2;
int leftMotor2 = 3;
int rightMotor1 = 4;
int rightMotor2 = 5;
bool speedLevel = 0; // 速度档位,0表示低速,1表示高速

// 定义PWM引脚
int leftPWM = 9;
int rightPWM = 10;

void setup() {
  // 初始化串口通信,波特率为9600
  Serial.begin(9600);
  // 设置外部中断0,当引脚0电平从高到低变化时触发RightCount_CallBack函数
  attachInterrupt(0, RightCount_CallBack, FALLING);
  // 设置外部中断1,当引脚1电平从高到低变化时触发LeftCount_CallBack函数
  attachInterrupt(1, LeftCount_CallBack, FALLING);

  // 设置电机引脚为输出模式
  pinMode(leftMotor1, OUTPUT);
  pinMode(leftMotor2, OUTPUT);
  pinMode(rightMotor1, OUTPUT);
  pinMode(rightMotor2, OUTPUT);
  // 设置PWM引脚为输出模式
  pinMode(leftPWM, OUTPUT);
  pinMode(rightPWM, OUTPUT);
}

void loop() {
  // 调用速度检测函数
  SpeedDetection();

  // 如果串口有数据可读
  if (Serial.available() > 0) {
    // 读取蓝牙模块发送到串口的数据
    int cmd = Serial.read();
    // 如果接收到的数据不是换行符,则进行控制
    if (cmd != 10) {
      // 打印接收到的命令
      Serial.print(cmd - 48);
      // 根据命令控制小车运动
      motorRun(cmd - 48);
    }
    // 如果当前是高速档位
    if (speedLevel) {
      // 设置左右轮PWM值为120,对应较低速度
      analogWrite(leftPWM, 120);
      analogWrite(rightPWM, 120);
    } else {
      // 设置左右轮PWM值为250,对应较高速度
      analogWrite(leftPWM, 250);
      analogWrite(rightPWM, 250);
    }
  }
}

// 速度计算函数
bool SpeedDetection() {
  // 获取当前时间(毫秒)
  time = millis();
  // 如果计时时间达到1秒
  if (abs(time - old_time) >= 1000) {
    // 关闭外部中断0和1
    detachInterrupt(0);
    detachInterrupt(1);
    // 计算左右轮转速(转/分钟),并打印到串口
    lv = (float)leftCounter * 60 / 20;
    rv = (float)rightCounter * 60 / 20;
    Serial.print("left:");
    Serial.print(lv);
    Serial.print("     right:");
    Serial.println(rv);
    // 重置左右轮脉冲计数器,记录当前时间,重新开启外部中断0和1
    leftCounter = 0;
    rightCounter = 0;
    old_time = millis();
    attachInterrupt(0, RightCount_CallBack, FALLING);
    attachInterrupt(1, LeftCount_CallBack, FALLING);
    return 1;
  } else {
    return 0;
  }
}

// 右轮编码器中断服务函数,当引脚0电平从高到低变化时触发,增加右轮脉冲计数器
void RightCount_CallBack() {
  rightCounter++;
}

// 左轮编码器中断服务函数,当引脚1电平从高到低变化时触发,增加左轮脉冲计数器
void LeftCount_CallBack() {
  leftCounter++;
}

// 小车运动控制函数,根据命令控制小车运动状态
void motorRun(int cmd) {
  switch (cmd) {
    case FORWARD:
      Serial.println("FORWARD");
      // 设置电机引脚电平,使小车前进
      digitalWrite(leftMotor1, HIGH);
      digitalWrite(leftMotor2, LOW);
      digitalWrite(rightMotor1, HIGH);
      digitalWrite(rightMotor2, LOW);
      break;
    case BACKWARD:
      Serial.println("BACKWARD");
      // 设置电机引脚电平,使小车后退
      digitalWrite(leftMotor1, LOW);
      digitalWrite(leftMotor2, HIGH);
      digitalWrite(rightMotor1, LOW);
      digitalWrite(rightMotor2, HIGH);
      break;
    case TURNLEFT:
      Serial.println("TURN LEFT");
      // 设置电机引脚电平,使小车左转
      digitalWrite(leftMotor1, HIGH);
      digitalWrite(leftMotor2, LOW);
      digitalWrite(rightMotor1, LOW);
      digitalWrite(rightMotor2, HIGH);
      break;
    case TURNRIGHT:
      Serial.println("TURN RIGHT");
      // 设置电机引脚电平,使小车右转
      digitalWrite(leftMotor1, LOW);
      digitalWrite(leftMotor2, HIGH);
      digitalWrite(rightMotor1, HIGH);
      digitalWrite(rightMotor2, LOW);
      break;
    case CHANGESPEED:
      Serial.println("CHANGE SPEED");
      // 切换速度档位
      if (speedLevel)
        speedLevel = 0;
      else
        speedLevel = 1;
      break;
    default:
      Serial.println("STOP");
      // 停止所有电机
      digitalWrite(leftMotor1, LOW);
      digitalWrite(leftMotor2, LOW);
      digitalWrite(rightMotor1, LOW);
      digitalWrite(rightMotor2, LOW);
  }
}

以上为代码的所有内容,如需要每段代码的详细解释请看本系列第二篇文章

六.软件配置

      1.Arduino IDE配置

            (1).打开Arduino IDE并写入代码程序

            (2).选择开发板

            (3).插入开发板并写入程序

      2.蓝牙串口APP配置

            (1).打开蓝牙串口APP,点击键盘,创建如下五个键位

 

             (2).设置完成后如下图所示

七.组装

      完成以上操作并将代码写入到开发板中后可将开发板和各模块组装到汽车模型中,即可进行测试。

八.文献资料

感谢以下文章为本篇文章提供文献参考及图片支持:

HC-05/06

Arduino 上使用 HC06 蓝牙模块 – Arduino 实验室 (nxez.com)icon-default.png?t=N7T8https://arduino.nxez.com/2019/02/18/arduino-uses-hc06-bluetooth-module.html?variant=zh-hkhttps://blog.csdn.net/mtobeiyf/article/details/52096966https://blog.csdn.net/qq_52785624/article/details/123865756https://zhuanlan.zhihu.com/p/138718488?utm_source=qq&utm_id=0

HC-05蓝牙模块使用教程[Arduino]_hc-05蓝牙模块的工作模式-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/Ming2017123123/article/details/104222500

[Arduino]HC-06蓝牙模块使用小结_arduinohc06蓝牙模块详解-CSDN博客文章浏览阅读4.6w次,点赞30次,收藏175次。简介蓝牙,顾名思义,蓝色的牙齿,并不能用来咬人,而是一种无线数据传输标准。 HC-05和HC-06是现在使用较多的两种蓝牙模块。两者之间的区别是HC-05是主从一体机,既能向自己的’主子’打小报告,也可以接收下达的命令;而HC-06只能工作在从机模式下,那就只能乖乖接收上级的命令啦。 在很多情况下,我们都想当“霸道总裁”,让下级乖乖听话就OK了,不需要他多废话。那就用HC-06就够了。 下面是_arduinohc06蓝牙模块详解https://blog.csdn.net/mtobeiyf/article/details/52096966

L298N

L298N介绍 及PWM调速原理-CSDN博客文章浏览阅读4.2w次,点赞41次,收藏369次。L298N介绍 及PWM调速原理_l298nhttps://blog.csdn.net/qq_52785624/article/details/123865756

L298N电机驱动模块的接线使用与代码实现_l298n的ena连接pwm-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_44751294/article/details/110503256

让步进电机动起来——L298N驱动步进电机 - 知乎步进电机特点:它是通过输入脉冲信号来进行控制的电机的总转动角度由输入脉冲数决定电机的转速由脉冲信号频率决定 步进电机主要用于一些有定位要求、进行精确控制的场合。特别适合要求运行平稳、低噪音、响应快、…icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/138718488?utm_source=qq&utm_id=0

总结:

   以上为本篇文章的所有内容,代码分段详细解释将在第二篇展示。如您对本篇文章存在疑问或提供有关改进意见,请在评论区指出,谢谢!!!

   第二篇链接Arduino硬件设计(一)|利用Arduino UNO R3制作手机蓝牙遥控小车---02-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/2301_80771046/article/details/136519380

  • 65
    点赞
  • 93
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
以下是一个简单的Arduino Uno R3蓝牙小车程序示例: ```cpp #include <AFMotor.h> #include <SoftwareSerial.h> #define BT_RX 10 #define BT_TX 11 AF_DCMotor motor1(1); AF_DCMotor motor2(2); SoftwareSerial bluetooth(BT_RX, BT_TX); // 蓝牙串口 void setup() { bluetooth.begin(9600); // 初始化蓝牙串口通信速率 } void loop() { if (bluetooth.available()) { // 如果接收到蓝牙数据 char command = bluetooth.read(); // 读取蓝牙数据 // 根据接收到的指令控制小车运动 if (command == 'F') { // 前进 motor1.setSpeed(255); motor1.run(FORWARD); motor2.setSpeed(255); motor2.run(FORWARD); } else if (command == 'B') { // 后退 motor1.setSpeed(255); motor1.run(BACKWARD); motor2.setSpeed(255); motor2.run(BACKWARD); } else if (command == 'L') { // 左转 motor1.setSpeed(200); motor1.run(BACKWARD); motor2.setSpeed(200); motor2.run(FORWARD); } else if (command == 'R') { // 右转 motor1.setSpeed(200); motor1.run(FORWARD); motor2.setSpeed(200); motor2.run(BACKWARD); } else if (command == 'S') { // 停止 motor1.setSpeed(0); motor1.run(RELEASE); motor2.setSpeed(0); motor2.run(RELEASE); } } } ``` 这个程序使用了AFMotor库和SoftwareSerial库。通过蓝牙串口通信,接收到不同的指令来控制小车的运动。指令包括:'F'(前进)、'B'(后退)、'L'(左转)、'R'(右转)和'S'(停止)。根据接收到的指令,设置两个直流电机的速度和方向来控制小车的运动。 请注意,在使用该程序之前,需要先安装AFMotor库和SoftwareSerial库。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

孟俊宇-MJY

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

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

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

打赏作者

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

抵扣说明:

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

余额充值