基于Arduino构建一个智能吸尘机器人

音视频及家电

734人已加入

描述

在当今的情况下,我们都忙于工作,没有时间正确打扫房子。这个问题的解决方法很简单,你只需要买一个家用吸尘器机器人,比如irobot roomba,它会通过按下一个按钮来清洁你的房子。但是这些商业产品有一个共同的问题,那就是成本。所以今天,我们决定做一个简单的扫地机器人, 与市面上的商业产品相比,它不仅制作简单,而且成本非常低。经常阅读的读者可能还记得我们很久以前制造的Arduino 吸尘机器人,但那个机器人非常笨重,需要一个大的铅酸电池才能移动。新的Arduino 吸尘器 我们将在这里建造将更紧凑,更实用。最重要的是,该机器人将配备超声波传感器和红外接近传感器。超声波传感器将允许机器人避开障碍物,以便它可以自由移动,直到房间被正确清洁,接近传感器将帮助它避免从楼梯上摔下来。

构建基于 Arduino 的地板清洁机器人所需的材料

由于我们使用非常通用的组件来构建真空吸尘器机器人的硬件部分,因此您应该能够在当地的爱好商店中找到所有这些组件。这是所需材料的完整列表以及所有组件的图像。

机器人

Arduino Pro 迷你 - 1

HC-SR04 超声波模块 - 3

L293D 电机驱动器 - 1

5Volt N20 电机和安装支架 - 2

N20 电动车轮 - 2

开关 - 1

LM7805 稳压器 - 1

7.4V 锂离子电池 - 1

红外模块 - 1

穿孔板 - 1

脚轮 - 1

中密度纤维板

通用便携式吸尘器

便携式吸尘器

