Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the simply-static domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /var/www/html/wp-includes/functions.php on line 6121
树莓派制作智能镜全过程

树莓派制作智能镜全过程

第一部分——点子与镜子

作为一个男人,跟女友逛商城时,像是梅西百货那种的,难免会走神。我就是那号人,去年一月在纽约就发生过一回。长话短说。在我闲晃时我发现一面有灯光照明的镜子。我完全能自己做一面出来,而且比这更好。我想要属于我自己的智能镜!

magic_mirror1

一回到家,我开始构想我需要的东西:一面镜子,薄的那种,一个树莓派,一些木头和油漆,还需要大量空余时间。

关于镜子

普通的镜子是不行的。镜子是要那种单面透光那种,或更加精细功能的:后面屏幕黑屏时,它是一面镜子;而信息在屏幕上显示时就该像普通玻璃窗那样。

和警察局问询室内那面镜子原理一样,当只有一间房有光时,它就像一面镜子,其他时候它就是普通玻璃窗。

magic_mirror3

我所需要的是一面观察镜。现在,请相信我,当你问买玻璃的要一面观察镜时,会被反问一些奇怪的问题。他们那些人往往有更多新奇点子……嘿嘿,肮脏的思想永远是快乐的源泉。

终于我还是得到了一块不错的观察镜。开始找乐子吧!

第二部分——显示器

magic_mirror4

解决了镜子问题后,是时候为魔镜项目入手一台显示器了。

在为魔镜选择合适的显示器过程中,有一些纠结的决定。我是买一台新显示器还是捡一台呢?我需要什么尺寸?屏幕最薄会是多少?我如何移动控制按钮?屏幕是否够亮来盖过我的堂堂仪表?

因为我用显示器作为仪容之用,选择合适尺寸差不多就是选择合适的宽度(也就是镜子合适的高度)。在一些测量和尝试用胶带固定在墙上我想放置镜子的位置后,24英寸屏幕会是完美的选择。额外带来的好处是,绝大多数(便宜的)24英寸屏幕初始就带有1080P分辨率,正是我想在这个项目所使用的分辨率。

为了合适的屏幕类型和品牌,我几乎跑遍了方圆20公里内的电器铺。我敢肯定保安大叔在盯着我,而我正仔细检查所有屏幕背面和底部。

大多数品牌被立即否定了,因为它们的电源和视频连接线在背后。我需要转接线是在侧面的那种。

magic_mirror5

最后我选择了Iiyama显示器,它最接近我所希望的——价格便宜,边框窄小,简单触控按钮和正确转接器方向。

直到现在,我还是不清楚显示器外壳能否轻易被卸除,控制面板如何在显示器内部被连接上。销售人员不许我做出怪异的动作,打开显示器外壳,所以买到这台合适的显示器纯属运气。

magic_mirror6

我订购了一台24英寸Iiyama E2481HS-B1显示器。为确定显示器和镜子之间气密性良好,我拆下了外壳。在刚刚开箱就进行拆卸显示器够战战兢兢的,但……勉强成功。

这台Iiyama显示器的好处是,显示控制器(金属盒内的电子元件)为这面镜子的其他零件留下了足够的空间,而又保持了它原本的苗条外形。

magic_mirror7

实际的显示板仅有9毫米厚,而小小的边框也只是10毫米宽。加上显示控制器后,就是下列尺寸:556毫米x323毫米x46毫米(外加6毫米的镜子厚度)。这些尺寸构成了新的木头外壳尺寸。

第三部分——外壳

magic_mirror8

在量度新外壳所需尺寸后,就开始享受DIY的喜悦吧。我用松木做了个结实坚固的框架,用地板地脚线固定镜子和显示器的位置,那尺寸刚刚好(30毫米宽),还有圆角边框效果。

镜子很可能会发热,那就需要通风口了。此外,在外壳的背后还加了几个既美观又结实的挂点。

小剧透:产品最终重量6.5千克,由我做的两个挂载点所推测得来。

magic_mirror11

补充一下,我在外壳的底部开了条细缝作为电源线槽。

当然,它需要进行上色。在涂抹油灰(我在打磨抛光时后悔涂太多油灰了)、一些地漆及上土层后,新外壳完工。

