用树莓派DIY便携式警报器

我一直在寻找一些能给自己孩子带来教益的瞬间。当我五岁的儿子来寻求我的帮助,别再让他的弟弟偷偷溜进他的房间的时候,我突然灵光一现,发现这是教他关于输入、输出和其他一些编程知识的绝佳时机。而且让他在解决自己实际问题中学习这些也会相对容易。

我本来可以用很多不同的方法来建立一个简单的警报系统,但是我想要让这个系统是一体化的并且在功能上不止能满足我儿子最初的原始需求。选择树莓派作为控制器是因为它很容易连接到网络、能播放MP3格式的文件、可以和像摄像机这样的USB外围设备进行交互,而且它具有GPIO(通用的输入输出),这样就可以把它和按钮、传感器、灯这样的简单电子元件连接起来。

这个警报系统的源代码非常简单,你可以在我的GitHub上查看。为了利用Linux系统下多线程的优势,我把任务分解了到两个Python脚本中。一个Python脚本(keypadd.py)负责监视小键盘上的有效编码。系统启动时被设置为”disarmed”状态。一旦检测到arm/disarm代码,系统状态就会因为一个在”armed.txt”文件中设置的字节发生翻转而改变。

第二个Python脚本(alarmd.py)利用树莓派的GPIO来监视PIR(无源红外线传感器)。如果检测到动作发生,脚本接着检查”armed.txt”文件判断系统是否产生警报。如果检测到动作的时候产生了警报,警报就会响起。

我建立这个警报系统来满足我自己的需求。下面的内容会一步步地指导你建立一个类似这样的系统。当建立系统的时候,一定要根据自己的需求来定制,比如可以增加激光绊线或者蜂窝式无线电等。

步骤 1:搭建树莓派

通过那些有关树莓派的指导,将你的树莓派连接到互联网。这样就可以从网上下载在接下来的几步中所需要的库文件和代码,树莓派也就能通过推特和电子邮件来发送检测到的入侵者的图片了。

步骤2:安装GPIO

这个库文件允许你控制树莓派的GPIO来使用PIR和键盘作为输入,旋转灯作为输出。在终端中使用下面三条命令来安装:

安装GPIO库

sudo apt-get update sudo apt-get install python-dev sudo apt-get install python-rpi.gpio

步骤3:安装fswebcam

安装fswebcam

sudo apt-get install fswebcam

你可以用这个命令手动拍摄照片:fswebcam -r 640×480 -d /dev/video0 testpictire.jpg。然后使用 “ls” 命令查看拍摄的照片是否出现在当前工作目录中。

步骤4:安装mgp123

mgp123是脚本”alarmd.py”用来播放”System armed(系统警报)”、”Motion detected.Please enter passcode(检测到物体移动,请输入密码)”等声音文件的命令行音频播放器。安装命令如下:

安装mpg123

sudo apt-get install mpg123

安装git

sudo apt-get install git-core

然后使用”clone”命令将代码下载到你的树莓派:

下载PiLarm代码

git clone https://github.com/BabyWrassler/PiLarm.git

现在,你有了一个叫作PiLarm的目录,它包含PiLarm项目的python文件和音频文件。在/etc/rc.local文件中含有”exit 0″的行之前添加下面两行设置alarmd.py和keypadd.py为开机启动。

设置开机启动脚本

python /home/pi/Alarm/keypadd.py & python /home/pi/Alarm/alarmd.py &

请自己熟悉代码,将代码和以上的流程图比较,弄清楚代码中的语句是怎样运行的。

keypadd.py文件的第96行包含了用于给系统警报和解除警报的密码(1912)。第97 行的是关机密码(5764),是用来正常关闭树莓派使它可以拔下电源。

如果你使用的是树莓派的摄像头组件,请返回去参考树莓派的官方指导查看你需要用哪些命令来替换alarmd.py中与fswebcam相关的命令。

步骤6:设置Twitter

在https://dev.twitter.com/apps/new页面中新建一个”App”来获得Twitter的API接口密钥。

