DIY树莓派小车(三)外壳设计和Web控制 完结
DIY树莓派小车(三)外壳设计和Web控制 完结
外壳
之前没学习过CAD,所以在这里我使用的建模工具是Tinkercad(一个基于浏览器的3D设计和建模程序),学习成本极低,可快速上手
导出图纸,淘宝定制亚克力板,经过漫长的等待,终于在今天收到了
安装完成后的小车
Web控制
以下所有代码均已上传至github
valieo/Raspberry-Car
安装bottle库
- 安装pip
pip是特定于Python的软件包管理器,没有安装pip的按照下述方式安装,安装了跳过此步
安装pip
sudo apt install python2-pip -y
或者安装pip3
sudo apt install python3-pip -y
- 如果系统中只安装了Python2,那么就只能使用pip。
- 如果系统中只安装了Python3,那么既可以使用pip也可以使用pip3,二者是等价的。
- 如果系统中同时安装了Python2和Python3,则pip默认给Python2用,pip3指定给Python3用。
我在这里安装的是pip3,以下代码也仅在python3下测试通过
- 安装bottle
pip3 install bottle
代码
1. 超声波测距模块
# 超声波测距模块 HC-SR04
import RPi.GPIO as GPIO
import timeclass Measure(object):def __init__(self, GPIO_TRIG, GPIO_ECHO) -> None:super().__init__()self.GPIO_TRIG = GPIO_TRIGself.GPIO_ECHO = GPIO_ECHOGPIO.setmode(GPIO.BCM)#设置 GPIO 的工作方式 (IN / OUT)GPIO.setup(GPIO_TRIG, GPIO.OUT)GPIO.setup(GPIO_ECHO, GPIO.IN)def getDistance(self):# 向Trig引脚发送10us的脉冲信号GPIO.output(self.GPIO_TRIG, True)time.sleep(0.00001)GPIO.output(self.GPIO_TRIG, False)# 开始发送超声波的时刻while GPIO.input(self.GPIO_ECHO)==0:passstartTime=time.time()# 收到返回超声波的时刻while GPIO.input(self.GPIO_ECHO)==1:passendTime=time.time()# 计算距离 距离=(声波的往返时间*声速)/2timeDelta = endTime - startTimedistance = (timeDelta * 34300) / 2return round(distance,2)
2. 电机驱动模块
# MotorControl.py
# TB6612FNG电机驱动
# 电机控制import RPi.GPIO as GPIO
'''
self.GPIO_PWM
self.GPIO_IN1
self.GPIO_IN2
self.freqself.last_pwm
self.pwm
'''
class Motor(object):def __init__(self, GPIO_PWM, GPIO_IN1, GPIO_IN2, freq=300) -> None:super().__init__()self.GPIO_PWM = GPIO_PWMself.GPIO_IN1 = GPIO_IN1self.GPIO_IN2 = GPIO_IN2self.freq = freqGPIO.setmode(GPIO.BCM)#GPIO.setwarnings(False)GPIO.setup(self.GPIO_PWM, GPIO.OUT)GPIO.setup(self.GPIO_IN1, GPIO.OUT)GPIO.setup(self.GPIO_IN2, GPIO.OUT)self.pwm = GPIO.PWM(self.GPIO_PWM, self.freq)self.last_pwm = 0self.pwm.start(self.last_pwm)''' 静态方法 TB6612FNG的STBY引脚1. GPIO_STBY int BCM编码号2. status bool 为true则TB6612FNG工作,反之待机 默认为false'''@staticmethoddef standby(GPIO_STBY,status=False):GPIO.setmode(GPIO.BCM)#GPIO.setwarnings(False)if status:GPIO.setup(status, GPIO.OUT)GPIO.output(status, True)else:GPIO.output(status, False)''' 设置PWM占空比1. dc 占空比 [0,100]'''def __setPWM(self, dc):if dc != self.last_pwm:self.pwm.ChangeDutyCycle(dc)self.last_pwm = dc''' 启动1. speed int 范围[-100,100] 正数则正转,负数则反转'''def run(self, speed):if(speed>=0):GPIO.output(self.GPIO_IN1, False)GPIO.output(self.GPIO_IN2, True)self.__setPWM(speed)else:GPIO.output(self.GPIO_IN1, True)GPIO.output(self.GPIO_IN2, False)self.__setPWM(-speed)'''停止'''def stop(self):GPIO.output(self.GPIO_IN1, False)GPIO.output(self.GPIO_IN2, False)self.__setPWM(0)def cleanup(self):self.stop()self.pwm.stop()
3. 小车控制
考虑到两个电机的转速可能不完全一致,所以需要一个微调功能。
摄像头模块在DIY树莓派小车(二)树莓派4B安装并使用摄像头和超声波模块中使用motion在8081端口开启了视频输出,可以直接调用,这里不再写有关摄像头模块的代码
# CarControl.py
# 控制小车移动 (前进 后退 左转 右转)
# 驱动:TB6612FNG
import RPi.GPIO as GPIO
from MotorControl import Motor
from Distance import Measure'''
TB6612FNG 接口# STBYGPIO_STBY = 27# 左边电机GPIO_PWMA = 18GPIO_AIN1 = 14GPIO_AIN2 = 15# 右边电机GPIO_PWMB = 19GPIO_BIN1 = 23GPIO_BIN2 = 24HC-SR04 接口GPIO_TRIG = 5GPIO_ECHO = 6小车功能1. 微调2. 变速3. 前进4. 后退5. 左转6. 右转7. 停车8. 测距
'''class Car(object):def __init__(self) -> None:super().__init__()'''电机模块'''# STBY引脚定义self.GPIO_STBY = 27GPIO.setmode(GPIO.BCM)#GPIO.setwarnings(False)GPIO.setup(self.GPIO_STBY, GPIO.OUT)# 左右两个电机self.motor_left = Motor(18,14,15)self.motor_right = Motor(19,23,24)# STBY = True TB6612FNG开始工作Motor.standby(self.GPIO_STBY,True)# 速度 占空比self.motor_speed = 60self.motor_left_speed = 60self.motor_right_speed = 60# 速度系数 用于微调self.motor_left_coefficient = 1.0self.motor_right_coefficient = 1.0'''超声波测距模块'''self.measure = Measure(5, 6)# 微调 使两个电机转速一致 left=True向左微调 反之向右def fineTuning(self, left):if left:# 向左微调 左边的电机减速 右边的电机加速self.motor_left_coefficient -= 0.05self.motor_right_coefficient += 0.05else:# 向右边微调 左边的电机加速 右边的电机减速self.motor_left_coefficient += 0.05self.motor_right_coefficient -= 0.05# 更改速度 [0,100]def setSpeed(self, speed):if speed>100:speed = 100if speed<0:speed = 0self.motor_speed = speedself.motor_left_speed = self.motor_left_coefficient * speedself.motor_right_speed = self.motor_right_coefficient * speed# 前进def forward(self):self.motor_left.run(self.motor_left_speed)self.motor_right.run(self.motor_right_speed)# 后退def backward(self):self.motor_left.run(-self.motor_left_speed)self.motor_right.run(-self.motor_right_speed)# 左转def turnLeft(self):self.motor_left.run(-self.motor_left_speed)self.motor_right.run(self.motor_right_speed)# 右转def turnRight(self):self.motor_left.run(self.motor_left_speed)self.motor_right.run(-self.motor_right_speed)# 停止def stop(self):self.motor_left.stop()self.motor_right.stop()# 测距def getDistance(self):return self.measure.getDistance()def getSpeed(self):return self.motor_speed# 释放资源def cleanup(self):self.motor_left.cleanup()self.motor_right.cleanup()GPIO.cleanup()
4. 获取树莓派信息
以下代码用于获取树莓派CPU温度、CPU使用率、RAM使用率
# RaspberryInfo.py
# 获取树莓派 CPU温度 内存使用率 CPU使用率import os# CPU温度
def getCpuTemp():res = os.popen('vcgencmd measure_temp').readline()return(res.replace("temp=","").replace("'C\n",""))# CPU使用率
def getCpuUsage():return(str(os.popen("top -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip()))# RAM信息
def getRAMinfo():p = os.popen('free')i = 0while 1:i = i + 1line = p.readline()if i==2:return(line.split()[1:4])# 内存使用率
def getRamUsage():RAM_stats = getRAMinfo()return round(int(RAM_stats[1]) / int(RAM_stats[0])*100,1)
5. 小车Web控制面板
通过按钮或者键盘来控制小车移动
键盘操作方法见下表
按键 | W | S | A | D | Q | E | Z | C |
---|---|---|---|---|---|---|---|---|
功能 | 前进 | 后退 | 左转 | 右转 | 加速 | 减速 | 左微调 | 右微调 |
<!-- index.html -->
<!-- 树莓派小车控制面板 -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Raspberry Car Control Panel</title><link href="http://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" media="screen"><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script><style type="text/css">#front {margin-left: 55px;margin-bottom: 3px;}#rear{margin-top: 3px;margin-left: 55px;}.btn{background: #62559f;}</style><script>$(function(){$("button").mousedown(function(){console.log(this.id + "mouse down");$.post("/cmd",this.id,function(data,status){});});// 鼠标弹起则停止移动$("button").mouseup(function(){console.log(this.id + "mouse up");$.post("/cmd","stop",function(data,status){});})// 键盘控制小车移动$(document).keydown(function(event){switch(event.keyCode){case 87://wconsole.log("press W");$.post("/cmd","forward",function(data,status){});break;case 83://sconsole.log("press S");$.post("/cmd","backward",function(data,status){});break;case 65://aconsole.log("press A");$.post("/cmd","turnLeft",function(data,status){});break;case 68://dconsole.log("press D");$.post("/cmd","turnRight",function(data,status){});break;case 81://qconsole.log("press Q");$.post("/cmd","speedUp",function(data,status){});break;case 69://econsole.log("press E");$.post("/cmd","slowDown",function(data,status){});break;case 90://zconsole.log("press Z");$.post("/cmd","leftFineTuning",function(data,status){});break;case 67://cconsole.log("press C");$.post("/cmd","rightFineTuning",function(data,status){});break;}});$(document).keyup(function(event){switch(event.keyCode){case 87://wcase 83://scase 65://acase 68://dcase 81://qconsole.log("key up");$.post("/cmd","stop",function(data,status){});break;}});});</script>
</head>
<body>
<div class="row"><div class="col-xs-12 col-sm-6 col-md-7"><div class="panel panel-default"><div class="panel-heading"><h3 class="panel-title">实时画面</h3></div><div class="panel-body"><iframe src="http://192.168.0.100:8081/" width="820" height="620" frameborder="1" name="name" scrolling="auto"></iframe></div></div></div><div class="col-xs-6 col-md-4"><div class="panel panel-default"><div class="panel panel-default"><div class="panel-heading"><h3 class="panel-title">信息</h3></div><div class="panel-body" ><iframe id="car-info" width="320" height="195" src="http://192.168.0.100:8088/info"></iframe></div></div><div class="panel-heading"><h3 class="panel-title">控制</h3></div><div class="panel-body" style="margin: 30px;margin-left: 40px"><div class="row" ><div class="col-md-2"></div><div class="col-md-2"><button id="forward" class="btn btn-large btn-primary" type="button"><span class="glyphicon glyphicon-triangle-top" aria-hidden="true"></span><br/>前进</button></div><div class="col-md-2"></div></div><br/><div class="row"><div class="col-md-2"><button id="turnLeft" class="btn btn-large btn-primary" type="button"><span class="glyphicon glyphicon-triangle-left" aria-hidden="true"></span><br/>左转</button></div><div class="col-md-2"><button id="backward" class="btn btn-large btn-primary" type="button"><span class="glyphicon glyphicon-triangle-bottom" aria-hidden="true"></span><br/>后退</button></div><div class="col-md-2"><button id="turnRight" class="btn btn-large btn-primary" type="button"><span class="glyphicon glyphicon-triangle-right" aria-hidden="true"></span><br/>右转</button></div></div><br/><div class="row"><div class="col-md-2"><button id="speedUp" class="btn btn-large btn-primary" type="button"><span class="glyphicon glyphicon glyphicon-plus-sign" aria-hidden="true"></span><br/>加速</button></div><div class="col-md-2"></div><div class="col-md-2"><button id="slowDown" class="btn btn-large btn-primary" type="button"><span class="glyphicon glyphicon glyphicon-minus-sign" aria-hidden="true"></span><br/>减速</button></div></div><br><div class="row"><div class="col-md-2"><button id="leftFineTuning" class="btn btn-large btn-primary" type="button"><span class="glyphicon glyphicon-triangle-left" aria-hidden="true"></span><br/>左微调</button></div><div class="col-md-2"></div><div class="col-md-2"><button id="rightFineTuning" class="btn btn-large btn-primary" type="button"><span class="glyphicon glyphicon-triangle-right" aria-hidden="true"></span><br/>右微调</button></div></div></div></div>
</div></body>
</html>
6. 树莓派小车信息页面
此页面嵌入到小车Web控制面板页面中,显示小车速度(PWM占空比)、距离、CPU温度、CPU使用率、内存使用率
此页面1秒刷新一次
<!-- info.html -->
<!-- 树莓派小车信息面板 -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><!--每1秒刷新一次--><meta http-equiv="refresh" content="1"> <title>信息</title>
</head>
<body><p>Speed: {{speed}}</p><p>Distance: {{distance}}cm</p><p>CPU Temp: {{cpuTemp}}℃</p><p>CPU Uasge: {{cpuUsage}}%</p><p>RAM Uasge: {{ramUsage}}%</p>
</body>
</html>
7. 启动
# Start.py
from bottle import get,post,run,request,template
from CarControl import Car
from RaspberryInfo import *car = Car()def main(status):print("Event: "+status)if status == "forward":car.forward()elif status == "backward":car.backward()elif status == "turnLeft":car.turnLeft()elif status == "turnRight":car.turnRight()elif status == "speedUp":car.setSpeed(car.getSpeed() + 5)elif status == "slowDown":car.setSpeed(car.getSpeed() - 5)elif status == "leftFineTuning":car.fineTuning(True)elif status == "rightFineTuning":car.fineTuning(False)elif status == "stop":car.stop()# 控制台
@get("/")
def index():print("request index.html")return template("index.html")# 控制小车
@post("/cmd")
def cmd():adss=request.body.read().decode()main(adss)return "OK"# 小车信息
@get("/info")
def info():print("Update status Information")return template("info.html", speed=car.getSpeed(), distance=car.getDistance(), cpuTemp=getCpuTemp(), cpuUsage=getCpuUsage(), ramUsage=getRamUsage())run(host='0.0.0.0', port=8088, debug=False)car.cleanup()
实测
启动
sudo motion # 打开摄像头python3 Start.py
在浏览器中输入如下Url进入树莓派小车控制页面
http://树莓派ip:8088
Web页面如下,可以通过网页上的按钮或者键盘控制小车(局域网内网络延迟很低,画面几乎实时显示)
控制面板右侧显示的是树莓派小车信息,其中Speed是PWM占空比,范围是[0,100],Distance是超声波测距的结果
当小车不能走直线时,如果向右偏,则需要使用左微调,反之使用右微调
遥控视频演示画面见我的个人网站(视频中使用充电宝给小车供电)
DIY树莓派小车(三)外壳设计和Web控制 完结
至此树莓派小车制作完毕
DIY树莓派小车(三)外壳设计和Web控制 完结相关推荐
- DIY树莓派小车(一)树莓派4B+TB6612FNG驱动直流电机
趁着暑假时间充裕,准备制作一辆简易的树莓派小车,让树莓派不再吃灰,写此文记录折腾的过程. DIY树莓派小车(一)树莓派4B+TB6612FNG驱动直流电机 小车需求简要介绍 采用双轮差速方式移动 双轮 ...
- 人工智能-树莓派小车(5)——用微信控制智能小车
之前所做的有一个特点就是需要在树莓派上连接一个USB麦克风,通过这个麦克风来进行语音的输入,但是在实际使用场景上来看,这是不合理的,因此需要一个可以远程操控智能小车的方案,因此萌发了将控制端移植到手机 ...
- 树莓派python编程小车_树莓派小车教程(三)——软件代码
原标题:树莓派小车教程(三)--软件代码 树莓派小车教程(三)--软件代码 2017-07-07 琳小豆 HelloWorld少儿编程 树莓派小车教程 (三) 在上一次教程中,我们已经完成了硬件连接. ...
- 树莓派python编程小车_Sunny的树莓派小车DIY教程(附视频)
一.组件介绍 大家好,我是Sunny.今天将给大家带来系列教程<树莓派小车系列>,先给大家介绍介绍我这次使用到的一些组件. 1.树莓派 2.小车底盘 3.小车车轮(马达) 4.L298N电 ...
- 树莓派小车教程(三)之——初步实现网页控制小车速度可调(顺序执行)
项目场景: 之前写了一篇手把手树莓派小车教程(二)之--基于Tornado框架的网页控制小车(按键+鼠标点击).当时只记录了如何通过Tornado框架能让网页控制小车跑起来(以恒定速度),但是项目中小 ...
- 简单的Web控制树莓派小车
说在前面:大四第一学期没课,决定做一个智能小车.从最初的一无所有,到小车可实现远程控制,虽然在这期间遇到了不少问题,但同时也让我学到了许多新知识.当然,小车的完成并非是我一个人的力量,各位大佬的教程给 ...
- 树莓派python编程小车_【树莓派】树莓派小车(三)Python控制小车
正文之前 由于最近忙于复习赶考,所以暂时没有拿起树莓派小车,直到昨天,终于空出时间来把代码整理一下来和大家分享. 正文 在树莓派小车系列之二中,讲到了树莓派的引脚定义方式有两种: PHYSICAL N ...
- 树莓派小车python操作流程--龙邱科技
▌第一部分 环境解决 1.1 软件版本 发货前已经配置好软件环境: Linux raspberrypi 5.4.51 Python 3.7 OpenCV-python 3.4.6.27 1.2 TF卡 ...
- ESP8266从点灯到遥控小车(三)——组装小车,0代码开发APP控制小车
ESP8266从点灯到APP遥控小车(三)--组装小车,0代码开发APP控制小车 文章目录 ESP8266从点灯到APP遥控小车(三)--组装小车,0代码开发APP控制小车 所需组件 一.小车所需组件 ...
最新文章
- webpack v3 结合 react-router v4 做 dynamic import — 按需加载(懒加载)
- java动态url_使用url Param的动态主题
- Erlang(起个中文名:易浪)不能错过的盛宴
- android微信朋友圈视频无法播放,微信朋友圈不能分享手机视频怎么回事?微信朋友圈大视频功能安卓不能用吗?...
- MDK4 如何生成bin文件
- netty的Helloworld---netty学习笔记
- 大文本存mysql怎么建索引_如何正确合理的建立MYSQL数据库索引
- java内核_测量时间:从Java到内核再到
- abap 添加alv上的工具栏的按钮_Excel里的置顶功能——快速访问工具栏
- Object.prototype的成员介绍
- 高德地图上展示终端信息
- 【数学题】Multicolored Markers【codeforces-Round #506-div3-F】
- docker安装jdk1.8
- 汇编语言L0C,单片机汇编语言指令查表.doc
- (四)UPF之常用低功耗单元(Isolation、Level Shifter、Power Switch、State Retention、Always on cell)
- 【算法竞赛学习笔记】佩尔方程-数学提升计划
- Soft Filter Pruning(SFP)算法笔记
- windows10无法搜索计算机,win10搜索功能失效用不了如何解决|win10搜索功能搜不了文件的解决方法...
- archlinux配置conky
- 3D目标检测SE-SSD 模型工程化复现