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:&nbsp;{{speed}}</p><p>Distance:&nbsp;{{distance}}cm</p><p>CPU Temp:&nbsp;{{cpuTemp}}&#8451</p><p>CPU Uasge:&nbsp;{{cpuUsage}}%</p><p>RAM Uasge:&nbsp;{{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控制 完结相关推荐

  1. DIY树莓派小车(一)树莓派4B+TB6612FNG驱动直流电机

    趁着暑假时间充裕,准备制作一辆简易的树莓派小车,让树莓派不再吃灰,写此文记录折腾的过程. DIY树莓派小车(一)树莓派4B+TB6612FNG驱动直流电机 小车需求简要介绍 采用双轮差速方式移动 双轮 ...

  2. 人工智能-树莓派小车(5)——用微信控制智能小车

    之前所做的有一个特点就是需要在树莓派上连接一个USB麦克风,通过这个麦克风来进行语音的输入,但是在实际使用场景上来看,这是不合理的,因此需要一个可以远程操控智能小车的方案,因此萌发了将控制端移植到手机 ...

  3. 树莓派python编程小车_树莓派小车教程(三)——软件代码

    原标题:树莓派小车教程(三)--软件代码 树莓派小车教程(三)--软件代码 2017-07-07 琳小豆 HelloWorld少儿编程 树莓派小车教程 (三) 在上一次教程中,我们已经完成了硬件连接. ...

  4. 树莓派python编程小车_Sunny的树莓派小车DIY教程(附视频)

    一.组件介绍 大家好,我是Sunny.今天将给大家带来系列教程<树莓派小车系列>,先给大家介绍介绍我这次使用到的一些组件. 1.树莓派 2.小车底盘 3.小车车轮(马达) 4.L298N电 ...

  5. 树莓派小车教程(三)之——初步实现网页控制小车速度可调(顺序执行)

    项目场景: 之前写了一篇手把手树莓派小车教程(二)之--基于Tornado框架的网页控制小车(按键+鼠标点击).当时只记录了如何通过Tornado框架能让网页控制小车跑起来(以恒定速度),但是项目中小 ...

  6. 简单的Web控制树莓派小车

    说在前面:大四第一学期没课,决定做一个智能小车.从最初的一无所有,到小车可实现远程控制,虽然在这期间遇到了不少问题,但同时也让我学到了许多新知识.当然,小车的完成并非是我一个人的力量,各位大佬的教程给 ...

  7. 树莓派python编程小车_【树莓派】树莓派小车(三)Python控制小车

    正文之前 由于最近忙于复习赶考,所以暂时没有拿起树莓派小车,直到昨天,终于空出时间来把代码整理一下来和大家分享. 正文 在树莓派小车系列之二中,讲到了树莓派的引脚定义方式有两种: PHYSICAL N ...

  8. 树莓派小车python操作流程--龙邱科技

    ▌第一部分 环境解决 1.1 软件版本 发货前已经配置好软件环境: Linux raspberrypi 5.4.51 Python 3.7 OpenCV-python 3.4.6.27 1.2 TF卡 ...

  9. ESP8266从点灯到遥控小车(三)——组装小车,0代码开发APP控制小车

    ESP8266从点灯到APP遥控小车(三)--组装小车,0代码开发APP控制小车 文章目录 ESP8266从点灯到APP遥控小车(三)--组装小车,0代码开发APP控制小车 所需组件 一.小车所需组件 ...

最新文章

  1. webpack v3 结合 react-router v4 做 dynamic import — 按需加载(懒加载)
  2. java动态url_使用url Param的动态主题
  3. Erlang(起个中文名:易浪)不能错过的盛宴
  4. android微信朋友圈视频无法播放,微信朋友圈不能分享手机视频怎么回事?微信朋友圈大视频功能安卓不能用吗?...
  5. MDK4 如何生成bin文件
  6. netty的Helloworld---netty学习笔记
  7. 大文本存mysql怎么建索引_如何正确合理的建立MYSQL数据库索引
  8. java内核_测量时间:从Java到内核再到
  9. abap 添加alv上的工具栏的按钮_Excel里的置顶功能——快速访问工具栏
  10. Object.prototype的成员介绍
  11. 高德地图上展示终端信息
  12. 【数学题】Multicolored Markers【codeforces-Round #506-div3-F】
  13. docker安装jdk1.8
  14. 汇编语言L0C,单片机汇编语言指令查表.doc
  15. (四)UPF之常用低功耗单元(Isolation、Level Shifter、Power Switch、State Retention、Always on cell)
  16. 【算法竞赛学习笔记】佩尔方程-数学提升计划
  17. Soft Filter Pruning(SFP)算法笔记
  18. windows10无法搜索计算机,win10搜索功能失效用不了如何解决|win10搜索功能搜不了文件的解决方法...
  19. archlinux配置conky
  20. 3D目标检测SE-SSD 模型工程化复现

热门文章

  1. jpg读取exif属性值
  2. CS - IT - 企业管理软件
  3. Directory文件夹
  4. Linux中搭建ftp服务器
  5. Python 批量将raw数据或图片一一存成.npy文件
  6. IE URL传参问题
  7. cookies设置以及作用范围
  8. cad必学的快捷方式,让你作图飞起
  9. Linux下的查找命令合集(which/whereis/locate/find)
  10. 适用于旧计算机的10款最佳轻量级Linux发行版