树莓派小车python驱动程序
前言
树莓派小车使用thonny软件驱动舵机、电机的python程序,终端使用cheese软件开启摄像头。
硬件:笔记本、树莓派4b小车(树莓派4b、sd卡、舵机云台、摄像头、tt马达、BST-AI拓展板、电池、车体外壳、轮子)
软件:Ubuntu22.04、thonny、cheese、向日葵
日期:2022.08.27
一、硬件部分(组装好小车)
如图所示:
二、软件部分
1.安装好Ubuntu22.04系统,thonny、cheese、向日葵软件
Ubuntu22.04系统,thonny、cheese、向日葵软件我之前博客都有安装介绍,这里不再赘述。
2.写入python程序
代码如下:
# -*- coding: utf-8 -*-
from __future__ import division
import time
import Adafruit_PCA9685
from pynput import keyboard
pwm = Adafruit_PCA9685.PCA9685()
#每个电机由两个阵脚的脉冲进行控制
mA1=8
mA2=9
mB1=10
mB2=11
mC1=1
mC2=2
pwm.set_pwm_freq(50)
# Configure min and max servo pulse lengths
servo_min = 150 # Min pulse length out of 4096
servo_max = 600 # Max pulse length out of 4096
# Helper function to make setting a servo pulse width simpler.
def set_servo_pulse(channel, pulse):
pulse_length = 1000000 # 1,000,000 us per second
pulse_length //= 60 # 60 Hz
print('{0}us per period'.format(pulse_length))
pulse_length //= 4096 # 12 bits of resolution
print('{0}us per bit'.format(pulse_length))
pulse *= 1000
pulse //= pulse_length
pwm.set_pwm(channel, 0, pulse)
def set_servo_angle(channel,angle):
angle=4096*((angle*11)+500)/20000
pwm.set_pwm(channel,0,int(angle))
#舵机初始位置
yaw_angle = 90
pitch_angle = 90
set_servo_angle(mC1,yaw_angle)
set_servo_angle(mC2,pitch_angle)
#舵机左转
def left_yaw():
global yaw_angle
yaw_angle += 0.5
set_servo_angle(mC2,yaw_angle)
time.sleep(0.01)
#舵机右转
def right_yaw():
global yaw_angle
yaw_angle -= 0.5
set_servo_angle(mC2,yaw_angle)
time.sleep(0.01)
#舵机上仰
def up_pitch():
global pitch_angle
pitch_angle -= 0.5
set_servo_angle(mC1,pitch_angle)
time.sleep(0.01)
#舵机下俯
def down_pitch():
global pitch_angle
pitch_angle += 0.5
set_servo_angle(mC1,pitch_angle)
time.sleep(0.01)
#最大频率是4096,4096时达到最高速度,1024,2048,3072
#向前,两个电机向相同方向旋转
def forward():
pwm.set_pwm(mA1,0,1024)
pwm.set_pwm(mA2,0,0)
pwm.set_pwm(mB1,0,1024)
pwm.set_pwm(mB2,0,0)
time.sleep(0.01)
#向后,两个电机向与forward()向反的方向旋转
def back():
pwm.set_pwm(mA1,0,0)
pwm.set_pwm(mA2,0,1024)
pwm.set_pwm(mB1,0,0)
pwm.set_pwm(mB2,0,1024)
time.sleep(0.01)
#原地左转,给右电机向前速度,给左电机向后速度
def spin_left():
pwm.set_pwm(mA1,0,1024)
pwm.set_pwm(mA2,0,0)
pwm.set_pwm(mB1,0,0)
pwm.set_pwm(mB2,0,1024)
time.sleep(0.01)
#原地右转,给左电机向前速度,给右电机向后速度
def spin_right():
pwm.set_pwm(mA1,0,0)
pwm.set_pwm(mA2,0,1024)
pwm.set_pwm(mB1,0,1024)
pwm.set_pwm(mB2,0,0)
time.sleep(0.01)
#左转,通过频率差值改变转向角度
'''def left():
pwm.set_pwm(mA1,0,512)
pwm.set_pwm(mA2,0,0)
pwm.set_pwm(mB1,0,1024)
pwm.set_pwm(mB2,0,0)
time.sleep(0.01)
#右转,通过频率差值改变旋转角度
def right():
pwm.set_pwm(mA1,0,1024)
pwm.set_pwm(mA2,0,0)
pwm.set_pwm(mB1,0,512)
pwm.set_pwm(mB2,0,0)
time.sleep(0.01)'''
def stop():
pwm.set_pwm(mA1,0,0)
pwm.set_pwm(mA2,0,0)
pwm.set_pwm(mB1,0,0)
pwm.set_pwm(mB2,0,0)
time.sleep(0.01)
#延时程序可以省略
#按键检测
def on_press(key):
'按下按键时执行。'
try:
if key == keyboard.KeyCode.from_char('enter'):
pass
elif key == keyboard.Key.left:
print("舵机向左")
left_yaw()
elif key == keyboard.Key.right:
print("舵机向右")
right_yaw()
elif key == keyboard.Key.up:
print("舵机向上")
up_pitch()
elif key == keyboard.Key.down:
print("舵机向下")
down_pitch()
elif key == keyboard.KeyCode.from_char('w'):
print("前进")
forward()
elif key == keyboard.KeyCode.from_char('s'):
print("后退")
back()
elif key == keyboard.KeyCode.from_char('a'):
print("左转")
spin_left()
elif key == keyboard.KeyCode.from_char('d'):
print("右转")
spin_right()
elif key == keyboard.KeyCode.from_char('q'):
exit(-1)
except AttributeError:
print('special key {0} pressed'.format(key))
#通过属性判断按键类型。
def on_release(key):
'松开按键时执行。'
#print('{0} released'.format(key))
print("停止")
stop()
if key == keyboard.Key.esc:
# Stop listener
return False
with keyboard.Listener(on_press=on_press,on_release=on_release) as listener:
listener.join()
#非阻塞式的键盘事件监听,不会影响程序其他线程的执行,阻塞式(with...as....)的键盘事件监听
将程序保存到Adafruit_Python_PCA9685文件夹下,使用thonny打开运行。
如果报如下错误:
可在终端运行:
sudo chmod 777 /dev/i2c-1
暂时开放权限
操作控制如下:
“w”前进 “s”后退 “a”左转 “d”右转
“↑”舵机云台上仰 “↓”舵机云台下俯 ”←“舵机云台左转 “→”舵机云台右转
终端运行
cheese
打开摄像头
总结
(万事开头难,路遥知马力)