magic_mirror14

有个木工小步骤我要去做的:我做了4个挂在块来安装显示器与镜子。现在准备好将它们上在镜框里面。

magic_mirror15

木工部分到此结束,进入魔镜的下一环节,安装硬件。

第四部分——安装硬件

magic_mirror16

魔镜开始成形。我订购了镜子,找到合适的显示器,完成打磨白色的外壳,是时候开始安装硬件了。

目前我手上有以下零件: 显示器 + 树莓派 + 一条HDMI线(连接树莓派和显示器) + 一条USB转micro USB转接线(用来为树莓派供电) + 一条显示器电源线

但接着我遭遇到小小挫折。在找合适的显示器时,我完全没想到看看显示器有没有一个USB口,用来驱动树莓派。我以为现在的显示器都默认装有USB口,不过我错了,它没有。

这不是不能解决的问题,但我真心希望只用一条线来驱动魔镜。所以我只能将电源分为两条线,一条给显示器,一条给240伏USB降压器。补充一点,我希望用一条普通C13电源线就能驱动智能镜。

magic_mirror17

也就是说,我要做的是中间带有USB充电器的接插电源线。在翻了我几个闲置线材抽屉后,我找到了个旧USB充电器。

magic_mirror18

拆开充电器比想象中的容易,只要一点点焊接工序,一些胶和绝缘胶布即可。我要设法做个外观高大上的电源线。

magic_mirror20

我做了试运行,确保电源线正常工作。我将所有零件连接好,插好电源线,打开显示器。树莓派启动正常,USB充电器没有发热过量。不错!

magic_mirror21

接着组装所有零件。这次没有倒霉事件:所有东西完美吻合。

magic_mirror24

另一个阶段完成了,包括所有实体部分(除了还没把两颗螺丝钉在墙上)。进入戏肉的部分:安装树莓派。

Magic Mirror: Part V – Installing the Raspberry Pi

第五部分——安装树莓派

magic-mirror25

那么,做完所有硬件之后,就轮到安装树莓派了。要达到智能镜的所有需求,树莓派就要有以下功能:

· Wifi连接 · 屏幕旋转90度,符合照镜方向 · 本地网络服务维持界面 · 在全屏幕下运行的浏览器,用于显示界面

基本安装

因为Raspbian操作系统的灵活性和背后有开源社群支持,我就选了它。下载了操作系统映像后,就把它写入SD卡。

拷贝一个映像档需要很长时间,那么有三种选择:

  1. 用树莓派技术文档中提到的rdisk方法拷贝。
  2. 拿杯咖啡,坐下,在等待中享受咖啡因的感觉。
  3. 上面两者都选。

我选了3。完成拷贝后,我启动树莓派、登入,进入命令行的sudo raspi-config开始配置向导。在这个配置中,有几件重要事项需要配置:

· 确保系统启动到桌面(取代命令行模式或调试模式)。 · 调整时区,使魔镜显示正确时间。 · 在高级选项部分,确保显存超过128MB。 如果你想做和这个一样的镜子,尽管尝试选择所有其他选项。只是记住,如果选砸了,就再泡杯咖啡重装系统吧。

Wifi连接

我不想在智能镜上加任何多余的连接线,就选择了以Wifi连接因特网。安装Wifi接收器真的依赖频宽和种类,因此写下完全过程是多余的。有最好的替代吗?看看这个神奇的网站……

老实说,这部分安装确实很花时间。一旦装好了,就能工作正常。

旋转屏幕

智能镜在设计上是纵向肖像模式,所以我需要将屏幕顺时针旋转90度,最终显示分辨率为1080 x 1920。我曾担心这会是最大的问题,最终却很容易解决了。

树莓派的BIOS设置储存在系统启动分区中。在这分区中,有一个config.txt文件,载有所有设置。要旋转显示器,在这文件内加上以下一行代码:
display_rotate=1

要让显示器连接更加可靠,我就不解释为何加上下面允许HDMI线热插拔的代码了:
hdmi_force_hotplug=1

配置文件存盘后重启树莓派,我不禁会心一笑:这感觉真好,腰不疼颈不酸了!