在”Access Level”中,选择访问权限的等级设置为”Read and Write”。这样之后你会获得”Consumer Key”, “Consumer Secret”, “Access Token”, “Access Secret”的值,而这些都是需要在创建TweetPony API对象的函数中插入的(插入位置在alarmd.py文件的第10行,默认内容为 “api = tweetpony.API(consumer_key = “abcd”, consumer_secret = “efgh”, access_token = “ijkl”, access_token_secret = “mnop”)。

步骤7:焊封面板套件Perma-Proto

Adafruit公司的面板套件Perma-Proto非常棒,因为它自带有适合树莓派上通用输入输出(GPIO)的连接器。树莓派上的引脚通过连接器固定在板子上,这让连接其余的部件变得非常简单。

将树莓派的3.3V电源接到Perma-Proto的正极上,树莓派的地线接到Perma-Proto的接地端。接下来的问题就是熟练、小心的布线,来把所有部件连接起来。我使用公引脚和母引脚作为连接器连接无源红外线传感器之类的器件,但你也可以把它们直接焊接起来。

注意音频放大器是在Perma-Proto板上的,从Perma-Proto的电源端获得电源,它并没有通过GPIO接头连接到树莓派上。音频线单独连接到放大器上,扬声器连接到放大器的螺丝接线端上。

键盘的连接线很短,因此在焊封前请一定设计好你的布局。

步骤8:完整的系统测试

现在你一定很想把这些都放进一个盒子里完成这个项目了,但是在你首先还得测试各个组件是否工作正常,因为一旦把它们放到一个狭小的空间中封装起来,出错的时候再解决故障就变得麻烦多了。

如果你的旋转灯出问题了,可能的一个原因是极性连接错误(polarity issue)。我在面包板上测试了自己的系统,手动把TIP120三极管接到电源或地端看看是否能解决问题。

如果是代码有问题,可能是一些组件连接到了错误的引脚,也可能是你忘记了设置一些常量的值,比如在第六步中要设置Twitter的一些键值。解决代码的错误,你可以使用Python的”print”命令来打印一些变量的内容到控制台,或者在代码中将一些事件标记为已执行。为了查看alarmd.py或者keypadd.py的控制台输出,你需要通过SSH进入到树莓派中通过命令”sudo python keypadd.py”或者”sudo python alarmd.py”自己运行这些脚本。

步骤9:安装外壳

大多数警报系统都被安装成永久固定不变的,但是我设计的这套系统是便携式的,这样可以很容易地扩展功能和重新作为其他用途。最后我选择了能把所有多西都装进去的最小的盒子。

我建立第一个PiLarm系统的时候树莓派的摄像头组件还不能使用,但是这些功能马上就要来了。如果你使用这个组件,弄清楚你要怎样加载它。如果你只是直接在外壳上钻一个孔把镜头露出来,你可能会使摄像头的视角范围变小。最好要么把摄像头安装在一个转轴上,要么把整个装置放置在一个三角架上来确保摄像头的视角。

如果你使用的是USB摄像头,直接用双面胶把它粘到外壳外面就行了,最好把露在外面的线孔都盖住。

外壳倒过来用效果更好,所以盖子的位置其实是底部。

在放置组件之前,要在外壳上为树莓派的螺母柱、Perma-Proto板的螺母柱、为扬声器预留的网格孔、LED灯、PIR、USB插孔、摄像头和旋转灯的连接线钻孔。可以不这样,但你肯定不想在某个连接器上掉下了钻孔留下的碎屑或者不小心钻透了某个很昂贵的器件。

键盘的连接线需要钻一排相互挨着的1/8″(10.3mm)的孔,用美工刀切掉相互之间的材料,做成一个槽。

双面胶会把摄像头和旋转灯固定到合适的位置。键盘可以用粘合剂。扬声器被螺栓固定到外壳上,Perma-Proto板和树莓派使用电路板的螺母固定到外壳上。

选择放置电路板的位置时,确保会为连线留下足够的空间。不要把连接线扭在一起或者在连接器上拉得过紧。连接线应该有适当的弯曲,连接器不应该承受任何拉力。PS3摄像头上的连接线很长,你可以把它整齐地盘绕成圈以免带来麻烦。

步骤10:和他人分享,激发他人的兴趣

恭喜你终于完成了!给我们发来你已经完成的系统的照片或者视频,让我们知道你是怎么个性化设计方案来满足自己的不同需求的。把你的杰作展示给那些你认为会因此产生灵感而成为创作者的人!

树莓派USB存储设备自动挂载

简单介绍实现命令行下USB存储设备自动挂载的方法,Linux gnome/kde窗口环境下有移动存储的管理程序,可以实现自动挂载移动存储设备,但是在命令行下 通常需要用mount命令手动挂载USB存储设备。

通过给linux下的设备管理服务udev添加规则配置文件,可以实现命令行下USB存储设备自动挂载。

输入命令:

sudo nano /etc/udev/rules.d/10-usbstorage.rules

复制粘贴这个脚本到编辑窗口

KERNEL!=”sd*”, GOTO=”media_by_label_auto_mount_end” SUBSYSTEM!=”block”,GOTO=”media_by_label_auto_mount_end” IMPORT{program}=”/sbin/blkid -o udev -p %N” ENV{ID_FS_TYPE}==””, GOTO=”media_by_label_auto_mount_end” ENV{ID_FS_LABEL}!=””, ENV{dir_name}=”%E{ID_FS_LABEL}” ENV{ID_FS_LABEL}==””, ENV{dir_name}=”Untitled-%k” ACTION==”add”, ENV{mount_options}=”relatime,sync” ACTION==”add”, ENV{ID_FS_TYPE}==”vfat”, ENV{mount_options}=”iocharset=utf8,umask=000″ ACTION==”add”, ENV{ID_FS_TYPE}==”ntfs”, ENV{mount_options}=”iocharset=utf8,umask=000″ ACTION==”add”, RUN+=”/bin/mkdir -p /media/%E{dir_name}”, RUN+=”/bin/mount -o $env{mount_options} /dev/%k /media/%E{dir_name}” ACTION==”remove”, ENV{dir_name}!=””, RUN+=”/bin/umount -l /media/%E{dir_name}”, RUN+=”/bin/rmdir /media/%E{dir_name}” LABEL=”media_by_label_auto_mount_end”

保存退出,再次插入usb存储设备会自动挂载到/media目录下面的目录 并且支持utf8格式的中文文件名。

树莓派日期时间不准的修正方法

在树莓派上,打date命令可以看到系统的日期时间:

(后面的CST表示中国标准时间)

树莓派没有电池,断电后无法保存时间。树莓派默认安装了NTP(Network Time Protocol)服务来获取互联网上ntp服务器提供的时间。如果这个时间不准,可以用这个命令校准一下。

sudo ntpd -s -d

如果还是不准,就用这个命令强制设置

sudo date –s=”2014-08-31 14:42:00″

最后,添加一些国内可用的ntp服务器,如果你的时间正常,可以不做这些设置。

打开ntp服务的配置文件

sudo nano /etc/ntp.conf

找到这两行

# You do need to talk to an NTP server or two (or three). # server ntp.your-provider.example

在下面添加以下内容,是一些亲测可用的ntp服务器。第一行最后的prefer表示优先使用此服务器,也就是复旦大学的ntp服务器。添加之后按Ctrl+X保存退出。

server ntp.fudan.edu.cn iburst prefer server time.asia.apple.com iburst server asia.pool.ntp.org iburst server ntp.nict.jp iburst server time.nist.gov iburst

重启ntp服务

sudo /etc/init.d/ntp restart

via

树莓派“瑞士军刀”扩展板开始发售

树莓派实验室自创建以来,一直致力于树莓派的介绍、学习以及基于树莓派的创作。在这两年中,我们整理和转载了很多有价值的文章和 DIY 方案,实验室也由最初的 One Man 运营发展成 Team 运营。接着,也就是近半年,在这里发生了更多的可能——我们研发了实验室的第一款硬件产品,树莓派瑞士军刀扩展板(Swiss Army Knife Shield,SAKS)。

SAKS 的设计初衷,是将实验室网站所积累的这些基于树莓派的 DIY 方案尽可能多地在一块扩展板上实现。由于这些 DIY 案例可能要用到LED、蜂鸣器、数码管、传感器等各种电子元件,这样每做一个案例不仅要软件重写,硬件上也要重新连线。我们在对这些进行归纳、高度抽象之后,最终设计出了 SAKS。SAKS 配备了常用的电子元件,通过精心的引脚设计,不仅使它能满足实验室的很多教程和 DIY 方案的硬件需求,更成为了一个极有开发潜力的扩展板。

产品特色

1. 本产品尺寸与 Raspberry Pi A+\B+\Raspberry Pi 2 兼容,可直插安装。

2. 常用功能器件的高度合理集成,整合更多功能单元。

3. 配备3.3V、5V电源引脚扩展单元。

4. 自带串口引脚单元,并配备了传输状态指示灯。

5. 配备I2C口引脚单元。

6. 高利用率的LED GPIO设计,8个LED,分两组,每组4个LED。一组为独享GPIO口,一组为共享GPIO口且支持跳线设置状态。

7. 2个开放的 3Pin 排插,可自行安装更多传感器。

今天,我们宣布 SAKS 扩展板正式发售,您可以进一步了解它、淘一块并能期待我们接下来围绕 SAKS 准备的一系列 DIY 教程。

最后打个真正的广告,欢迎加入实验室QQ群:242144314 和我们一起 DIY。

点击查看更多有关 SAKS 的图片

树莓派Linux串口编程实现自发自收

串口是计算机上一种非常通用设备通信的协议,常用PC机上包含的是RS232规格的串口,具有连接线少,通讯简单,得到广泛的使用。

Linux对所有设备的访问是通过设备文件来进行的,串口也是这样,为了访问串口,只需打开其设备文件即可操作串口设备。在linux系统下面,每一个串口设备都有设备文件与其关联,设备文件位于系统的/dev目录下面。如linux下的/ttyS0,/ttyS1分别表示的是串口1和串口2。

树莓派UART端口的位置:见下图的TXD、RXD。

本文是基于树莓派的环境,树莓派中可以使用串口/dev/ttyAMA0

要使用这个串口,必须先进行设置:

1.修改/boot/cmdline.txt

输入下面指令:

sudo nano /boot/cmdline.txt

删除粗体部分:

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

最终变为

dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

2.修改/etc/inittab

输入下面指令:

sudo nano /etc/inittab

注释掉最后一行内容:

#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

OK,重启下raspberry pi现在就可以自己编写程序测试串口了。我是把TXD与RXD短接,实现自发自收的。

程序如下:

recv.h

#ifndef _RECV_H #define _RECV_H #include #include #include #include #include #include #include #include #include #define BAUDRATE B115200 ///Baud rate : 115200 #define DEVICE “/dev/ttyAMA0” #define SIZE 1024 #endif

recv.c

#include “Recv.h” int nFd = 0; struct termios stNew; struct termios stOld; //Open Port & Set Port int SerialInit() { nFd = open(DEVICE, O_RDWR|O_NOCTTY|O_NDELAY); if(-1 == nFd) { perror(“Open Serial Port Error!

“); return -1; } if( (fcntl(nFd, F_SETFL, 0)) < 0 ) { perror("Fcntl F_SETFL Error! "); return -1; } if(tcgetattr(nFd, &stOld) != 0) { perror("tcgetattr error! "); return -1; } stNew = stOld; cfmakeraw(&stNew);//将终端设置为原始模式,该模式下所有的输入数据以字节为单位被处理 //set speed cfsetispeed(&stNew, BAUDRATE);//115200 cfsetospeed(&stNew, BAUDRATE); //set databits stNew.c_cflag |= (CLOCAL|CREAD); stNew.c_cflag &= ~CSIZE; stNew.c_cflag |= CS8; //set parity stNew.c_cflag &= ~PARENB; stNew.c_iflag &= ~INPCK; //set stopbits stNew.c_cflag &= ~CSTOPB; stNew.c_cc[VTIME]=0; //指定所要读取字符的最小数量 stNew.c_cc[VMIN]=1; //指定读取第一个字符的等待时间,时间的单位为n*100ms //如果设置VTIME=0,则无字符输入时read()操作无限期的阻塞 tcflush(nFd,TCIFLUSH); //清空终端未完成的输入/输出请求及数据。 if( tcsetattr(nFd,TCSANOW,&stNew) != 0 ) { perror("tcsetattr Error! "); return -1; } return nFd; } int main(int argc, char **argv) { int nRet = 0; char buf[SIZE]; if( SerialInit() == -1 ) { perror("SerialInit Error! "); return -1; } bzero(buf, SIZE); while(1) { nRet = read(nFd, buf, SIZE); if(-1 == nRet) { perror("Read Data Error! "); break; } if(0 < nRet) { buf[nRet] = 0; printf("Recv Data: %s ", buf); } } close(nFd); return 0; } 上面的是接受程序,可以接受字符串信息并打印,发送程序跟上面一样,只要把read改为write就行了,这里就不记录了。 程序运行结果: 参考文档: http://blog.csdn.net/leaglave_jyan/article/details/6656389 http://www.ibm.com/developerworks/cn/linux/l-serials/index.html via (转自 http://blog.csdn.net/scottly1/article/details/26575985)

