文档章节

通过WEB控制树莓派RGB灯光

e哥
 e哥
发布于 2016/11/04 19:12
字数 2316
阅读 800
收藏 2
点赞 1
评论 0

        前段时间玩了下RPi.GPIO,感觉挺有意思的。之后也看了wiringPi和BCM2835库。

        wiringPi:http://wiringpi.com/             BCM2835:http://www.airspayce.com/mikem/bcm2835/

        如果是用python操作树莓派GPIO推荐用RPi.GPIO,如果用C的话推荐用BCM2835,BCM2835主页对它使用介绍比wiringPi主页要明了些,使用起来很方便。

        好了回到今天的主题,前一篇博客介绍了RPi.GPIO的使用方法,今天就准备写写用它来实现手机网页操控rgb灯光。实现的功能有:改变灯光颜色、灯光闪烁和呼吸效果。

        先来看看视频演示:http://v.qq.com/x/page/v03437u3g8d.html

                     

        要使手机能访问树莓派的网页,就得在树莓派上搭建网络服务器。bottle这个包搭建网络服务非常方便,只需简单几行代码就行,而且使用它也不需要安装其他软件,你甚至不需要安装bottle直接把bottle.py放入自己的项目中就行,我就是这么做的。bottle主页:http://www.bottlepy.org/docs/dev/   或者直接下载pdf手册:https://git.oschina.net/ginnywzj/web_rgb/attach_files

接下来连接树莓派和RGB灯光:

                          

        电路示意图用Fritzing画的。

接下来就是上代码了:

        本项目总共5个代码文件:bottle.py、main.py、RGB_light.py、jquery-3.1.1.min.js、index.html。bottle.py和jquery-3.1.1.min.js是直接从网上下载的就不在这里介绍了,RGB_light.py是一个python包里面有个python类(RGB_light)用来控制树莓派引脚的pwm输出,如果想知道它的工作原理可以查看RPi.GPIO使用手册.pdf。下文主要介绍main.py和index.html。

main.py: 

01 #!/usr/bin/env python3
02 
03 import RPi.GPIO as GPIO
04 from RGB_light import RGB_light
05 from bottle import request, route, run, static_file     #bottle使用介绍:https://git.oschina.net/ginnywzj/web_rgb/attach_files
06 import time, threading
07 
08 rgb = 0
09 RGBLight = RGB_light(GPIO.BOARD, 1, 33, 35, 37) #初始化rgb灯GPIO引脚,引脚编号系统为GPIO.BOARD、共阳、red通道为33引脚,green通道为35引脚,blue通道为37引脚s
10 light_type = 'static'    #'static':静态 'breath':呼吸 'flash':闪烁
11 
12 #访问文件根目录
13 @route('/')
14 def index():
15     global rgb, light_type
16     rgb = 0xffffff
17     light_type = 'static'
18     return static_file('index.html', './page')
19 
20 #网页上的静态文件需要做传输处理
21 @route('/<filename>')
22 def server_static(filename):
23     return static_file(filename, root='./page')
24 
25 #POST方式获取Ajax传输过来的rgb值
26 @route('/rgb', method='POST')
27 def rgbLight():
28     red = request.POST.get('red')
29     green = request.POST.get('green')
30     blue = request.POST.get('blue')
31     print('red='+ red +', green='+ green +', blue='+ blue)
32     red = int(red)
33     green = int(green)
34     blue = int(blue)
35     if 0 <= red <= 255 and 0 <= green <= 255 and 0 <= blue <= 255:
36         global rgb
37         rgb = (red<<16) | (green<<8) | blue
38 
39 #POST方式获取Ajax传输过来的type值
40 @route('/lightType', method='POST')
41 def lightType():
42     global light_type
43     light_type = request.POST.get('type')
44     print("lightType="+light_type)
45 
46 #灯光循环检测控制
47 def lightLoop():
48     global rgb, light_type
49     flashTime = [0.3, 0.2, 0.1, 0.05, 0.05, 0.1, 0.2, 0.5, 0.2] #闪烁时间间隔
50     flashTimeIndex = 0 #闪烁时间间隔索引
51     f = lambda x: (-1/10000.0)*x*x + (1/50.0)*x #用抛物线模拟呼吸灯
52     x = 0
53     while True:
54         if light_type == 'static':   #静态显示
55             RGBLight.set_rgb(rgb)
56             time.sleep(0.05)
57         elif light_type == 'breath': #闪烁显示
58             red = int(((rgb & 0xff0000)>>16) * f(x))
59             green = int(((rgb & 0x00ff00) >> 8) * f(x))
60             blue = int((rgb & 0x0000ff) * f(x))
61             _rgb = int((red << 16) | (green << 8) | blue)
62             RGBLight.set_rgb(_rgb)
63             time.sleep(0.02)
64             x += 1
65             if x >= 200:
66                 x = 0
67         elif light_type == 'flash':  #呼吸灯显示
68             RGBLight.set_rgb(rgb)
69             time.sleep(flashTime[flashTimeIndex])
70             RGBLight.set_rgb(0)
71             time.sleep(flashTime[flashTimeIndex])
72             flashTimeIndex += 1
73             if flashTimeIndex >= len(flashTime):
74                 flashTimeIndex = 0
75 
76 #开辟新线程负责rgb灯光显示
77 t = threading.Thread(target = lightLoop)
78 t.start()
79 
80 #设置服务器ip地址和端口(提示:使用前请设置成你的树莓派ip地址)
81 run(host='192.168.21.104', port=8080)

