MAK ER : mattwach / 译:趣无****尽
墨水屏与任意一款的外框的搭配,效果都会十分经典。它专属的怀旧属性,使得用它来创作的显示屏作品都会经久耐看。
今天我们带来的一个复古的墨水屏电子钟,可以显示时间,还自带天气预报功能(通过 GPS 自动设置获得)。显示屏只需要四节 AAA 电池就可以续航六个月左右,为了保证安全和可靠性,它不需要连接任何网络。
特性
1、通过 GPS 自动设置。
2、显示当前温度和湿度。
3、显示过去 25 小时内的压力图。
4、日出和日落的时间。
5、显示当前的月相。
6、可在12小时或24小时模式之间选择。
7、可在英文和公制单位之间选择。
本项目有三个不同的版本,分别是「简易」版本、「低功率」版本和「Arduino Mini」版本。
「简易」版本是基于 Arduino Nano 搭建。这个版本可以减少成本、零件数量和制作的复杂性;缺点是需要用一个 USB 5V 的适配器来给时钟供电。
「低功率」版本使用一个 32k 的振荡器,以极小的功率保持精确的计时,振荡器可让时钟用电池运行。
这两种版本都可以在面包板上进行构建和实验,最终的 PCB 板可通过原型板、CNC 铣削、化学蚀刻获得,资料可在本项目文件库中下载。
材料清单
「简易」版本组件清单
Arduino Nano × 1
Waveshare 2.9 EPaper 模块 × 1
Adafruit MS8607 压力/湿度/温度传感器 × 1
带有9600 Baud TX 的 GPS 模块 × 1
电路板 × 1
按钮开关(用来改变 UTC 时间偏移和显示偏好) × 若干
制作外壳的材料 × 若干
USB 充电器 × 1
充电线 × 1
「低功率」版本组件清单
除与简易版本一样,还增加了一些组件
Waveshare 2.9 EPaper 模块 × 1
Adafruit MS8607压力/湿度/温度传感器 × 1
电路板 × 1
按钮开关 × 若干
制作外壳的材料 × 若干
Atmega328P DIP 版 × 1
32768 Hz 晶体 × 1
Adafruit GPS 模块 × 1
LED × 1
电阻 × 1
10uF 电容 × 若干
100nF 电容 × 若干
AAA 电池 × 4
3×2 排针 × 1(用于通过ICSP对芯片进行编程,可选)
1×2 排针 × 1(用于UART调试,可选)
「Arduino Mini」版本
这是一个最简单的版本,当处于 “零件荒 “时,如缺少 Atmega328P 芯片时,你可以采用这个”最简”版本的固件来运行。亦或者你对自己的焊接技术有信心,你可以在微控制器上焊接一个 32k 的晶体,采用 32k 版本的固件。
如原理图所示,采用 “便宜的 GPS “方案来连接。你也可以使用别的 GPS(Adafruit),但要替换原理图中的 GPS 部分。
便宜的 GPS(可选)
如果你认为没有必要增加功能(在低功耗部件部分有介绍),你可以放置任何能以 9600 波特传输 NMEA 字符串的 GPS 模块(大多数的GPS模块都可以)。
但现在有一个新的问题需要解决:这些单元中的大多数缺少一个启用/禁用的引脚,而 GPS 单元通常消耗 30-100 毫安的电力。如图所示,我们可以用一个 N-MOSFET(或类似的)黑掉一个禁用开关。我们也可以在 falstad 中进行尝试。
电源开关电路是可选的。细节可参考附录 B。
「低功率」版本的硬件改装
如果你制作「简易」版本,不需要阅读这一部分。在「低功率」版本中,这些改装将大大改善电池寿命。
为了说明问题,我们将假设电源来自一组 AAA 电池,可以提供 1000 毫安时。让我们假设你使用的是 32K 的Adafruit 版本,并且没有做任何修改。下面是一个电源分解的例子。
“睡眠/关闭” CPU、GPS、MS8607 和 EPaper:测量值为 30-70uA(我们认为是 50uA)。
屏幕更新:5 毫安,每分钟两秒一次:5×2/60=166uA
GPS 更新:每天一次,每次 50 毫安,每次 10 秒。50×10/86400=6uA
MS8607 LED:100uA
Adafruit GPS 上拉电阻:500uA
因此,我们有(50+166+6+100+500)=822uA 的平均电流消耗,相当于约 50 天的功率。
如果去掉 MS8607 LED 和 GPS 上拉电阻,我们的用电量就会减少到 222uA,也就是大约 187 天的用电量,大大增加了使用时间。
1、建议从 MS8607 上拆下 LED。
2、Adafruit GPS 的上拉电阻是由 Adafruit 的设计人员添加的,使得 EN 引脚变成一个可选项。不过它也有一个缺点,就是当你把它拉到地(禁用 GPS)时,大约有 500uA 的电流在上拉电阻中被消耗掉。
由于这个设计的使能引脚是主动驱动的,你可以去掉这个电阻。
3、专业的迷你修改。Google 引擎搜索 “Arduino mini 低功耗 “了解详情,基本上,你会想去掉电压调节器和 LED,来减少电源使用。我们改用 MS8607 的电压调节器(3.3V 空闲时损失 35-55uA 的功率)为 pro mini 供电。
4、在 pro mini 的图中,我还去掉了晶体振荡器,为 32K 晶体的芯片做准备。只有在 32K 晶体版本的情况下才可以去掉这个晶体,而且只有在对 pro mini 的内熔丝进行重新编程后才去掉,稍后会解释。
固件
在这个步骤中,我附上了 nano 和 32k 晶体版本的 .hex 文件(这两个版本都适用于 pro-mini,如果你不确定使用哪个版本,就使用 nano 版本)。
如果想自己构建/修改源代码,可以访问GitHub:https://github.com/mattwach/epaper_clock
自己构建 .hex 固件文件(可选)
请注意,这段代码没有使用 Arduino 库,因为产生的代码太大,无法在 Atmega328P 上安装(个人偏好)。
它采用 C 语言编写,使用了 Arduino 和 AVR 基础库作为基础。如果你想编译代码,你需要安装(免费的)avr-gcc 工具,复制 epaper 项目的源码。然后进入 firmware/ 目录并输入。
make
如果代码建立了,可以打开Makefile,查看这些选项。
CLOCK_MODE ?= USE_32K_CRYSTAL
UART_MODE ?= HARDWARE_UART
F_CPU ?= 8000000
如果你正在构建 32k 晶体固件,配置已经正确了。如果构建 nano 的版本,你需要注释 32k 那段,取消注释 nano 那段代码,然后再次 make。
还有一个特殊的调试模式,通过硬件 UART 以 9600 波特的速度转储信息。你现在可以忽略,但要记住它,因为以后可能用到。
最后,你可以通过改变几个变量来决定 GPS 应该多长时间被激活。默认每天运行一次,但如果 GPS 需要很长时间锁定,它会减少运行频率,从而减少电池的消耗。请在 src/gps.c 中阅读所有相关内容。
资料链接可参考
avr-gcc工具:https://www.pololu.com/docs/0J61/6.3
GitHub:https://github.com/mattwach/epaper_clock
源码、固件、Makefile 等文件可在本项目文件库中下载:
https://make.quwj.com/project/434
使用 ICSP 上传固件
该步骤是为那些上传代码到独立的 Atmega328P 芯片的小伙伴准备的,如果你要上传到 Arduino Nano,请跳到下一个步骤。
你需要一个 ISP(或ICSP)编程器。可以用一个备用的 Aruino Uno/Nano 自己做一个。可以在 Google 引擎搜索”Arduino ISP Programmer”。请注意,这些指南中的很多内容都假定你的真正目的是安装一个引导程序,但对于我们来说,不需要引导程序,因为我们将直接用 ICSP 上传 .hex 文件。
断电检测
在我的 Atmega328P 上,断电检测设置为 3.5V(可能是旧版本),所以我用这个命令禁用断电检测。
/usr/bin/avrdude -patmega328p -cusbasp -Uefuse:w:0xFF:m
你的可能不一样,这取决于你的 “ISP programmer”(-c选项)。也有可能你不需要设置,只是以防万一。
使用 Avrdude
我们可以使用一个叫avrdude的免费工具,来把它创建的十六进制文件上传到你的Uno/Nano/。我们也可以直接用命令行下载并使用avrdude。
用 Arduino IDE 在输出记录打开的情况下运行一个上传(点灯的 demo 或者其他的 demo),然后复制它使用的命令。或者
阅读官方的 avrdude 文档或者阅读参考网上使用 avrdude 的教程。这里是我在 nano 版本中使用的 avrdude 命令(通过 make 上传),供参考。
/usr/bin/avrdude \
-v \
-patmega328p \
-carduino \
-P/dev/ttyUSB0 \
-b57600 \
-D \
-Uflash:w:epaper_firmware_using_arduino_nano.hex:i
这个是我在 ISP 版本中使用
/usr/bin/avrdude \
-v \
-patmega328p \
-cusbasp \
-Uflash:w:epaper_firmware_using_32k_crystal.hex:i
我使用的是 Linux。Mac 和 Windows 也能正常工作,但像 -P 这样的选项会有所不同(即在 Windows 中可能是 -PCOM1)。
资料链接可参考
avrdude:https://www.nongnu.org/avrdude/
Arduino IDE:https://www.arduino.cc/en/software
固件文件可在本项目文件库中下载:
https://make.quwj.com/project/434
32K 晶振
选择「简易」版本可跳过这一步。如果你使用的是 32k 晶体固件,则需要安装晶体以使固件发挥作用。
首先,你需要配置 ATMega328P 的内部内熔丝,以使用内部的 8Mhz 晶体。
先做这一步很重要,因为 32K 晶体将取代任何现有晶体。如果你不改变这些内熔丝,芯片会变得没有反应,直到你重新连接一个 8 或16Mhz 的振荡器。
Arduino pro mini 也需要 ISP 来改变内熔丝(但我可能是错的)。我查找了 “Arduino ISP”,来获得正确的引脚映射,以便将 ISP 连接器与面包板对接。
在连接了我的 ISP programmer 后,可以用这个命令检查当前的内熔丝配置。
$ avrdude -patmega328p -cusbasp
...
avrdude: safemode: Fuses OK (E:FF, H:DE, L:E2)
L:E2 是我们想要的内部 8mhz 的设置。如果你的值不一样,可以用类似于这个的命令来更新它。
/usr/bin/avrdude -patmega328p -cusbasp -Ulfuse:w:0xE2:m
然后重新检查。
内熔丝设置完毕后,你就可以焊接晶体了。建议将晶体直接连接到微控制器引脚上,以减少杂散电容。太多的电容会使晶体需要更长的时间来开始振荡(或无法启动)。
第一步(可选)
请参考步骤 1、步骤 2或步骤 3 来选择设计的原理图。
1、可以在面包板上验证到目前为止的情况,只需将一个 LED/Resistor 从 D5 接地,然后上传固件。如果一切正常,LED 将每秒短暂地闪烁一次。
2、添加 EPaper 显示屏。显示器上的数据都不会是正确的,但它应该显示一些数据。
3、添加 PHT 模块,并验证它是否工作。
4、添加 GPS 模块。
如果测试正常,我们可以把所有东西转移到一个更“永久”的固定装置上。
组装线路板
你可以选择使用 perf 板,用 CNC 切割板子,或者送到工厂去定制。
Kicad 设计文件可以在 schematic/ 目录中找到。有三种硬件可供选择(都是从后面显示的,因为这是你手工布线的方式)。
我使用 CNC 来制作 ATMega328P 版本。如果你没有用 CNC 切割过 PCB 但又十分感兴趣,可以尝试在 google 引擎上搜索 “3018 PCB”,你会发现很多关于这个主题的视频和文章。
间隙设置 0.4 毫米,但你可以更窄(可能不会更宽)。我使用 Flatcam 将 Kicad 的 Gerber 输出转换为 G 代码。
资料链接可参考
Kicad:https://www.kicad.org/
Flatcam:http://flatcam.org/
schematic/: https://github.com/mattwach/epaper_clock/tree/main/schematic
设计外壳
外壳设计使用一个 3D 打印的支撑结构和两个 CNC 部件:一个顶盖和前面板。数控部件是用木头做的,它会比塑料看起来更漂亮。可在 OpenSCAD 中预先设计整个外壳。
采用 0.2 毫米的层高打印主要结构,大概花费五个多小时。
使用 OpenSCAD 的 “projection”功能,为顶盖和前板创建了2D DXF 文件。
我通常会使用一个名为 “Carbide Create”的免费程序,为数控机床制作 G 代码。但面板有一个 45 度的倒角,而Carbide Create是一个太基本的程序,不能很好地处理这个问题。所以我尝试了一个不同的程序,叫做”CamBam”,它的效果非常好。(CamBam 不是免费的,但可以免费使用 40 次)
资料链接可参考
case_design/:https://github.com/mattwach/epaper_clock/tree/main/case_design
OpenSCAD:https://openscad.org/
projection: https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Using_the_2D_Subsystem#3D_to_2D_Projection
Carbide Create: https://carbide3d.com/carbidecreate/
CamBam: http://www.cambam.info/
附录A:时钟漂移校正(可选)
32k/CPU 晶体不会是完美的。当 GPS 开启时,它会修正漂移。但是如果漂移不好或者你的 GPS 信号不好,你也可以在固件中应用一个校正。就需要构建代码,在 main.c 的顶部,有一些被注释掉的定义。
你可以取消对上面两个 #define 语句的加注,以启用校正。
如果你的时钟已经慢了,只需取消对 CLOCK_DRIFT_TOO_SLOW 的注释;如果你的时钟太快了,就不要注释。唯一要做的是设置 CLOCK_DRIFT_SECONDS_PER_CORRECT…
数学方法
大约一天后,查看时钟漂移了多少。例如,你等了 23 个小时。
如果这时你看到时钟慢了 10s,修正的算式为:
(3600×23)/10 = 8280秒,每次修正。
#define CORRECT_CLOCK_DRIFT
#define CLOCK_DRIFT_SECONDS_PER_CORRECT 8280
#define CLOCK_DRIFT_TOO_SLOW
其他方法
首先从 5000 数值开始尝试,并观察时钟仍然过快或过慢,再对其进行调整。还是太慢?试试 2500。太快了?试试 10000。做好记录,并反复调整到可以接受的数值。
附录B:便宜的 GPS 电源控制(关于 BS170 N-MOSFET)
回到前面 “便宜的 GPS ” 那一步,其中描述了关于电源控制电路,上面的电源切断电路被称为 “low side switch”。它的好处是比较容易理解,而且零件数量少,但还是会有一些设计上的问题。
GPS 的地线并不与 GND 相连,而是与 MOSFET 相连。这意味着从 GPS 到微控制器的 UART 信号会有 MOSFET 的压降加在上面(Vds),增加了噪声的敏感性,并可能造成的错误。
如果你的微控制器的输入被规定为 3.3V 为最大值,你就不会想使用这种设计(选择 ATMega328P 就没有这个限制)。
3.3V(上面的 EN 引脚)对每个 MOSFET 来说都不是一个很强的开启电压。UART 是一个数字信号,地线的差异并不大,也许它无论如何都会工作?
我尝试过了,起初工作得很好,但随着时间的推移,我逐渐发现它并不可靠。为了了解原因,我们参考一下我最初选择的 BS170 作为我的 N-MOSFET 的特性曲线。
在 X 轴的 3.3V 时,我们将坐在图上的 3.0 和 4.0V 线之间。因此,也许我们会得到 100mA?也许足够?
万用表告诉我,GPS 消耗 40-60mA,但我认为这是一个平均值。根据 GPS 试图做什么,它只是需要比晶体管能够允许的更多的电流,因此 GPS 的地(MOSFET 漏极)电压会上升。这既造成了UART错误,又降低了 GPS 装置的整体电压,而 GPS 装置有时仍然可以工作,有时则进入复位循环。
一个解决方案是使用一个 “high side”电源电路,需要在上面增加一个 P-MOSFET 来实现这个目标。它消除了单独接地的问题,并提供一个完整的 5V(电池)栅极电压波动,这将使相关的 P-MOSFET 完全打开。
在 falstad 中的一个高边设计实例。
目前我已经购买了带有低端布线的 PCB,所以我次要解决方案是放弃 BS170,而用 FQP30N06L 代替。这种较高电流的 MOSFET(最大30A!)似乎严重过剩,但其曲线看起来要好得多。在 3.3V 电压下,大约有 10A 的电流余量,比 BS170 改进了 100 倍,现在应该足够了,而且很稳定。
N-MOSFET 的特性曲线:
https://pdf.elecfans.com/ONSEMI/MMBF170.html