Project Door Sign

tekita

这部分我要单独拿出来写,在我用gemma 4驱动起来让我以为已经摆脱了token饥荒的时候,多了许多妄想,比如我一直想搞一个门牌.我有一块差不多10年前买的raspberry pi zero w.多次折腾,一直没有想清楚要用来做什么,作为好看的小摆件.以下备忘:

Round 1: Il Raspberry Pi Zero è rotto.

老pi zero刷了系统进去,连接同一个2.4g路由器,启动后找不到它:
where the fuck you are
扫描同一个路由器网络内的设备ip

1
nmap -sn 192.168.31.0/24       

反复折腾一天认为老的zero可能是有问题,不过配件们都在路上了,NFC模块, 电子墨水屏什么的,还买了彩色的排针.

回家跟老婆垂头丧气地讲了那块pi坏了的情况,又到了月底,收入压力又来了,信用卡账单水电什么的,想购置一块新的zero 2的计划暂时停留在购物车里.我横向排比了几个替代品,香橙派,nanopi,各种吧,有几个问题阻止了我,llm的回答经常会说,想把我现在已经为pi zero准备的配件接上,要么是没有原生支持,软件驱动层存在种种不确定性.

第二日,因为我在鞋类入库插件和入库商品打印标签功能的优异表现,小金主按时打来了一点钱.我于是干脆下单了Zero 2, 341元

Round 2 焊接

等待zero 2到达之前,彩色排针到了,我想反正这个旧的也是坏了,干脆焊接一下,我是有低温电烙铁的,而且焊锡丝中间是带松香的. 眼花手抖,很不容易焊完了40个点,恍惚间眼前出现小时候看我爸焊接的场景,他那时候修录音机,修电视,还有音响什么的.以第一次焊接来说,我这还算是可以,发了照片给gemini看,他说:
SPI
焊点复盘
优点: 锡量给得很足,每个焊点都完整包裹了针脚。

细节观察: 焊点表面看起来稍微有一点点“圆润”或者是带一点点磨砂感,这通常是因为不可调温烙铁温度较高,或者是锡丝里的助焊剂(松香)挥发较快导致的。

安全性: 最重要的一点——我看了一遍,没有发现连焊。这意味着你现在插上电,这块板子不会因为 GPIO 短路而烧毁。

建议的小优化(强迫症进阶版)
如果你觉得有的焊点像“小球”而不是“小火山”,下次可以试试:

烙铁多停留半秒: 让锡液彻底流进孔里,形成一个内凹的圆锥形(小火山)。

清洁烙铁头: 普通烙铁头容易积碳,焊几个点就在湿海绵或钢丝球上蹭一下,焊点会更亮。

然后,无论我刷lite的系统还是legacy的32位pi os,它还是处于失联状态.

Round 3 the problem is the TF card

新的zero 2到了之后,我踌躇了一会,才开始摆弄,我直接买了出厂就焊接好排针的版本,刷了系统,插上去之后,过了半天还是没找到它……,LLM开始瞎猜,说是不是供电不足blabla. 琢磨这全新的pi上的焊点看起来如此平整,总不可能是出厂就有问题吧. 我端详了一会手里的BanQ京东联名64g TF卡,从NDSi里抠出来一块为了让NDSi可以拍照的8G的sandisk TF卡,姑且一试.
brand new zero 2
结果这么一试还真就是卡的问题, 这个小8G驱动起来了,我终于可以这样连接它了

1
ssh b9@b9.local

忽然想到,难道之前的zero是没有问题的?!

Round 4 E-Paper

我开始将墨水屏的杜邦线连接到SPI排线, 想要驱动它.
SPI
1 在pi上我安装了需要的git, clone了它官方的项目:,
2 按照官方建议的顺序启动了SPI接口:

1
sudo raspi-config

选择Interfacing Options -> SPI -> Yes 开启SPI接口
3 看起来程序运行完全正常(SPI通信、busy信号都正常),但屏幕没有显示内容。

下面是Claude给我的建议,我因此意识到我可能使用错了测试程序.

最可能的原因

1. 接线引脚接错了(最常见!)

SPI
你的图片显示接了很多跳线,请对照下面的接线表仔细检查:

e-Paper 引脚 Pi Zero 2 GPIO 物理引脚
VCC 3.3V Pin 1
GND GND Pin 6
DIN MOSI (GPIO 10) Pin 19
CLK SCLK (GPIO 11) Pin 23
CS CE0 (GPIO 8) Pin 24
DC GPIO 25 Pin 22
RST GPIO 17 Pin 11
BUSY GPIO 24 Pin 18

⚠️ DC、RST、BUSY 这三个引脚最容易接错,而且接错后程序仍然能正常运行并输出 busy/release 日志,但屏幕没有反应。

2. 确认你用的是哪个版本的模块

微雪 2.9inch 有多个版本(V1/V2/V3/B/C),驱动不同!

1
2
3
# 检查你的模块背面丝印,或者试试
python3 -c "from waveshare_epd import epd2in9_V2; print('V2 ok')"
python3 -c "from waveshare_epd import epd2in9; print('V1 ok')"

如果版本不对,换对应的测试脚本:

1
2
# V2版本用
python3 epd_2in9_V2_test.py

3. 快速验证接线的方法

运行这个小脚本,如果屏幕有任何反应(哪怕闪一下),说明接线基本正确:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import RPi.GPIO as GPIO
import time

RST_PIN = 17
DC_PIN = 25
CS_PIN = 8
BUSY_PIN = 24

GPIO.setmode(GPIO.BCM)
GPIO.setup(RST_PIN, GPIO.OUT)
GPIO.setup(BUSY_PIN, GPIO.IN)

# 硬复位
GPIO.output(RST_PIN, GPIO.HIGH)
time.sleep(0.1)
GPIO.output(RST_PIN, GPIO.LOW)
time.sleep(0.01)
GPIO.output(RST_PIN, GPIO.HIGH)
time.sleep(0.1)

print("BUSY pin:", GPIO.input(BUSY_PIN)) # 应该输出 0 或 1
GPIO.cleanup()

你能告诉我模块背面写的版本号是什么吗? 或者拍一下模块背面的照片,我可以帮你确认驱动版本。

我确定我的屏幕背面写的是V2, 结果用V2的test一发跑通,我十分兴奋地发现A大人电报留言说本来约定的会议他忽然发现是五一假期,于是建议延后.于是我在开心地打算休息半日的情况下,犯下了一个后面折腾了半天的错误 –> 我直接拔掉了USB供电.

Round 5: sudo shutdown -h now

过了一会儿,我打算刷一个新的图片给电子墨水屏,然后让它一直保持那样,于是我又把pi的供电插了回去.这一次石沉大海,这家伙又找不到了,claude说因为系统挂载了SPI设备,在退出之前可能写文件失败,系统损坏了.我重新刷镜像,按照建议用f3软件测试tf卡,都表示没有问题.

在多次重刷,最后我降级到64位的legacy lite pi os, 它总算复活了(过去了两小时, 重新插排线, 重做镜像,重新扫描):

当重做了镜像但是用了同样主机名称提示:

1
2
3
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

时可以:

1
ssh-keygen -R b9.local

不过这次的怪现象是,可以找到并ssh连接它,但是它很快就会失联.claude判断它可能由于运行的负载瞬间提升,因为我没有安装散热片,它可能overheat了.不过我觉得不是,我去摸了CPU,还没有我手指头热.那么问题很可能是这块TF还是有什么问题,比如是个贴牌货的可能:

1
2
3
4
5
6
7
8
9
10
11
12
13
dmesg | grep -i mmc
[ 2.313447] mmc-bcm2835 3f300000.mmcnr: mmc_debug:0 mmc_debug2:0
[ 2.314609] mmc-bcm2835 3f300000.mmcnr: DMA channel allocated
[ 2.412513] sdhost-bcm2835 3f202000.mmc: loaded - DMA enabled (>1)
[ 2.453956] mmc1: new high speed SDIO card at address 0001
[ 2.493590] mmc0: host does not support reading read-only switch, assuming write-enable
[ 2.497474] mmc0: new high speed SDHC card at address 0001
[ 2.499475] mmcblk0: mmc0:0001 ASTC 7.38 GiB
[ 2.503630] mmcblk0: p1 p2
[ 2.505226] mmcblk0: mmc0:0001 ASTC 7.38 GiB (quirks 0x00004000)
[ 3.524637] EXT4-fs (mmcblk0p2): orphan cleanup on readonly fs
[ 3.526684] EXT4-fs (mmcblk0p2): mounted filesystem c6c3fb9d-86a8-472f-b6ab-6eef573c5cac ro with ordered data mode. Quota mode: none.
[ 5.956951] EXT4-fs (mmcblk0p2): re-mounted c6c3fb9d-86a8-472f-b6ab-6eef573c5cac r/w.

