Python3实现树莓派4驱小车控制程序详解
本文介绍如何使用Python3在树莓派上实现四驱小车的运动控制。内容涵盖硬件准备、L298N驱动模块连接注意事项、GPIO引脚配置文件config.ini的编写,以及基于configparser和RPi.GPIO库的控制程序car_controler.py核心代码。重点解析前后左右四个电机的引脚定义及方向控制逻辑,为硬件爱好者提供完整的软件实现参考。
前言
前言
约一两个月前,我偶然获得了一台树莓派一代设备,发现其性能相当强劲,由此萌生了自制四驱小车的想法。作为软件背景出身的人,通过软件操控实体硬件一直是我心中的梦想。为此,我投入了大量时间进行研究和实验,记录当时遇到的坑、实现思路以及大部分源代码。目前,我的树莓派小车已实现以下主要功能:
- 控制小车执行前进、后退、左转、右转、后左转向及后右转向动作。
- 通过两个舵机控制摄像头,实现上下左右旋转监控。
- 开发网页版小车控制程序,包含车辆控制、实时监控及摄像头旋转功能。
- 开发微信小程序版小车控制程序,功能基本与网页版一致。
注:本文仅介绍上述第一项功能(基础运动控制),其他功能的实现将在后续博文中详细介绍。
准备工作
准备工作
- 为树莓派安装操作系统(网络资料丰富,推荐使用raspbian系统)。
- 安装Python3运行环境。
- 准备四个步进电机及配套驱动模块,并完成组装连接。我的电机及组件购自“亚博智能科技”,L298N四路电机驱动模块购自“深圳市艾尔赛科技”。
可能遇到的常见问题及解决方案:
- 首先需关注电机驱动的输入电压。电压过低可能导致电机无法带动负载,而电压过高则可能损坏设备,需保持适中。
- 电机驱动模块的GND引脚必须与树莓派的一个GND输出端相连。若未共地,可能导致驱动异常。例如,我遇到的情况是:手接触驱动电路中的金属部分时电机能正常转动,但手一离开电机便无法正常运转,这通常是由于接地不良引起的。
基本实现思路
基本实现思路
- 将连接的GPIO端口封装为配置文件,明确定义小车各轮子所需的引脚号。
- 控制程序读取该配置文件,根据配置实现小车的方向控制逻辑。
- 小车控制程序定义了私有方法,分别对应各个方向的移动动作。此外,定义一个接收方向参数的公共方法,该方法内部调用具体的私有移动方法,从而封装底层细节。
需要特别说明的是,由于不同硬件使用的引脚可能不同,且电机安装位置存在差异,以下提供的程序代码不能保证直接适用于所有硬件组合,用户需根据实际硬件调整引脚配置。
配置文件与源码示例
配置文件内容示例(文件名为:config.ini):
[car]
# This is the parmaters that will control the car's wheels
# The number is the interface number of GPIO (GPIO.BOARD)
LEFT_FRONT_1 = 7
LEFT_FRONT_2 = 11
RIGHT_FRONT_1 = 13
RIGHT_FRONT_2 = 15
LEFT_BEHIND_1 = 31
LEFT_BEHIND_2 = 33
RIGHT_BEHIND_1 = 35
RIGHT_BEHIND_2 = 37
小车控制程序源码(文件名为:car_controler.py):
# coding=utf-8
import RPi.GPIO as GPIO
import time
import configparser
class FourWheelDriveCar():
# Define the number of all the GPIO that will used for the 4wd car
def __init__(self):
'''
1. Read pin number from configure file
2. Init all GPIO configureation
'''
config = configparser.ConfigParser()
config.read("config.ini")
self.LEFT_FRONT_1 = config.getint("car", "LEFT_FRONT_1")
self.LEFT_FRONT_2 = config.getint("car", "LEFT_FRONT_2")
self.RIGHT_FRONT_1 = config.getint("car", "RIGHT_FRONT_1")
self.RIGHT_FRONT_2 = config.getint("car", "RIGHT_FRONT_2")
self.LEFT_BEHIND_1 = config.getint("car", "LEFT_BEHIND_1")
self.LEFT_BEHIND_2 = config.getint("car", "LEFT_BEHIND_2")
self.RIGHT_BEHIND_1 = config.getint("car", "RIGHT_BEHIND_1")
self.RIGHT_BEHIND_2 = config.getint("car", "RIGHT_BEHIND_2")
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(self.LEFT_FRONT_1, GPIO.OUT)
GPIO.setup(self.LEFT_FRONT_2, GPIO.OUT)
GPIO.setup(self.RIGHT_FRONT_1, GPIO.OUT)
GPIO.setup(self.RIGHT_FRONT_2, GPIO.OUT)
GPIO.setup(self.LEFT_BEHIND_1, GPIO.OUT)
GPIO.setup(self.LEFT_BEHIND_2, GPIO.OUT)
GPIO.setup(self.RIGHT_BEHIND_1, GPIO.OUT)
GPIO.setup(self.RIGHT_BEHIND_2, GPIO.OUT)
def reset(self):
# Rest all the GPIO as LOW
GPIO.output(self.LEFT_FRONT_1, GPIO.LOW)
GPIO.output(self.LEFT_FRONT_2, GPIO.LOW)
GPIO.output(self.RIGHT_FRONT_1, GPIO.LOW)
GPIO.output(self.RIGHT_FRONT_2, GPIO.LOW)
GPIO.output(self.LEFT_BEHIND_1, GPIO.LOW)
GPIO.output(self.LEFT_BEHIND_2, GPIO.LOW)
GPIO.output(self.RIGHT_BEHIND_1, GPIO.LOW)
GPIO.output(self.RIGHT_BEHIND_2, GPIO.LOW)
def __forword(self):
self.reset()
GPIO.output(self.LEFT_FRONT_1, GPIO.HIGH)
GPIO.output(self.LEFT_FRONT_2, GPIO.LOW)
GPIO.output(self.RIGHT_FRONT_1, GPIO.HIGH)
GPIO.output(self.RIGHT_FRONT_2, GPIO.LOW)
GPIO.output(self.LEFT_BEHIND_1, GPIO.HIGH)
GPIO.output(self.LEFT_BEHIND_2, GPIO.LOW)
GPIO.output(self.RIGHT_BEHIND_1, GPIO.HIGH)
GPIO.output(self.RIGHT_BEHIND_2, GPIO.LOW)
def __backword(self):
self.reset()
GPIO.output(self.LEFT_FRONT_2, GPIO.HIGH)
GPIO.output(self.LEFT_FRONT_1, GPIO.LOW)
GPIO.output(self.RIGHT_FRONT_2, GPIO.HIGH)
GPIO.output(self.RIGHT_FRONT_1, GPIO.LOW)
GPIO.output(self.LEFT_BEHIND_2, GPIO.HIGH)
GPIO.output(self.LEFT_BEHIND_1, GPIO.LOW)
GPIO.output(self.RIGHT_BEHIND_2, GPIO.HIGH)
GPIO.output(self.RIGHT_BEHIND_1, GPIO.LOW)
def __turnLeft(self):
'''
To turn left, the LEFT_FRONT wheel will move backword
All other wheels move forword
'''
self.reset()
GPIO.output(self.LEFT_FRONT_2, GPIO.HIGH)
GPIO.output(self.LEFT_FRONT_1, GPIO.LOW)
GPIO.output(self.RIGHT_FRONT_1, GPIO.HIGH)
GPIO.output(self.RIGHT_FRONT_2, GPIO.LOW)
GPIO.output(self.LEFT_BEHIND_1, GPIO.HIGH)
GPIO.output(self.LEFT_BEHIND_2, GPIO.LOW)
GPIO.output(self.RIGHT_BEHIND_1, GPIO.HIGH)
GPIO.output(self.RIGHT_BEHIND_2, GPIO.LOW)
def __turnRight(self):
'''
To turn right, the RIGHT_FRONT wheel move backword
All other wheels move forword
'''
self.reset()
GPIO.output(self.LEFT_FRONT_1, GPIO.HIGH)
GPIO.output(self.LEFT_FRONT_2, GPIO.LOW)
GPIO.output(self.RIGHT_FRONT_2, GPIO.HIGH)
GPIO.output(self.RIGHT_FRONT_1, GPIO.LOW)
GPIO.output(self.LEFT_BEHIND_1, GPIO.HIGH)
GPIO.output(self.LEFT_BEHIND_2, GPIO.LOW)
GPIO.output(self.RIGHT_BEHIND_1, GPIO.HIGH)
GPIO.output(self.RIGHT_BEHIND_2, GPIO.LOW)
def __backLeft(self):
'''
To go backword and turn left, the LEFT_BEHIND wheel move forword
All other wheels move backword
'''
self.reset()
GPIO.output(self.LEFT_FRONT_2, GPIO.HIGH)
GPIO.output(self.LEFT_FRONT_1, GPIO.LOW)
GPIO.output(self.RIGHT_FRONT_2, GPIO.HIGH)
GPIO.output(self.RIGHT_FRONT_1, GPIO.LOW)
GPIO.output(self.LEFT_BEHIND_1, GPIO.HIGH)
GPIO.output(self.LEFT_BEHIND_2, GPIO.LOW)
GPIO.output(self.RIGHT_BEHIND_2, GPIO.HIGH)
GPIO.output(self.RIGHT_BEHIND_1, GPIO.LOW)
def __backRight(self):
'''
To go backword and turn right, the RIGHT_BEHIND wheel move forword
All other wheels move backword
'''
self.reset()
GPIO.output(self.LEFT_FRONT_2, GPIO.HIGH)
GPIO.output(self.LEFT_FRONT_1, GPIO.LOW)
GPIO.output(self.RIGHT_FRONT_2, GPIO.HIGH)
GPIO.output(self.RIGHT_FRONT_1, GPIO.LOW)
GPIO.output(self.LEFT_BEHIND_2, GPIO.HIGH)
GPIO.output(self.LEFT_BEHIND_1, GPIO.LOW)
GPIO.output(self.RIGHT_BEHIND_1, GPIO.HIGH)
GPIO.output(self.RIGHT_BEHIND_2, GPIO.LOW)
def __stop(self):
self.reset()
def carMove(self, direction):
'''
Car move according to the input paramter - direction
'''
if direction == 'F':
self.__forword()
elif direction == 'B':
self.__backword()
elif direction == 'L':
self.__turnLeft()
elif direction == 'R':
self.__turnRight()
elif direction == 'BL':
self.__backLeft()
elif direction == 'BR':
self.__backRight()
elif direction == 'S':
self.__stop()
else:
print("The input direction is wrong! You can just input: F, B, L, R, BL,BR or S")
if __name__ == "__main__":
raspCar = FourWheelDriveCar()
while(True):
direction = input("Please input direction: ")
raspCar.carMove(direction)
以上即为本文的全部内容,希望这对大家的学习有所帮助,也欢迎大家继续支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









