WebStick – 基於 ESP8266 的網頁伺服器棒棒
Toby
Toby

自從我看了 ESP8266 的 SD Web Server Youtube 教學之後,我一直都很想要自己做一個來玩玩看。你想想看,有一根可以隨身攜帶(?)、足夠便宜到可以送人而且能夠把虛擬的東西(網站)實體化,不是一件很有趣的事情嗎?

可是之前一直都沒有時間研究這個東西,其中一個原因是以前的焊接技術還沒足夠讓我可以直的完成這個 project,另外就是因為那個時候我對燒錄器設計還是沒有甚麼概念,導致到當我要做到跟一片 Wemos D1 mini 同等效能的 ESP8266 的時候,完全沒辦法好好的設計和焊接成成品出來。

開坑

早在 2018 年,我就已經買來了一片 Wemos D1 mini 跟超級難買的 SD shield 來當小型網頁伺服器。當時的我對網頁編程和嵌入式開發還是非常的入門,結果做出來的東西就是長這樣

Wemos D1 + SD Shield + 小容量 SD 卡

雖然是能用,而且我也把它用 USB 供電吊在我的桌面旁邊當作實驗品開發了一段時間,但是由於用的是別人的 code 加上當時我並不是太熟悉 Arduino C++ (和當時還沒有 ChatGPT),導致最後開發出來的東西不但不好看而且很難用

設計嘗試,失敗收場

之後一年我試著把這個設計弄成一片真正的電路板。由於當時我還沒有開發燒錄器的能力(特別是要想辦燒焊那兩個超小的 BC817 transistor),因此我的想法是先把 ESP8266 焊到板子上,再透過現成的燒錄器對它進行開發(見下面那一排燒錄用排針),然而後來我弄著弄著就覺得不對勁,而且這種每次都要插燒錄器才能寫東西的系統感覺開發起來就很麻煩,應該不會有人想用,所以最後還是沒拿來生產。

第一代的 ESP8266 網頁伺服器,最後沒做生產真是一個明智的決定

5 年之後,我終於做出了 WebStick 原型機

WebStick 這東西其實在我腦海中已經卡住很多年了。但是一直就軟硬體技術原因無法開坑。直到最近開始學會了 drag soldering 跟找到了一款可以讓我進行超精密焊接(但是缺點是一次性)的烙鐵頭後,我終於把這個封塵多年的 project 重新抓出來做。

首先:燒錄器

網上有很多不同的設計,有自動的也有半自動(燒錄的時候要按 FLASH 按鈕)。半自動的能省下兩顆 transistor 跟兩顆電阻,但是由於編程的時候每次都要按 FLASH 和 RESET 有夠麻煩,所以我在設計的時候便選擇了自動燒錄器。以下是我參考的設計圖:

燒錄器設計圖

但是這設計圖差了點東西,就是圖裡沒有標注到 GPIO15 應該要 PULL LOW。在設計電路板的時候記得把 GPIO15 經電阻(如 10k)接地,這樣 SPI CS 才能正常使用。

為甚麼我會知道? 這真是個他媽的好問題(被坑)
這顆電阻雖然不加也可以,但是會無法使用 SPI

另外這兩顆 BC817 的 routing 也弄得我懷疑人生,不過後來還是在板上 route 好了。

我都不知道自己當晚是怎樣發神經想到可以這樣 route 的,嘛總之能動就好了。

其次:SD 卡

ESP8266 有內置的 SPI 針腳可以用來讀取 SD 卡。很多人以為 SD 卡模組上面有特別 IC 去把 SD 卡轉換成 ESP8266 可以讀取的信號,然而實際上的讀取方法聽上去有點奇妙,就是直接把 SD 卡當成 SPI Slave Device 來讀取。

那你會好奇,如果 SD 卡可以直接接 ESP8266,那外面在賣的 SD 卡模組上面那顆 IC 是幹甚麼用的?這是個好問題,那是防呆用的(不對)

你看,不是所有 MCU 都是在用 3.3V Logic Level 的說。例如說 Arduino UNO 在用的 Atmega328 就是支援 3.3v – 5v 輸入。SD 卡只能用 3.3V 讀取,過高的通訊電壓會把它弄壞,因此很多模組為了相容更多的開發板,只好加上一顆用來轉換信號線電壓的 IC,通稱 LLC (Logic Level Converter ,大陸好像叫 「電平轉換器」)。但是由於我在用的 ESP12E 只支援 3.3V,所以剛好與 SD 卡需要的電壓一樣,所以就不用轉直接接 MCU 就好啦。

