树莓派小车
去年买的树莓派4B ,闲着没事查阅资料做了个树莓派小车
写个博客记录一下吧
1. 材料准备
- 树莓派 x1
- 杜邦线公对公、母对母、公对母 若干( 多买点)
- L298N电机驱动模块X1
- 树莓派摄像头 X1( 装在小车上 电脑可以使用VNC 远程观测、操控很好玩)
摄像头支架 ( 用来把摄像头固定在小车上)- 双层智能小车底盘X1(带轮胎,马达的 某宝一搜就有)
- 充电电池X8 ( 用来给小车马达供电的,推荐使用充电电池 ,毕竟太耗电了)
- 充电宝(5v3a ,用来给树莓派 供电)
- 泡沫板+双面胶+剪刀( 剪泡沫板用双面胶贴在小车上用来固定)
拼装
这个先鸽了 … 东西都在学校, 手机坏了,只找到一张半成品时的图
不太了解电机驱动的接口作用 ,踩了三天的坑 一直不能用树莓派控制马达 ,最后尝试用树莓派给驱动模块个5V供电就能动了…(吃了数电模电的亏)
把那张图贴出来解释一下结构吧
2.核心代码
一开始不清楚怎么实现按下按键小车动 +松开停止的功能,后来想起以前用pygame做过飞机大战的游戏?? 用控制飞机的思路来控制GPIO输出信号不就完了 。
写完代码一共百行,而且重复较多 ,整体来说还是简单易懂的
下面代码整体功能就是 通过键盘的wasd或者上下左右按键操控小车。
import RPi.GPIO as GPIO
import time
import pygame
from pygame.locals import * # 用来检测事件,比如键盘按键操作
GPIO.setmode(GPIO.BCM)
IN1=19
IN2=26
IN3=6
IN4=13
GPIO.setup(IN1,GPIO.OUT)
GPIO.setup(IN2,GPIO.OUT)
GPIO.setup(IN3,GPIO.OUT)
GPIO.setup(IN4,GPIO.OUT)#set to output
class Car():
key_right_status = False
key_left_status = False
key_up_status = False
key_down_status = False
def move(self):
if self.key_right_status:
Clear()
Right()
if self.key_left_status:
Clear()
Left()
if self.key_down_status:
Clear()
Back()
if self.key_up_status:
Clear()
Up()
def key_control(car):
"""控制键盘的函数"""
for event in pygame.event.get():
# 判断是否是点击了退出按钮
if event.type == QUIT:
print("exit")
exit()
# 在按下键盘时,设置hero的属性为True
elif event.type == KEYDOWN:
if event.key == K_a or event.key == K_LEFT:
car.key_left_status = True
elif event.key == K_d or event.key == K_RIGHT:
car.key_right_status = True
elif event.key == K_w or event.key == K_UP:
car.key_up_status = True
elif event.key == K_s or event.key == K_DOWN:
car.key_down_status = True
elif event.type == KEYUP:
if event.key == K_a or event.key == K_LEFT:
car.key_left_status = False
# 检测按键是否是d或者方向键right
elif event.key == K_d or event.key == K_RIGHT:
car.key_right_status = False
elif event.key == K_w or event.key == K_UP:
car.key_up_status = False
elif event.key == K_s or event.key == K_DOWN:
car.key_down_status = False
def Back():#every time call this fun we change the GPIO and after 0.2s clear them
print("Back!")
GPIO.output(IN1,GPIO.HIGH)
GPIO.output(IN2,GPIO.LOW)
GPIO.output(IN3,GPIO.HIGH)
GPIO.output(IN4,GPIO.LOW)
time.sleep(0.2)
Clear()
def Up():
print("UP!")
GPIO.output(IN1,GPIO.LOW)
GPIO.output(IN2,GPIO.HIGH)
GPIO.output(IN3,GPIO.LOW)
GPIO.output(IN4,GPIO.HIGH)
time.sleep(0.2)
Clear()
def Right():
print("RIGHT!")
GPIO.output(IN1,GPIO.LOW)
GPIO.output(IN2,GPIO.LOW)
GPIO.output(IN3,GPIO.LOW)
GPIO.output(IN4,GPIO.HIGH)
time.sleep(0.2)
Clear()
def Left():
print("LEFT!")
GPIO.output(IN1,GPIO.LOW)
GPIO.output(IN2,GPIO.HIGH)
GPIO.output(IN3,GPIO.LOW)
GPIO.output(IN4,GPIO.LOW)
time.sleep(0.2)
Clear()
def Clear():#to clean the condition of GPIO
GPIO.output(IN1,GPIO.LOW)
GPIO.output(IN2,GPIO.LOW)
GPIO.output(IN3,GPIO.LOW)
GPIO.output(IN4,GPIO.LOW)
def main():
Clear()
screen = pygame.display.set_mode((320, 568), 0, 32)
car=Car()
while True:
key_control(car)
car.move()
if __name__ == '__main__':
main()
运行代码,即可操控小车了 ~
3.后期改进
- 充电宝+电池组+树莓派太重了 某宝好像有专门给树莓派供电的,可以考虑入手改进
- 只能在同一局域网或者 电脑给树莓派开热点( 推荐这个,摄像头展示图像延迟低) ,如果加上4g模块 ,就可以无视距离远程操控了。
- L298N应该是入门的驱动模块,能接受的信号太少了,上文实现的转弯功能是一侧两个轮胎停止,另一侧两个前进实现的。可以考虑更新驱动模块。
- 树莓派搭配摄像头 ? 是不是可以搭配上点CV技术(知道可以实现,就是太菜了不会做 - -)
- 还有一个是搭配其他传感器, 比如加上红外传感,碰到障碍自动转弯等
暂时就想到这么坑 学业问题可能就无法实现了,有空一定!