Skip to content

使用 ESP32 和电子墨水屏,结合 AI 生成图片,制作低功耗每日自动更新的个性化日历

  • 这是一款基于 ESP32 的电子墨水 AI 日历。只属于当天的不可保存不可变更的图文,和低功耗无开关设计,恰似昨日不可留,今日如新,明日不可知,静默流逝而不觉的时光。
  • https://github.com/daolanx/eink-ai-calendar

ai-calendar-front

ai-calendar-back

ai-calendar-screenshots

ai-calendar-components

起因

最早也是看到凉糕大佬的 《我在数字时代做了一个电子日历,让油画和照片可以被装进去》, 觉得效果惊艳,也想有个类似的东西来提醒自己时间的不可挽留不可预知独特又容易淡忘。

最初其实是想要一个能够获取在线相册的电子日历,最好能把 NAS 上相册随机显示,不过购物 APP 找了一圈,首先相册基本都是存本地存储卡的(后来自己做才懂为什么),其次屏幕也是黑白的居多,顶多有个三色的屏幕,然后显示上要么是纯相册,要么是日历,密密麻麻的信息。也就是市面上还真没有想要的产品。

于是想能不能自己做,跟着上文评论区找到了热心的 Ymriri 实现的 esp32_7color。很欣赏这种热心和动手能力,能个前后端分离的电商管理平台,魔改成相册管理,整合自己的项目和技术做出结果。但是。。代码太乱一言难尽,看到项目文档写了,“我知道你想说什么,这个文件夹结构太乱了,我也知道,但是我懒得改了,你可以自己改” 。。后来在代码里看得云里雾里的,几次折腾以后放弃了。

最后找到 Debatrixeink-calendar,他代码最简单,于是仗着有 cursor + gpt 编程搭子,从未接触的 python c 都敢碰,用这个边学边改。

从 NAS 相册日历到 AI 图文日历

最早其实是想找群晖接口来读取相册数据,后来一个是接口调取比较麻烦,二是做着做着忽然有灵感,AI 图片如结合当天信息进行生成,其实更符合日历的感觉。于是就去找 AI 文生图接口。

最早尝试了 cloudflare 的 workers-ai, 其实能运行,但是网速调用太慢了。于是想想国内接口的应该能快一点,用了阿里云的 AI SDK,感觉确实快了一些。

为什么用 C/S 架构

看凉糕和 Debatrix 大佬的代码,都是 C/S 架构。做的时候会发现 C/S 架构明显更麻烦,服务端部署在哪里是个问题,我猜这也是很多商品相册,相册放存储卡的原因,因为从维护成本,安全隐私考虑,确实本地更合适,可能商家早就想到这一点了,产品功能上做了取舍只支持本地化。

我想干脆我直接 ESP32 端获取原始图片,色彩抖动处理,数据处理不也一样吗,就多费一点电而已。实际调试好想不行,确实会不支持,原因未知,可能就是算力存储问题。这方面资料太少,因此我也先继续用 C/S 架构。

那 C/S 架构,服务端部署在哪里,最初是想用 serverless,因为按需使用最符合这个场景。之前尝试用 cloudflare 的 workers, 实际测试不行,因为这个 workers 不支持 python 的一些库函数,比如 PIL 等。然后也看了阿里云的个轻量级的 ECS 和 serverless. 迫于文档和计费,我想想能不能树莓派部署,但是树莓派又得插上电麻烦,正好家里有支持 Docker 的群晖 NAS, Docker 镜像部署在 NAS 上,安全又省心。

更简洁的 UI

既然凉糕的待办信息换成格言,UI 也需要进行修改。看了一圈类似开源日历,可能和程序员信息导向习惯堆砌信息有关, 大多信息堆叠。于是我上购物 APP 参考日历台历,感觉好的布局也不多,有一些看似好看,实际信息是分散的。其实也没找到更好的布局,目前主要做的就是删减信息,相关信息聚合,更简洁。有些大佬会用 figma 重新设计,还没学到。

更简洁的功能

Debatrixeink-calendar 包含很多功能,比如图片存储,hash 检查,还有开关控制,LED 控制。其实最早是是想加一个开关控制刷新,但是控制电路自己也不太会,额外的电路可能外观设计更麻烦,可能不能变更有仪式感。于是就去掉了开关和 LED。

每日刷新一次怎么实现,RTC 时钟模块好像可以做到,一想又变复杂了。我发现除了唤醒机制,还有个特性是 wifi 连接以后能获取时间。于是我想到,每个小时唤醒一次,wifi 连接以后,获取时间,正好是凌晨就更新,这样就实现了每日刷新。不依赖 RTC 和 Server 的 每日凌晨更新。