树莓派 SAKS 扩展板上手把玩 之 通过串口登录树莓派

本文所介绍的内容基于树莓派瑞士军刀扩展板(SAKS),由于 SAKS 基于树莓派通用的 GPIO 设计,文中的原理和代码也适用于其他情况。

本文由树莓派实验室创作,遵循CC协议(署名-非商业性使用-禁止演绎-相同方式共享),欢迎树莓派爱好者们遵循协议内容转载传播。谢绝不遵守协议的转载和抄袭。

SAKS 扩展板特别将树莓派的串口(TXD\RXD)引出,方便玩家使用 USB to TTL 模块连接树莓派。

首先,你需要准备一个 USB to TTL 模块。或者直接使用封装好了的 USB to TTL 连接线。按照以上方法连接之后,就可以通过 Putty 等支持串口方式登录的 SSH 客户端连接树莓派了。

注意,如果系统没有安装过 USB to TTL 模块的驱动,那么需要先安装驱动。

以 Putty 为例,设置 SSH 连接的步骤如下。

1.确认串口模块,并设置码率

在 Windows 设备管理器中找到串口设备。

点击属性,设置码率为 115200。

2.配置 Putty 连接

按照图中配置设定。其中串口号请以你的设备管理器中实际的编号替换。

然后就可以连接登录树莓派了。