(这里要吐槽下,添加代码为什么没有行号(难道是我没发现),还得自己用UltraEdit添加,添加了行号别人复制了又不能直接用,希望开源中国能更新下)

        主要看第21行、26行、40行、77行和81行。

        1、第21行是创建一个网页静态文件传输通道。index.html文件中引用了jquery-3.1.1.min.js和两张图片,如果不添加它们的传输通道,这些文件将不能传输到手机,在bottle说明手册中也明确说明了。

        2、第26行、40行是接收index.html网页回传数据的方式,可以为GET或者POST,但要保持index.html和main.py一致。

        3、第77行是开辟一个python线程。为什么要另外开辟线程呢?main.py有两个任务:1、监听手机传回的数据;2、控制树莓派引脚pwm输出。main.py启动后会产生一个线程,当执行到81行(run(host='192.168.21.104', port=8080))这个线程就给了bottle。bottle会一直监听手机,如果有数据传回它就会执行被它装饰了的函数(例如27行的rgbLight)。如果灯光只是静态的显示颜色,那么只要监听到一个数据就在装饰函数中修改一次pwm输出就可以,这样单个线程也没问题。但本文的灯光还有闪烁和呼吸效果,这样就需要main.py一直控制pwm输出,单线程的main.py是一直在监听手机的没办法一直控制pwm,所以必须创建新线程来单独控制pwm。

        4、第81行是设置服务器的ip地址和端口号,这里必须修改成你自己树莓派的ip地址,否则不能运行会报错。查看ip地址指令:ifconfig。

index.html:

01 <!doctype html>
02 <html>
03 <head>
04     <meta charset="utf-8">
05     
06     <!--适应手机大小,不允许放大缩小-->
07     <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
08     
09     <title>web rgb</title>
10     <script src="jquery-3.1.1.min.js">
11     </script>
12     <style type="text/css">
13 		body,div,img{ border:0; margin:0; padding:0;}
14     </style>
15 </head>
16 
17 <body>
18 	<div style="width:100%; height:40px; line-height:40px; text-align:center; font-size:20px; color:white; background-color:blue; margin:auto">
19     	通过WEB控制树莓派RGB灯光
20     </div>
21     <img width="300" height="300" src="color_range.png" id="myimg" style="display:none" alt="range"/>
22    
23     <div style="width:300px; height:300px; position:relative; text-align:center; margin:auto; margin-top:20px; margin-bottom:40px;" id="colorRange">
24     
25         <canvas id="mycanvas" width="300" height="300">
26             你的浏览器不支持html5 Canvas元素。
27         </canvas>
28         
29         <img width="30" height="30" src="color_picker.png" id="picker" style="position:absolute; top:135px; left:135px;" alt="picker" />
30     </div>
31     <div style="font-size:20px; text-align:center; border:1px solid gray; border-radius:10px; width:100%; height:40px; line-height:40px;">
32         <input type="radio" name="radio1" value="static" checked/>静态&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
33         <input type="radio" name="radio1" value="breath"/>呼吸&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
34         <input type="radio" name="radio1" value="flash"/>闪烁
35     </div>   
36 </body>
37 	<script>
38 		var RadiusRange = 150;
39 		var RadiusPicker = 15;
40 		var offsetX = window.screen.width / 2 - RadiusRange;
41 		var offsetY = 60;
42 		var centerX = offsetX + RadiusRange;
43 		var centerY = offsetY + RadiusRange;
44 		
45 		var colorRange = $('#colorRange')[0];
46 		var colorPicker = $('#picker')[0];
47         var myCanvas = $('#mycanvas')[0];
48         var myImg = $('#myimg')[0];
49         var ctx = myCanvas.getContext('2d');
50         myImg.onload = function(){ctx.drawImage(myImg, 0, 0);}
51         
52         colorRange.addEventListener('touchstart', touch, false);	//监听touchstart事件
53         colorRange.addEventListener('touchmove', touch, false);		//监听touchmove事件
54         function touch(e)
55         {
56          	var X = e.touches[0].clientX;
57 			var Y = e.touches[0].clientY;
58 			var x = X - centerX;
59 			var y = Y - centerY;
60             if(Math.sqrt(x*x + y*y) < RadiusRange-5)
61 			{
62 				colorPicker.style.left = X - offsetX - RadiusPicker +'px';
63 				colorPicker.style.top = Y - offsetY - RadiusPicker +'px';
64 				
65 				var rgba = ctx.getImageData(X-offsetX, Y-offsetY, 1, 1).data;
66 				var red = rgba['0'];
67 				var green = rgba['1'];
68 				var blue = rgba['2'];
69 				$.post('/rgb', {red: red, green: green, blue: blue});
70 			}  
71 			
72 			//阻止事件上抛给浏览器
73 			event.preventDefault(); 
74         }	
75 		
76 		//rgb灯光显示类型选择
77 		$('input').click(function() {
78 			var type = this.value;
79 			$.post('/lightType', {type: type});;
80 		});
81     </script>
82 </html>

        index.html需要手机浏览器支持html5的canvas元素,现在绝大部分都支持。 jquery的使用可以参考jquery主页API文档:http://api.jquery.com/

        看看index.html在手机上显示效果:

                                                         

        1、第52行和53行建立对touchstart事件和touchmove事件监听。这两个事件只在手机端起作用,所以在pc端访问时拖动鼠标,是不能选中颜色的。pc端相对应的事件为:onmousedown、onmousemove。如果想在pc端使用可以修改为相应事件(类似:drawCanvas.onmousedown=function(){})。

        2、第54行的touch函数功能是判断触摸点是否在颜色选择框内,在的话就移动picker和上传被选中点的rgb值给树莓派。

        3、第73行是阻止事件上抛,没有它你选择颜色时手机浏览器就会认为是在切换页面。

        4、第77行,选择灯光效果,在pc端也能操作。

        如果想查看所有代码可到我的码云上看哦:https://git.oschina.net/ginnywzj/web_rgb

        你也可以直接用树莓派下载然后运行试玩,方法如下:

                git clone https://git.oschina.net/ginnywzj/web_rgb.git

                cd web_rgb

                //修改main.py中的ip地址

                python3 main.py

        在这之前我玩过BLE蓝牙控制灯光,蓝牙虽然省电但连接真心慢,每次都要开启手机蓝牙然后等待连接,基本上要消耗10秒。现在树莓派3B有了wifi,让它连上家里的路由器,手机一般都连着,通过wifi来控制灯光速度很快,而且不需要安装APP,只要打开操控网页就行,使用很方便。

        RPi.GPIO+bottle还可以制作出很多好玩的,大家不妨也来制作一个玩玩。

© 著作权归作者所有

共有 人打赏支持
e哥
粉丝 7
博文 4
码字总数 7777
作品 0
深圳
树莓派摄像头VLC网络监控

备忘 树莓派有网口,又有摄像头可以用,当然不能浪费资源,下面我就用红外摄像头来做个昼夜均可使用的摄像头监控~ 连接好树莓派的CSI摄像头,我用的是带有红外灯的,并且有光感控制的,只有在...

乐_然 ⋅ 03/11 ⋅ 0

树莓派开启VNC,电脑远程实时操控树莓派桌面

一般远程控制树莓派,命令行使用SSH服务,但是有的时候,我们想远程控制树莓派的桌面。这时就要启用VNC了。 1.在树莓派上开启VNC服务: 这样在树莓派上就开启了VNC服务,开启成功后,在桌面右...

乐_然 ⋅ 03/07 ⋅ 0

树莓派pi3 串口问题的解决办法

转载: https://blog.csdn.net/aguangg6655la/article/details/54985423 其他参考1:https://blog.csdn.net/xukai871105/article/details/22713925 其他参考2:https://www.briandorey.com/......

zhenguo26 ⋅ 04/18 ⋅ 0

如何使用树莓派制作一个数字针孔摄像头

学习如何使用一个树莓派 Zero、高清网络摄像头和一个空的粉盒来搭建一个简单的相机。 在 2015 年底的时候,树莓派基金会发布了一个让大家很惊艳的非常小的 树莓派 Zero。更夸张的是,他们随 ...

19% ⋅ 昨天 ⋅ 0

树莓派3b连接串口类型GPS使用使用串口并关闭蓝牙板载方法

树莓派3上用户目前无法正常是使用GPIO中的UART串口(GPIO14&GPIO15),也就是说用户无论是想用串口来调试树莓派,还是想用GPIO中的串口来连接GPS,蓝牙,XBEE等等串口外设目前都是有问题的。 原因...

huazwz ⋅ 04/11 ⋅ 0

