夏普GP2Y1010AU0F灰尘传感器价格较便宜,能检测出室内空气中的灰尘和烟尘含量。另外还有韩国SYHITECH生产的DSM501A粉尘传感器也有类似功能。
检测原理
其原理如下图,传感器中心有个洞可以让空气自由流过,定向发射LED光,通过检测经过空气中灰尘折射过后的光线来判断灰尘的含量。

电路图


因为数据是通过pin 5的电压模拟信号输出的,而树莓派的引脚不支持模拟信号直接读取(需要增加数模转换芯片),所以先用Arduino来实验。
使用过新浪开放平台的朋友都知道用户对小应用(用户数较少的)的授权Token很容易过期,自动续期要求授权过的用户在过期前重新打开授权页。如果你想实现一个自动备份自己微博的App,就不得每天(周)自己去访问授权页(想死的心都有了吧?)。这里介绍一种通过脚本自动登录微博获取最新oAuth token的方法(需要微博登录名和密码),合适自己玩。将脚本部署在树莓派上后,我再也不用每周都去登录一次授权页了,只是收到报警消息后(经常是帐号被冻结了)需要手动处理一下。
Phantomjs

Phantomjs 是一个开源的,没有界面可运行在命令行,跨平台,基于WebKit的全功能浏览器,可以用来做网站自动化测试。从源代码编译比较费时间,可以直接下载二进制版本,树莓派的版本在这里可下载。Phantomjs下载好了后就一个可执行文件,依赖非常少,我很喜欢这种方式。
代码
以下代码使用提供的微博用户名和密码登录,获得Token后还会打开微博首页看帐号是否被冻结了。
var page = require('webpage').create(),
system = require('system'),
fs = require('fs'),
address;
var weibo_userid = system.args[1]
var weibo_passwd = system.args[2]
var startUrl = "https://api.weibo.com/oauth2/authorize?client_id=<your_app_key>&redirect_uri=<your_return_url>/&response_type=token";
var verify_weibo_freeze = false;
page.onResourceReceived = function (res,network) {
if (res.stage == "end") {
// console.log("\t<-" + res.url);
if (res.url.indexOf("authorize?client_id")>0) {
startUrl = res.url
}
if (res.url.indexOf("?access_token")>0) {
var pos1 = res.url.indexOf("access_token=")
var pos2 = res.url.indexOf("&")
var access_token = res.url.substring(pos1+"access_token=".length, pos2)
console.log(weibo_userid + " login OK, access_token is: " + access_token)
verify_weibo_freeze = true
}
if (verify_weibo_freeze && res.url != "http://weibo.com/" && res.url.indexOf("http://weibo.com/")>-1) {
var pos1 = res.url.indexOf("/",8)
var pos2 = res.url.indexOf("?")
var weibo_name = res.url.substring(pos1+1,pos2)
console.log(weibo_name+" status verified OK")
phantom.exit();
}
}
};
page.onLoadFinished = function() {
if (verify_weibo_freeze) {
page.open("http://weibo.com/", function() {
phantom.exit();
})
}
};
page.onConsoleMessage = function(msg) {
console.log(msg);
};
page.open(startUrl, function(status) {
if ( status === "success" ) {
page.includeJs("https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
var offset = page.evaluate(function(a,b) {
$("#userId").val(a)
$("#passwd").val(b)
if ($('.WB_btn_login').hasClass("formbtn_01")) {
// console.log("Found button!")
return $('.WB_btn_login').offset()
}
return undefined
}, weibo_userid, weibo_passwd);
page.sendEvent('click', offset.left + 1, offset.top + 1);
});
}
})