网络服务器

要维持界面(很简单的一个网页),我需要在树莓派上Apache服务器。这在树莓派上是其中一个很常见的应用,安装过程简直行云流水。

首先我运行下列指令,确定我用的是最新系统软件。
sudo apt-get update && apt-get upgrade -y

现在是时候真的安装Apache了:
sudo apt-get install apache2 apache2-doc apache2-utils

完成了!就是所有这些。但要保证在服务器上能用到一些PHP脚本(以后会更多的),我也加上了PHP支持:
sudo apt-get install libapache2-mod-php5 php5 php-pear php5-xcache

又完成了!重启之后,网页服务器就挂载上线运行了!我在/var/www文件夹内放置了index.php文件,将浏览器首页指向树莓派的IP地址,发现成功了。

信息模式(kioskmode)

现在就是要确定树莓派能够显示我在信息模式(kioskmode)下用Chromium浏览器显示的网页。Chromium浏览器是个能在树莓派操作系统上运行的开源浏览器。

一如既往,安装很简单:
sudo apt-get install chromium x11-xserver-utils unclutter

但这一次,它需要一些额外设置,在信息模式下禁用屏幕保护和自动重启。我在/etc/xdg/lxsession/LXDE/autostart作了编辑,在前面加上了#号。
@xscreensaver -no-splash

另外我还加了以下代码:
@xset s off @xset -dpms @xset s noblank @chromium –kiosk –incognito http://localhost

这样就能完全禁用所有屏保功能,及Chromium浏览器在开机后自动启动,开启全屏模式并导向本地主页。

存盘并再一次重启,检查工作效果。树莓派并不是世界上最快的电脑,它需要花点时间,但最终测试页还是在旋转了90度的画面上显示出来。要得!

进入项目的最后部分,界面开发。

第六部分——界面开发

回顾一下,我买了合适的镜子、显示器,做了个新外壳,安装好硬件及配置完成树莓派,那就进入最后一步——界面开发。

需求和功能

我开始项目时,我发现不能通过镜子直接进行任何交互,要不然在铮亮的镜面上会抹上油脂和什么脏东西。但还有更重要的原因,还有别的更好设备可用于用户交互。我希望智能镜只是个被动信息来源。

而更更重要的是,镜子就是镜子,不应被大量(无用的)信息所填满。只有边上能用来作摘要性显示,给本帅哥留些足够自恋的空间吧。

这样我需要以下信息类别目录来满足我对信息的需求:

· 问候语 贴心问候,每日美好的开始。

· 天气 看到我穿的衬衫吗?不错吧!嗯?今天穿T恤衫不会鸡冻吧?

· 时钟和日历 现在赶时间吗?还有足够时间顾影自怜吧?

· 消息反馈 我只是担心自己形象帅不帅吗?还有别的需要上心吗?

当然,未来版本当中有大量的改进可能,现在列出的这些应该够用了。

基本安装

前面提过,程序界面不是一个在树莓派桌面上神奇的应用,仅仅是一个全屏幕网页。我能用HTML、CSS和Javascript开发外,还有一个额外的好处,在我将它放入智能镜之前,能在我的苹果电脑上开发测试。

magic-mirror28

在自己写的代码基础上,我用了一些开源库文件来优化它的运行速度:

Jquery

像大多数网站那样,智能镜使用Jquery来简化DOM操作方式,对我这种懒人最为适用。

Moment.js

它对我在时间安排操作上帮助不少,尤其是在争分夺秒时更节省不少时间。

FeedToJson

将RSS订阅用JSON数据转成javascript的方便工具。

iCal Parser

将iCal数据转化为JSON。可惜这个库文件并不完美,需要一些额外的优化。

以上这些库文件,加上我自己的HTML和Javascript足够使我的镜子成精了。

设计

我的智能镜需要个酷炫设计。我本人是个严重果粉,那么在设计上要遵从苹果系的设计指标

边框、倾角、阴影效果有时是用户界面厚重感的因素,甚至能盖过显示内容的光芒。所以,专注在内容设计,把用户交互界面摆在辅助位置上。