SAKS 精心设计了串口通讯灯一组,红灯亮表示有上行数据,绿灯亮表示有下行数据。

我们后面将介绍更多基于 SAKS 扩展板的有趣的内容,欢迎持续关注!

本文属于《树莓派瑞士军刀扩展板(SAKS)DIY 教程》系列文章,查看系列文章目录,请访问:https://shumeipai.nxez.com/swiss-army-knife-shield-for-raspberry-pi-diy-tutorials

PiJuice 树莓派电池解决方案,可续航6小时

专门为树莓派设计的 PiJuice 供电产品正在众筹网站上募集资金。这款产品旨在移动中提供电力,使树莓派更加便于携带。PiJuice是相当简单的设备。它采用可充点1400毫安时锂离子电池为树莓派提供电力,并且与树莓派的HAT布局兼容,采用RGB LED显示状态,并且支持树莓派的电源管理软件。

PiJuice 工作时利用到树莓派主板上5个GPIO引脚,带有实时时钟,使其能够独立维持时间轨迹,附带的软件允许在电量不多的情况下,让其进入睡眠模式,研发小组估计,所提供的1400毫安时电池将让树莓派连续运行6个小时。

研发团队正在努力拿出5000和10000毫安时电池,分别可以让树莓派连续运行16和28小时。另外,研发团队还将拿出一款PiJuice太阳能电池板为树莓派供电,方便树莓派在户外环境当中使用,比如安全摄像系或者气象观测站等等。