不說不知道,如果你走去翻 Wemos D1 SD shield 的設計電路圖,它基本上就只有一個 SD 卡插槽,跟一顆差不多看不見大小的電容來做 ripple filter。真的有夠簡單欸

把兩個東西整合理起

當兩個電路都有了,剩下的部分就是把電路給整合到同一片板子上。我本來是打算用名片大小的設計,這樣做不但能有一種「這是送你的見面禮」感覺,而且也有更多的空間來寫使用教學,有點像國外嵌入式工程師大神做的能跑 Linux 的名片一樣

國外工程師做的,能跑 Linux 的名片

它的設計是角落的部分有一個以 PCB 做的 USB A 接頭,然而問題在於 USB A 接口的 4 針電路板厚度最低要求是 2mm,一般 PCB 只能做 1mm – 1.6mm,再往上(或下)就會變得特別貴,所以外國大神的做法是用一片 1mm 板,然後用回流焊把它疊上去做成兩層 1mm = 2mm 的 USB 插頭。

他會使用這種方法是滿合理的,畢竟他那片 QFN 的 CPU 也要用到回流焊,那多焊一片東西也沒差,相反我這邊全部都是烙鐵能焊的 SOP 針腳,沒理由要特別為這個頭多回流一次,所以我就採用更為傳統的方法:在 BOM list 中加上一個 USB A 公頭(

這是最終版本設計(印刷中、正面)
最終版本(背面)

嘛不過這個最終成品我還沒拿到手,手上的是另一個測試用的版本

正面,全長大約 7cm
背面,除了走線外沒甚麼東西

這樣插上電腦的話便會進入 Serial Mode / Flash Mode (由 Arduino IDE 跟 esptool.py 切換)如果插上手機充電器就變成一個 2W 的小型網頁伺服器。

17-08-2023 更新

後來這是完成後的 WebStick 原型機

網頁系統開發

網頁一般開發就是前端 + 後端,前端的部分就是基本的 HTML CSS 跟 JS 沒甚麼特別的。只要把前端資料放進 SD 卡的 www 資料夾裡,ESP12 裡面的 firmware 就會把裡面的檔案 以 HTTP 伺服器 serve 出去。簡單來說就像 Apache 新裝好的邏輯一樣。

但是後端這真的是一個大坑,從 HTTP listener 到 Router、Permission Management 跟 Cookie / Login 系統,寫了我快 50KB 的 code(還沒加上 library)

因為 code 講出來沒有人會有興趣,簡單來說後端提供的功能包括

  • HTTP Static File Server (把 SD 卡的檔案 serve 出去)
  • Directory Listing (沒 index 的情況下把資料夾內容以 HTML 列出)
  • mDNS Transponder (可以用 webstick.local 來連接)
  • User Authentication / Cookie (使用 Cookie based login 方案,而非在網上常見的 basic auth)
  • File System API (可以直接上傳檔案到 SD 卡 及進行基本檔案操作)
  • System Info API (可以查看 SD 卡剩下容量、WiFi 連接狀態和資訊等等)

所以這邊我就放一些截圖

基本的 HTM 頁面
Directory Listing 功能
登入界面,使用 Cookie based 登入方案

然後下面是一些要登入才能用的機能

精簡版本的 ArozOS 檔案管理員
簡單的 Markdown / Text Editor
比 Google 慢超多的檔案搜尋功能
SD 卡和 WiFi 連接狀態
音樂播放器
影片播放器(雖然只能夠放 webm 這類為 web streaming 設計的格式)
圖片瀏覽器
多分頁的簡易編程界面(基於 Ace Editor)

嘛,說到這裡,你可能會覺得這也太好了吧?差不多等於我用 25 港幣做了一個 NAS 啊?不過這東西也有好幾個超明顯的決點

  • 一次只能有一個登入狀態(因為 runtime memory 有限,沒辦法放這麼多 cookie / session key)
  • 網速很慢(2 – 4 mbps),大概只能放文字檔、小型經壓縮的多媒體檔案(如 < 5MB 的 mp3、webm 或 jpg)
  • 無法以 AP 模式運作:很多資源都需要依賴 cdn 才讓系統達到能用的載入速度,在使用 cdn 的前提下就無法以 AP / offline 模式使用了。

但是作為一台 poor-man NAS 來說,放個簡單的 htm 檔案(對,不是 html 因為要相容舊的 FAT 檔案命名格式),簡單介紹自己和一些連接到其他 social network platform 的 hyperlink 之類的,間中當成遠端寫筆記的小工具或是放一下自己最喜歡的 mp3 之類的,也是滿夠用的啦(