利用足够的实体空间,它是个重要内涵,在感官上更让人注意和易于理解。

怎么做到这一点?用Helvetica Neue字体,用天气图标对应显示天气信息。

magic-mirror29

镜子在背后没有光源时就只是一面镜子,用黑色背景是个重要设定。而为了有最好的对比度,显示内容字体应为白色,在加一些灰色阴影边缘,那灰度为50吧……

我大可以加上一些其他色彩,但目前为止我只想做到简洁的黑白界面。我可不想镜子比我的尊容还要出彩。

API设计

为了接收我想在镜子上显示的数据,我用了一些开源API和反馈代码。还有谁不太清楚什么是API,维基百科里面有详尽的解释:

“电脑操作系统(Operating system)’或‘程序库’提供给应用程序调用使用的代码。”

我心中的API就像你家的DVD播放器背后那样充满接口——如果你将其他设备连接到它的话,它就变得更加有用,这些接口本质上就是API。API让设备变得功能强大、有趣,尤其对我这种电脑狂人来说。

Openweathermap.org

Openweathermap有很好的API接口,能够免费得到天气预报信息。它允许你查询区域内的信息,定义你想要的信息类别。在这里我用了两个连接,一个是当前天气,另一个是预报天气。

iCal Calendar

iCloud允许你以iCal格式分享日历。因为javascript无法做到这一点(因为多站点脚本安全问题),我需要通过PHP代理服务器来开启数据。这其实很容易,只有三行代码而已:

12<!--?php <br ?-->    $url "https://p01-calendarws.icloud.com/ca/subscribe/1/mysupersecreticloudhash";    echo file_get_contents($url);

只需查询calendar.php就能将在同一个服务器内日历表在界面上显示出来。

前面说过的iCal语法分析编辑帮我把信息解析成有用信息。可是,iCloud在他们的反馈中用了一些非标准标签,我要添加额外的代码行来将代码解析为javascript文件。

magic-mirror30

NOS新闻订阅

新闻订阅只是用到了荷兰公共广播公司的RSS订阅功能。可是,他们不支持JSON格式数据,因此我用了FeedToJson插件来把RSS数据转为JSON格式的。

其他内容,例如当前日期与实践,还有问候语都只是一些简单的javascript语句。

自动更新

你看了这篇博客这么久,应该能接受更进阶的信息了吧。那么瞪大眼看下去吧……

在开发当中,我遇到了一个很不爽的境地,就是没有键盘和鼠标连在智能镜上的问题。如果我更新界面,就没有一个简单方法在智能镜上更新页面的方法。最简单直接的方法是重启整个树莓派,但让我在调试每个更新上花时间太多了。

我用GIT分布控制系统更新文件,而每个更新版本都有本身的哈希校验提交码,我用PHP就能读取出来。这启发了我再代码行内加上一个片段,将本地页面和刚刚开发的页面进行哈希比对。如果两者不符,程序将重新载入网页,显示最新版本。

我用以下PHP代码获取当前网页上的哈希校验码:

1trim(`git rev-parse HEAD`)));

对比过程在javascript主文件内完成,但只有在HTML文件有当前版本的哈希校验值前提下才能实现:

1var gitHash = '';

现在,对比过程就很直观,每3秒进行一次:

1234567891011121314(function checkVersion()    {        $.getJSON('githash.php', {}, function(json, textStatus) {            if (json) {                if (json.gitHash != gitHash) {                    window.location.reload();                    window.location.href=window.location.href;                }            }        });        setTimeout(function() {            checkVersion();        }, 3000);    })();

所有这些神奇的操作,让更新智能镜界面变得简单。只需用SSH登入树莓派,进入合适的文件夹,然后处理一个git推送请求。

给我交出代码来!

得了得了……好奇了吧?所有代码在GitHub上都有。有件事情要说一声:代码很少标注,以面条式代码填充,通篇都是TODO语句。哈,不怕晃晕菜的,尽管扎进去吧。

未来展望

智能镜还能做更多的功能,这是一个陆续发展过程。如有新功能上的建议,请不吝提供。让我知道你想在界面上的创意。不过请记住,少为美。:)

发布于 分类 Linux