树莓派随身工具箱:中间人劫持获取控制权

  *本文原创作者:Rc4x,本文属FreeBuf原创奖励计划,未经许可禁止转载   导读   上文讲解了树莓派随身工具箱的环境搭建,这段时间又对其进行了一些优化,主要是从便携美观上面改进。同...

FreeBuf ⋅ 04/26 ⋅ 0

PHP再学习5——RESTFul框架 远程控制LED

0.前言 去年(2013年)2月第一次接触yeelink平台,当时该平台已经运行了一些时间也吸引了不少极客。试想自己也将投身IoT(物联网)行业,就花了些时间研究了它。陆陆续续使用和研究了一年,大...

thinkyoung ⋅ 2014/12/02 ⋅ 0

如何使用树莓派测定颗粒物(PM 2.5)

使用两个简单的硬件设备和几行代码构建一个空气质量探测器。 我们在东南亚的学校定期测定空气中的颗粒物。这里的测定值非常高,尤其是在二到五月之间,干燥炎热、土地干旱等各种因素都对空气...

作者: Stephan Tetzel ⋅ 05/08 ⋅ 0

树莓派可视化编程软件 - BlocklyPi

本项目是一个基于Blockly的树莓派可视化编程软件,类似于Mixly,可以让让零基础不会编程的人玩转树莓派gpio。 使用说明 见项目 地址 更多说明详见BlocklyPi 实际使用 详见 http://hgccloud....

王逸伦 ⋅ 06/11 ⋅ 0

EAI激光雷达X4使用hector_slam建图(二)

通过上一节,我在虚拟机下测试雷达驱动成功,现在,我们就拿树莓派3B为例,给激光雷达单独供电后,按着上一节来操作图上为PC端通过VNC与树莓派远程桌面连接,接在按着上一节在树莓派上操作完...

zhu751191958 ⋅ 01/04 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

从 Confluence 5.3 及其早期版本中恢复空间

如果你需要从 Confluence 5.3 及其早期版本中的导出文件恢复到晚于 Confluence 5.3 的 Confluence 中的话。你可以使用临时的 Confluence 空间安装,然后将这个 Confluence 安装实例升级到你现...

honeymose ⋅ 15分钟前 ⋅ 0

用ZBLOG2.3博客写读书笔记网站能创造今日头条的辉煌吗?

最近两年,著名的自媒体网站今日头条可以说是火得一塌糊涂,虽然从目前来看也遇到了一点瓶颈,毕竟发展到了一定的规模,继续增长就更加难了,但如今的今日头条规模和流量已经非常大了。 我们...

原创小博客 ⋅ 今天 ⋅ 0

MyBatis四大核心概念

本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 MyBatis 作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:Sql...

waylau ⋅ 今天 ⋅ 0

以太坊java开发包web3j简介

web3j(org.web3j)是Java版本的以太坊JSON RPC接口协议封装实现,如果需要将你的Java应用或安卓应用接入以太坊,或者希望用java开发一个钱包应用,那么用web3j就对了。 web3j的功能相当完整...

汇智网教程 ⋅ 今天 ⋅ 0

2个线程交替打印100以内的数字

重点提示: 线程的本质上只是一个壳子,真正的逻辑其实在“竞态条件”中。 举个例子,比如本题中的打印,那么在竞态条件中,我只需要一个方法即可; 假如我的需求是2个线程,一个+1,一个-1,...

Germmy ⋅ 今天 ⋅ 0

Springboot2 之 Spring Data Redis 实现消息队列——发布/订阅模式

一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式,这里利用redis消息“发布/订阅”来简单实现订阅者模式。 实现之前先过过 redis 发布订阅的一些基础概念和操...

Simonton ⋅ 今天 ⋅ 0

error:Could not find gradle

一.更新Android Studio后打开Project,报如下错误: Error: Could not find com.android.tools.build:gradle:2.2.1. Searched in the following locations: file:/D:/software/android/andro......

Yao--靠自己 ⋅ 昨天 ⋅ 0

Spring boot 项目打包及引入本地jar包

Spring Boot 项目打包以及引入本地Jar包 [TOC] 上篇文章提到 Maven 项目添加本地jar包的三种方式 ,本篇文章记录下在实际项目中的应用。 spring boot 打包方式 我们知道,传统应用可以将程序...

Os_yxguang ⋅ 昨天 ⋅ 0

常见数据结构(二)-树(二叉树,红黑树,B树)

本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程《Algorithms, Part I》中的Slides 相关命题的证明可参考《算法(第...

浮躁的码农 ⋅ 昨天 ⋅ 0

android -------- 混淆打包报错 (warning - InnerClass ...)

最近做Android混淆打包遇到一些问题,Android Sdutio 3.1 版本打包的 错误如下: Android studio warning - InnerClass annotations are missing corresponding EnclosingMember annotation......

切切歆语 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部