跳到內容

電量計與風扇

前提:已完成手動適配頁裡的 overlay 和 config.txt 配置塊—— 其中已經包含本頁用到的 stc3117-gauge 和 i2c-fan 那幾行。

電池電量由一顆 STC3117 電量計(I2C 地址 0x70)測量,掛在計算模組的 SDA0/SCL0 上。它位於樹莓派 / ESP32-S3 之間的 I2C 多路切換器後面,上電時切換給樹莓派(也就是樹莓派佔用螢幕的時候)。

Raspberry Pi OS 沒有編譯 CONFIG_FUEL_GAUGE_STC3117,所以 TypixDeck 系統把驅動做成 DKMS 模組—— 每當安裝了新核心及其 headers,它都會自動重新編譯。

Terminal window
sudo apt install -y dkms linux-headers-rpi-v8 linux-headers-rpi-2712
# (the dwc2fix kernel from the USB audio page brings its own headers)
[ -d ~/typixdeck-pi-gen ] || git clone --depth 1 -b typixdeck https://github.com/TypixNode/pi-gen.git ~/typixdeck-pi-gen
SRC=/usr/src/stc3117-fuel-gauge-6.18
sudo mkdir -p $SRC
sudo cp ~/typixdeck-pi-gen/typixdeck-stage/03-battery-dkms/files/{stc3117_fuel_gauge.c,Makefile,dkms.conf} $SRC/
sudo dkms add -m stc3117-fuel-gauge -v 6.18
sudo dkms install -m stc3117-fuel-gauge -v 6.18
sudo reboot

檢查:

Terminal window
dmesg | grep stc3117
cat /sys/class/power_supply/stc3117-battery/{capacity,voltage_now,current_now,status}
upower -d | grep -E 'percentage|state'

UPower 會自動接管這塊電池,所以各個桌面(labwc 面板、Phosh、Plasma)的電池圖示無需額外配置就能用。

stc3117-gauge 描述了這塊板子:

屬性 值 原因
shunt-resistor-micro-ohms 10000 10 mΩ 電流取樣電阻
charge-full-design-microamp-hours 2400000 604070 鋰聚合物電池,約 2400 mAh
voltage-min/max-design-microvolt 3.0 V / 4.2 V
factory-internal-resistance-micro-ohms 140000 電量計看到的整包內阻(電芯 + 保護板 + 線材),用 CPU 負載階躍實測;驅動預設的 200 mΩ 會讓初始電量估低約 15 個百分點

匯流排:CM4 預設目標是 i2c_csi_dsi(GPIO44/45,i2c-10);CM5 要傳 i2c_csi_dsi0 引數 (RP1,GPIO38/39)——所以兩者的 config.txt 寫法不同。不要讓 CM4 指向 i2c_csi_dsi0:在 CM4 上那是 GPIO0/1,屬於 DPI 螢幕(會報 pin gpio0 already requested)。換用其他電池時,可以用 capacity-uah、 shunt-uohm、rint-uohm 引數覆蓋對應數值。

不要在 TypixDeck 上直接載入主線的 stc3117_fuel_gauge。它把 16 × 16 位的 OCV 表當 16 個位元組寫進去, 把表寫壞;把千分比當百分比上報(4.6% 顯示成 46%);把電流按無符號讀、正負號約定還是反的;還會把 ESP32-S3 已經啟動的電量計復位。TypixDeck 版修掉了這些,並且增加了:

  • 每塊電池只初始化一次,並與 ESP32-S3 協同。 電量計的狀態由兩顆處理器共享,所以它們通過電量計自身 帶電池供電的 RAM 裡的一個標記來協調:誰先拿到匯流排,誰就根據測得的電壓設定初始電量並寫入標記; 另一方只讀不寫。拔掉電池 RAM 會清空,下次重新初始化。沒有這個機制時,剛裝好的系統可能在滿電時只顯示 3–6%。
  • 4.2 V 放電曲線,適配 604070 電池,並與對應的電量斷點表一起寫入(主線的曲線屬於 4.35 V 電芯,在這裡 永遠到不了 100%)。
  • 只有在連續一致的證據下才重新初始化——電壓和電流不在同一個轉換週期,負載變化時的單次讀數不可信。
  • 提供 charge_now / charge_full,供自行計算百分比的面板外掛使用;多路切換器把電量計交給 ESP32-S3 期間,電池不會被判定為“已拔出”。

config.txt 配置塊裡的 i2c-fan,emc2301 那幾行,把 Raspberry Pi OS 自帶的 i2c-fan overlay 繫結到板上 同一對 SDA0/SCL0 上的 EMC2301。不加的話,控制器一直停在上電預設的 100% 佔空比,系統裡也沒有風扇感測器。

  • 這個 overlay 會自己啟用那條匯流排——不要同時再加 dtparam=i2c_vc=on。
  • 如果要調引數,在 6.12 及更新的核心上 minpwm 必須 ≤ 51:更大的值會讓驅動拒絕第一檔冷卻狀態, 風扇 probe 靜默失敗。midtemp、maxtemp、maxpwm 可以放心調。

CM5 還驅動一個樹莓派 5 式的四線 PWM 風扇(pwmfan)。原版曲線對封閉機殼來說太保守——50 °C 起只有 29%—— 所以 TypixDeck 系統保持觸發溫度不變,把每一檔的佔空比調高:

觸發溫度 原版 PWM TypixDeck PWM 實測
50 °C 75 130 3.6k → 6.5k RPM
60 °C 125 180
67.5 °C 175 220
75 °C 250 255 全速 10.0k RPM
[cm5]
dtparam=cooling_fan=on
dtparam=fan_temp0_speed=130
dtparam=fan_temp1_speed=180
dtparam=fan_temp2_speed=220
dtparam=fan_temp3_speed=255

這些引數名由 CM5 自己的裝置樹定義(fan_temp0..3、_hyst、_speed),所以是安全的;拼錯一個 dtparam 正是“開機後風扇不轉”的經典原因。檢視當前實際生效的值:

Terminal window
od -An -t u1 /proc/device-tree/cooling_fan/cooling-levels # PWM per state
for d in /sys/class/hwmon/hwmon*; do [ -r $d/fan1_input ] && echo "$(cat $d/name) $(cat $d/fan1_input) rpm pwm=$(cat $d/pwm1)"; done

hwmon 編號每次開機可能不同——請按 name 查詢風扇,不要寫死 hwmonN。