树莓派巡线机器人制作

众所周知,树莓派是一个基于ARM微处理器的开发平台。凭借其强大的计算能力,它在广大电子爱好者中经常会创造出奇迹。为了更好地了解树莓派及其工作原理,让我们尝试使用树莓派制作一个巡线机器人。

树莓派线跟随机器人

如果你对机器人感兴趣,那么你应该非常熟悉“巡线机器人”这个名称。这种机器人只需使用一对传感器和马达就能沿着线行走。使用树莓派制造这样一个机器人,会让我们打开更大的想象空间。

寻线机器人的原理

红外线传感器模块

寻线机器人能够在红外传感器的帮助下跟踪线条。红外线传感器具有红外线发射器和红外线接收器,其中,红外线发射器(红外LED)主要发射光,它发射出的红外线只有在被反射时才会返回。接收器(光电二极管)则等待接收返回后的红外光。然而,不是所有的表面都能反射红外线,只有白色的表面才能完全反射红外线,而黑色的表面会吸收红外光。

白线跟随原理

黑线跟随原理

使用这样的两个红外传感器来随时检查机器人是否处于轨道上,如果机器人偏离轨道,我们就通过两个电机来校正它。电机应该是双向旋转的,而且需要的工作电流较大,因此,我们需要额外使用电机驱动模块,如L293D。机器人还需要一个像树莓派(Raspberry Pi)这样的主控大脑,它会根据红外传线传感器模块的数值来指示电机工作。下面是一个简化的控制原理图。

树莓派线跟随机器人控制原理图

两个红外传感器被放置在轨道线的两侧。如果没有传感器检测到黑线,树莓派将命令电机向前移动,如下所示:

巡线机器人沿轨道线前进

如果左边的传感器检测到黑线,那么树莓派就会命令机器人,通过单独旋转右边的轮子,使机器人向左转。

巡线机器人左转

如果右边的传感器检测到黑线,那么树莓派就会命令机器人,通过单独旋转左边的轮子,使机器人向右转。

巡线机器人右转

如果两个传感器都检测到黑线,机器人就会停止。

巡线机器人检测到黑线后停止

这样,机器人就能够在不脱离轨道的情况下沿着轨道线一直前进。下面让我们看看电路和代码。

树莓派寻线机器人电路图

树莓派巡线机器人电路原理图

在这个电路中,包含了两个红外线传感器模块和一对连接到树莓派的直流电机。整个电路由一个移动电源供电(在电路中用电池来表示)。同时,由于树莓派电路板上并没有提供针脚的描述,我们需要用下面的图片来验证每一个引脚的接口定义。图片是基于树莓派2B的,如果你采用树莓派3B,也可以查阅: 树莓派3的外围I/O数据接口

Raspberry-Pi-2-Model-B-GPIO接口定义

如上图所示,左上角的引脚是+5V引脚,我们使用这个+5V引脚给红外传感器供电,如图所示(红色线)。然后,我们用黑色线将GND引脚连接到红外线传感器和电机驱动模块的GND。黄线分别将传感器1和2的输出引脚与GPIO引脚2和3连接起来。同时,要驱动电机,我们需要连接L293D电机驱动板的四个引脚(A,B,A,B)。这四个引脚分别与树莓派的GPIO14,4,17和18连接。电机与L293D电机驱动模块连接,驱动模块使用电池供电。一定要将电池的负极与树莓派的接地连接起来,这样才能保证电路的正常工作。

树莓派编程

首先需要导入GPIO,下面的函数是对树莓派的GPIO引脚进行编程。我们还将“GPIO”重命名为“IO”,所以在程序中,每当我们想要引用GPIO引脚时,我们都会使用“IO”这个词。

import RPi.GPIO as IO

有时,当我们试图使用某个GPIO引脚时,可能它正在执行一些其他功能。在这种情况下,当我们执行程序时会收到警告。下面的命令是告诉树莓派忽略警告继续执行程序。

IO.setwarnings(False)

我们可以参考树莓派的GPIO引脚定义,无论是采用电路板上的引脚号码或采用引脚的功能号码,比如,电路板上的“PIN 29”是“GPIO5”。所以在这里,我们要用下面的代码告诉树莓派具体用的是“29”还是“5”来表示引脚号。

