本篇是在前一篇測試使用 cnadler86 的 2026 新版韌體可成功拍照的基礎上, 進一步測試是否可以成功掛載 TF 卡.
本系列之前的測試文章參考 :
ESP32-S3 CAM 開發板背後有一個 TF 卡槽, 使用的是比 SPI 介面快的 SDMMC 介面, ESP32-S3 內建的 SDMMC 主機控制器 (Host Controller) 支援 1-bit, 4-bit 甚至 8-bit 並行傳輸, 1-bit 模式只需要三根腳 : CMD (指令線, GPIO38), CLK (時脈線, GPIO39), D0 (資料線 GPIO40); 而 SPI 則需要四根腳 : CS, MOSI, MISO, CLK.
SDMMC 是 CPU 與 SD 卡的溝通管道 (介面/協議), 而 SDHC/SDXC 則是儲存設備 SD 卡的規格 (容量等級), SD 卡規格有兩種 :
- SDHC (2GB - 32GB) : 出廠預設為 FAT32
- SDXC (64GB - 2TB) : 出廠預設為 exFAT
ESP32-S3 CAM 的 SDMMC 控制器支援 SDXC 高容量標準, 但受限於 MicroPython 的 vfs (虛擬檔案系統) 模組只支援 FAT 或 FAT32 格式, 所以如果插上 64GB 以上的 TF 卡, MicroPython 會報錯 (OSError: [Errno 19] ENODEV). 因此 ESP32-S3 CAM 開發板可用的 TF 卡容量最大是 32GB, 建議使用 8GB, 這是 ESP32 的神卡, 對 ESP32 開發者來說, 手上有 8GB 卡其實比 64GB 卡還珍貴, 原因是 :
- 原生 FAT32 支援 :
8GB 卡屬於 SDHC 標準, 出廠就是 FAT32 格式, 插上去 MicroPython 直接能掛載 (os.mount), 完全不需要找工具格式化. - 備份方便 :
映像檔小, 如果您想備份整張卡的系統與資料, 備份 8GB 只要幾分鐘. - 速度匹配 :
ESP32 的 SDMMC 介面寫入速度極限約在 1MB/s - 4MB/s 之間, 再快的卡也跑不滿, 所以舊的 8GB 卡 (通常是 Class 4 或 Class 10) 剛好能物盡其用.
對於 ESP32-S3 CAM 這種物聯網裝置來說, 8GB 其實已是海量的空間, 因為 ESP32 的鏡頭模組 (ov2640/ov5640) 產生的檔案遠比手機小, 8GB 卡片足夠進行數週甚至數月的監控記錄. 由於 ESP32 沒有 H.264 硬體影片編碼器, 它錄影的方式其實是把一張張 JPEG 照片串起來存成 .avi (MJPEG 格式), 以 VGA (640x480) 格式錄影的話, 8GB 大約可錄 3.5 ~ 4 小時 (15 FPS, 0.6 MB/秒); 以 SVGA (800x600) 格式錄影可錄約 2 小時 (10 FPS, 1.0 MB/秒).
我最近買的 3 片 ESP32-S3 CAM 開發板經 Gemini 判定確實是 Freenove 相容開發板 :
這塊板子的設計非常特殊, 與市面上常見的 ESP32-S3 CAM 不同, 主要特徵如下 :
- 獨特的絲印圖例 :
板子背面有一組非常特殊的符號說明 :
- : Camera (代表相機用腳位)
~ : SD Card (代表 SD 卡用腳位)
* : PSRAM (代表記憶體用腳位)
這是 Freenove 這款板子 (以及它的代工廠/複製品) 獨有的標示方式, 一般的 ESP32-S3 開發板不會這樣特地標註這三種符號. - SD 卡腳位確認 (GPIO 38, 39, 40) :
GPIO 38, 39, 40 旁邊都有一個波浪號 ~, 對照背面的圖例, 波浪號代表 SD Card, 這證實了這塊板子的 SD 卡確實是連接在 38 (CMD), 39 (CLK), 40 (D0) 上, 它只拉出了 D0 一條資料線, 沒有 D1, D2, D3. - 模組型號確認 (N16R8) :
金屬遮罩上的晶片型號清楚寫著 ESP32-S3-N16R8, N16 表示程式儲存空間有 16MB Flash, 而 R8 表示執行記憶體有 8MB (Octal PSRAM), 所以下載 MicroPython 韌體時必須選擇支援 SPIRAM / Octal SPIRAM 的版本, 否則這 8MB 的記憶體會無法使用, 相機跑到高解析度時就會記憶體不足.
TF 卡 (Micro SD) 使用前須先用 PC 將其格式化為 FAT32 格式, 這是 MicroPython 唯一支援的格式 (它只認得最古老最簡單的 FAT32, 如果是 exFAT 或 NTFS 會讀不到). 斷電後將已格式化為 FAT32 的 TF 卡插入開發板再通電, 然後執行下列程式 :
import camera
import machine
import os
import time
import gc
# --- 1. 掛載 TF 卡 (如果還沒掛載) ---
try:
# 檢查是否已經有 /sd 路徑,沒有才掛載
try:
os.listdir('/sd')
print("✅ TF 卡已掛載")
except OSError:
print("💾 嘗試掛載 TF 卡...")
sd = machine.SDCard(slot=1, width=1, clk=machine.Pin(39), cmd=machine.Pin(38), d0=machine.Pin(40))
os.mount(sd, '/sd')
print("✅ 掛載成功!")
except Exception as e:
print(f"⚠️ TF 卡掛載失敗,將存檔至內存: {e}")
save_path = "" # 存到根目錄
else:
save_path = "/sd/" # 存到 SD 卡
# --- 2. 執行拍照 ---
gc.collect()
cam = camera.Camera()
cam.init()
try:
# 設定格式
cam.reconfigure(pixel_format=camera.PixelFormat.JPEG, frame_size=camera.FrameSize.SVGA) # 試試 SVGA (800x600)
time.sleep(1.5) # 等暖機
# 拍照
print("📸 拍攝中...")
cam.capture() # 清緩存
buf = cam.capture()
# --- 3. 存檔 ---
filename = f"{save_path}vibe_photo_{time.ticks_ms()}.jpg"
with open(filename, "wb") as f:
f.write(buf)
print(f"🎉 照片已儲存至: {filename}")
print(f"大小: {len(buf)/1024:.2f} KB")
except Exception as e:
print(f"❌ 拍攝失敗: {e}")
finally:
cam.deinit()
此程式會先試圖掛載 TF 卡然後進行拍照, 若掛載成功, 照片會儲存在 TF 卡內, 否則存在 Flash 內, 結果 TF 卡掛載失敗 :
💾 嘗試掛載 TF 卡...
⚠️ TF 卡掛載失敗,將存檔至內存: extra keyword arguments given
📸 拍攝中...
<memoryview>
24616
🎉 照片已儲存至: vibe_photo_23376332.jpg
大小: 24.04 KB
詢問 Gemini 可能原因, 它認為韌體作者 cnadler86 可能在編譯時就把這塊板子特殊的 SD 卡腳位(38, 39, 40) 寫死在韌體核心裡了, 所以不需要傳入 clk, cmd, 與 d0 參數, 傳入參數只要保留 slot 和 width 即可, 建議掛載程式修改為 :
import machine
import os
print("========================================")
print("💾 Freenove S3 - TF 卡掛載測試 (Freenove 專用版)")
print("========================================")
try:
# 修正重點:
# 既然是 Freenove 專用韌體,腳位已經內建好了。
# 我們只要告訴它:「用 Slot 1 (SDMMC),跑 1-bit 模式」即可。
sd = machine.SDCard(slot=1, width=1)
# 掛載
try:
os.mount(sd, '/sd')
print("✅ 掛載成功!(/sd)")
except OSError as e:
if "already mounted" in str(e):
print("⚠️ 提示: 已經掛載過了,無需重複掛載")
else:
raise e
# 驗證容量
stat = os.statvfs('/sd')
total_mb = (stat[0] * stat[2]) / 1024 / 1024
print(f"📦 卡片容量: {total_mb:.2f} MB")
print("📂 檔案列表:", os.listdir('/sd'))
except Exception as e:
print(f"❌ 掛載失敗: {e}")
print("\n【除錯提示】")
print("1. 確保卡片格式是 FAT32。")
print("2. 確保卡片已插緊 (Freenove 的卡槽有時需要推到底)。")
print("3. 如果還是失敗,請嘗試將 width=1 改為不寫 (預設值測試)。")
結果還是失敗 :
========================================
💾 Freenove S3 - TF 卡掛載測試 (Freenove 專用版)
========================================
❌ 掛載失敗: 16
【除錯提示】
1. 確保卡片格式是 FAT32。
2. 確保卡片已插緊 (Freenove 的卡槽有時需要推到底)。
3. 如果還是失敗,請嘗試將 width=1 改為不寫 (預設值測試)。
錯誤代碼 16 (OSError: [Errno 16] EBUSY) 表示 "資源忙碌中", Gemini 建議冷開機重試, 但結果還是一樣, TF 卡如果掛載成功會在根目錄下建立一個名為 'sd' 的資料夾, 用下列程式檢查沒有此資料夾 :
>>> import os
>>> print(os.listdir('/'))
['boot.py', 'photo_0.jpg', 'photo_1.jpg', 'photo_2.jpg', 'vibe_photo_23376332.jpg', 'vibe_victory.jpg']
Gemini 認為 TF 卡接在板子的 38, 39, 40 (SDMMC 1-bit), 但此版韌體寫死的 TF 卡腳位可能不是 38/39/40, 當用預設值 (不加參數) 時, 它嘗試去連錯誤的腳位或已被佔用的腳位, 所以才會報錯 EBUSY (資源忙碌), 建議改用通用版 (Generic) 韌體 (檔名裡要有 SPIRAM 或 OCT), 不要使用 Freenove 版韌體.


沒有留言 :
張貼留言