更美观的外观

最早是用凉糕的模型打印,发现模型可以用,但是需要去掉 ESP32 的引脚,我尝试了电烙铁去引脚没成功。还有外壳我觉得塑料的或者积木的都没有木质的感觉。于是去买了木质的相框,原相框背面背板太厚,于是又单独买了薄的背板。用游标卡尺测量内径比着买电池,这样刚好能放下芯片和电池。

然后是怎么连接背板和相框,最早想的是找个日记本类似的小锁扣,但是没有找到合适的,也不想边框突兀一个插销。后来想到可以用磁吸,买了磁铁,发现吸力有点大,怕固定胶粘不住,于是 3d 打印设计了磁铁盒子,减少吸力增加粘胶面积。

目前使用上感觉还好但磁力偏小,更好其实是后盖直接用磁铁,相框用磁铁盒子来达到合适的磁力。

3D 建模我也不会,也是请教 gpt 告知步骤现学现卖,自己操作软件,新建矩形,布尔差值运算,来实现遮罩和磁铁盒子。

开发心得

坦白讲,这段时间也是技术迷茫期的探索之旅。之前我其实对技术是有抵触和陌生感的。这段时间从苹果的沃兹Linux 的托瓦兹 这类牛人的演讲受到启发,无论技术创始人,还是用技术的牛人的观点看,真正的技术其实是用来玩,或者创造价值的,而不是枯燥的考试和工作。他们并不是刻苦努力达成的,沃兹正好赶上了硅谷发展,是玩着数学和电路长大的,托瓦兹是也是为了好玩做的 Linux,为了维护 Linux 做了 Git。很遗憾没有亲身经历硅谷高速发展的阶段,也在大学和工作里曲解了一些认知,并没真正的去理解技术。

那还原到基本的技术认知,这次开发学到的是:

1. 保持勇气和好奇

之前面对不熟悉的技术栈,我总是有些抵触感,但这次借助 cursor 和 GPT,我能更好地解读代码,选择去尝试。AI 虽然会影响程序员,但也带来了更多机会。比如这次,我对 ESP32 和 Python 并不熟悉,但在 AI 的辅助下,能进行调试和改造,接触到更多有趣有用的项目。不过,我也发现 AI 目前还无法独立完成所有任务,某些方面仍有局限,缺乏整体认知。但它作为编程助手,可以帮助生成功能明确的代码。程序员与 AI 的关系就像厨师与配菜员,也想 EVA 驾驶人和机甲,可以密切合作, 释放潜力。

过程中的困难,我想起最近玩黑神话,无论大头还是秀士黑熊虎先锋有些 BOSS 开始觉得完全没希望很难过,后面克服畏难,索性抱着切磋学习的态度去玩,渐渐就熟悉了看清了然后过了,真是一种奇怪的体验,比起方式方法,更重要的其实是勇气。有勇气去尝试,一切才有可能。

关于勇气,罗琳 说人生都会经历失败,除非你活的很小心,就像没有活过,那更是一种失败。

2. 格物致知

技术本质是方式而不是目的。因此学习最好的方式不是学而是用起来。过程中会不断发现问题或者目标,不断整合资源方法,去解决问题靠近目标可能是更好的方式。这样学习过程中包含了学习的方法和不断克服困难的心态。收获远大于单纯的学习获得答案。

python, esp32,墨水屏的端,之前都不熟悉,但是会发现在 web 的处理,在程序的基本逻辑,端的处理上,大体是相似的。会有一种熟悉感,可能这就是大佬说的计算机和程序基础,触类旁通。

还有些问题可能有很多种处理方式,甚至有很多方案,在选项集里它们不是零和博弈和排它的,没有所谓的唯一标准答案,取舍在于自己当前的判断取舍。

3. 完成比完美更重要

很多人说过这条,不过自己经历过才知道什么意思。过程中不断有冲动想重构,用 python 的 flask,甚至用 nodejs 重构的想法冒出来,但是理智告诉自己,这样会降低完成进度甚至可能性,追求完美可能就无法完成。需要聚焦目标,先完成功能,保持克制和清醒。

4. 乐于分享

沃兹说技术是做好的事和分享。希望这次我做到了。

感谢

感谢开源,能让我们接触到热心的人,有趣的项目,整合创造自己想做的东西; 感谢 AI 让我们能更容易参与和使用不熟悉技术的项目。