Benchtop(工作檯) 是做什麼的?
將「我想要一個能……的東西」轉化為一個可實際製作的資料夾:包含指南、零件清單、可列印外殼、可訂購電路板、要燒錄的韌體,以及一個展示頁面。
核心理念
所有內容皆從單一檔案 project.json 以及 assets/parts/ 中的零件定義產生。你撰寫並編輯該檔案;腳本則從中推導出繪圖、檢查、外殼、電路板、腳位號碼和頁面。
這就是讓輸出結果值得信賴的原因。手繪的接線圖和手打的腳位表遲早會相互矛盾,而初學者無法判斷哪一個是錯的。因此:永遠不要手繪接線示意圖,永遠不要手動將 GPIO 編號輸入韌體,永遠不要引用零件檔案中沒有的尺寸。修改 project.json(或零件檔案)然後重新生成。
scripts/lib/types.ts 是結構定義(schema),每個欄位都有註解。
examples/luft/project.json 是一個完整的專案檔案(包含零件、連接、外殼、韌體和展示區塊);在撰寫你的第一個專案檔案之前,請先閱讀它。其韌體位於 examples/luft/firmware/(這是唯一需要手寫的部分,可作為 main.cpp 應如何撰寫的範例),但不包含其他生成的輸出:請在副本上執行腳本,以查看每個腳本產生什麼。
設定
腳本使用 bun 從本技能的目錄執行 TypeScript。核心功能(檢查、BOM、採購、指南、概念頁、登陸頁面、韌體框架)無相依套件。
| 步驟 | 需要 | 如果缺少 |
|---|---|---|
| 外殼、PCB | bun install --cwd scripts 一次 (JSCAD, tscircuit, 固定版本) | 腳本會印出命令並退出代碼 3。告訴使用者即將安裝的內容,然後執行它。 |
| 指南 PDF、螢幕截圖 | Chrome、Chromium 或 Edge | HTML 仍然有效;使用者可以從瀏覽器列印為 PDF。 |
| 編譯韌體 | PlatformIO (pio) | 框架仍會寫入;但會標註為「未編譯」。 |
| 3D 渲染 | Blender 需在 PATH 環境變數中 | render.ts 會輸出一行訊息並退出代碼 3;頁面會回退使用線繪圖和 3D 檢視器。 |
在使用者選擇的專案資料夾中工作(詢問一次;預設為 ./<slug>/)。所有指令都使用該資料夾:
bun <skill>/scripts/<name>.ts <projectDir>
流程
六個階段。每個階段結束時,使用者都能看到一些成果並做出決定。不要跳過決定直接執行:在第一階段做出錯誤的猜測會浪費之後的所有努力。如果使用者中途加入(「我有零件了,我需要一個外殼」),則從該階段開始,並建立所需的最小 project.json。
1. 構思
閱讀 references/imagine.md。了解這個東西是做什麼的、為誰而做、放在哪裡、如何供電,以及使用者的技能和工具。提供兩到三個真正不同的方向,而不是同一種盒子三種尺寸。一旦選定方向,撰寫第一個 project.json(僅零件和外殼區塊,尚無連接),然後執行:
bun scripts/concept.ts <projectDir> # out/concept.html: 閉合視圖、內部視圖、尺寸、成本
向使用者展示概念頁(開啟它,或使用 shoot.ts 截圖)。決定:這就是你要的東西嗎? 在這裡反覆迭代;這是改變主意最便宜的階段。
2. 零件與電路
閱讀 references/circuit.md。從 assets/parts/ 中挑選零件(列出該資料夾;每個檔案都有一個 blurb 簡介)。不在其中的零件,則放入 <projectDir>/parts/。其焊盤位置的來源決定了指南和外殼是否可信,因此在手動輸入電路板或模組之前,請先查閱零件目錄。該目錄的快照隨技能一起提供;無需設定:
bun scripts/catalog.ts find "<exact model>" # 這個電路板或模組在目錄中嗎?
bun scripts/catalog.ts pads <part_id> # 它是否包含來自製造商 CAD 檔案的焊盤位置?
bun scripts/catalog.ts import-part <part_id> --id <id> --out <projectDir>/parts/<id>.json
當 pads 列出一個資料集時,import-part 會寫入零件檔案草稿:包含來自製造商檔案的焊盤和外型、接地引腳,如果目錄中有,還包含 GPIO 編號、邏輯電平、高度和連接器開口。它會印出無法推導的資訊(電源引腳、價格,通常是高度);請從數據手冊中補齊這些資料。僅導入你將要購買的、相同製造商和版本的確切電路板:有品牌的電路板的焊盤位置對於具有相同晶片的仿冒品毫無參考價值。當目錄中沒有該零件的焊盤資料時,請根據數據手冊或製造商的圖紙撰寫檔案,遵循 references/circuit.md(「新增零件」)的說明。然後撰寫 connections 並進行檢查:
bun scripts/validate.ts <projectDir> # 電氣規則檢查,如果出錯則退出代碼 1
錯誤會阻止後續流程。每個發現會說明什麼錯了、為什麼重要以及如何修改;修正 project.json 並重新執行,直到沒有錯誤為止。警告則是需要判斷的情況:解決它們或用簡單的語言向使用者說明。切勿為了讓檢查通過而編輯零件檔案來隱藏發現,除非零件檔案確實有誤,並且在這樣做時要明確說明。當零件的實際耗電超過電源供應能力,且韌體會加以限制時,請在零件的條目中使用 peakMa 和 peakMaWhy 來聲明(請參閱參考文件),而不是隱藏它。
3. 採購與製造路徑
決定,需明確詢問:你想要一塊完成的 PCB,還是想要自己焊接? 用一句話解釋三條路徑,並為這個專案和這個人推薦一條:
build.path | 使用者要做什麼 | 適合情況 |
|---|---|---|
wire | 按照指南,在模組之間焊接(或壓接,joint: "dupont")導線 | 一次性專案、連接較少、希望本週完成 |
pcb-diy | 訂購一塊空的載板,將模組焊接到上面 | 需要多個單位、連接較多、希望整齊且穩固 |
pcb-assembled | 訂購已安裝插座的電路板,直接插入模組 | 沒有烙鐵,或是要送給沒有烙鐵的人的禮物 |
然後取得即時價格。首先閱讀 references/sourcing-stores.md;其中涵蓋哪些商店有 API、哪些需要在網路上搜尋,以及針對使用者所在國家的增值稅和關稅問題。
bun scripts/shopping.ts <projectDir> --region NO # out/shopping/index.html: 使用者會去購買的清單
bun scripts/source.ts <projectDir> # 每個零件的價格和庫存候選,來自具有 API 的商店
bun scripts/bom.ts <projectDir> # out/bom.csv, out/bom.md, 預估總金額
從 shopping.ts 開始。它不需要任何 API:對於每個零件,它會顯示圖紙、清單必須符合的規格(尺寸、引腳順序、供電範圍、高度),以及用於在該使用者所在地區(兩位數國家代碼;商店列表在 assets/stores.json)的零售商開啟正確搜尋的按鈕。僅該頁面就足以讓使用者進行購買,並且當你無法自行查詢價格時,這是一個合適的交接點。它絕不會下訂單。然後,在有辦法的情況下,進一步尋找真實的產品列表和價格:
捆綁的零件目錄(references/catalog.md)包含的是製造商的事實,而不是價格:find 和 show 會返回附有來源連結的尺寸和引腳資訊,用於撰寫零件檔案。一個完整的目錄(由 --db 或 BENCHTOP_CATALOG 指定)也包含商店列表:
bun scripts/catalog.ts listings "<part>" --norway。其數字是賣家和製造商的聲明,而非實際測量值。
預計 API 商店會遺漏通用的仿冒模組(大多數專案使用的廉價感測器和顯示板),並可能提供尺寸或引腳順序不同的品牌電路板作為替代。那不符合規格:請按照參考文件中指定的網路零售商進行搜尋,尋找零件檔案所描述的確切型號。
source.ts 收集候選項;由你選擇。偏好一兩家商店而非五家(小訂單的運費占主導地位),檢查每個列表是否與零件檔案是同一型號(仿冒品之間的引腳順序和尺寸不同),然後將你的選擇寫入 project.sourcing:每個零件一行,並在 note 中說明要選擇的型號,以及每個商店一個 shipping 條目(如果商店只在結帳時顯示運費,則省略其 price)。當一個列表涵蓋多個零件時(例如一個電阻包涵蓋三個電阻),給它一行,並在 covers 中指名其他參考編號。使用者說他們已經擁有的零件,在其 parts 條目中設置 "owned": true,而不是一個採購行:它仍會保留在指南和檢查中,成本為零,而購物頁面會告訴使用者要驗證他們抽屜裡的那個零件是否符合規格。重新執行 bom.ts;它會列印包含運費的實際總金額。在使用者訂購任何東西之前,向他們顯示這個數字。一個被報告為「不可用」的商店是其自身的問題,而不是停止的理由:繼續使用其他商店。
4. 製造檔案
生成所選路徑需要的檔案,然後在展示之前,仔細檢查每一個輸出。在迭代過程中,只執行你正在處理的那個腳本。在交接之前,至少完整執行一次整個流程,以確保沒有任何檔案過時或遺漏:
bun scripts/build.ts <projectDir> --region NO # 按順序執行每個步驟;如果電氣檢查失敗則停止
它會為每個步驟印出一行,將任何生成器標記的內容重複列在一個清單中,並寫入 out/build-report.md。它跳過的步驟會告訴你原因(缺少 Blender、尚無展示文案等)。它會編譯韌體:編譯錯誤會導致構建失敗,而晶片系列第一次編譯時會下載其工具鏈(約 1 GB,需幾分鐘),這是預期行為。報告顯示 NOT COMPILED 表示韌體未經檢查;在交接時要說明這一點。個別腳本如下:
bun scripts/guide.ts <projectDir> --pdf # out/guide/index.html + guide.pdf
bun scripts/enclosure.ts <projectDir> # out/enclosure/: body.stl, lid.stl, .3mf, assembly.glb, print.md
bun scripts/pcb.ts <projectDir> # 僅 PCB 路徑。pcb/board.tsx + out/pcb/: gerbers.zip, schematic.svg, pcb.png, order.md
bun scripts/firmware.ts <projectDir> # firmware/: platformio.ini, include/pins.h, 啟動測試, main.cpp 框架
bun scripts/compile.ts <projectDir> # 使用 PlatformIO 編譯啟動測試和 main;錯誤訊息格式為 file:line
bun scripts/render.ts <projectDir> # out/renders/: hero.png, hero-alpha.png, exploded.png, top.png (需要 Blender)
bun scripts/drawing.ts <projectDir> # out/drawings/: 接線圖、附尺寸的外殼圖、腳位圖、1:1 貼合檢查頁
bun scripts/shoot.ts <projectDir>/out/guide/index.html <projectDir>/out/shots --pages 1,3,4 --width 900
在執行每個步驟之前,閱讀其參考文件:references/guide.md、references/enclosure.md、references/pcb.md、references/firmware.md、references/renders.md、references/drawings.md。每個文件都說明了當結果不正確時應該檢查什麼以及應該修改 project.json 中的什麼。然後將實際的韌體行為寫入 firmware/src/main.cpp,僅使用 pins.h 中的常數。
外殼和 PCB 腳本會印出警告(一個通風口被另一個零件擋住、一個埠未到達外殼壁、一個導線安裝的零件被遺漏在電路板上)。這些是設計問題,而不是雜訊。修正佈局,或告訴使用者後果是什麼。
guide.ts 和 drawing.ts 會在每次構建時檢查自身的繪圖,並為每個問題印出一行:一條導線終止於被更高零件遮擋的焊盤、一個引腳名稱沒有清晰的放置位置、在分解視圖中零件重疊、在接線圖中導線穿過另一個零件。每一行都會標明頁面、步驟和零件名稱。佈局問題可以透過 bench 修正;渲染器的問題屬於生成器;無法解決的幾何問題需要修改來源資料。不要為了讓渲染器的檢查通過而修改正確的零件幾何形狀。一個標記為 geometryEvidence.status: "unresolved"(其佈局與證據矛盾;目前是 INMP441 麥克風)的零件仍然可以構建:外殼、圖紙、指南和包裝都是根據檔案中的數字製作的,每次構建會輸出一次 warning:,並且每個受影響的輸出都會帶有「LAYOUT NOT VERIFIED」的標記。在交接時首先重複該警告,告訴使用者在列印前測量該零件並在專案的 parts/ 資料夾中修正它,並且永遠不要將此類外殼呈現為可列印狀態。貼合測試列印是最終關卡。--strict-geometry(或 BENCHTOP_STRICT_GEOMETRY=1)會將警告變回拒絕,並提供部分邏輯指南;載板在任何模式下都會被拒絕,因為電路板需要花錢且沒有便宜的貼合測試。--strict 在存在任何繪圖問題時都會以非零退出。通過檢查意味著受測試的繪圖不變性(invariants)成立,並不表示零件檔案是正確的。
5. 展示
閱讀 references/showcase.md。撰寫 showcase 區塊(標題、運作方式、特色、數據、常見問題、主題),然後:
bun scripts/package.ts <projectDir> # dist/<slug>/ (index.html, guide/, files/) + dist/<slug>.zip
bun scripts/shoot.ts <projectDir>/dist/<slug>/index.html <projectDir>/out/shots --width 1320 --height 2400
仔細檢查頁面的所有部分:--from 2400 會從 2400 像素處開始擷取視窗。文案是你的責任,這是產品頁面與僅填入名詞的模板的區別所在;參考文件說明了如何撰寫文案以及如何選擇主題。頁面上的價格來自 project.sourcing,前提是每個零件都有對應的採購行。以與專案不同貨幣購買的採購行會帶有自己的 currency;總額會按貨幣分別顯示(「401 NOK + 7.95 USD」),絕不進行換算。如果沒有採購資訊,頁面會說明該數字是基於典型價格的估算。
package.ts 每次都會從 project.json 重新構建指南,因此絕對不要手動修正生成的檔案:該修正將在下一次執行時遺失,並且檔案之間的差異會持續存在,直到手動修正。如果生成器有誤,請修改其輸入,如果無法透過該方式修正,請在輸出中告訴使用者什麼是錯的,而不是默默修補。
6. 交接
簡要告訴使用者:套件的位置在哪裡、總成本是多少、首先要做什麼,以及哪些部分尚未經過驗證。要具體說明。請參閱「此處的精度含義」。
此處的精度含義
在將仿冒零件用於外殼或載板之前,請閱讀 references/geometry-evidence.md。檢查 assets/geometry-evidenc
…(截斷)