Sublime 是一个相当好用的文本编辑器,界面简洁,功能强大。最近Sublime 3 Beta 出来了, 体验了一下,发现启动速度比之前快了很多。
下载安装
下载地址: http://www.sublimetext.com/3
安装Package Control
Sublime 支持插件来丰富其功能,package control 本身也是一个插件,可以用来管理其他插件,所以我们要先安装Package Control,Sublime 3需要安装Pacakge Control Alpha.
cd "Library/Application Support/Sublime Text 3"
cd Packages/
git clone https://github.com/wbond/sublime_package_control.git "Package Control"
cd "Package Control"
git checkout python3
除了SD卡上的存储,树莓派还可以使用U盘来做存储,有时候我们可能需要替换已有的U盘为更大容量的。在Mac上可以采用下面的方法:
备份已有的U盘,把U盘从树莓派上拔下来插在Mac上,找出U盘对应的盘符(下例为/dev/disk2
)
20:51:19 hugozhu-mac-mini ~ $ diskutil list
/dev/disk0
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *500.1 GB disk0
1: EFI 209.7 MB disk0s1
2: Apple_HFS Macintosh HD 499.2 GB disk0s2
3: Apple_Boot Recovery HD 650.0 MB disk0s3
/dev/disk2
#: TYPE NAME SIZE IDENTIFIER
0: FDisk_partition_scheme *2.1 GB disk2
使用 dd 命令把U盘拷贝到raspberrypi.img
前几天并发编程群里有同学对volatile的用法提出了疑问,刚好我记得Twitter有关实时搜索的这个PPT对这个问题解释的很清晰并有一个实际的应用场景,于是周末把这个问题摘录了一些和并发相关的内容如下:
并发 - 定义
悲观锁 - Pressimistic locking
- 一个线性在执行一个操作时持有对一个资源的独占锁。(互斥)
- 一般用在冲突比较可能发生的场景下
乐观锁 - Optimistic locking
- 尝试采用原子操作,而不需要持有锁;冲突可被检测,如果发生冲突,具有相应的重试逻辑
- 通常用在冲突较少发生的场景下
非阻塞算法 - Non-blocking algorithm
- 算法确保对线程间竞争共享资源时候,不会因为互斥而使任一线程的执行无限延迟;
tcpdump工具是分析网络协议和数据包的利器,也可以在Android上使用(需要root)。
首先在android上安装tcpdump
wget http://www.strazzere.com/android/tcpdump
adb push tcpdump /data/local/tmp/tcpdump
adb chmod 755 /data/local/tmp/tcpdump
然后使用root用户启动tcpdump,在android上进行相应的操作后,按ctrl+c中断
adb shell
shell@android:/ $ su
root@android:/ # /data/local/tmp/tcpdump -h
tcpdump version 3.9.8
libpcap version 0.9.8
Usage: tcpdump [-aAdDeflLnNOpqRStuUvxX] [-c count] [ -C file_size ]
[ -E algo:secret ] [ -F file ] [ -i interface ] [ -M secret ]
[ -r file ] [ -s snaplen ] [ -T type ] [ -w file ]
[ -W filecount ] [ -y datalinktype ] [ -Z user ]
[ expression ]
root@android:/ # /data/local/tmp/tcpdump -p -vv -s 0 w /sdcard/capture.pcap
树莓派使用了一个无线网卡连接家里的无线路由器,在实际使用过程中发现连续运行多天后会掉线,而且掉线后基本上就再也连不上网了,需要重启树莓派才能恢复,十分麻烦。
假设无线路由器IP是192.168.1.1,于是每隔15分钟检查一下,是否能从树莓派上ping通路由器;如果不能则重启无线网络,脚本如下:
network.sh
#!/bin/bash
export PATH=/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
ping_count() {
count=0
`timeout 5 ping 192.168.1.1 | while read LINE; do
{
if [[ "${LINE}" =~ "64 bytes from" ]]; then
let "count = $count + 1"
echo "export count=$count"
fi
}
done`
echo $count
}
if [[ $(ping_count) < 1 ]]; then
ifconfig wlan0
ifconfig wlan0 down
sleep 1
ifconfig wlan0 up
sleep 1
netcfg -r wlan0-Hugo-Nas
sleep 5
if [[ $(ping_count) < 1 ]]; then
echo "Fatal error: wifi is down, rebooting now..."
reboot
fi
fi
树莓派提供了一个连接头让我们访问CPU的17个GPIO接口,如下图

这些接口可配置成输入或输出。本文主要讨论GPIO引脚作为输出时电流的限制。
阻抗 (impendance)
阻抗和和电阻的区别(resistance)在于电阻的阻值是固定的,不会随着电流变化,阻抗则不然,可能随着外部变化,如电流或频率变化。从另一个角度来说,电阻是线性的,但阻抗不是。比如放大器的阻抗会随着输出的信号频率变化。
树莓派的的每个GPIO引脚都有一个寄存器可以设置引脚的驱动强度,也就是在保持输出电压为逻辑0和1的情况下,可以改变阻抗的大小从而改变GPIO引脚的输出电流大小。
通过如下电路测量相同电流下不同阻抗对应的GPIO电压输出(其中用到了一个电位器调节电流保持恒定):

通过计算后,下表是当输出电流为2,4 … 16mA时,对应的阻抗大小以及如果发生短路时的短路电流大小。
树莓派的GPIO接口数目有限,驱动一个步进电机需要占用4个, 一个Nokia 5110液晶也要占4个, 传感器输入至少需要一个,多玩几个外设后接口就不够用了。如果接口可以复用就可以让树莓派驱动更多的外设了,本文讨论如何使用74HC595集成电路芯片来扩展树莓派的I/O接口。
芯片介绍
SN74HC595N是德州仪器公司生产的集成电路芯片,是一个8位串行输入变串行输出或并行输出移位寄存器,具有高阻关断,高电平和低电平三态输出。在IO扩充上,可以最多串联15片,也就是高达120个IO扩充。

(注意到芯片上的小凹槽了吗,拿芯片的时候以这个为参考物就不会搞反了)
接口的常用命名方式有以下两种:
接口代号(编号) |
说明 |
接口代号(编号) |
说明 |
Q7’(9) |
serial data output |
QH’ (9) |
serial data output |
MR (10) |
Master Reset (Active Low) |
SRCLR (10) |
Shift register CLeaR |
SH_CP (11) |
shift register clock input |
SRCLK (11) |
Shift Register CLocK input |
ST_CP (12) |
storage register clock input |
RCLK (12) |
storage Register CLocK input |
OE (13) |
output enable input (Active Low) |
OE (13) |
Output Enable |
DS (14) |
serial data input |
SER (14) |
SERial data input |
Qx (15,1-7) |
data output |
Qx (15,1-7) |
data output |
背景介绍
把网站托管在树莓派上后如果家里停电或是宽带故障,会造成网站中断。本文提供一个免费的解决方案(前提是你需要有自己的一个域名,并由DNSPod解析)
DNSPod
首先需要在DNSPod里设置好需要failover的域名CNAME:比如hugozhu.myalert.info

其中默认
指向pi.myalert.info
, 这是一个域名的A Record,会由运行在树莓派上的脚本来更新动态IP,国外
则指向github。当停电时我们需要自动把`默认`这条纪录修改成github。
使用下面命令获得相应CNAME的domain_id:
curl -k https://dnsapi.cn/Domain.List -d "login_email=xxx&login_password=xxx"
使用下面命令获得相应CNAME的record_id: