*MAKER: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/ 目录并输入。
1 | make |
如果代码建立了,可以打开Makefile,查看这些选项。
123456789 | # This is the Low-power stand alone chip configuration.CLOCK_MODE ?= USE_32K_CRYSTALUART_MODE ?= HARDWARE_UARTF_CPU ?= 8000000 # This is the easy-to-build firmware that is based on an Ardino Nano#CLOCK_MODE ?= USE_CPU_CRYSTAL#UART_MODE ?= SOFTWARE_UART#F_CPU ?= 16000000 |
如果你正在构建 32k 晶体固件,配置已经正确了。如果构建 nano 的版本,你需要注释 32k 那段,取消注释 nano 那段代码,然后再次 make。
还有一个特殊的调试模式,通过硬件 UART 以 9600 波特的速度转储信息。你现在可以忽略,但要记住它,因为以后可能用到。
12 | # Uncomment to activate debug via the UART TX (9600 baud)#DEBUG_CFLAG := -DDEBUG |
最后,你可以通过改变几个变量来决定 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(可能是旧版本),所以我用这个命令禁用断电检测。
1 | /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 上传),供参考。
12345678 | /usr/bin/avrdude \ -v \ -patmega328p \ -carduino \ -P/dev/ttyUSB0 \ -b57600 \ -D \ -Uflash:w:epaper_firmware_using_arduino_nano.hex:i |
这个是我在 ISP 版本中使用
12345 | /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 后,可以用这个命令检查当前的内熔丝配置。
123 | $ avrdude -patmega328p -cusbasp...avrdude: safemode: Fuses OK (E:FF, H:DE, L:E2) |
L:E2 是我们想要的内部 8mhz 的设置。如果你的值不一样,可以用类似于这个的命令来更新它。
1 | /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 的顶部,有一些被注释掉的定义。
1234567 | // Clock drift correction// If your clock runs too fast or too slow, then you can enable these//#define CORRECT_CLOCK_DRIFT// number of seconds that a second should be added or removed//#define CLOCK_DRIFT_SECONDS_PER_CORRECT 1800// define this if the clock is too slow, otherwise leave it commented out//#define CLOCK_DRIFT_TOO_SLOW |
你可以取消对上面两个 #define 语句的加注,以启用校正。
如果你的时钟已经慢了,只需取消对 CLOCK_DRIFT_TOO_SLOW 的注释;如果你的时钟太快了,就不要注释。唯一要做的是设置 CLOCK_DRIFT_SECONDS_PER_CORRECT…
数学方法
大约一天后,查看时钟漂移了多少。例如,你等了 23 个小时。
如果这时你看到时钟慢了 10s,修正的算式为:
(3600×23)/10 = 8280秒,每次修正。
123 | #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://www.onsemi.com/pdf/datasheet/mmbf170-d.pdf
falstad 中的一个高边设计实例。