从小对机器人非常感兴趣,正好身边有一个raspberry pi,平时就当Linux的服务器练练命令行,写写脚本。这次打算把raspberry pi的强大的GPIO都利用起来,做个小机器人。


首先从网上买了机器人相关的配件,主要是驱动机器人移动的电机、L298N电机驱动板、HC-SR04超声波距离探测传感器、机器人车身等配件。用来制作机器人的是raspberry pi B+。此型号一共有40个GPIO口,足以满足入门型机器人的制作要求。


以下是我连接L298N电机驱动板和HC-SR04距离传感器的GPIO针脚示意图。



3V3 

5V

uVcc


SDA1

5V



SCL1

GND



GP4

TXD0



GND

RXD0


N3

GP17

GP18

uEcho

N2

GP27

GND

uGND

N1

GP22

GP23

N4


3V3

GP24

uTrig


MOSI

GND



MISO

GP25



SCLK

CE0



GND

CE1



EED

EEC



GP5

GND



GP6

GP12



GP13

GND



GP19

GP16



GP26

GP20

ENB


GND

GP21

ENA


raspberry pi驱动电机的主要原理是,通过在电机两极上施加电压使之转动,利用两个针脚之间的高低电平差决定转动方向。


首先为了驱动电机,写了一个关于motor的类文件。

pi@raspberrypi ~/robot/class $ cat motor.py
#!/usr/bin/python
import RPi.GPIO as GPIO
from time import sleep
import sys
import os,tty,termios,time

time_sleep = 1
class motor:
    RIGHT = 15
    LEFT = 16
    RIGHTB = 13
    LEFTB = 11
    RIGHTPWM = 40
    LEFTPWM = 38


    def __init__(self):
        GPIO.setmode(GPIO.BOARD)
        GPIO.setwarnings(False)

        GPIO.setup(self.RIGHTPWM, GPIO.OUT)
        self.rightpwm = GPIO.PWM(self.RIGHTPWM, 500)
        self.rightpwm.start(0)
        GPIO.setup(self.RIGHT, GPIO.OUT)
        GPIO.setup(self.RIGHTB, GPIO.OUT)
        GPIO.setup(self.LEFTPWM, GPIO.OUT)
        self.leftpwm = GPIO.PWM(self.LEFTPWM,500) 
        self.leftpwm.start(0)
        GPIO.setup(self.LEFT, GPIO.OUT)
        GPIO.setup(self.LEFTB, GPIO.OUT)
        
    def motor(self,leftspeed,left,rightspeed,right): # initiate speed
        self.rightpwm.ChangeDutyCycle(leftspeed*100) # leftspeed 0 to 1
        GPIO.output(self.RIGHTPWM, right)            # right True or False
        self.leftpwm.ChangeDutyCycle(rightspeed*100) # rightspeed 0 to 1
        GPIO.output(self.LEFTPWM, left)              # left True or False
   
    
    def forward(self,lspeed,rspeed, second):
        GPIO.output(self.LEFTB, False)
        GPIO.output(self.LEFT, True)
        GPIO.output(self.RIGHT, True)
        GPIO.output(self.RIGHTB, False)
        self.motor(lspeed,0,rspeed,0)
        if second > 0:
            time.sleep(second)
            self.stop()
    def stop(self):
        self.motor(0,0,0,0)

    def reverse(self, lspeed,rspeed, second):
        GPIO.output(self.LEFTB, True)
        GPIO.output(self.LEFT, False)
        GPIO.output(self.RIGHT, False)
        GPIO.output(self.RIGHTB, True)
        self.motor(lspeed,0,rspeed,0)
        if second > 0:
            time.sleep(second)
            self.stop()

    def right(self, lspeed, rspeed, second):
        GPIO.output(self.LEFTB, True)
        GPIO.output(self.LEFT, True)
        GPIO.output(self.RIGHT,True)
        GPIO.output(self.RIGHTB, False)
        self.motor(lspeed,0,rspeed,0)
        if second > 0:
            time.sleep(second)
            self.stop()

    def left(self, lspeed, rspeed, second):
        GPIO.output(self.LEFTB, False)
        GPIO.output(self.LEFT, True)
        GPIO.output(self.RIGHT,True)
        GPIO.output(self.RIGHTB, True)
        self.motor(lspeed,0,rspeed,0)
        if second > 0:
            time.sleep(second)
            self.stop()

    def pivot_right(self, lspeed, rspeed, second):
        GPIO.output(self.LEFTB, True)
        GPIO.output(self.LEFT, False)
        GPIO.output(self.RIGHT,True)
        GPIO.output(self.RIGHTB, False)
        self.motor(lspeed,0,rspeed,0)
        if second > 0:
            time.sleep(second)
            self.stop()

    def pivot_left(self, lspeed, rspeed, second):
        GPIO.output(self.LEFTB, False)
        GPIO.output(self.LEFT, True)
        GPIO.output(self.RIGHT,False)
        GPIO.output(self.RIGHTB, True)
        self.motor(lspeed,0,rspeed,0)
        if second > 0:
            time.sleep(second)
            self.stop()

然后编写通过控制端电脑键盘控制机器人的程序,此程序调用motor.py这个驱动脚本

#!/usr/bin/python

import motor
import time
import sys
import os,tty,termios,time

time_sleep = 0.070
lspeed = 1 
rspeed = 1
m = motor.motor()

def getch():
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    try:
        tty.setraw(sys.stdin.fileno())
        ch = sys.stdin.read(1)
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    return ch

while True:
    char = getch()
    
    if(char == 'w'):
        m.forward(lspeed,rspeed,time_sleep)
    if(char == 's'):
        m.reverse(lspeed,rspeed,time_sleep)
    if(char == 'a'):
        m.left(lspeed,rspeed,time_sleep)
    if(char == 'd'):
        m.right(lspeed,rspeed,time_sleep)
    if(char == 'q'):
        m.pivot_left(lspeed,rspeed,time_sleep)
    if(char == 'e'):
        m.pivot_right(lspeed,rspeed,time_sleep)
    if(char == 'c'):
        os.system('/home/pi/camera/startstream.sh')
    if(char == 'x'):
        os.system('/home/pi/camera/stopstream.sh')
    if(char == 'n'):
        os.system('/home/pi/robot/class/autodrive.sh')
    if(char == 'f'):
        print("Program Ended")
        break

此后我可以通过wifi网络用电脑远程控制机器人了。