via

树莓派 SAKS 扩展板实用应用 之 树莓派关机键

本文所介绍的内容基于树莓派瑞士军刀扩展板(SAKS),由于 SAKS 基于树莓派通用的 GPIO 设计,文中的原理和代码也适用于其他情况。

本文由树莓派实验室创作,遵循CC协议(署名-非商业性使用-禁止演绎-相同方式共享),欢迎树莓派爱好者们遵循协议内容转载传播。谢绝不遵守协议的转载和抄袭。

树莓派是精简版的微型电脑,连电源开关都精简掉了。要完成正常的关机和重启的操作,需要通过终端输入关机和重启命令才行。当树莓派没有配备显示器时,登录 SSH 关机更显得颇为麻烦。现在既然有了 SAKS 扩展板,为什么不用上面的轻触开关来实现一个关机和重启的按键功能呢?

本例程中涉及到的 SAKS 扩展板引脚编号如下:

功能 注释 BOARD

编码 BCM

编码 wiringPi

编码 开关组 KEY-K1 轻触开关(右) 16 23 4 LED排灯 LED-D8 LED(黄) 26 7 11 LED-D9 LED(红) 24 8 10

我们将要实现的功能,是将 SAKS 扩展板的 K1 轻触开关改造成树莓派的关机和重启键,同时配以两个 LED 来指示操作状态。

轻触开关1次,进入重启倒计时,黄色 LED 闪烁,倒计时为10秒,倒计时结束后立刻重启。

在重启倒计时过程中再次轻触开关1次,由重启倒计时切换到关机倒计时,红色 LED 闪烁,倒计时结束后立刻关机。

在关机倒计时过程中,再次轻触开关1次,取消倒计时,LED 停止闪烁,系统恢复正常运行。

这样一个按键配上两个 LED 就能实现关机、重启、取消指令的操作了。实现代码如下:

#!/usr/bin/env python # coding=utf-8 import RPi.GPIO as GPIO import time import os,sys import signal #定义关机键和关机状态指示灯的GPIO引脚 GPIO.setmode(GPIO.BCM) pin_btn = 23 pin_led_reboot = 7 pin_led_halt = 8 #初始化SAKS上相应按键和LED的状态,按键内部上拉、LED不亮 GPIO.setup(pin_btn, GPIO.IN, pull_up_down = GPIO.PUD_UP) GPIO.setup(pin_led_reboot, GPIO.OUT, initial = GPIO.HIGH) GPIO.setup(pin_led_halt, GPIO.OUT, initial = GPIO.HIGH) #初始化按下关机键的次数 press_times = 0 #按下关机键后等待并倒数10次 count_down = 10 led_on_reboot = 0 led_on_halt = 0 def onPress(channel): global press_times, count_down print(‘pressed’) press_times += 1 if press_times > 3: press_times = 1 #重启模式 if press_times == 1: GPIO.output(pin_led_reboot, 0) GPIO.output(pin_led_halt, 1) print(‘system will restart in %s’ % (count_down)) #关机模式 elif press_times == 2: GPIO.output(pin_led_reboot, 1) GPIO.output(pin_led_halt, 0) print(‘system will halt in %s’ % (count_down)) #模式取消 elif press_times == 3: GPIO.output(pin_led_reboot, 1) GPIO.output(pin_led_halt, 1) print ‘cancel’ count_down = 10 #设置按键检测,检测到按下时调用 onPress 函数 GPIO.add_event_detect(pin_btn, GPIO.FALLING, callback = onPress, bouncetime = 500) try: while True: #重启模式 if press_times == 1: if count_down == 0: print “start restart” os.system(“shutdown -r -t 5 now”) sys.exit() led_on_reboot = not led_on_reboot #黄色 LED 闪烁 GPIO.output(pin_led_reboot, led_on_reboot) #关机模式 if press_times == 2: if count_down == 0: print “start shutdown” os.system(“shutdown -t 5 now”) sys.exit() led_on_halt = not led_on_halt #红色 LED 闪烁 GPIO.output(pin_led_halt, led_on_halt) if press_times == 1 or press_times == 2: count_down -= 1 print “%s second” % (count_down) time.sleep(1) except KeyboardInterrupt: print(‘User press Ctrl+c, exit;’) finally: GPIO.cleanup()

