搜索代码

第27/31课:Car-5 SunFounder智能车使用Arduino跟随你的手 | Robojax

第27/31课:Car-5 SunFounder智能车使用Arduino跟随你的手 | Robojax

简介

你是否曾想打造一个能对你的存在做出直观响应的机器人?本项目将一辆标准的SunFounder智能车改装为一辆手势控制的车辆,使其能够跟随你的手。这辆车不使用遥控器或智能手机应用,而是结合超声波和红外传感器来检测你手的位置和距离,让你通过简单自然的动作引导它向左、向右或向前移动。

27-SunFounder-Car-5-Follow-Hand

本项目是Robojax Arduino课程(第27/31课)的一部分,使用SunFounder 3合1 Arduino套件构建。这是学习传感器融合的绝佳方式,即多个传感器协同工作以产生更复杂、更灵敏的行为。其实际价值在于理解如何结合不同类型的输入来做出决策,这是机器人和自动化领域的基本概念。

以下是一些你可以基于此逻辑扩展的实际想法:

  • 互动展品:创建一个跟随参观者的小型机器人展示,以吸引他们的注意力。
  • 自主避障平台:修改代码,让车辆通过避开障碍物来在房间中导航,而不是跟随手。
  • 教育机器人套件:将此作为基础项目,向学生教授传感器集成、逻辑和电机控制。
  • 智能送货小车:在受控环境中,此逻辑可适用于在仓库或工厂环境中跟随人员的小型推车。

硬件与组件

本项目使用SunFounder 3合1 Arduino套件中包含的组件。你将使用的核心组件包括:

  • SunFounder智能车底盘:带有轮子和电机的物理平台。
  • Arduino板:运行代码的车辆“大脑”。
  • 超声波传感器(HC-SR04):用于测量车辆前方物体(你的手)的距离。
  • 两个红外避障传感器:安装在左右两侧,用于检测手在两侧的存在。
  • 电机驱动器:一个模块(通常是L298N或类似型号),用于根据Arduino的信号控制车辆电机的速度和方向。
  • 电源:为Arduino和电机供电的电池。

接线指南

car_7_8_follow_hand

如视频中所述,本项目的接线与之前课程中避障车的接线完全相同。传感器和电机都连接到Arduino的数字和模拟引脚。如需视觉参考,请参阅SunFounder智能车的接线图。

代码定义了每个组件使用的特定引脚,这些将在下一节中详细说明。

代码解释

本节重点介绍代码中你可能希望为自己的车辆调整的用户可配置部分。完整程序可在Robojax资源页面下载。

在代码的最顶部,你会找到引脚定义。如果你以不同于讲师的方式接线,这些是最关键的需要理解的行。

const int A_1B = 5;
const int A_1A = 6;
const int B_1B = 9;
const int B_1A = 10;

const int rightIR=7;
const int leftIR=8;

const int trigPin = 3;
const int echoPin = 4;

以下是每组引脚的作用:

  • 电机引脚(A_1A、A_1B、B_1A、B_1B):这些是连接到电机驱动器以控制两个电机的引脚。“A”和“B”标签通常分别指左电机和右电机。如果你的电机驱动器连接到不同的Arduino引脚,则必须更改这些值。
  • 红外传感器引脚(rightIR、leftIR):这些数字输入引脚读取左右红外避障传感器的信号。值为0表示检测到障碍物(你的手),而1表示路径畅通。
  • 超声波传感器引脚(trigPin、echoPin):trigPin是输出引脚,发送短超声波脉冲,而echoPin是输入引脚,读取反射脉冲的持续时间以计算距离。

loop()函数内部,你会找到主要行为逻辑。有一个你可能希望调整的变量:

int speed = 150;

speed变量控制运动期间发送到电机的功率。其范围可以从0(停止)到255(最大速度)。你可以增加此值(例如,到200)以获得更快的车辆,或减少此值(例如,到100)以获得更可控、更慢的运动。

代码还包含诸如moveForward()turnLeft()turnRight()之类的函数。这些函数用于控制车辆的运动,并根据传感器读数被调用。你无需修改它们,但可以将它们用作构建块来创建自己的自定义行为。

“跟随你的手”逻辑的工作原理

这个项目的奇妙之处在于Arduino如何解读来自三个传感器的数据。逻辑简单明了,并在loop()函数中持续执行。

首先,小车使用超声波传感器测量正前方物体的距离。然后,它检查两个红外传感器,判断物体是在左侧还是右侧。决策过程如下:

  1. 前进:如果超声波传感器测得的距离大于5厘米但小于10厘米,小车前进。这形成了一个“最佳区域”,小车会跟随你的手。
  2. 左转:如果距离不在该区域内,小车会检查红外传感器。如果左侧传感器被遮挡(你的手在左侧)而右侧传感器畅通,小车左转。
  3. 右转:相反,如果右侧传感器被遮挡而左侧畅通,小车右转。
  4. 停止:如果以上条件均不满足——例如,你的手太远或太近——小车停止。

这套简单的规则使小车能够根据你手的位置动态反应,形成流畅而直观的跟随行为。

项目现场演示

在视频演示中,讲师实时展示了小车的表现。串口监视器用于显示超声波传感器读取的距离。当小车静止且你的手距离较远(例如36厘米)时,它保持停止状态。一旦你将手放在小车前方5-10厘米的区域内,它便开始前进。

演示还重点展示了转向逻辑。当你的手放在小车左侧时,左侧红外传感器被触发,小车左转。同样,将手放在右侧会使小车右转。当你移动手时,小车会持续跟随,只有在你将手移出传感器范围或离得太近时才会停止。这证实了传感器融合和逻辑按预期工作,打造出一个响应灵敏且趣味十足的项目。

章节

  • [00:00] 手跟随智能小车简介
  • [00:35] 关于Robojax Arduino课程与套件
  • [01:41] 项目概览与代码设置
  • [02:19] 引脚定义与设置说明
  • [03:19] 跟随手部动作的代码逻辑
  • [05:48] 小车实际运行现场演示
  • [07:28] 最终演示与性能评估

图像

Car 7 8 follow hand
Car 7 8 follow hand
27 SunFounder Car 5 follow hand
27 SunFounder Car 5 follow hand
898-Lesson 27/31: Car-5 SunFounder Smart Car Follows Your Hand
语言: C++
/*
Lesson 27/31: Car-5 SunFounder Smart Car Follows Your Hand
Get this code and watch video Download and resource page https://robojax.com/RJT610
YouTube video https://www.youtube.com/watch?v=mcbJlE7-8ro

*/
const int A_1B = 5;
const int A_1A = 6;
const int B_1B = 9;
const int B_1A = 10;

const int rightIR=7;
const int leftIR=8;

const int trigPin = 3;
const int echoPin = 4;

void setup() {
  Serial.begin(9600);

  //motor
  pinMode(A_1B, OUTPUT);
  pinMode(A_1A, OUTPUT);
  pinMode(B_1B, OUTPUT);
  pinMode(B_1A, OUTPUT);

  //IR obstacle
  pinMode(leftIR,INPUT);
  pinMode(rightIR,INPUT);
  
  //ultrasonic
  pinMode(echoPin, INPUT);
  pinMode(trigPin, OUTPUT);
}

void loop() {

  float distance = readSensorData();

  int left = digitalRead(leftIR);  // 0: Obstructed   1: Empty
  int right = digitalRead(rightIR);
  int speed = 150;

  if (distance>5 && distance<10){
    moveForward(speed);
  }else if(!left&&right){
    turnLeft(speed);
  }else if(left&&!right){
    turnRight(speed);
  }else{
    stopMove();
  }
}

float readSensorData() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  float distance = pulseIn(echoPin, HIGH) / 58.00; //Equivalent to (340m/s*1us)/2
  return distance;
}

void moveForward(int speed) {
  analogWrite(A_1B, 0);
  analogWrite(A_1A, speed);
  analogWrite(B_1B, speed);
  analogWrite(B_1A, 0);
}

void moveBackward(int speed) {
  analogWrite(A_1B, speed);
  analogWrite(A_1A, 0);
  analogWrite(B_1B, 0);
  analogWrite(B_1A, speed);
}

void turnRight(int speed) {
  analogWrite(A_1B, speed);
  analogWrite(A_1A, 0);
  analogWrite(B_1B, speed);
  analogWrite(B_1A, 0);
}

void turnLeft(int speed) {
  analogWrite(A_1B, 0);
  analogWrite(A_1A, speed);
  analogWrite(B_1B, 0);
  analogWrite(B_1A, speed);
}

void stopMove() {
  analogWrite(A_1B, 0);
  analogWrite(A_1A, 0);
  analogWrite(B_1B, 0);
  analogWrite(B_1A, 0);
}

文件📁

Arduino 库(zip 格式)