在组件需求部分,我们谈到了便携式真空吸尘器,下图正是展示了这一点。这是一款来自亚马逊的便携式吸尘器。这带有一个非常简单的机制。它在底部有三个部分(一个用于储存灰尘的小室,中间部分包括电机、风扇和顶部的电池插座(有一个电池盖或盖子)。它有一个直流电机和一个风扇。这个电机通过一个简单的开关直接连接到 3V(2*1.5volt AA 电池)。由于我们用 7.4V 电池为机器人供电,我们将切断内部电池的连接并从 5V 供电电源。所以,我们去掉了所有不必要的部件,只剩下两线电机。你可以在下图中看到。

机器人

HC-SR04 超声波传感器模块

机器人

为了检测障碍物,我们使用了流行的HC-SR04 超声波距离传感器 ,也可以称之为避障传感器。工作很简单,首先,发射器模块发送一个超声波,该超声波在空气中传播,遇到障碍物,然后反弹回来,接收器接收到该波。通过用Arduino计算时间,我们可以确定距离。在之前关于基于 Arduino 的超声波距离传感器项目的文章中,我们已经非常深入地讨论了这种传感器的工作原理。如果您想了解有关 HC-SR04 超声波距离传感器模块的更多信息,可以查看。

用于楼梯检测的地板传感器(IR 传感器)

机器人

在功能部分,我们已经讨论了机器人可以检测楼梯并防止自己跌倒的功能。为此,我们使用了IR Sensor。我们将在IR 传感器和 Arduino之间建立一个接口。IR Proximity Sensor的工作原理很简单,它有一个 IR LED 和一个光电二极管,IR LED 发出 IR 光,如果有任何障碍物挡在发出的光的前面,它就会被反射,并检测到反射光由光电二极管。但是反射产生的电压会非常低。为了增加它,我们可以使用运算放大器比较器,我们可以放大并获得输出。红外模块具有三个引脚 - Vcc、接地和输出。通常,当传感器前面有障碍物时,输出会变低。所以,我们可以用它来检测地板。如果在一瞬间,我们从传感器检测到高电平,我们可以停止机器人,将其转回或做任何我们想要防止它从楼梯上掉下来的事情。在上一篇文章中,我们制作了一个面包板版本的红外接近传感器模块并详细解释了工作原理,如果您想了解更多关于该传感器的信息,可以查看。

基于Arduino的地板清洁机器人电路图

机器人

我们有三个检测障碍物的超声波传感器。因此,我们需要连接超声波传感器的所有地线并将它们连接到公共地线。此外,我们连接传感器的所有三个 Vcc 并将其连接到公共 VCC 引脚。接下来,我们将触发和回声引脚连接到 Arduino 的 PWM 引脚。我们还将 IR 模块的 VCC 连接到 5V,并将地连接到 Arduino 的接地引脚,IR 传感器模块的输出引脚连接到 Arduino 的数字引脚 D2。对于电机驱动器,我们将两个使能引脚连接到 5v,并将驱动器电压引脚连接到 5V,因为我们使用的是 5 伏电机。在上一篇文章中,我们制作了一个Arduino 电机驱动器扩展板,您可以查看它以了解有关L293D 电机驱动器 IC的更多信息及其操作。Arduino、超声波模块、电机驱动器和电机在 5 伏电压下工作,更高的电压会杀死它,我们使用 7.4 伏电池,将其转换为 5 伏,使用 LM7805 稳压器。将真空吸尘器直接连接到主电路。

为基于 Arduino 的地板清洁机器人构建电路

机器人

要将每个组件焊接在一起,首先,我拿了一小块点状穿孔板,根据电路图放置每个组件,然后焊接所有东西。这部分非常简单,但要小心。此外,我们使用了两个母头来放置Arduino pro mini。完成穿孔板焊接后,我们将电线连接到超声波模块,并将它们连接到相应的引脚上,如图所示。

为基于 Arduino 的地板清洁机器人建造外壳

为了得到一些关于我的机器人的想法,我在网上搜索了吸尘器机器人,得到了一些圆形机器人的图像。所以,我决定造一个圆形机器人。为了构建机器人的追逐和身体,我有很多选择,如泡沫板、MDF、纸板等。但我选择 MDF 是因为它很硬并且具有一些防水特性。如果您这样做,您可以决定为您的机器人选择哪种材料。

为了构建机器人,我拿了 MDF 板,然后画了两个半径为 8 CM 的圆, 在那个圆内,我还画了另一个半径为 4 CM的圆用于安装真空吸尘器。然后我剪掉了圆圈。此外,我已经为车轮路径切割并移除了适当的部分(请参阅图像以更好地理解)。最后,我为脚轮打了三个小孔。下一步是使用支架将电机安装在底座上,同时将脚轮放置并固定到其位置。之后,将超声波传感器放置在机器人的左侧、右侧和中间。此外,将 IR 模块连接到机器人的底部。不要忘记在外面添加开关。这就是构建机器人的全部内容,如果您对此感到困惑,可以参考以下图片。

机器人

最上面的部分,我还在泡沫板上画了一个半径为11CM的圆,剪下来。对于顶部和底部之间的间距,我切了三个 4 厘米长的塑料管。之后,我将塑料垫片粘在底部,然后粘在顶部。如果需要,您可以用塑料或类似材料覆盖机器人的侧面部分。

机器人

基于Arduino的地板清洁机器人 - 代码

该项目的完整代码在文档末尾给出。这个 Arduino 代码类似于基于 Arduino 的超声波距离传感器代码,唯一的变化是地板检测。在以下几行中,我将解释代码是如何工作的。在这种情况下,我们没有使用任何额外的库。下面我们一步一步地描述了代码。我们没有使用任何额外的库来解码来自 HC-SR04 传感器的距离数据,因为它非常简单。在以下几行中,我们描述了如何。首先,我们需要为连接到 Arduino 板的所有三个超声波距离传感器定义 Trigger Pin 和 Echo Pin。在这个项目中,我们有三个 Echo 引脚和三个 Trigger 引脚。请注意,1 是左传感器,2 是前传感器,3 是右传感器。

 

常量 int trigPin1 = 3; 
常量 int echoPin1 = 5; 
常量 int trigPin2 = 6; 
常量 int echoPin2 =9; 
常量 int trigPin3 = 10; 
常量 int echoPin3 = 11; 
int irpin = 2;

 

然后我们为距离定义变量,这些变量都是 (int) 类型变量,对于持续时间,我们选择使用 (long)。同样,我们每个人都有三个。另外,我已经定义了一个整数来存储运动的状态,我们将在本节后面讨论它。

 

持续时间长1;
持续时间长2;
持续时间长3;
int距离左;
int 距离前沿;
int distanceright; 
诠释a = 0;

 

接下来,在设置部分,我们需要使用 pinModes() 函数将所有透视引脚设置为输入或输出。要从模块发送超声波,我们需要将触发引脚设为高电平,即所有触发引脚都应定义为 OUTPUT。为了接收回声,我们需要读取回声引脚的状态,因此所有回声引脚都应定义为 INPUT。此外,我们启用串行监视器以进行故障排除。为了读取 IR 模块的状态,我将irpin定义为输入。

 

pinMode(trigPin1,输出);
pinMode(trigPin2,输出);
pinMode(trigPin3,输出);
pinMode(echoPin1,输入);
pinMode(echoPin2,输入);
pinMode(echoPin3,输入);
pinMode(irpin,输入);

 

这些数字引脚被定义为电机驱动器输入的输出。

 

pinMode(4,输出);
pinMode(7,输出);
pinMode(8,输出);
pinMode(12,输出);

 

在主循环中,我们为三个传感器设置了三个部分。所有部分的工作方式相同,但每个部分用于不同的传感器。在本节中,我们从每个传感器读取障碍物距离并将其存储在每个定义的整数中。要读取距离,首先,我们必须确保触发引脚清晰,为此,我们需要将触发引脚设置为 低电平 2 µs。现在,为了产生超声波,我们需要将触发引脚设为 高电平 10 µs。这将发送超声波,在 pulseIn() 函数的帮助下,我们可以读取行进时间,并将该值存储到变量“持续时间”中。这个函数有2个参数,第一个是echo pin的名字,第二个可以写高或 低。HIGH 表示 pulseIn () 函数将等待  由反弹的声波引起 的引脚变为高电平并开始计数,然后 在声波结束时等待引脚变为低电平将停止计数。该函数以微秒为单位给出脉冲的长度。为了计算距离,我们将持续时间乘以 0.034(空气中的声速为 340m/s)再除以 2(这是由于声波的来回传播)。最后,我们将每个传感器的距离存储在相应的整数中。

 

数字写入(trigPin1,低);
延迟微秒(2);
数字写入(trigPin1,高);
延迟微秒(10);
数字写入(trigPin1,低);
持续时间1 = 脉冲输入(echoPin1,高);
距离左 = 持续时间 1 * 0.034 / 2;

 

在得到每个传感器的距离后,我们可以在if 语句的帮助下控制电机,从而控制机器人的运动。这很简单,首先,我们给了一个障碍物距离值,在这个例子中,它是 15cm(根据你的意愿改变这个值)。然后我们根据该值给出条件。例如,当左侧传感器前方有障碍物(即左侧传感器的距离应小于或等于 15 厘米)且其他两个距离较高(即传感器前方没有障碍物)时,然后借助数字写入功能,我们可以将电机驱动到正确的位置。后来,我检查了红外传感器的状态。如果机器人在地板上,则 IR 引脚的值为LOW,如果不是,则值为高。然后我将该值存储在int s 变量中。我们将根据这个状态来控制机器人。

这部分代码用于向前和向后移动机器人:

 

if(s==HIGH) 
  { 
    digitalWrite(4, LOW); 
    数字写入(7,高);
    数字写入(8,低);
    数字写入(12,高);
      延迟(1000);
    a=1; 
        }

 

但是这种方法有一个问题,当电机向后移动,地板回来,机器人向前移动时,它会重复使机器人卡住。 为了克服这个问题,我们在理解 floor 不存在后将值 (1) 存储在int中。我们还检查这种情况是否有其他运动。

检测到没有地板后,机器人不会向前移动。相反,它会向左移动,这样我们就可以避免这个问题。

 

if ((a==0)&&(s==LOW)&&(distanceleft <= 15 && distancefront > 15 && distanceright <= 15) || (a==0)&&(s==LOW)&&(distanceleft > 15 && distancefront > 15 && distanceright > 15))

 

在上述情况下。首先,机器人会检查楼层状态和整数值。只有满足所有条件,机器人才会继续前进。

现在,我们可以为电机驱动器编写命令了。这将驱动右电机向后和左电机向前,从而将机器人向右转动。

这部分代码用于向右移动机器人:

 

数字写入(4,高);
数字写入(7,低);
数字写入(8,高);
数字写入(12,低);

 

如果机器人检测到地板不存在,则该值变为 1,机器人将向左移动。左转后,'a' 的值从 1 变为 0。

 

 if ((a==1) &&(s==LOW) ||(s==LOW) && (distanceleft <= 15 && distancefront <= 15 && distanceright > 15) || (s== LOW) && (distanceleft <= 15 && distancefront <= 15 && distanceright > 15) || (s==LOW) && (distanceleft <= 15 && distancefront > 15 && distanceright > 15) || (distanceleft <= 15 && distancefront > 15 && distanceright > 15)) 
  { 
    digitalWrite(4, HIGH); 
    数字写入(7,低);
    数字写入(8,低);
    数字写入(12,高);
    延迟(100);
    a=0;
  }

 

这部分代码用于向左移动机器人:

 

if ((s==LOW)&&(distanceleft > 15 && distancefront <= 15 && distanceright <= 15) ||(s==LOW)&& (distanceleft > 15 && distancefront > 15 && distanceright <= 15) ||( s==LOW)&& (distanceleft > 15 && distancefront <= 15 && distanceright > 15) ) 
    { 
    digitalWrite(4, LOW); 
    数字写入(7,高);
    数字写入(8,高);
    数字写入(12,低);
  }

 

机器人
 

 

//定义引脚
常量 int trigPin1 = 3;
常量 int echoPin1 = 5;
常量 int trigPin2 = 6;
常量 int echoPin2 = 9;
常量 int trigPin3 = 10;
常量 int echoPin3 = 11;
int irpin = 2;
// 定义变量
持续时间长1;
持续时间长2;
持续时间长3;
int距离左;
int 距离前沿;
int distanceright;
诠释a = 0;
无效设置(){
  pinMode(trigPin1,输出);
  pinMode(trigPin2,输出);
  pinMode(trigPin3, OUTPUT);// 将 trigPin 设置为输出
  pinMode(echoPin1,输入);// 将 echoPin 设置为输入
  pinMode(echoPin2,输入);
  pinMode(echoPin3,输入);
  pinMode(irpin,输入);
  pinMode(4,输出);
  pinMode(7,输出);
  pinMode(8,输出);
  pinMode(12,输出);
}
无效循环(){
  数字写入(trigPin1,低);
  延迟微秒(2);
  数字写入(trigPin1,高);
  延迟微秒(10);
  数字写入(trigPin1,低);
  持续时间1 = 脉冲输入(echoPin1,高);
  距离左 = 持续时间 1 * 0.034 / 2;
  Serial.print("距离1:");
  Serial.println(distanceleft);
  数字写入(trigPin2,低);
  延迟微秒(2);
  数字写入(trigPin2,高);
  延迟微秒(10);
  数字写入(trigPin2,低);
  持续时间2 = 脉冲输入(echoPin2,高);
  距离前沿 = 持续时间 2 * 0.034 / 2;
  Serial.print("距离2:");
  Serial.println(distancefront);
  数字写入(trigPin3,低);
  延迟微秒(2);
  数字写入(trigPin3,高);
  延迟微秒(10);
  数字写入(trigPin3,低);
  持续时间3 = 脉冲输入(echoPin3,高);
  distanceright = duration3 * 0.034 / 2;
  Serial.print("距离3:");
  Serial.println(distanceright);
  int s = digitalRead(irpin);
  如果(s==高)
  {
    数字写入(4,低);
    数字写入(7,高);
    数字写入(8,低);
    数字写入(12,高);
      延迟(1000);
    a=1;
    }
  if ((a==0)&&(s==LOW)&&(distanceleft <= 15 && distancefront > 15 && distanceright <= 15) || (a==0)&&(s==LOW)&&(distanceleft > 15 && distancefront > 15 && distanceright > 15))
  {
    数字写入(4,高);
    数字写入(7,低);
    数字写入(8,高);
    数字写入(12,低);
  }
  if ((a==1)&&(s==LOW)||(s==LOW)&&(distanceleft <= 15 && distancefront <= 15 && distanceright > 15)||(s==LOW)&&(distanceleft <= 15 && distancefront <= 15 && distanceright > 15)||(s==LOW)&& (distanceleft <= 15 && distancefront > 15 && distanceright > 15)||(distanceleft <= 15 && distancefront > 15 && distanceright > 15))
  {
    数字写入(4,高);
    数字写入(7,低);
    数字写入(8,低);
    数字写入(12,高);
    延迟(100);
    a=0;
  }
  if ((s==LOW)&&(distanceleft > 15 && distancefront <= 15 && distanceright <= 15) ||(s==LOW)&& (distanceleft > 15 && distancefront > 15 && distanceright <= 15) ||( s==LOW)&& (distanceleft > 15 && distancefront <= 15 && distanceright > 15))
  {
    数字写入(4,低);
    数字写入(7,高);
    数字写入(8,高);
    数字写入(12,低);
  }
}

 

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分