项目场景:

前两天笔者写了一份手把手树莓派小车教程(一)之——小车跑起来的教程。当时只是让小车能动起来,不过项目中的小车肯定是需要一个用户界面能够操控的。
能看到这一部分的读者们可能基本都会简单的控制小车了。接下来这篇博客我们详细讲解一下如何用网页web端来控制小车运行。


Tornado框架:

笔者对网页控制小车需要用到基于python的异步io框架Tornado。首先需要在树莓派上搭建基于Tornado搭建Web服务(Liunx):

sudo pip install tornado
wget https://pypi.python.org/packages/source/t/tornado/tornado-4.3.tar.gz
tar xvzf tornado-4.3.tar.gz
cd tornado-4.3
python setup.py build
sudo python setup.py install

笔者是用的python3环境。为了工程的正常开展,在这里我们同样选择在python3环境下搭建Tornado框架。

sudo apt-get install python3-tornado

代码编写:

小车刚开始运行的代码可以先看之前提到的手把手树莓派小车教程(一)之——小车跑起来的教程。下面写的代码是对能跑起来代码的一个扩充。
xiaoche.py:

# coding:utf-8
import RPi.GPIO as GPIO
import time
import sys
import tornado.ioloop
import tornado.web
import tornado.httpserver
import tornado.options
from tornado.options import define,options#GPIO.setmode(GPIO.BOARD)
define("port",default=8080,help="run on the given port",type=int)
IN1 = 11
IN2 = 12
IN3 = 13
IN4 = 15def init():GPIO.setmode(GPIO.BOARD)GPIO.setup(IN1,GPIO.OUT)GPIO.setup(IN2,GPIO.OUT)GPIO.setup(IN3,GPIO.OUT)GPIO.setup(IN4,GPIO.OUT)def right(tf):GPIO.output(IN1,GPIO.HIGH)GPIO.output(IN2,GPIO.LOW)GPIO.output(IN3,False)GPIO.output(IN4,False)time.sleep(tf)GPIO.cleanup()def left(tf):GPIO.output(IN1,GPIO.LOW)GPIO.output(IN2,GPIO.HIGH)GPIO.output(IN3,False)GPIO.output(IN4,False)time.sleep(tf)GPIO.cleanup()def before(tf):GPIO.output(IN1,False)GPIO.output(IN2,False)GPIO.output(IN3,GPIO.HIGH)GPIO.output(IN4,GPIO.LOW)time.sleep(tf)GPIO.cleanup()def cabk(tf):GPIO.output(IN1,False)GPIO.output(IN2,False)GPIO.output(IN3,GPIO.LOW)GPIO.output(IN4,GPIO.HIGH)time.sleep(tf)GPIO.cleanup()def zuoshang(tf):GPIO.output(IN1,GPIO.HIGH)GPIO.output(IN2,GPIO.LOW)GPIO.output(IN3,GPIO.HIGH)GPIO.output(IN4,GPIO.LOW)time.sleep(tf)GPIO.cleanup()def youshang(tf):GPIO.output(IN1,GPIO.HIGH)GPIO.output(IN2,GPIO.LOW)GPIO.output(IN3,GPIO.LOW)GPIO.output(IN4,GPIO.HIGH)time.sleep(tf)GPIO.cleanup()def youxia(tf):GPIO.output(IN1,GPIO.LOW)GPIO.output(IN2,GPIO.HIGH)GPIO.output(IN3,GPIO.LOW)GPIO.output(IN4,GPIO.HIGH)time.sleep(tf)GPIO.cleanup()def zuoxia(tf):GPIO.output(IN1,GPIO.LOW)GPIO.output(IN2,GPIO.HIGH)GPIO.output(IN3,GPIO.HIGH)GPIO.output(IN4,GPIO.LOW)time.sleep(tf)GPIO.cleanup()class IndexHandler(tornado.web.RequestHandler):def get(self):self.render("xiaoche.html")def post(self):init()sleep_time=0.1arg=self.get_argument('k')if(arg=='w'):before(sleep_time)#print("1")elif(arg=='x'):cabk(sleep_time)elif(arg=='a'):left(sleep_time)elif(arg=='d'):right(sleep_time)elif(arg=='q'):zuoshang(sleep_time)elif(arg=='z'):youshang(sleep_time)elif(arg=='e'):zuoxia(sleep_time)elif(arg=='c'):youxia(sleep_time)else:return Falseself.write(arg)
if __name__ == '__main__':tornado.options.parse_command_line()app = tornado.web.Application(handlers=[(r"/",IndexHandler)])http_server = tornado.httpserver.HTTPServer(app)#print("1")http_server.listen(options.port)print("Demo is runing at 192.168.1.102:8080")tornado.ioloop.IOLoop.instance().start()#print("1")

可以看到与之前的代码是多了对tornado框架的运用,若想了解该框架原本如何运用,可以参考树莓派4B上 tornado的安装 以及访问传参。可以看到我的代码是要控制8个不同的方向的,需要用到的按键是键盘上绕s一圈的英文字母qweadzxc。中间有部分注释掉的代码是用来调试的。后面有个print(“Demo is runing at 192.168.1.102:8080”)。中间的192.168.1.102是我树莓派连接时的IP地址,后面8080是自己设定的端口号。
接下来是web网页的代码编写。网页文件名称需要和self.render()里面的名称一样。且与python文件放到同一目录下。
xiaoche.html:

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script><title>小车</title></head><body><!--keyCode 键盘码 在键盘事件发生的时候 记录对应按的哪个键--><script type="text/javascript">function go(k){$.post('/',{k:k},function(){});}$(function(){window.document.onkeydown = abc;function abc(ev){ev = (ev) ? ev : window.event;// 指定方向键 ,w(上-->87),a(左-->83),s(下-->65),d(右-->67)if(ev.keyCode=='87'){<!-- console.log('w'); -->go('w');}if(ev.keyCode=='65'){<!-- console.log('a'); -->go('a');}if(ev.keyCode=='88'){<!-- console.log('s'); -->go('x');}if(ev.keyCode=='68'){<!-- console.log('d'); -->go('d');}if(ev.keyCode=='81'){<!-- console.log('w'); -->go('q');}if(ev.keyCode=='69'){<!-- console.log('w'); -->go('e');}if(ev.keyCode=='90'){<!-- console.log('w'); -->go('z');}if(ev.keyCode=='67'){<!-- console.log('w'); -->go('c');}}var i= null;$('.before').mousedown(function(){i = setInterval(function(){<!-- console.log('w'); -->go('w');},40);});$('.left').mousedown(function(){i = setInterval(function(){<!-- console.log('a'); -->go('a');},40);});$('.cabk').mousedown(function(){i = setInterval(function(){<!-- console.log('x'); -->go('x');},40);});$('.right').mousedown(function(){i = setInterval(function(){<!-- console.log('d'); -->go('d');},40);});$('.zuoshang').mousedown(function(){i = setInterval(function(){<!-- console.log('q'); -->go('q');},40);});$('.youshang').mousedown(function(){i = setInterval(function(){<!-- console.log('e'); -->go('z');},40);});$('.zuoxia').mousedown(function(){i = setInterval(function(){<!-- console.log('z'); -->go('e');},40);});$('.youxia').mousedown(function(){i = setInterval(function(){<!-- console.log('c'); -->go('c');},40);});$('#main span').mouseup(function(){clearInterval(i);});});</script><style type="text/css">#main{width: 150px;height: 150px;background: #ccc;}#main span{width: 50px;height: 50px;float: left;}#main span.on2{background: #ff00ff;}#main span.on3{background: #555555;position: absolute;left: 8px;top: 8px;}#main span.on4{background: #555555;position: absolute;left: 108px;top: 8px;}#main span.on5{background: #555555;position: absolute;left: 8px;top: 108px;}#main span.on6{background: #555555;position: absolute;left: 108px;top: 108px;}</style><div id="main">  <span></span><span class="on2 before"></span><span></span><span class="on2 left"></span><span></span><span class="on2 right"></span><span></span><span class="on2 cabk"></span><span></span><span class="on3 zuoshang"></span><span></span><span class="on4 zuoxia"></span><span></span><span class="on5 youshang"></span><span></span><span class="on6 youxia"></span><span></span>
</div>
</body>
</html>

如下图所示,我的html文件是这个样子的。这里请注意,我现在是直接从如图所示文件目录下打开的xiaoche.html文件。此时的文件不具备控制能力。

上面的代码中除了定义了这几个方块外,还创立了键盘控制函数、鼠标点击事件函数,go()函数用来接收前面两个函数传来的参数;可以注意到键盘是定义了几个数字,用来对应相应的键盘字母。

$(function(){window.document.onkeydown = abc;function abc(ev){ev = (ev) ? ev : window.event;

寻找字母方法:写到如上图函数的时候。点开html文件。先按键盘F12,在弹出来窗口内找到如下图所示console处。按下任何键盘都会给出相应的数字。记录后即可使用。

注意:

最后关于鼠标点击事件上的数字40,与python文件中主函数有的time.sleep(0.1)是对小车接收信号速度的调整。接收信号过多(过快)可能导致小车一直在跑无法停止。过少(过慢)则会边开边卡,尽量自己多测试,取到适合的位置。


运行调试:

起初看教程的时候我以为直接写完代码,运行之后直接打开html文件即可。但仔细查看资料后才发现是需要登录IP+端口号才行,网页如下图所示:

上图是运行python代码之后用IP+端口号登录的结果,可以看到网页地址与之前的不一样了。此时无论是按键还是点击事件小车都可以做出相应的行为。而且每做一次行为,python运行环境的shell中会多出很多记录:

出现这样的数据,且小车运行不异常。说明小车基本可以由网页直接控制了。希望读者在看完我的记录后能有启发。也能最终调试出这样的一串记录。

参考:

公开课 树莓派教程
树莓派小车调试记录
20-2 树莓派搭建服务器 Tornado Web服务器
树莓派4B上 tornado的安装 以及访问传参
手把手树莓派小车教程(一)之——小车跑起来
树莓派-网络监控(4)数据交互 基于python异步io框架Tornado

总结:

希望我教程能够帮助到在读的各位。本篇文章还是有些局限性的。比如小车现在是恒定速度行驶的,且现在还是最快速度行驶,遥控起来不免有些急促。所以接下来需要将其改为能够调节速度的网页遥控小车。后面会给大家讲解如何实现。
感谢各位观看,如有不足,欢迎在评论内留言与讨论。如果觉得写得好的,可以给我点赞+收藏+关注哦,再次感谢各位!

树莓派小车教程(二)之——基于Tornado框架的网页控制小车(按键+鼠标点击)相关推荐

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

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

  2. 实习手册八(Python基于Tornado框架的接口响应服务)最终章

    目录 前言 Tornado_program common handler_base mysql_base sqlalchemy_base redis_base model log user serve ...

  3. 树莓派小车教程(四)之——基本实现网页控制小车速度可调(同步执行)

    项目场景: 之前的小车教程序列里写到了网页控制小车速度的初步实现.当时只是初步实现小车速度的加减,但运行起来还是出现了些问题,如不能实现小车的移动与变速同时进行.手指离开按键后小车仍有延迟等. 问题分 ...

  4. 实习手册一(Python基于Tornado框架的接口响应服务)软件下载与环境配置

    目录 一.软件下载及环境配置: 1.Homebrew 2.python3.9 3.PyCharm专业版 4.MySQL 5.Navicat for MySQL 6.Redis 7.Postman 此次 ...

  5. C#小项目飞翔的小鸟游戏详细教程(Flying bird),基于Winform框架

    C#小项目飞翔的小鸟游戏详细教程(Flying bird),基于Winform框架 实现效果: 1.空格,鼠标左键控制小鸟跳 2.管道随机大小 3.小鸟与管道碰撞,小鸟碰到地面 4.小鸟煽动翅膀动画 ...

  6. MIP开发教程(二) 使用MIP-CLI工具调试MIP网页

    初始化 MIP 配置 新建一个 MIP 网页 编写 MIP 网页代码 校验 MIP 网页 调试 MIP 网页 1. 初始化 MIP 配置 首先在html目录下进行初始化 MIP 配置: $ mip i ...

  7. 展示一下基于flask框架的网页播放器的代码

    <p>下面是基于Flask框架的网页播放器的代码:from flask import Flaskapp = Flask(<strong>name</strong>) ...

  8. 基于51单片机的蓝牙控制小车的简单实现(有源代码,无图) (上篇)

    1. 简介 这是2016年底两周时间做的一个蓝牙小车,它分为上下两篇,本文是上篇.原本是发在了http://bbs.elecfans.com/ 的,不过由于我的博客都在CSDN上,因此我就把它们重新复 ...

  9. 【51】基于51单片机的蓝牙控制小车的简单实现(有源代码,无图)

    原文地址:http://bbs.elecfans.com/forum.php?mod=viewthread&tid=544143 此帖子现在有一个后续版本,实现了手机端的蓝牙程序控制小车运动以 ...

最新文章

  1. 我亲手调教的AI,竟然开始歧视我了!
  2. 3142:[HNOI2013]数列 - BZOJ
  3. java线程切换 notify_浅谈 Java线程状态转换及控制
  4. dataset的去重计数 g2_向工程渣土运输车辆计数 漏洞损失说“不”
  5. codeforces71A-C语言解题报告
  6. 数据对象、属性和相似性
  7. Linux命令收藏-进程管理
  8. MFC - CStdioFile 读取txt文件UNICODE 中文异常
  9. Struts2 + Spring + Hibernate 通用 Service 和 DAO
  10. python opcua_理解python中的免费OPC/UA代码
  11. 头目一天不来,就公然上班睡觉,主管怎么当得
  12. 【数字识别】基于matlab离散Hopfield神经网络数字识别【含Matlab源码 226期】
  13. kindle可以上网但是无法下载_两年深度使用经验告诉你:Kindle 这样用,绝对不吃灰...
  14. html轮播图片不显示不了,图片轮播的奇怪现象【图片显示不完整】
  15. 恒生电子 java笔试_恒生电子笔试题
  16. revel MySQL_使用Revel(go)开发网站
  17. 两个无线路由器的连接(修订)
  18. 【ubuntu使用排坑】fsckd-cancel-msg:Press Ctrl+C to cancel all filesystem checks
  19. MySQL主键约束-PRIMARY KEY
  20. SQL server in 用法

热门文章

  1. 网络洗稿产业链被曝光
  2. 使用 JAVA 手写一个录屏GUI程序
  3. Python自动化办公之Word,全网最全看这一篇就够了
  4. 制作或从其他格式转换ico图标
  5. 突破年薪20w,不敲代码行不行?
  6. 我的世界pe服务器语音,我的世界手游如何开麦克风,我的世界国服版 (网易)怎么开语音?...
  7. python编辑游戏脚本_用PYTHON做一个简单的游戏脚本(基础,详细)
  8. 恒压供水一对一变频一拖三三台变频器ABB 恒压供水一对一变频 一拖三
  9. 摄像头分辨率怎么调整_2020年有哪些值得买的摄像头推荐?
  10. 云队友丨比智商在线、情商感人更重要的,是一个人的“时间商”