1.目标:
实现一个智能小车,包含感应,语音,运动等功能。
2.物料:
树莓派4,L298n模块,HC-SR501红外人体感应模块,摄像头模块,usb麦克风,蓝牙音箱,小车底板(包含四个电机)。
3.过程:
3.1 树莓派4烧录注意点:
多试几个镜像,镜像不对会启动失败,可以去清华大学镜像站下img。
3.2.人体感应模块接线
hc-sr501插线,三个跳线面对自己,从左到右,5V,GND,GPIO,我接的是5v,gnd,gpio18引脚。
3.3语音合成
调用百度智能平台语音api
3.4小车
3.4.1 用3.5V锂电池。
3.4.2 2个马达分别接上L298n左右两边的out1,2和out3,4(没有红黑区别,)
3.4.2 小车没有舵机,所以依靠左右轮子前进和后退实现转弯
3.4.3 L298n 的电源地,树莓派的 GND 引脚也要接到这里(用公-母线),即 L298N 和 树莓派需要共地。
3.4.4 GPIO端口分别接 树莓派 19 16 26 20 (倒数第二、三排)接口
3.4.5 播放声音文件 omxplayer -o alsa t.wav
4.代码
东拼西凑了网上一些代码 车子跑起来了
#!/usr/bin/env python3
from bottle import get,post,run,request,template
import RPi.GPIO as GPIO
import time
# L298N引脚接GPIO
IN1 = 19
IN2 = 16
IN3 = 26
IN4 = 20
Trig_Pin = 6
Echo_Pin = 13
def checkdist():
#发出触发信号
GPIO.output(Trig_Pin,GPIO.HIGH)
#保持10us以上(我选择15us)
time.sleep(0.000015)
GPIO.output(Trig_Pin,GPIO.LOW)
while GPIO.input(Echo_Pin) == 0:
pass
#发现高电平时开时计时
t1 = time.time()
while GPIO.input(Echo_Pin) == 1:
pass
#高电平结束停止计时
t2 = time.time()
#返回距离,单位为米
return (t2-t1)*340*100/2
def init():
GPIO.setmode(GPIO.BCM)
GPIO.setup(IN1,GPIO.OUT)
GPIO.setup(IN2,GPIO.OUT)
GPIO.setup(IN3,GPIO.OUT)
GPIO.setup(IN4,GPIO.OUT)
#GPIO13
GPIO.setup(Trig_Pin,GPIO.OUT,initial=GPIO.LOW)
#GPIO19
GPIO.setup(Echo_Pin,GPIO.IN)
# 前进
def forward(tf):
GPIO.output(IN1,GPIO.HIGH)
GPIO.output(IN2,GPIO.LOW)
GPIO.output(IN3,GPIO.HIGH)
GPIO.output(IN4,GPIO.LOW)
time.sleep(tf)
GPIO.cleanup()
# 后退
def down(tf):
GPIO.output(IN1,GPIO.LOW)
GPIO.output(IN2,GPIO.HIGH)
GPIO.output(IN3,GPIO.LOW)
GPIO.output(IN4,GPIO.HIGH)
time.sleep(tf)
GPIO.cleanup()
# 左转弯
def left(tf):
GPIO.output(IN1,GPIO.LOW)
GPIO.output(IN2,GPIO.HIGH)
GPIO.output(IN3,GPIO.HIGH)
GPIO.output(IN4,GPIO.LOW)
time.sleep(tf)
GPIO.cleanup()
# 右转弯
def right(tf):
GPIO.output(IN1,GPIO.HIGH)
GPIO.output(IN2,GPIO.LOW)
GPIO.output(IN3,GPIO.LOW)
GPIO.output(IN4,GPIO.HIGH)
time.sleep(tf)
GPIO.cleanup()
# 停止
def stop():
GPIO.output(IN1,False)
GPIO.output(IN2,False)
GPIO.output(IN3,False)
GPIO.output(IN4,False)
GPIO.cleanup()
@get("/")
def index():
return template("index")
@post("/cmd")
def cmd():
print("按下了按钮 : "+request.body.read().decode())
init()
sleep_time = 0.2
arg = request.body.read().decode()
if(arg=='up'):
forward(sleep_time)
elif(arg=='down'):
down(sleep_time)
elif(arg=='left'):
left(sleep_time)
elif(arg=='right'):
right(sleep_time)
elif(arg=='stop'):
stop()
else:
return False
#return "OK"
@post("/goto")
def goto():
print("按下了按钮 : "+request.body.read().decode())
init()
sleep_time = 1
arg = request.body.read().decode()
if(arg=='go_1'):
forward(sleep_time)
init()
left(sleep_time)
init()
forward(sleep_time)
elif(arg=='go_2'):
forward(sleep_time)
init()
right(sleep_time)
init()
forward(sleep_time)
elif(arg=='go_3'):
forward(sleep_time*2)
init()
left(sleep_time)
init()
forward(sleep_time)
else:
return False
@post("/starthy")
def starthy():
print("按下了红外按钮 : ")
global open
open = True
init()
detct()
@post("/closehy")
def closehy():
print("close : ")
global open
open = False
@post("/dist")
def dist():
init()
try:
for num in range(10,20):
a = checkdist();
print(str(a)+"cm")
time.sleep(1)
if(a>20):
forward(0.1)
init()
except KeyboardInterrupt:
GPIO.cleanup()
run(host="0.0.0.0",port="8089")
5.问题汇总
5.1 vnc viewer上显示黑屏“cannot currently show the desktop”
sudo raspi-config -> Advanced Options -> A5 Resolution --> 1280x720
5.2 碰到一个很奇怪的坑:python文件不要取名dis.py 这是个系统库,叫这个名字会有问题
网友评论