从你的 grep -i mmc 日志来看,系统虽然勉强爬了起来,但底层的 SD 卡(ASTC 7.38 GiB) 已经发出了明确的“求救信号”。
这里的 ASTC 标识通常出现在一些入门级或 OEM 代工的存储芯片上,配合 orphan cleanup(孤儿节点清理)和 readonly fs(只读文件系统)的日志,基本可以判定:这张卡在物理寿命或文件系统一致性上已经处于崩溃边缘。

Round 6: let it be, and it will be

在我买的新16g sandisk到之前,我决定忽视8g贴牌卡的警示,放手运行一下看看可不可以让墨水屏显示一张喜欢的图片.结果它可以.
上传显示的图片需要做预处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/usr/bin/python
# -*- coding:utf-8 -*-
from PIL import Image, ImageFilter

img = Image.open("/Users/wanghe/Downloads/y-3.png")

# 转灰度
img = img.convert("L")

# 原图 396x694,目标比例 128:296 = 0.432
# 以高度 694 为基准,计算对应宽度
target_w = int(694 * 128 / 296) # = 299

# 从中间裁剪宽度
left = (396 - target_w) // 2
img = img.crop((left, 0, left + target_w, 694))

# 缩放到 128x296
img = img.resize((128, 296), Image.LANCZOS)

# 锐化
img = img.filter(ImageFilter.SHARPEN)
img = img.filter(ImageFilter.SHARPEN)


# 量化到4个灰度级别
def quantize_4gray(pixel):
if pixel < 80:
return 0
elif pixel < 150:
return 85
elif pixel < 220:
return 170
else:
return 255


img = img.point(quantize_4gray)
img.save("/Users/wanghe/Downloads/yotubato_epd.png")
img.show()
print("完成!")

一个完整的prepare给墨水屏驱动的脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/bin/bash
# 微雪电子墨水屏环境初始化脚本
# 适用于 Raspberry Pi Zero 2 + 2.9inch e-Paper V2

set -e # 遇到错误立即停止

echo "============================="
echo " 开始初始化墨水屏环境"
echo "============================="

# 1. 更新系统
echo "[1/5] 更新系统包..."
sudo apt update && sudo apt upgrade -y

# 1.5 修复 initramfs.conf(防止 apt upgrade 报错)
echo "[1.5/5] 修复 initramfs.conf..."
sudo bash -c 'cat << EOF > /etc/initramfs-tools/initramfs.conf
MODULES=most
BUSYBOX=auto
KEYMAP=n
COMPRESS=gzip
DEVICE=
NFSROOT=auto
CAN_HALT=n
EOF'

# 2. 安装依赖
echo "[2/5] 安装依赖..."
sudo apt install -y git python3-pip python3-pil python3-numpy

# 3. 开启 SPI
echo "[3/5] 开启 SPI..."
sudo raspi-config nonint do_spi 0
echo "SPI 已开启"

# 4. 克隆微雪电子库
echo "[4/5] 克隆微雪电子 e-Paper 库..."
cd ~
if [ -d "e-Paper" ]; then
echo "e-Paper 目录已存在,跳过克隆"
else
git clone https://github.com/waveshareteam/e-Paper.git
fi

# 5. 安装 Python 库
echo "[5/5] 安装 Python 依赖..."
pip3 install RPi.GPIO spidev --break-system-packages

echo ""
echo "============================="
echo " 初始化完成!"
echo "============================="
echo ""
echo "验证 SPI 是否正常:"
echo " ls /dev/spi*"
echo ""
echo "运行测试脚本:"
echo " cd ~/e-Paper/RaspberryPi_JetsonNano/python/examples/"
echo " python3 epd_2in9_V2_test.py"

Summary:

一定要sudo shutdown -h now!,一定不要轻易认为东西坏了,要反复测试! 至于我打算用这东西干嘛.