接下来运行。

sudo python powerbutton.py

将这个脚本设为开机启动,编辑 rc.local:

vim /etc/rc.local

在 exit 0 所在行之前插入一行,文件路径需根据实际自行修改:

python /home/pi/powerbutton.py &

后面我们后面将开始介绍如何基于 SAKS 扩展板 DIY 各种有趣、实用的东西,欢迎持续关注!

本文属于《树莓派瑞士军刀扩展板(SAKS)DIY 教程》系列文章,查看系列文章目录,请访问:https://shumeipai.nxez.com/swiss-army-knife-shield-for-raspberry-pi-diy-tutorials

树莓派磨制“魔镜”全记录

第一部分——点子与镜子

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

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

关于镜子

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

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

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

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

第二部分——显示器

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

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

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

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

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

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

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

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

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

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

第三部分——外壳

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

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

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

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

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

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

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

第四部分——安装硬件

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

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

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

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

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

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

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

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

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

Magic Mirror: Part V – Installing the Raspberry Pi

第五部分——安装树莓派

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

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

基本安装

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

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

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

我选了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开发外,还有一个额外的好处,在我将它放入魔镜之前,能在我的苹果电脑上开发测试。

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

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

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

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

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

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

设计

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

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

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

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

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

我大可以加上一些其他色彩,但目前为止我只想做到简洁的黑白界面。我可不想镜子比我的尊容还要出彩。(译者注:镜子:好吧,我不告诉你谁是世界上最帅的男人。镜子,碎。)

API设计

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

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

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

Openweathermap.org

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

iCal Calendar

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

$url = “https://p01-calendarws.icloud.com/ca/subscribe/1/mysupersecreticloudhash”; echo file_get_contents($url);

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

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

NOS新闻订阅

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

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

自动更新

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

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

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

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

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

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

var gitHash = ”;

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