IO.setmode (IO.BCM)

我们前面说到,电路中将设置6个引脚作为输入/输出引脚。前两个引脚是读取红外线传感器数据的输入引脚。后四个是输出引脚,前两个用于控制右电机,后两个用于控制左电机。

IO.setup(2,IO.IN) #GPIO 2 -> Left IR out
IO.setup(3,IO.IN) #GPIO 3 -> Right IR out

IO.setup(4,IO.OUT) #GPIO 4 -> Motor 1 terminal A
IO.setup(14,IO.OUT) #GPIO 14 -> Motor 1 terminal B

IO.setup(17,IO.OUT) #GPIO 17 -> Motor Left terminal A
IO.setup(18,IO.OUT) #GPIO 18 -> Motor Left terminal B

红外传感器如果检测到白色的面,将输出“True”,所以只要两个传感器的状态都是“True”,机器人就可以继续前进。

if(IO.input(2)==True and IO.input(3)==True): #both white move forward    
     IO.output(4,True) #1A+
     IO.output(14,False) #1B-

     IO.output(17,True) #2A+
     IO.output(18,False) #2B-

如果右边的红外传感器检测到黑线,机器人将执行右转动作。当条件满足时,停止右电机,单独旋转左电机,如下面的代码所示:

elif(IO.input(2)==False and IO.input(3)==True): #turn right 
        IO.output(4,True) #1A+
        IO.output(14,True) #1B-

        IO.output(17,True) #2A+
        IO.output(18,False) #2B-

如果左红外传感器检测到黑线,机器人将执行左转动作。当条件满足时,停止左电机,单独旋转右电机,如下面的代码所示:

elif(IO.input(2)==True and IO.input(3)==False): #turn left
        IO.output(4,True) #1A+
        IO.output(14,False) #1B-

        IO.output(17,True) #2A+
        IO.output(18,True) #2B-

如果两个传感器都检测到黑线,这意味着机器人执行停止动作。这可以通过设置电机的两个端子都为“True”来实现,如下面的代码所示:

else:  #stay still
     IO.output(4,True) #1A+
     IO.output(14,True) #1B-

     IO.output(17,True) #2A+
     IO.output(18,True) #2B-

完成变成后,我们可以在白色的瓷砖地面,用黑色胶带粘贴出我们想要的轨道线形状,这样就可以开始享受机器人巡线的乐趣了。下面是完整的Python代码,将其保存到树莓派上,在树莓派命令窗口中执行代码即可。

import RPi.GPIO as IO
import time
IO.setwarnings(False)
IO.setmode(IO.BCM)

IO.setup(2,IO.IN) #GPIO 2 -> Left IR out
IO.setup(3,IO.IN) #GPIO 3 -> Right IR out

IO.setup(4,IO.OUT) #GPIO 4 -> Motor 1 terminal A
IO.setup(14,IO.OUT) #GPIO 14 -> Motor 1 terminal B

IO.setup(17,IO.OUT) #GPIO 17 -> Motor Left terminal A
IO.setup(18,IO.OUT) #GPIO 18 -> Motor Left terminal B

while 1:

 

    if(IO.input(2)==True and IO.input(3)==True): #both while move forward     
        IO.output(4,True) #1A+
        IO.output(14,False) #1B-

        IO.output(17,True) #2A+
        IO.output(18,False) #2B-

    elif(IO.input(2)==False and IO.input(3)==True): #turn right  
        IO.output(4,True) #1A+
        IO.output(14,True) #1B-

        IO.output(17,True) #2A+
        IO.output(18,False) #2B-

    elif(IO.input(2)==True and IO.input(3)==False): #turn left
        IO.output(4,True) #1A+
        IO.output(14,False) #1B-

        IO.output(17,True) #2A+
        IO.output(18,True) #2B-

    else:  #stay still
        IO.output(4,True) #1A+
        IO.output(14,True) #1B-

        IO.output(17,True) #2A+
        IO.output(18,True) #2B-

分享到: