2026/05/21

ESP32-C3 與 MPU6050 的進階開發

 


引言 (Introduction)

在嵌入式開發與 Maker 的世界裡,微機電感測器(MEMS)的讀取通常是踏入硬體互動的第一步。然而,當我們試圖在底層硬體(ESP32-C3 SuperMini)上,將生硬的 MPU6050 角度數據轉化為流暢、具備擬真物理互動的 OLED 遊戲或模擬時,往往會踩入一連串教科書上沒寫的「硬體與演算法地雷」。

本篇文章將完整記錄如何從開機死鎖(Hang)的黑畫面一步步排查,導入精確的感測器融合(Sensor Fusion)與全零點校正,並最終在記憶體受限的單晶片上,徒手刻出一個支援 30 顆方塊實時碰撞、相互依靠堆疊的輕量級物理引擎。

第一章:幽靈的開機死鎖——解密 ESP32-C3 的 Strapping Pins 陷阱

很多初學者在將 MPU6050 連接上 ESP32-C3 SuperMini 並使用預設的 I2C 腳位(SDA=8, SCL=9)後,會遇到一個極其詭異的現象:程式燒錄成功(Upload OK),但序列埠監視器(Serial Monitor)永遠只印出第一行引導碼:

Plaintext
ESP-ROM:esp32c3-api1-20210207

隨後整個系統陷入無限期的死鎖,連 setup() 裡最頂端的 Serial.println() 都來不及執行。

核心原因分析:

問題不在軟體,而在硬體的「開機配置腳(Strapping Pins)」。ESP32-C3 晶片在硬體重置(Reset)的瞬間,會去偵測 GPIO 8 與 GPIO 9 的電位狀態,以決定晶片是要進入「SPI Boot 正常開機」還是「ROM Boot 燒錄模式」。

當 MPU6050 模組上的 4.7kΩ I2C 上拉電阻(Pull-up Resistors)直接把 GPIO 8 的電位拉高或拉低到異常狀態時,晶片在開機瞬間就會誤判啟動模式,進而硬體級鎖死。

工程解決方案:

徹底避開衝突腳位,在軟體中手動重新映射通訊軌道。我們將 I2C 匯流排改至安全且完全不影響開機配置的 GPIO 4 (SDA)GPIO 5 (SCL)

C++
Wire.begin(4, 5); // 徹底避開 GPIO 8 開機地雷
Wire.setTimeOut(50); // 設置硬體超時防線

透過更換安全引腳與加入 setTimeOut 超時防線,即便硬體通訊中斷,底層函式庫也不會再讓 CPU 無限期死等硬體回應。

第二章:桌上的「鬧鬼」滑行——全感測器零點深度校正

當 I2C 通訊順利暢通後,我們嘗試在 OLED 上繪製一個基準框,並讓小球隨角度滑動。此時第二個經典盲點浮現:將板子平放在絕對靜止的桌面上,小球卻在幾秒鐘內自己緩緩「滑出平台」撞牆。

為什麼單純校正陀螺儀(Gyro)是不夠的?

一般的範例程式只會在開機時對陀螺儀進行取樣取平均,以扣除角速度的漂移(Drift)。然而,放在桌上靜止時,加速度計(Accelerometer)本身也帶有硬體偏置误差(Offset)

受限於晶片封裝、洞洞板表面的銲接傾角、或是桌面本身的微小傾斜,加速度計讀到的 $X, Y$ 軸絕對不會是完美的 0.0。由於互補濾波器(Sensor Fusion)會不斷參考加速度計的絕對角度,這 $\pm 2^\circ \sim 3^\circ$ 的微小硬體誤差會被誤判為持續的傾斜,導致小球產生「自動滑行」的靈異現象。

深度水平校正演算法:

我們必須在開機時執行取樣(例如 200 次),不僅記錄陀螺儀偏置,更要把當前桌面狀態下的加速度計絕對三角角度(Roll/Pitch)直接記錄下來,並在 loop 運算中扎實地扣除它:

C++
// 減去開機時的桌面偏置,將當前狀態定義為「絕對 0 度基準」
float accRoll  = rawAccRoll - errorAccRoll;
float accPitch = rawAccPitch - errorAccPitch;

這樣一來,不論銲接再怎麼歪、桌面再怎麼斜,只要放在桌上不動,數值就會死死咬在 0 度,水晶球便能滑順地定格在正中央。

第三章:從冰面滑行到重力暴衝——非線性物理與 LERP 緩動

為了提升視覺的擬真度與互動的爽快感,系統的滾動速度不能是死板的線性移動,必須引入真正的加速度(Acceleration)與慣性阻尼(Friction)

  1. 重力加速度累積:傾斜角度(Roll/Pitch)作為力(Force)施加在物體上,速度隨時間持續累積($V = V + a$)。手腕傾斜角度越大,施加的加速度越高,物體會呈現指數級的暴衝感。

  2. LERP (線性插值) 濾波緩動:為了消除未過濾的手震雜訊,我們不讓方塊直接瞬移到目標物理座標,而是利用緩動公式:

    $$\text{Current Position} += (\text{Target Position} - \text{Current Position}) \times \text{Factor}$$

    這讓物體在畫面上移動時,產生了一種如同在冰面上滑行的油潤液壓感與重力慣性。

第四章:極限壓榨效能——30 顆粒子實時碰撞堆疊引擎

專案的終極挑戰,是在單晶片上實施群體粒子模擬:在 OLED 畫面上繪製最大邊界框,生成 30 個 $4 \times 4$ 像素的獨立小方塊,當它們受到重力滑向特定牆角時,必須互相堆疊依靠、自然緊密排列,且彼此絕不產生重疊或穿透。

幽靈隱形牆的 Debug 經驗:

在初期測試中,主迴圈明明只命令 U8g2 繪製 30 個方塊,但當方塊滑落到底部時,卻會在距離底壁還有 10 像素的地方「憑空卡住」,死死地排成一列,彷彿撞上了隱形牆。

經查,元凶在於交叉碰撞檢查(Axis-Aligned Bounding Box, AABB)的內部迴圈上限被硬編碼寫死了常數:

C++
for (int j = 0; j < 30; j++) { ... } // ❌ 越界讀取地雷

當這個常數與實際陣列大小產生偏差時,C++ 在執行碰撞判定時,會讀取到陣列邊界之外的未初始化記憶體垃圾數據(Uninitialized Memory)。這些垃圾數據在物理邏輯上被誤判為「已經死死躺在底部的方塊」,導致真實的 30 個方塊在移動時,提前撞上了這些看不到的記憶體幽靈。

工業級物理引擎解法:

  1. 內存徹底清空:開機時使用 memset(boxes, 0, sizeof(boxes)); 徹底洗淨陣列,抹除一切硬體隨機殘留值。

  2. 多重鬆弛迭代(Relaxation Iterations):當多個方塊在牆角同時擠壓時,方塊 A 撞 B、B 又同時撞牆。我們在單次 loop 內加入 3 次迭代解算(Sweep),在極短的時間差 $dt$ 內反覆修正重疊座標,讓 30 顆方塊能夠展現出如同沙子般完美、扎實的依靠堆疊視覺特效。

C++
// 核心多重鬆弛迭代碰撞檢查結構
for (int k = 0; k < 3; k++) { 
  for (int i = 0; i < NUM_BOXES; i++) {
    // 預計移動的新座標計算與 AABB 矩形碰撞判定...
    // 發生重疊時,精確倒推邊緣座標並將該軸向速度(vx/vy)安全歸零
  }
}

結語 (Conclusion)

透過這一連串的硬體引腳更換、雙重零點校正、LERP 緩動機制,以及修正越界內存的碰撞演算法,原本生硬跳動的感測器訊號,在 ESP32-C3 上成功被賦予了真實的動態生命力。

完整的粒子堆疊物理引擎代碼已開源(詳見上文),不論你是想為你的機器人專案加入更滑順的角度追蹤,還是想在小螢幕上實作精緻的街機互動,這套整合了 Sytem Architecture (SA) 穩定防禦UI/UX 視覺美學 的底層框架,都能為你的下一個 Maker 作品打下最扎實的技術基石!

2026/05/20

🚀 AI Studio 新功能登場 - 創建 Android 應用!

 🚀 AI Studio 新功能登場!

現在你可以直接在 AI Studio 建立 Android 應用程式原型,透過 USB 連接手機,一鍵安裝,立刻在手機上預覽! 從原型到實機,只要幾秒鐘,開發流程更快、更直覺。



使用情況和成本
與他人分享應用程式時,API 呼叫次數會計入您的使用限額。如果您使用付費模式,則可能會產生費用。如果您的應用程式可能產生費用,我們會在設定過程中以及您共享應用程式之前提前告知您。


#AIStudio #Android開發 #應用程式原型 #USB安裝 #即時預覽 #程式生活 #開發者工具 #Maker社群 #技術分享 #工程師日常



2026/05/12

我的第一片 PCB 冒險 - Day 3 請教專家來幫忙

這幾天花不少時間, 把電路全部都在看一次, 確定接線都有正確連到, 
也請教幾位有實戰經驗的專家, 聽從他們的建議, 如 5V 的正確位置, 接線, 接地散熱, 再接上紅綠LED電源充電指示...

那麼就送洗吧...一週後就知道會不會動了... 😅


TP4056 很容易發熱, 聽取專家建議
Pin9 GND 大量的鋪銅, 可以幫 TP4056 散熱


ezsyEDA Pro 無法直接鋪,還是我不會操作?
聽取以前專家建議, 把 GND 全部加粗

加上 Via 過孔把熱由正面傳到背面, 把熱源散到背面


依照 TP4056 基本電路設計, 加上了紅綠 SMD LED, 
將來可以知道電池充電狀態

充電中-紅燈
充完結束-綠燈
電壓不對, 溫度太高太低, 無電池, 不亮燈


2026/05/09

我的第一片 PCB 冒險 - Day 2 - PCBA 不會動 ~~

EasyEDA Pro - DRC check 都過了, Auto routing 也完成...
我就膽大心粗的送洗~~😅

等了幾天, JLCPCB 板子也洗好, 送到了....結果~ 不會動就是不會動~ 🥲

尺寸大小都是我想要的, 間隔距離也都剛好...但拉線錯一大堆~~🙂

仔細瞧瞧...

On/Off Switch 上居然沒有接線, 原來 PCB 上標註了 $1N14616, $1N14616 這樣的符號要特別注意...它可能就是原理圖上的線沒有接好....

Day 2 的冒險讓我深刻體會到:

  • DRC ≠ ERC,製造規則檢查不代表邏輯正確。

  • Netlabel 名稱一致性非常重要,哪怕是一個小小的 + 都可能造成斷線。

  • 社群的力量不可或缺,很多錯誤自己看不出來,卻能靠朋友的提醒避免大災難。

雖然一路踩坑,但每解決一個問題就更有成就感。這些錯誤與修正過程,正是 PCB 學習最寶貴的經驗。

打開 PCB Layout,竟然看到 On/Off 開關完全沒有接線! 這代表原理圖裡的連線沒有真正拉好,EasyEDA 就會生成 $1N14616 這樣的臨時符號。看起來像有線,其實是孤立的網路。 😣

這顆 C6 電容也沒有接線😣

更慘的是,原理圖裡的 GND Netlabel 不見了,結果 PCB 上就變成 $1N10953。🥲 解法很簡單:刪掉錯誤的線,重新加上正確的 GND Netlabel,馬上就恢復正常。




檢查 SS14 二極體的 VBAT_SW,發現線長顯示 0mm,代表完全沒有接線。😣 這提醒我:除了看 Ratsnest,也要用 Net Length 來驗證線路是否真的存在。


原來原理圖裡有 VBAT_SW+VBAT_SW 兩個不同字串,結果 PCB 上就連不起來。 更糟的是,移動文字時 EasyEDA 有時會自動加上 +,必須小心檢查。最後我刪掉錯誤的 Netlabel,重新放置正確的 VBAT_SW,線路才全部回來。😅



把原理圖裡的 + 移掉之後, PCB 上的線都連回來了~ 😅



最驚險的錯誤是 H5/H6 的 female header 居然左右相反!🥲 這個問題完全是我自己看不出來,還好有網友呂大哥幫忙指出,否則打樣出來就會變成「反插」災難。

接下加入分壓電路, 可以較準確計算電量剩下量...把 5V 的線變的短, 減少短路機會...
好多坑啊~~

待續...😣


2026/05/03

Vercel 無法正常與 GitHub 連結的解決方法

前一陣子, Vercel 突然連不到 GitHub 造成幾位同學無法把 Repo 丟回到 GitHub, 
無法自的的 CI/CD 真的很麻煩. 
沒想到, 我今晚也碰上了...花了一些時間找了 Reddit 論壇幾編文章, 終於解決掉這問題了.


  1. In Vercel網站, 點選 setting -> Account setting -> Authentication (也可以用搜尋的, 比較快)
  2. 找到 GitHub 換下右邊 3 個點
  3. 選取 Re-Authenticate
  4. 右下角會看到 Login Connection added.(下圖)

  5. 回到 Vercel -> Import project 
  6. 重新連結成功, 已經可以正常的由 Vercel 連回到 GitHub 






2026/05/02

我的第一片 PCB 冒險 - Day 1

 原理圖的魔法與 PCB, 差很多~


我使用 EasyEDA Pro 網頁版來畫電路板, 它看起來很簡單,直到開始才發現...Gemini AI 跟你說的名詞, 或是選單位置...有時, 找不到就是找不到啊...

今天是我挑戰 PCB 自製初體驗的第一天! 目標是打造一個「智慧喝水提醒器裝置」。剛開始在 Gemini AI 的幫忙下,一個一個原件放到原理圖(Schematic)自己覺得還蠻順利的...😊。
看著那些 NodeMCU、MPU-6050 陀螺儀和 OLED 螢幕的邏輯連線井然有序,我心裡還偷笑....😏

然而,當我滿懷自信地按下「轉 PCB」的那一刻,哈哈哈…怎麼亂成一團?! 😅 螢幕上出現的不是想像中精美的電路板,而是散落一地的零件,還有無數糾結在一起、像亂掉的毛線球一樣的藍色飛線 (Ratsnest)!

原理圖畫好後, 零件會灑落一地


課後筆記:

  1. 原理圖 ≠ 實體空間:原理圖只管 "誰連誰"(邏輯),但 PCB 是真實的 "排位賽" 。你要考慮零件的大小、正反面,還要預留放電池的空間。
  2. 電源線不能太細:AI 提醒,ESP8266(對的, 我在 ESP8266上做的實驗. 在發射訊號時會有瞬間脈衝大電流,所以電源走線(3.3V/GND)要設定到 20-25 mil 以上才安全,不能像普通訊號線一樣細。
在 Design rules 裡新增一條 Power line, 這裡設成 0.65mm 已後 auto-routing (自動拉線時), 指定 5V, 3.3V, VBAT...等等, 相關的線路就是會用到 0.65mm, 真方便!

雖然第一步就卡在 - 找不到板框邊界(Board OutLine)」,還差點把鋪銅當成邊界!,但搞懂這些邏輯後,對這片板子更有感情了! 😅 歡迎在下方留言拉我一把,或分享你當年的「初次佈線慘劇」!

Gemini 設計提示:

將整個專案整合進一片 PCB (印刷電路板) 是將實驗原型轉化為專業產品的關鍵步驟。使用 JLCPCB 旗下的 EasyEDA (嘉立創 EDA) 工具,我們可以依照以下四個核心階段來完成設計。

身為資深工程師,我會引領你完成這項「一體化電路」的佈局:


第一階段:電路原理圖 (Schematic) 繪製

在 PCB 佈線前,必須先在 EasyEDA 中建立正確的邏輯連接。

  1. 核心模組化佈局

    • NodeMCU 插座:使用兩個 1x15 排母 (Female Header),讓 NodeMCU 可以插拔,方便教學。

    • I2C 總線匯流:將 NodeMCU 的 D1 (SCL)D2 (SDA) 線路拉出,並聯至 OLEDMPU-6050 的對應腳位

    • 中斷喚醒線路:預留一條走線將 MPU-6050 的 INT 腳位連接到 NodeMCU 的 RST 。建議中間加一個 0Ω 跳線電阻 或排針,方便切換是否使用 WoM 喚醒模式。

  2. 旗艦級電源管理 (Power Management)

    • 充電區:配置 TP4056 充電電路,輸入端接 USB-C 母座,輸出端接 700mAh 鋰電池

    • 穩壓區:使用 HT7333-A (SOT-89 封裝) 作為核心。將電池正極接至 HT7333 輸入,HT7333 輸出接至 NodeMCU 的 3V3 腳位 (繞過板載 AMS1117 以省電)

    • 濾波電容:在 HT7333 的輸入與輸出端各並聯一個 10uF 陶瓷電容。並在電源輸入端並聯一個 220uF 以上的電解電容,以緩衝 ESP8266 啟動時的脈衝電流


第二階段:PCB 佈局 (Layout) 策略

佈局決定了產品的實用性。考慮到這是一個水壺掛件,建議採用長條形設計:

  1. 分層與空間分配

    • 正面 (Top Side):放置 SSD1306 OLED。將螢幕放在 PCB 的最頂端或正中央。

    • 背面 (Bottom Side):放置 700mAh 鋰電池。可以使用電池背膠固定在 PCB 背面無零件處。

    • 內嵌式 MPU-6050:MPU-6050 必須固定得非常穩固。建議將其放置在 PCB 的幾何中心,減少因電路板形變導致的數值偏差。

  2. 操作介面優化

    • FLASH 按鈕:雖然 NodeMCU 自帶按鈕,但在 PCB 上加焊一個較大的側面輕觸按鈕(並聯至 GPIO 0),會讓使用者在切換顯示模式時更好操作


第三階段:佈線 (Routing) 與工程細節

  1. 電源走線 (Power Traces):電源線(3.3V 與 GND)必須夠寬(建議 20-25 mil),因為 ESP8266 發射訊號時會有大電流突發

  2. 訊號線:I2C 訊號線使用標準 8-10 mil 即可。保持 SDA 與 SCL 平行且盡量縮短長度

  3. 鋪銅 (Copper Pour):在 PCB 頂層與底層進行大面積 GND 鋪銅,有助於散熱與減少雜訊干擾。

待續👋

2026/04/26

Google AI Studio 新功能:Design Preview 初體驗

 過去在使用 Google AI Studio 生成介面時,大家應該都有相同的感覺——色調幾乎固定,變化不大。雖然功能性沒問題,但在設計呈現上總覺得少了一點自由度。


就在今天,我在實作一個 App 的過程中,意外發現 Google AI Studio 推出了 「Design Preview」 功能。這個新選項讓使用者在生成介面之前,可以先挑選一個樣式。雖然目前只有五種預設風格,但至少能讓介面不再千篇一律,算是邁出了一小步。


對於開發者來說,這樣的功能有兩個好處:

  • 快速測試不同風格:不用再手動去調整 CSS 或配色,直接在生成階段就能看到差異。
  • 降低設計門檻:即使沒有設計背景,也能透過預設樣式讓介面看起來更有特色。


不過,五種樣式畢竟有限。如果你希望更進一步探索色彩與風格的可能性,我推薦大家試試我自己開發的 「Stonez56 色彩探索家 Web App」。這個工具提供 25 種色彩方案,可以自由調整、套用,讓你的介面設計更靈活、更有創意。

App 網址: https://56theme.vercel.app/
影片說明網址: https://youtu.be/bTK76SJbJk8

Google AI Studio 的 Design Preview 功能,算是官方在設計自由度上的一個起點;而透過外部工具的補充,開發者就能把這個起點延伸成更廣闊的設計空間。