ESP32初體驗
前一陣子讀了黑暗執行緒關於使用ESP32做了辦公室抒壓小物的文章(https://blog.darkthread.net/blog/diamond-sutra-reader/)後,才發現目前竟然有這麼廉價的IoT解決方案,不到新台幣二百元,就能擁有一片體積迷你、又支援WiFi4和Bluetooth 4.0的小板子,常見的GPIO、SPI等介面也都具備,想接個sensor互動、接片LCD顯示文字和圖片都不成問題。對我而言,算是補了Arduino和Raspberry Pi功能之間的空缺帶,個人覺得CP值大勝Arduino。
在購物網站逛了老半天,最後選了ESP-WROOM-32開發板,售價$195元,就能有Wi-Fi 2.4GHz和藍牙4.0連網能力,感覺吊打Arduino啊!(至少對我的需求而言是如此)
運氣不錯,在農曆年節前送到了(賣家早早就出貨,但無奈應該是年節前貨運爆倉的關係,硬是拖了一個禮拜才到門市),剛好可以趁連假有空來玩一玩。這次除了訂購ESP32板子本體外,也訂購了2個顯示器:SSD1306和ST7735,讓板子有UI輸出,作品也才更有趣嘛!最後借了LINE貼圖,搞了個電子賀卡。
ST7735顯示器彩度僅有16 bits,也就是R5G6B5格式(紅5 bits、綠6 bits、藍5 bits),所以我先用繪圖軟體將圖片調整成符合顯示器解析度的大小128×160,並且儲存成.bmp格式。接著自己用C#寫了一個小程式,將這個.bmp檔讀取出來,再把每個pixel的色彩值輸出成一個二維的uint16_t陣列:
uint16_t img1[160][128] = { { 65535, 65535, /* ... */ 65535 }, { 65535, 65535, /* ... */ 65535 }, /* ... * / };
並且把這個陣列hardcode在程式碼中。接著利用繪圖函式庫,把每個pixel畫在畫面上。
試了一張圖片發現可行後,便準備了四張圖片,打算讓這四張圖片輪播,弄得像個電子相框一樣,當成春節電子賀卡。 結果把每一張圖片的陣列都貼上去後,編譯時發現似乎超過資料節區的長度,導致編譯失敗,於是最後縮減到剩二張圖片,然後趁著大年初一還沒過完,趕緊拍個影片發到LINE群組去。🤣
為了解決上述hardcode圖片陣列的空間不足問題,我想了一個新的解法:利用ESP32和電腦連接時建立的序列埠(COM)來傳資料!
於是我將原本產生陣列的C#程式改寫,改成對COM port寫入資料,資料格式是:
byte[] datastream = { HEIGHT, // 圖片高 WIDTH, // 圖片寬 255, // pixel (0, 0) 的高位元組 255, // pixel (0, 0) 的低位元組 255, // pixel (1, 0) 的高位元組 255, // pixel (1, 0) 的低位元組 /* ... */ };
當然在ESP32這一端的程式也改成去讀取COM port過來的資料,並繪製在畫面上……。一切看起來都那麼地簡單,那麼地順利,俗話說的好:沒有意外的話,就要出意外了。
接下來就是漫長的debug時光……。
遇到的問題有好幾項,扣除比較腦殘的問題,主要就是COM port在寫入資料會有掉包的問題發生,電腦端這頭其實都寫完了,但ESP32端只畫出一小塊,而且可能色彩也怪怪的,但是PC端程式只要每寫入一段就sleep一下的話,整個流程就很順暢,圖片也可正常繪出。想了幾天後,發現可能是ESP32端程式寫法問題,我是每讀取2 bytes(也就是1個pixel),就繪一個點,但繪圖花費的I/O時間可能較長,可能會導致buffer滿了或爆掉,而且我原本的COM port讀寫邏輯兩端也沒有一個交握調控機制,也許是這個問題導致的,之後有空再來研究吧~