项目来源背景
自从上了大学,感触很多,身为一个计算机系的小白,见识到了大佬们的学识渊博,就此下定决心,要向他们不断的靠近(身为一个什么也不懂的小白,难免都不太愿意跟我交流)。起初真正意义上认识树莓派是源于我哥,也算是我的启蒙人吧。之后我又加入了学校的工作室,看见了学长玩剩下的树莓派(看样子已经灰尘满满),就好奇的问了一句(想白嫖),之后学长就把树莓派给了我,树莓派小车就此诞生了。
树莓派介绍
怎么说呢,我觉得树莓派是个“微型”的奇迹,虽然只有卡片般的大小,但涵盖了计算机所具有的功能, 树莓派起初是为学习计算机编程教育而生的,它最大的特点是成本较为低廉,功耗较小,接口较为丰富,几乎拥有了普通电脑的所有接口,因此,其十分合适作为一些小型设备终端的芯片控制模块与服务器模块,综述了树莓派的各项特点并加以利用,针对与树莓派的GIOP针脚对其进行硬件或开发板面包版的连接,利用python语言进行程序设计,输入与调试,搭建完成了一个基于树莓派的可远程控制的python小车项目,并且,对小车完成后的其他扩展方向进行了讨论,对现有的功能进行列举。
下图为树莓派3b+
Raspbian操作系统的安装
对于要启动电脑程序,必然是少不了系统的安装,树莓派也是如此,树莓派的系统是安装在TF卡上,至于系统的安装建议去官网下载,在百度上大多博主都安装的是NOOBS系统,本次小车安装的是raspberry pi系统,因为不仅有操作界面,而且具有的桌面功能较多,方便后期使用代码编程。
首先,去官网:https://www.raspberrypi.org/downloads/ 下载安装镜像的文件,根据系统平台下载,直接安装即可,打开选择系统和SD卡,然后写入即可。
树莓派的启动
在一系列的下载,烧录完成之后,将SD卡从读卡器取出,直接插入到树莓派,接入显示器、键盘、鼠标,开机,即可看到成功进入树莓派的系统。鄙人当时因条件有限,没有显示器,HDMI线都是问学长借的,利用的是ssh通道为小车传输数据,简称VNC模块,就是无线连接的意思。
下图为启动画面(之后有条件了,直接将树莓派接入显示器)
树莓派GPIO引脚的作用图
要了解小车工作的原理首先要了解到树莓派上GPIO引脚的作用,Rasberry Pi可以提供5v(引脚2和4)和3.3v(引脚1和17)电源。它还为引脚6、9、14、20、25、30、34和39上的电路提供了接地(GND)。GPIO引脚集成到了电脑。用户可以控制它们的行为,以允许他们从传感器读取数据,并控制LED,电动机和显示器等组件。 Pi的较旧型号具有26个GPIO引脚,而较新的型号均具有40个GPIO引脚。
介绍完树莓派的来历之后,就正式步入我们今天的话题,如何从0-1搭建一个属于自己的智能小车呢?
硬件模块
小车外壳(因学校3D打印机一直处于损坏且无人问津状态,只好上某宝自主搜寻购买,建议有条件的同学可以自行3D打印小车外观)
树莓派3B+(3B以上型号的树莓派都可参考本文章)
32G及以上TF卡
安卓手机一部
12V(或其他)电池
L298N电机驱动模块
稳压模块(12V/或其他 转 5V)用于树莓派供电及舵机供电
小车底盘(带舵机、电机的方便些)
树莓派摄像头(raspberry pi 摄像头,某宝十几块钱一个,就是外壳有点难拼,可能动手能力较差,轻喷!)
其他(舵机支架、开关等)
如何运行
超声波避障模块
#!/usr/bin/env python
from Adafruit_PWM_Servo_Driver import PWM
import RPi.GPIO as GPIO
import time
import sys
PWMA = 18
AIN1 = 22
AIN2 = 27
PWMB = 23
BIN1 = 25
BIN2 = 24
BtnPin = 19
Gpin = 5
Rpin = 6
TRIG = 20
ECHO = 21
# Initialise the PWM device using the default address
# bmp = PWM(0x40, debug=True)
pwm = PWM(0x40,debug = False)
servoMin = 150 # Min pulse length out of 4096
servoMax = 600 # Max pulse length out of 4096
def setServoPulse(channel, pulse):
pulseLength = 1000000.0 # 1,000,000 us per second
pulseLength /= 50.0 # 60 Hz
print "%d us per period" % pulseLength
pulseLength /= 4096.0 # 12 bits of resolution
print "%d us per bit" % pulseLength
pulse *= 1000.0
pulse /= (pulseLength*1.0)
# pwmV=int(pluse)
print "pluse: %f " % (pulse)
pwm.setPWM(channel, 0, int(pulse))
#Angle to PWM
def write(servonum,x):
y=x/90.0+0.5
y=max(y,0.5)
y=min(y,2.5)
setServoPulse(servonum,y)
def t_up(speed,t_time):
L_Motor.ChangeDutyCycle(speed)
GPIO.output(AIN2,False)#AIN2
GPIO.output(AIN1,True) #AIN1
R_Motor.ChangeDutyCycle(speed)
GPIO.output(BIN2,False)#BIN2
GPIO.output(BIN1,True) #BIN1
time.sleep(t_time)
def t_stop(t_time):
L_Motor.ChangeDutyCycle(0)
GPIO.output(AIN2,False)#AIN2
GPIO.output(AIN1,False) #AIN1
R_Motor.ChangeDutyCycle(0)
GPIO.output(BIN2,False)#BIN2
GPIO.output(BIN1,False) #BIN1
time.sleep(t_time)
def t_down(speed,t_time):
L_Motor.ChangeDutyCycle(speed)
GPIO.output(AIN2,True)#AIN2
GPIO.output(AIN1,False) #AIN1
R_Motor.ChangeDutyCycle(speed)
GPIO.output(BIN2,True)#BIN2
GPIO.output(BIN1,False) #BIN1
time.sleep(t_time)
def t_left(speed,t_time):
L_Motor.ChangeDutyCycle(speed)
GPIO.output(AIN2,True)#AIN2
GPIO.output(AIN1,False) #AIN1
R_Motor.ChangeDutyCycle(speed)
GPIO.output(BIN2,False)#BIN2
GPIO.output(BIN1,True) #BIN1
time.sleep(t_time)
def t_right(speed,t_time):
L_Motor.ChangeDutyCycle(speed)
GPIO.output(AIN2,False)#AIN2
GPIO.output(AIN1,True) #AIN1
R_Motor.ChangeDutyCycle(speed)
GPIO.output(BIN2,True)#BIN2
GPIO.output(BIN1,False) #BIN1
time.sleep(t_time)
def keysacn():
val = GPIO.input(BtnPin)
while GPIO.input(BtnPin) == False:
val = GPIO.input(BtnPin)
while GPIO.input(BtnPin) == True:
time.sleep(0.01)
val = GPIO.input(BtnPin)
if val == True:
GPIO.output(Rpin,1)
while GPIO.input(BtnPin) == False:
GPIO.output(Rpin,0)
else:
GPIO.output(Rpin,0)
def setup():
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(TRIG, GPIO.OUT)
GPIO.setup(ECHO, GPIO.IN)
GPIO.setup(Gpin, GPIO.OUT) # Set Green Led Pin mode to output
GPIO.setup(Rpin, GPIO.OUT) # Set Red Led Pin mode to output
GPIO.setup(BtnPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set BtnPin's mode is input, and pull up to high level(3.3V)
GPIO.setup(AIN2,GPIO.OUT)
GPIO.setup(AIN1,GPIO.OUT)
GPIO.setup(PWMA,GPIO.OUT)
GPIO.setup(BIN1,GPIO.OUT)
GPIO.setup(BIN2,GPIO.OUT)
GPIO.setup(PWMB,GPIO.OUT)
pwm.setPWMFreq(50) # Set frequency to 60 Hz
def distance():
GPIO.output(TRIG, 0)
time.sleep(0.000002)
GPIO.output(TRIG, 1)
time.sleep(0.00001)
GPIO.output(TRIG, 0)
while GPIO.input(ECHO) == 0:
a = 0
time1 = time.time()
while GPIO.input(ECHO) == 1:
a = 1
time2 = time.time()
during = time2 - time1
return during * 340 / 2 * 100
def front_detection():
write(0,90)
time.sleep(0.5)
dis_f = distance()
return dis_f
def left_detection():
write(0, 175)
time.sleep(0.5)
dis_l = distance()
return dis_l
def right_detection():
write(0,5)
time.sleep(0.5)
dis_r = distance()
return dis_r
def loop():
while True:
dis1 = front_detection()
if (dis1 < 40) == True:
t_stop(0.2)
t_down(50,0.5)
t_stop(0.2)
dis2 = left_detection()
dis3 = right_detection()
if (dis2 < 40) == True and (dis3 < 40) == True:
t_left(50,1)
elif (dis2 > dis3) == True:
t_left(50,0.3)
t_stop(0.1)
else:
t_right(50,0.3)
t_stop(0.1)
else:
t_up(60,0)
# print dis1, 'cm'
# print ''
def destroy():
GPIO.cleanup()
if __name__ == "__main__":
setup()
L_Motor= GPIO.PWM(PWMA,100)
L_Motor.start(0)
R_Motor = GPIO.PWM(PWMB,100)
R_Motor.start(0)
keysacn()
try:
loop()
except KeyboardInterrupt:
destroy()
就此附上小车超声波避障模块运行图
遥控控制模块
#!/usr/bin/python
print("2345")
import pylirc
import time
import RPi.GPIO as GPIO
PWMA = 18
AIN1 = 22
AIN2 = 27
PWMB = 23
BIN1 = 25
BIN2 = 24
BtnPin = 19
Gpin = 5
Rpin = 6
blocking = 0
def t_up(speed,t_time):
L_Motor.ChangeDutyCycle(speed)
GPIO.output(AIN2,False)#AIN2
GPIO.output(AIN1,True) #AIN1
R_Motor.ChangeDutyCycle(speed)
GPIO.output(BIN2,False)#BIN2
GPIO.output(BIN1,True) #BIN1
time.sleep(t_time)
def t_stop(t_time):
L_Motor.ChangeDutyCycle(0)
GPIO.output(AIN2,False)#AIN2
GPIO.output(AIN1,False) #AIN1
R_Motor.ChangeDutyCycle(0)
GPIO.output(BIN2,False)#BIN2
GPIO.output(BIN1,False) #BIN1
time.sleep(t_time)
def t_down(speed,t_time):
L_Motor.ChangeDutyCycle(speed)
GPIO.output(AIN2,True)#AIN2
GPIO.output(AIN1,False) #AIN1
R_Motor.ChangeDutyCycle(speed)
GPIO.output(BIN2,True)#BIN2
GPIO.output(BIN1,False) #BIN1
time.sleep(t_time)
def t_left(speed,t_time):
L_Motor.ChangeDutyCycle(speed)
GPIO.output(AIN2,True)#AIN2
GPIO.output(AIN1,False) #AIN1
R_Motor.ChangeDutyCycle(speed)
GPIO.output(BIN2,False)#BIN2
GPIO.output(BIN1,True) #BIN1
time.sleep(t_time)
def t_right(speed,t_time):
L_Motor.ChangeDutyCycle(speed)
GPIO.output(AIN2,False)#AIN2
GPIO.output(AIN1,True) #AIN1
R_Motor.ChangeDutyCycle(speed)
GPIO.output(BIN2,True)#BIN2
GPIO.output(BIN1,False) #BIN1
time.sleep(t_time)
def keysacn():
val = GPIO.input(BtnPin)
while GPIO.input(BtnPin) == False:
val = GPIO.input(BtnPin)
while GPIO.input(BtnPin) == True:
time.sleep(0.01)
val = GPIO.input(BtnPin)
if val == True:
GPIO.output(Rpin,1)
while GPIO.input(BtnPin) == False:
GPIO.output(Rpin,0)
else:
GPIO.output(Rpin,0)
def setup():
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(AIN2,GPIO.OUT)
GPIO.setup(AIN1,GPIO.OUT)
GPIO.setup(PWMA,GPIO.OUT)
GPIO.setup(BIN1,GPIO.OUT)
GPIO.setup(BIN2,GPIO.OUT)
GPIO.setup(PWMB,GPIO.OUT)
GPIO.setup(Rpin, GPIO.OUT) # Set Red Led Pin mode to output
GPIO.setup(BtnPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def IR(config):
if config == 'KEY_CHANNEL':
t_up(50,0)
print ("t_up")
if config == 'KEY_NEXT':
t_stop(0)
print ("t_stop")
if config == 'KEY_PREVIOUS':
t_left(50,0)
print ("t_left")
if config == 'KEY_PLAYPAUSE':
t_right(50,0)
print ("t_right")
if config == 'KEY_VOLUMEUP':
t_down(50,0)
print ("t_down")
def loop():
while True:
s = pylirc.nextcode(1)
while(s):
for (code) in s:
print ('Command: ', code["config"])
IR(code["config"])
if(not blocking):
s = pylirc.nextcode(1)
else:
s = []
def destroy():
GPIO.cleanup()
pylirc.exit()
if __name__ == '__main__':
setup()
L_Motor= GPIO.PWM(PWMA,100)
L_Motor.start(0)
R_Motor = GPIO.PWM(PWMB,100)
R_Motor.start(0)
keysacn()
pylirc.init("pylirc", "./conf", blocking)
try:
loop()
except KeyboardInterrupt:
destroy()
![请添加图片描述](https://img-blog.csdnimg.cn/449939501544437e934cb21469998bd7.PNG?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAbTBfNTY0NzY2NDM=,size_20,color_FFFFFF,t_70,g_se,x_16)
小车寻迹模块
#!/usr/bin/python
# coding=utf-8
#本段代码实现树莓派智能小车的红外避障效果
#代码使用的树莓派GPIO是用的BOARD编码方式。
import RPi.GPIO as GPIO
import time
import sys
T_SensorRight = 26
T_SensorLeft = 13
PWMA = 18
AIN1 = 22
AIN2 = 27
PWMB = 23
BIN1 = 25
BIN2 = 24
BtnPin = 19
Gpin = 5
Rpin = 6
def t_up(speed,t_time):
L_Motor.ChangeDutyCycle(speed)
GPIO.output(AIN2,False)#AIN2
GPIO.output(AIN1,True) #AIN1
R_Motor.ChangeDutyCycle(speed)
GPIO.output(BIN2,False)#BIN2
GPIO.output(BIN1,True) #BIN1
time.sleep(t_time)
def t_stop(t_time):
L_Motor.ChangeDutyCycle(0)
GPIO.output(AIN2,False)#AIN2
GPIO.output(AIN1,False) #AIN1
R_Motor.ChangeDutyCycle(0)
GPIO.output(BIN2,False)#BIN2
GPIO.output(BIN1,False) #BIN1
time.sleep(t_time)
def t_down(speed,t_time):
L_Motor.ChangeDutyCycle(speed)
GPIO.output(AIN2,True)#AIN2
GPIO.output(AIN1,False) #AIN1
R_Motor.ChangeDutyCycle(speed)
GPIO.output(BIN2,True)#BIN2
GPIO.output(BIN1,False) #BIN1
time.sleep(t_time)
def t_left(speed,t_time):
L_Motor.ChangeDutyCycle(speed)
GPIO.output(AIN2,True)#AIN2
GPIO.output(AIN1,False) #AIN1
R_Motor.ChangeDutyCycle(speed)
GPIO.output(BIN2,False)#BIN2
GPIO.output(BIN1,True) #BIN1
time.sleep(t_time)
def t_right(speed,t_time):
L_Motor.ChangeDutyCycle(speed)
GPIO.output(AIN2,False)#AIN2
GPIO.output(AIN1,True) #AIN1
R_Motor.ChangeDutyCycle(speed)
GPIO.output(BIN2,True)#BIN2
GPIO.output(BIN1,False) #BIN1
time.sleep(t_time)
def keysacn():
val = GPIO.input(BtnPin)
while GPIO.input(BtnPin) == False:
val = GPIO.input(BtnPin)
while GPIO.input(BtnPin) == True:
time.sleep(0.01)
val = GPIO.input(BtnPin)
if val == True:
GPIO.output(Rpin,1)
while GPIO.input(BtnPin) == False:
GPIO.output(Rpin,0)
else:
GPIO.output(Rpin,0)
def setup():
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM) # Numbers GPIOs by physical location
GPIO.setup(Gpin, GPIO.OUT) # Set Green Led Pin mode to output
GPIO.setup(Rpin, GPIO.OUT) # Set Red Led Pin mode to output
GPIO.setup(BtnPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set BtnPin's mode is input, and pull up to high level(3.3V)
GPIO.setup(T_SensorRight,GPIO.IN)
GPIO.setup(T_SensorLeft,GPIO.IN)
GPIO.setup(AIN2,GPIO.OUT)
GPIO.setup(AIN1,GPIO.OUT)
GPIO.setup(PWMA,GPIO.OUT)
GPIO.setup(BIN1,GPIO.OUT)
GPIO.setup(BIN2,GPIO.OUT)
GPIO.setup(PWMB,GPIO.OUT)
if __name__ == '__main__':
setup()
keysacn()
L_Motor= GPIO.PWM(PWMA,100)
L_Motor.start(0)
R_Motor = GPIO.PWM(PWMB,100)
R_Motor.start(0)
try:
while True:
SR = GPIO.input(T_SensorRight)
SL = GPIO.input(T_SensorLeft)
if SL == False and SR == False:
print "t_up"
t_up(50,0)
elif SL == True and SR ==False:
print "Left"
t_left(50,0)
elif SL==False and SR ==True:
print "Right"
t_right(50,0)
else:
t_stop(0)
except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy() will be executed.
GPIO.cleanup()
小车寻迹图
最后附上小车的摄像头图片(别问为什么不买USB摄像头,问就是经费不够!!!)
在小车上搭载了一个环保简易支架,既美观又省钱,就是有点不防都,手机视频端控制时画面不稳定,这边建议各位读者千万别省这个钱,老老实实去某宝买个舵机!
小车目前已实现功能
小车目前已有功能:蜂鸣音乐,遥控控制,超声波避障,自动寻迹及WIFI模块视频控制功能,鄙人已附上部分代码,若有需要的同学,可在评论区联系我哦。
发文目的
本次想把自己做的项目展现给读者,是想真正意义上的让对人工智能感兴趣的同学取得学习的捷径,不用把时间花在找寻可靠的方法上!