洒家去年买了一台树莓派 3B,买来之后装上系统玩了几天,就一直挂在墙上吃灰,不知道拿它干什么。终于有一天,洒家突发奇想,不如拿以前玩剩下的电子元件做一个智能闹钟。
一开始洒家用的是 1602 液晶屏。它只能显示 2 行字,每行 16 个字符,而且只能显示英文、数字等字符,无法显示汉字。成品除了基本的显示时间日期功能外,还有闹钟、天气预报等功能。电路焊在了洞洞板上,然后用螺丝和铜柱随便固定在旧光盘上:
这个版本有一个严重缺点,不能用代码控制背光,夜里睡觉时感觉很刺眼。洒家最近升级了一波硬件,买了一块 12864 中文液晶屏,重新设计了电路和代码,可以控制屏幕按时熄灭背光。
这个 12864 液晶屏自带一套 GB2312 字符集的中文字库,含有 8000 多个常用汉字。洒家把代码改了改,汉化了界面。然后集成了 feed 阅读器 API、头条新闻 API、日历 API 和天气预报 API。至此,它可以滚动显示时间、日期、闹钟、IP 地址、天气、空气质量、日程、新闻和 feed 了。
电路板上有一个蜂鸣器,作为闹钟发声元件。这是洒家随手写的一个设置闹钟时间的网页:
这个树莓派运行的代码都是随手瞎写的,非常丑陋,下面就不贴了,只是简单写一写经验。
软件¶
时钟程序是用 Python 写的,用了 RPi.GPIO
控制 GPIO
端口。每一类任务分配一个线程。整个系统用 wpa_supplicant
连接 WiFi,编辑 /etc/rc.local
开机自启动时钟程序,用 crontab
定期重启。具体内容略去。
新闻和天气 API¶
洒家用了和风天气提供的免费天气预报和空气质量 API,效果不错,和手机上的数据一致。
洒家又用了聚合数据提供的免费新闻头条 API。比起严肃新闻,人们更喜欢看今日头条类的快餐式内容。可能是为了迎合人们的口味,这个头条新闻 API 返回了一堆娱乐社会星座相关的狗血猎奇无聊新闻。一开始洒家用了黑名单过滤了很多关键词,但是收效甚微,只好改用白名单,只接收央视网、人民网等渠道的新闻。
Feed API¶
洒家一开始使用的是 Feedly 和它的 API。然而免费用户只能获取有效期只有 1 个月的 auth token,每个月都需要打开 https://feedly.com/v3/auth/dev 申请新 token,接收一封邮件,最后把 token 导到树莓派里,非常麻烦。
2020 年 11 月,洒家决定改用 Inoreader 和它的 API。首先打开偏好设置 - 开发者
,注册一个 application(OAuth 配置这些都不用填)。然后用旧版 ClientLogin 方式获取一个 auth token。调用 API 时,AppId、AppKey、auth token 一起发送。洒家只需要显示最新文章的标题,只需要调用 Stream contents API,设置时间范围,并排除已读文章。
另外,这两个平台都有一个共同的问题。由于众所周知的原因,它们的的 API 都被墙了,需要在自己的 VPS 上开一个反向代理。
日历 API¶
洒家使用的 Google Calendar 可以生成日历私密分享链接,位于设置 - 我的日历设置 - <日历名程> - 集成日历
。洒家使用 icalendar 库解析返回的 .ics
文件内容,然后显示到屏幕上。
这个 API 当然也被墙了,也需要设置反向代理。
硬件¶
驱动蜂鸣器和液晶屏¶
树莓派的 GPIO 输出的高电平电压是 3.3 V,电流输出能力不足,无法直接驱动液晶屏的背光和蜂鸣器。于是洒家买了 ULN2003APG(高压大电流达林顿晶体管芯片)做了个开关电路间接控制这些元件。理想中我以为它只是一个与外部无关的大电流反相输出电路,没想到事情比我想像得复杂。一开始一顿测试,输出端悬空,输入端接 5V/0V,输出端电压都只能达到 0.6 V/1.1 V。洒家的模电和电路分析水平比较差,百思不得其解。后来索性直接把蜂鸣器接入电路,发现当负极接输出端时,测得电压值基本正常了。想一想可能是阻抗、上拉什么的原因。
设计电路¶
电路并不复杂,先在面包板上调一调:
然后用 Loch Master 设计电路:
拿出生锈的电烙铁在洞洞板上一顿操作就完工了。然后找了个旧文件夹,剪掉封皮,打孔之后把一套东西固定在上面,就可以挂在墙上了。
树莓派的问题¶
在树莓派上 SD Card 很不可靠,经常出现文件内容损坏的现象。严重的时候 ssh 连不上,运行 Python 就崩溃,apt-get
不能用 https 协议更新文件。随便 Google 一下 Raspberry Pi data corruption
,好多人都遇到过这个毛病。洒家没找到有效的解决方法,只能注意一下不能随便拔电源,定期运行检测命令:
debsums --changed
dpkg --search /path/to/corrupted/file
然后重新安装相应的包。
总结¶
然并卵。一顿操作猛如虎,早上还是听不见闹钟。