项目场景:

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


问题分析:

之前的教程中小车的移动与变速只能够按顺序调节,非常的不方便。而且随着低电平输出时间的增多,小车移动约不受控制。因运行时间的增长而导致小车运行与按键之间存在延迟。

因此我们需要进行同步调节(通过网页端按键的交替捕捉),且小车的运行时的低电平+高电平输出时间不能变。

经过大量的资料查询,我找到了这样一篇博客:JS实现两个键盘按键同时触发的事件。里面有个html是如下图所示的画面:

里面是一个简单的英文短语,但能通过电脑右边的上下左右键盘进行同步移动。若按键方向相反,会按照后按的按键进行移动。若方向出现夹角,会朝两方向(∠45°)同时移动。

经过一定的调试之后,我在两个地方加了console.log()方法通过F12按键进行输出记录查看。

switch(ev.keyCode){case 37:delta_x=-1;<!-- console.log('w'); -->break;case 38:delta_y=-1;console.log('x'); <!-- 第一处 -->break;
var timer = window.setInterval(()=>{if(delta_x==-1){console.log('s');}  <!-- 第二处 -->var unit = 10;var p = document.getElementsByTagName('p')[0];var left = window.getComputedStyle(p,null).left;var top = window.getComputedStyle(p,null).top;          p.style.left=parseInt(left)+delta_x*unit+'px';p.style.top=parseInt(top)+delta_y*unit+'px';},50);

在这两个地方加输出函数后,网页通过F12查看按键输出会有这样的现象:

在先按"←"再一起按"↑"时,会有这两处字母交替出现,随着第二处代码最后"50"的增大会x与s的比值会减少。

但先按"↑"再一起按"←"时,随着"←"的按下,x会停止出现,s则一直存在。

我们需要的则是第一个现象。可以让方向控制都作为x,变速控制都作为s。这样就能实现在小车行驶的同时变速。但也是因为有第二个现象。不能先按变速按键再一起按方向按键,否则只能一直行驶,速度不变。


代码产出:

根据上面的方法以及现象,我写出了这样的网页文件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">var before1=0;var cabk1=0;var left1=0;var right1=0;var zuoshang1=0;var youshang1=0;var zuoxia1=0;var youxia1=0;<!-- var jiasu=0; --><!-- var jiansu=0; -->function go(k){$.post('/',{k:k},function(){});}$(function(){window.document.onkeydown = abc;function abc(ev){ev = (ev) ? ev : window.event;// 指定方向键 ,w(上-->87),a(左-->65),x(下-->68),d(右-->88)switch(ev.keyCode){case 87:before1=1;<!-- console.log('w'); -->break;case 65:left1=1;<!-- console.log('a'); -->break;case 88:right1=1;<!-- console.log('x'); -->break;case 68:cabk1=1;<!-- console.log('d'); -->break;case 81:zuoshang1=1;<!-- console.log('q'); -->break;case 69:zuoxia1=1;<!-- console.log('e'); -->break;case 90:youshang1=1;<!-- console.log('z'); -->break;case 67:youxia1=1;<!-- console.log('c'); -->break;case 74:<!-- jiasu=1; --><!-- console.log('j'); -->go('j');break;case 75:<!-- jiansu=1; --><!-- console.log('k'); -->go('k');break;default:break;}}document.addEventListener('keyup',(e)=>{var ev = e || window.event;switch(ev.keyCode){case 87:before1=0;<!-- console.log('w'); -->break;case 65:left1=0;<!-- console.log('a'); -->break;case 88:right1=0;<!-- console.log('x'); -->break;case 68:cabk1=0;<!-- console.log('d'); -->break;case 81:zuoshang1=0;<!-- console.log('q'); -->break;case 69:zuoxia1=0;<!-- console.log('e'); -->break;case 90:youshang1=0;<!-- console.log('z'); -->break;case 67:youxia1=0;<!-- console.log('c'); -->break;default:break;}},false);     var i= null;$('.before').mousedown(function(){i = setInterval(function(){<!-- console.log('w'); -->go('w');},50);});$('.left').mousedown(function(){i = setInterval(function(){<!-- console.log('a'); -->go('a');},50);});$('.cabk').mousedown(function(){i = setInterval(function(){<!-- console.log('x'); -->go('x');},50);});$('.right').mousedown(function(){i = setInterval(function(){<!-- console.log('d'); -->go('d');},50);});$('.zuoshang').mousedown(function(){i = setInterval(function(){<!-- console.log('q'); -->go('q');},50);});$('.youshang').mousedown(function(){i = setInterval(function(){<!-- console.log('e'); -->go('z');},50);});$('.zuoxia').mousedown(function(){i = setInterval(function(){<!-- console.log('z'); -->go('e');},50);});$('.youxia').mousedown(function(){i = setInterval(function(){<!-- console.log('c'); -->go('c');},50);});$('.jiasu').mousedown(function(){i = setInterval(function(){<!-- console.log('j'); -->go('j');},100);});$('.jiansu').mousedown(function(){i = setInterval(function(){<!-- console.log('k'); -->go('k');},100);});$('#main span').mouseup(function(){clearInterval(i);});});var timer = window.setInterval(()=>{if(before1==1)  {<!-- console.log('s'); -->go('w');} if(cabk1==1)    {<!-- console.log('x'); -->go('x');} if(left1==1)    {<!-- console.log('a'); -->go('a');} if(right1==1)   {<!-- console.log('d'); -->go('d');} if(zuoshang1==1){<!-- console.log('q'); -->go('q');} if(zuoxia1==1)  {<!-- console.log('e'); -->go('e');} if(youshang1==1){<!-- console.log('z'); -->go('z');} if(youxia1==1)  {<!-- console.log('c'); -->go('c');} },80);</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;}#main span.on7{background: #10e62a;position: absolute;left: 300px;top: 58px;}#main span.on8{background: #f10606;position: absolute;left: 370px;top: 58px;}</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><span class="on7 jiasu"></span><span></span><span class="on8 jiansu"></span><span></span>
</div>
</body>
</html>

上面的html中结合了onkeydown与keyup方法来对每个按键影响的变量进行0/1的赋值。最后通过var timer = window.setInterval(()=>函数来判断变量的数值以进行go()函数的调用。且这些变量中并没有加减速。因此加减速能与他们分开并交替传输到python代码中。

接下来给出python代码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 = 15#IO口初始化
def init():GPIO.setmode(GPIO.BOARD)GPIO.setwarnings(False)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()
#变速
def change(tf):GPIO.output(IN1,False)GPIO.output(IN2,False)GPIO.output(IN3,False)GPIO.output(IN4,False)time.sleep(tf)#GPIO.cleanup()sleep_time=0.012
change_time=0.001
class IndexHandler(tornado.web.RequestHandler):def get(self):self.render("xiaoche.html")def post(self):init()global sleep_timeglobal change_timearg=self.get_argument('k')if(arg=='w'):before(sleep_time)change(change_time)#print("1")elif(arg=='x'):cabk(sleep_time)change(change_time)elif(arg=='a'):left(sleep_time)change(change_time)elif(arg=='d'):right(sleep_time)change(change_time)elif(arg=='q'):zuoshang(sleep_time)change(change_time)elif(arg=='z'):youshang(sleep_time)change(change_time)elif(arg=='e'):zuoxia(sleep_time)change(change_time)elif(arg=='c'):youxia(sleep_time)change(change_time)elif(arg=='j'):if(change_time>0.001):sleep_time=sleep_time+0.0001;change_time=change_time-0.0001;elif(arg=='k'):if(change_time<0.003):sleep_time=sleep_time-0.0001;change_time=change_time+0.0001;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:8888")tornado.ioloop.IOLoop.instance().start()#print("1")

该函数内的代码与网页控制小车速度的初步实现里代码唯一不同的地方是将sleep_time也设定成了全局变量,与change_time相反的增减,以此达到每次循环的时间都是一样的。运行时的效果也是比较明显的。

但是两个时间的比例还是需要多次试验才能定下。否则比例不当会造成小车边开边卡。
运行结果在图片上还是没什么变化,还是需要自己一步步调试才能成功。


不足:

现在网页控制还是有点不足的,由于可以同步。导致各个方向控制的按键中,若有多个同时按下,可能导致驱动异常。且必须先按方向键才能接着一起按变速键,否则无法实现变速。

总结:

其实自己也没想的,这么快就已经出到小车教程系列四了。希望看到这了的朋友能够在树莓派小车上有自己的突破。

关于小车行驶方面是没有问题了,只在这方面有需求的读者们一个系列看到这里希望能基本解决你们的需求。不过我的项目中不仅是小车能开,还需要装载摄像头与监测模块、4G模块,目的是能够远程控制小车在摄像头监视下行驶,且能够监测小车周围的环境数据。希望接下来也能够写出这样的记录,能为之后同需求的读者提供帮助。

感谢各位观看,如有不足,欢迎在评论内留言与讨论。如果觉得写得好的,可以给我点赞+收藏+关注哦,再次感谢各位!

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

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

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

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

    项目场景: 前两天笔者写了一份手把手树莓派小车教程(一)之--小车跑起来的教程.当时只是让小车能动起来,不过项目中的小车肯定是需要一个用户界面能够操控的. 能看到这一部分的读者们可能基本都会简单的控制 ...

  3. Arduino循迹小车教程四----代码篇

    文章目录 一.完整的代码 二.循迹代码详解 1.循迹的原理 2.判断情况 3.调速代码 4.循迹代码 5.调试问题 总结 代码分享给同学们啦,在同学们运行小车的过程中,总会遇见各种奇怪的情况,比如小车 ...

  4. 【ppt幻灯片制作】Focusky教程 | 怎样实现像PPT那样控制播放速度?

    Focusky (也称为"FS软件")输出的文件可以轻松实现像PPT那样控制播放速度, 根据客观需要,使播放暂停或者前进后退. 1."选项"-> &quo ...

  5. stm32项目_stm32f103c8t6项目_循迹避障小车完整制作过程_智能小车设计_STM32智能小车教程-循迹-避障-蓝牙遥控-跟随

    [硬件] 元件选型 照片上传出问题了,改天补上,着急的可以看视频 视频链接在这里 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sKjJGMXv-16463139639 ...

  6. 基于SPCE061A的语音控制小车设计

    目 录 第一章 前言--------------------------1 第二章 语音控制小车设计要求-----------------2 2.1 功能设计要求------------------- ...

  7. 简单循迹小车实验心得_红外自动循迹小车实验报告

    红外自动循迹小车实验报告 1摘要 本实验完成采用红外反射式传感器的自寻迹小车的设计与实现.采用与白色地面色差很大的黑色 路线引导小车按照既定路线前进,在意外偏离引导线的情况下自动回位,并能显示小车停止 ...

  8. 无线控制模块c语言编程,基于STM32F103ZET6无线语音控制小车设计与实现.doc

    基于STM32F103ZET6无线语音控制小车设计与实现 基于STM32F103ZET6无线语音控制小车设计与实现 摘要:本文以STM32F103ZET6单片机作为控制核心,通过LD3320语音识别模 ...

  9. 树莓派小车教程(一)之——小车跑起来

    项目背景: 前段时间笔者接触到了一个关于救援小车的项目,这个小车还需要适应比较复杂的地形.因此淘宝里类似于树莓派智能小车的产品(大都是亚克力板拼接或底座太低)不太适合.因此笔者买了一个能够水陆两栖的遥 ...

最新文章

  1. java实现的18位×××格式验证算法
  2. AtcoderGrandContest 005 F. Many Easy Problems
  3. Nginx和lvs在负载均衡方面的对比
  4. IOC和DI的区别详解
  5. 法兰程序CAD开发的进展
  6. 同步中心服务器,同步中心以非常慢的速度同步脱机文件 - Windows Server | Microsoft Docs...
  7. WCDMA是什么意思?CDMA是什么意思?GSM是什么意思
  8. ORA-01438错误的解决方法
  9. Wacom发布Cintiq Companion 2
  10. android 新浪微博分享链接地址,Android 集成新浪微博分享及授权 (上)
  11. “梦中行千里不如现实行一步。”创业亦是如此丨国仁网络资讯
  12. 滑雪是不是要去北海道?学会Python电脑就能玩滑雪小游戏
  13. NPOI导出漂亮的Excel报表
  14. 锐龙R3 4300U怎么样 相当于什么水平
  15. 解决AppBarLayout嵌套WebView滑动冲突的问题
  16. 主动学习(Active learning)简介
  17. SPFA算法判断负权环(bfs_spfa,dfs_spfa)
  18. Ubuntu 10.04 LTS 下 Android 4.1.2_r1 源代码的下载
  19. persona 典型用户
  20. B1030 (完美数列)

热门文章

  1. [转]Flash socket通讯中的安全策略问题详解
  2. uni-app开发之HBuilderX连接夜神模拟器
  3. 编码器c语言斌编程,旋转编码器的编程思路
  4. 计算机金融专业结课论文题目,金融硕士论文题目精选40例
  5. CPU部件实现之ALU、寄存器堆、PC、RAM
  6. 伏格尔法解决传输运输问题
  7. 看门狗 (监控芯片)
  8. [Android应用开发] 01.快速入门
  9. 我的实用设计模式之Observer模式
  10. 软件测试工程师考核标准,(软件测试工程师考核标准.docx