py 新人买了个树莓派练习,目的是实现一个 2.4g 键盘遥控的小车(已经实现的其他功能后面都不提),同时具有针对延迟问题的避障处理,目前基本都实现了,就差一个避障逻辑没弄明白只实现了一半,下面分三个部分介绍下目前我的情况,希望有前辈能指点一下:
关于 curses 库的官方文档和更详细的文档: https://docs.python.org/zh-cn/3/howto/curses.html http://doc.codingdict.com/python_352/library/curses.html
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import curses
import subprocess
import RPi.GPIO as io
# 定义各种硬件对应的 GPIO 引脚编号
# BCM 编码是需要查询官方引脚图定义的
# 面包板使用的扩展板有详细标记(例):GPIO xx
io.setmode(io.BCM)
rt1 = 16 # rt1/rt0:右前后轮正负极,1 正 0 负,r 右 l 左后面全都这么设置的
rt0 = 20
lt1 = 21 # lt1/lt0:左前后轮正负极
lt0 = 26
ena = 12 # a 右 b 左使能引脚
enb = 19
disb = 25 # 红外模块引脚
freq = 50 #频率 50
#进行 curses 库的初始化设置
screen = curses.initscr()
curses.noecho()
curses.cbreak()
screen.keypad(True)
io.setwarnings(False)
# 除了避障模块为读取信号,其余均为输出信号
io.setup(rt1,io.OUT)
io.setup(rt0,io.OUT)
io.setup(lt1,io.OUT)
io.setup(lt0,io.OUT)
io.setup(disb,io.IN) #模块检测距离不够输出 0 给树莓派,距离正常输出 1 给树莓派
io.setup(ena,io.OUT)
io.setup(enb,io.OUT)
# 设置,初始化并启用舵机和马达 pwm 调速
enr = io.PWM(ena,50)
enl = io.PWM(enb,50)
enr.start(0)
enl.start(0)
# 小车前进( 20 占空比)
def forward():
io.output(rt1,io.HIGH) # 正高电平,负低电平,pwm 设置慢速前进
io.output(rt0,io.LOW)
io.output(lt1,io.HIGH)
io.output(lt0,io.LOW)
enr.ChangeDutyCycle(20)
enl.ChangeDutyCycle(20)
# 小车后退( 20 占空比)
def backward():
io.output(rt1,io.LOW) # 正低电平,负高电平,pwm 设置慢速后退
io.output(rt0,io.HIGH)
io.output(lt1,io.LOW)
io.output(lt0,io.HIGH)
enr.ChangeDutyCycle(20)
enl.ChangeDutyCycle(20)
# 停止舵机和小车
def stop():
io.output(rt1,io.LOW) # 四个轮子重置为低电平
io.output(rt0,io.LOW)
io.output(lt1,io.LOW)
io.output(lt0,io.LOW)
enr.ChangeDutyCycle(0) # enr/enl 左右车轮占空比重置为 0
enl.ChangeDutyCycle(0)
# 清理
def clean():
curses.nocbreak()
screen.keypad(0)
curses.echo()
curses.endwin()
pwmud.stop()
pwmlr.stop()
enr.stop()
enl.stop()
io.cleanup()
try:
while True:
char = screen.getch() #等待键盘按下按键
if char == ord('k'): #按键 k 会让整个程序退出
break
elif char == 10: #我的蓝牙键盘方向键中间是 ok 键,按下就是车轮停止工作
stop()
elif char == curses.KEY_UP: #按方向上键,先进行判断红外传感器如果读到 0 就让按键不工作
if io.input(disb) == 0: #就是前面有障碍就让上键不能让小车前进
stop()
else:
while True: #否则进入让小车停止的判断
forward()
#screen = curses.initscr()
#char = screen.getch()
if char == 10: #如果前方无障碍物,按下 ok 键,小车停止前进跳出循环
stop() #之后可以用方向下键后退
break
if io.input(disb) == 0: #如果按过前进按键后不操作直到快撞上
stop() #红外距离不够,自动停车
break
#if char == 10: #后面 7 行是测试的,好像没用
# stop()
# enr.ChangeDutyCycle(0)
# enl.ChangeDutyCycle(0)
#elif char == 10:
#stop()
#break
elif char == curses.KEY_DOWN: #如果按下后退键,小车就后退
backward()
finally:
clean()
print("已释放 GPIO 口")
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.