(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上都有。有件事情要说一声:代码很少标注,以面条式代码填充(译者注:就是大量复杂逻辑结构诸如if、when之类的条件语句,没想到老外还是有和国人程序猿一般的生物,反面例子啊),通篇都是TODO语句。哈,不怕晃晕菜的,尽管扎进去吧。

未来展望

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

尽管有很多改进需要跟进,项目就总结到这儿吧。请关注我的博客,我会登出更多的照片来秀一下成品。

via org

2019-6-9 更新:

经过数年,无数 Maker 前赴后继地创造、加入到制作队伍,已经形成了一个专门 DIY 魔镜的社区。

网站不仅提供了完整的项目源码、一键安装脚本。还分享了项目中所用到的每个第三方模块,非常丰富,感觉已经发展成了一个平台化的系统软件。

https://talk.quwj.com/topic/17

不要驱动,简单粗暴的用树莓派驱动USB打印机

网上很多文章都是再说如何用树莓派来做一个通用打印服务器,但是在很多应用场景下,配置CUPS什么的真的是自己zuo自己die的好途径,各类linux下的驱动配置起来令人吐血。而驱动各种热敏票据打印机,比如打胶带啊,二维码贴纸啊,小票之类的打印机因为根本找不到linux的驱动,要搞起来更是Mission Imposiable。所以本文的目的就是为了不用驱动直接用USB接口的各类热敏打印机。因为没有驱动,所以我们只能用简单粗暴的方式通过USB直接操作打印机了。下面来看看怎么搞:

首先,你得有一台打印机,淘宝有卖的,几十元到一两百,可以打热敏胶带,所以做个打印服务器标签的东西也不错的,其他用途可以自行开发。

先把打印机用usb线接到树莓派上,然后在树莓派执行 lsusb 命令,这个时候会列表连接上的所有usb设备,如下:

Bus 005 Device 001: ID 0000:0000 Bus 001 Device 001: ID 0000:0000 Bus 004 Device 001: ID 0000:0000 Bus 003 Device 001: ID 0000:0000 Bus 002 Device 006: ID 15d9:0a37 Bus 002 Device 001: ID 0000:0000

这个时候不知道谁是打印机呢!不过不要紧,你拔掉打印机的usb线后再执行一次,看缺谁,谁就是打印机了。

ID后冒号隔开的两个数字就是usb设备的 vendor ID和product Id了,记下来先,一会儿连接的时候有大用。

为了连接打印机,你需要安装python-usb这个库,用于直接通过usb接口来操作usb设备。本文的第一个坑就出在这里,因为pip库里的版本有一个bug的方式在后面的库会用到,所以必须用从github里最新的去除了bug的代码里安装才不会出问题。所以只能用这样子的方式来安装才行。

git clone https://github.com/walac/pyusb.git cd pyusb python setup.py install

安装好后我们就可以通过usb接口来操作打印机了,由于大多数打印机都支持EPSON的打印协议(很古老的协议了,所以到处都支持),所以我们可以安装一个叫python-escpos 的库来通过python-usb来用EPSON的协议操作打印机。

sudo pip install python-escpos

但是此处还是有坑,因为这货的文档基本上和实际情况就是牛头不对马嘴。所以就别管这货的文档了。

from escpos import * pt = printer.Usb(0x0fe6, 0x811e, 0, out_ep=0x03)

此处要注意 out_ep 不能用默认值,默认的铁定打不了,但是这里的封装又有问题不能去自动获取,所以下面给一段自动获取 out_ep 的代码

import usb.core import usb.util import sys dev = usb.core.find(idVendor= 0x5345, idProduct= 0x1234) cfg = dev.get_active_configuration() intf = cfg[(0,0)] ep = usb.util.find_descriptor( intf, # match the first OUT endpoint custom_match = \ lambda e: \ usb.util.endpoint_direction(e.bEndpointAddress) == \ usb.util.ENDPOINT_OUT ) dev.reset()

我手头的打印机获取到的out_ep是0x03,所以我就写的这个值。 之后呢就可以愉快的打印了:

from escpos import * usb = printer.Usb(0x0fe6, 0x811e, 0, out_ep=0x03) usb.text(u”终于可以愉快的打印啦

“.encode(‘gbk’)) usb.image(‘image path’)#打印图片(黑白2值) usb.qr(‘值’)#打印二维码 usb.set(codepage=None, align=‘center’)#设置页面居中 usb.cut()#切纸 usb.close()#关闭连接

祝玩得愉快。

via http://liming.me/post/usb

树莓派(Raspberry Pi)USB无线网卡自动连接

Raspberry Pi 使用USB无线网卡的时候不会因为路由重启而掉线。

#!/bin/bash while true ; do if ifconfig wlan0 | grep -q “inet addr:” ; then sleep 60 else echo “Network connection down! Attempting reconnection.” ifup –force wlan0 sleep 10 fi done ——邪恶的分割线—– #!/bin/bash if ifconfig wlan0 | grep -q “inet addr:” ; then exit else echo “Network connection down! Attempting reconnection.” ifup –force wlan0 fi #crontab -e #*/10 * * * * bash /home/network-monitor.sh #每十分钟执行一次

将代码复制到你的根目录中保存为network-monitor.sh然后运行命令。

sudo chmod +x ./network-monitor.sh

把它设置为可执行文件,使用命令可在后台运行。

sudo ./network-monitor.sh &

它会每60秒检查,如果你的无线网络具有网络连接。如果它发现它没有网络地址将尝试强制重新连接并继续这样执行,直到重新建立连接。如果你想阻止它在后台运行,首先使用以下命令.

fg

将迫使它为前台运行,然后你可以使用ctrl-c停止.

测试了它几个方面。

首先关闭我的WiFi接入点,该脚本没有检测到网络连接并开始试图强迫一个连接。几分钟后,重新建立连接供电接入点回来后。

另一个试验,我删除了MAC地址从地址列表中允许接入点的MAC地址过滤。网络连接了下来,重新启用的MAC地址和它一、两分钟后回来了。

via http://49mm.com/archives/category/raspi/page/2

树莓派用作DNS查询服务器实现上网加速

将DNS公共查询服务器架设在树莓派上面,常用的DNS查询将会缓存到树莓派上,能起到DNS查询加速、提升上网体验的作用。本文将以开源的轻量级DNS转发服务程序 DNSMASQ 为基础实现这个功能。

首先找到网上的解决方案,在树莓讨论版上《[HOW TO] Use your RPI as a DNS server and speed up yo’ net!》,当然这个解决方案是基于这篇文章的《DNS on Raspberry Pi — Speed up your internet Experience》,使用树莓派最大的好处是有强大的社区支持,基本上你所遇到的问题网上都有相关的解决方案,得益于Debian的丰富的包,一些软件可以直接apt安装,我在这里再简单的阐述一下关于DNS公共查询服务器的设置:

原作者为我们直接打包了命令,所以我们可以直接执行下面的代码:

curl “https://raw.github.com/stephendotexe/raspberrypi/master/roles/dnsmasq_server” | sudo sh

其实这里运行的脚本会附带的给我们装上dnsmasq这款软件,当然你也可以通过下面的命令手动安装:

sudo apt-get install -y dnsmasq

下面我们就需要配置DNSMASQ了,配置文件一般位于路径 /etc/dnsmasq.conf 。基本上配置文件内容如下所示:

# Dnsmasq.conf for raspberry pi # /etc/dnsmasq.conf # http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq.conf.example # Set up your local domain here domain=raspberry.local resolv-file=/etc/resolv.dnsmasq min-port=4096 server=8.8.8.8 server=8.8.4.4 # Max cache size dnsmasq can give us, and we want all of it! cache-size=10000 # Below are settings for dhcp. Comment them out if you dont want # dnsmasq to serve up dhcpd requests. # dhcp-range=192.168.0.100,192.168.0.149,255.255.255.0,1440m # dhcp-option=3,192.168.0.1 # dhcp-authoritative

这里的 server 所指示的就是上级DNS服务器的地址,这里用的是Google的 8.8.8.8 和 8.8.4.4 ,也就是说本地缓存查不到的域名将会发送给上级DNS服务器然后本地再缓存结果,可以改成你所需要的,一般就用谷歌的,我就不改了:-)

如果你改动过设置,请重启服务:

sudo service dnsmasq restart

到这里基本上就配置完成了,你可以在树莓派上 nslookup 或者 dig 一下看看结果,当然如果找不到这些命令是因为你没有安装 dnsutils ,直接通过下面的命令安装即可:

sudo apt-get install dnsutils

这里再讲解一个小技巧,大家电脑上的hosts文件一般不陌生,在DNS被投毒污染或者我们需要配置测试Web服务器时会要改这里的域名和IP对应关系,这里我们可以让dnsmasq替我们代劳。切换到 /etc/dnsmasq.d/ 路径下,新建一个 test.conf 文件,内容如下:

address=/appspot.com/74.125.155.141

别忘了重启一下服务:

sudo service dnsmasq restart

这样当查询appspot.com的时候,dnsmasq将直接返回这里设定的IP地址,轻松避免了DNS投毒攻击。

又一个让树莓派开机运行Python脚本的方法

这个方式不用修改 rc.local 文件。机制上类似于 Windows 的“开始”菜单中的“启动”菜单。方法如下:

在 /home/pi/.config 下创建一个文件夹,名称为 autostart,并在该文件夹下创建一个xxx.desktop文件(文件名以.desktop结尾,前面可以自定义),文件内容如下:

[Desktop Entry] Name=example Comment=My Python Program Exec=python /home/pi/example.py Icon=/home/pi/example.png Terminal=false MultipleArgs=false Type=Application Categories=Application;Development; StartupNotify=true

以上 Name、Comment、Icon 可以自定,分别表示这个启动项目的名称、备注以及显示的图标。Exec 表示调用的指令,和在终端输入运行脚本的指令格式一致。

之后 sudo reboot 重启,就可以看到 example.py 在树莓派启动后也自动启动了。

树莓派上使用htpdate同步时间

最近住处的网络由电信换为移动宽带之后,之前一直使用的 Raspberry Pi 树莓派板子上出现系统时间不正确的问题(显示为 1970 年 1 月 1 日),由于树莓派板子上没有 RTC 硬件和电池,因此树莓派上的系统时间重启是保存不了的。

之前设置的是每次开机自动使用 ntpdate 命令从 NTP 服务器上同步时间,但现在每次运行时都提示:

root@XBian:~# ntpdate ntp.sjtu.edu.cn 13 Oct 23:49:01 ntpdate[1484]: no server suitable for synchronization found

同时公司里电信网络环境下这个命令又是完全正常的,移动宽带环境下直接 ping 这个 NTP 服务器也是通的,因此估计就是移动宽带直接把 NTP 给封了。

在谴责移动的同时只能另想办法,还好网上已经有人想到这种应对 NTP 被防火墙封掉类似的需求了,开源的 htpdate 命令直接使用 HTTP 协议(这个是不可能封的了)来进行系统时间同步,项目主页在这里:

https://github.com/iridium77/htpdate

htpdate 的原理也非常简单,直接解析 HTTP 协议头中的服务器时间信息,然后设置本地时间,我们来看百度返回的 HTTP 头:

HTTP/1.1 200 OK Date Mon, 13 Oct 2014 16:05:18 GMT Content-Type text/html Transfer-Encoding chunked Connection Keep-Alive Cache-Control private Expires Mon, 13 Oct 2014 16:05:18 GMT Server BWS/1.1 BDPAGETYPE 2 BDQID 0x8b40c1f700000bd4 BDUSERID 13923551 Set-Cookie BDSVRTM=133; path=/ Set-Cookie BD_HOME=1; path=/

上面的 Date Mon, 13 Oct 2014 16:05:18 GMT 就是百度的 Web 服务器上的系统时间了。

htpdate 命令做时间同步会有 0.5 秒左右的误差(看看 HTTP 头就知道里面很多时间都是以秒为单位哈),对于我的树莓派来说就完全没有关系,如果对这个比较在意的话只能尽量用 NTP 时间同步了。

htpdate 使用上也很简单,简单编译安装之后把这条命令加到 Raspberry Pi Raspbian 系统的 /etc/rc.local 文件中(不加 -t 参数基本不能同步成功哦):

htpdate -t -s ntp.neu.edu.cn

然后重启树莓派就可以正常同步系统时间了。

via