imuslab
托比的實驗記錄部落格
在不更改電路板 BOM 表下把 Macropad 變成 Numpad
話說幾個月之前,我設計並開源了一個四鍵的 macropad (快速鍵鍵盤)方案。電路板上使用 WCH 制的 CH552G 晶片,配合機械鍵與幾顆電阻電容就做成了一個超簡易的四鍵機械 macropad 後來在 hackaday 上分享後不知道為甚麼突然爆紅,收到很多留言,所以我就在想,說不定我可以用同一套零件的方案改用 grid layout 來做到數字鍵盤欸?所以我就來試試看了。 甚麼是 Grid Layout? 以 Arduino 的基本電路為例,通常要抓一個按鈕是不是被按下,一般都會對一個針腳進行讀取(e.g. digitalRead),但是在這樣的情況下,每一個按鈕就會需要用到一個 GPIO 針腳。如果我要做一個標準的 4 x 5 鍵數字鍵盤的話,我不就是需要用上 Arduino Mega 才行了嗎?所以這當然是不可行的。 但是如果你有留意到,外面很多 Arduino 按鈕的範例都是使用 Pull Low (下拉)和檢測針腳是不是 high (高電平)的方法來實現的。因此如果我們有辮法在需要讀到某個按鈕的時候的狀態的時候才對它提供高電平,而沒在讀取的時候提供低電平(即使按下也不會產生高電平狀態)的話,那樣我們就能用一只 GPIO 來選擇讀取哪個按鈕,另一只 GPIO 來讀取選擇了的按鈕來增加總讀取的按鈕數量。 於是就出現了 grid layout 跟 line scanning 的方法了。簡單來說就是對於一個 4 x 5 的 grid 而言,我們只需要控制 5 個針腳以選擇哪一行 (row),然後 4 個針腳來讀取哪一列 (column) 就好。以這樣的方法,原本會需要用到 20 個針腳的電路,現在用 4 + 5 = 9 個針腳就能讀完了。 可是,這樣會出現一個問題。在小量生產 PCBA 的情況下,每一顆零件和焊接費用都是滿貴的。而這個 layout 會讓 10K 電阻比原先的 BOM (四顆)多了一顆!? 不過解決方法也很簡單,只要把電路反過來,使用 pull HIGH + LOW activate 的設計(即是說按鈕按下的時候 MCU 是讀取到 LOW / 0 而不是 HIGH /1 ),那電路的設計就變成下面的樣子,把電阻搬到 INPUT line 上面,從而省下一顆電阻( 設計好了之後就是電路板設計了。這裡用的是 EasyEDA,根據上面的原理大致畫一畫之後電路板就出來了。 正面(預留了 numpad + macropad 兩者的插孔) 背面 組裝的部分也是沒甚麼特別的,先把 micro USB 和 CH552G 焊上去之後,再焊一些比較大的零部件,最後就是燒錄程序作測試。 背面電路板,原型機板本背面甚麼都沒有印 正面裝上 keycap 後的效果,由於是開發軟體用的原型機所以用上了最便宜的量產通用型鍵帽 測試用的 Arduino 寫的 Ch552 numpad firmware,需要先灌 CH55X Arduino 燒錄器 外殼設計與打印 由於這片電路板背面也有零件,因此沒辦法馬上使用,必須要先把外殼生出來才能安心放桌面上使用(不然把零件撞掉就麻煩了),這裡使用 Aprint Editor 簡單的為這台東西設計個外殼 因為不知道要傾斜角度多少會比較舒適,因此設計成可以拆卸的結構以方便測試 原型機成品 由於這是原型機,主要作為軟體開發和測試用,因此外殼甚麼的都是拿手邊剛好有的材料來印(黑色 PLA)。但是外型差不多就是這樣。 正面 底部,兩則的是防滑膠條;用戶可以在那個洞黏上金屬板以增加重量 Micro USB 與 firmware program 的按鈕有一個凹位方便開發者使用 後方的 IO 就只有 micro USB 口與兩顆 LED 最終(小)量(生)產的版本應該會好看很多,但是功能上這東西的確比我想像中的要好(這篇文章就是用這個鍵盤寫的),如果加上配重塊與專用鍵帽的話我猜真的可以取代現在我在用的數字鍵盤的樣子(?
Zoraxy – 新手向 Reverse Proxy Server( 反向代理服務器)
我猜很多 web devs(網頁開發者)都知道什麼是反向代理伺服器 (Reverse Proxy Server)。當您在 homelab 或 cluster 上部署多個 service 並希望使用單一gateway server 和不同 subdomain 將它們 expose 在網際網路上時,反向代理伺服器尤其有用。在這篇部落格文章中,我就來分享一下我為什麼要用 Go 開發自己的反向代理伺服器來取代Apache / Nginx 和把它部署到我的分散式 homelab 中的經驗。 甚麼是 Reverse Proxy? 想像一下,你正在音樂節上隨著你最喜愛的表演,突然你想要一杯 冰涼的飲料。由於你不想錯過任何的表演環節,所以你派你的好朋友(即反向代理伺服器),去替你把飲料拿來(網頁內容)。你的朋友穿過人群,排隊等候,完全不會打擾你觀賞表演,最後在不知甚麼時候帶回了那杯冰涼的飲料。在這種情況下,反向代理伺服器扮演著你和音樂節混亂背後的幕後伺服器之間的中間人角色,隔離你(用戶)和後面混亂的內部網絡 routing,直接由中間人向你提供所需的內容。 不僅僅是為你轉發和中繼網頁內容 ,現代的反向代理可做到比中繼代理之外更多的事情。例如說負載平衡、故障切換(failover)等。像Nginx Proxy Manager(NPM,不是那個黑洞 npm)這樣的管理工具甚至具有內置的自動 SSL證書更新等功能。這就是為什麼反向代理通常被認為是 homelab(或任何類型的網站系統)的“核心”的原因。 那為甚麼我要重新寫一個屬於自己的 Reverse Proxy 伺服器? 如果你是一名資深的 devops 工程師,那你一定有親身體驗過寫 Apache 或 Nginx 配置文件的痛苦,那必定是一個難以忘懷的經歷。當你試圖從 Stack Overflow上 Copy & Paste 一些看不懂的東西到你的 config 檔,並試著根據自己的了解進行修改,卻發現怎樣 route 都是怪怪的。再加上很多開源專案都很依賴於 Rewrite Rules 和 Headers 中某些特殊設置的 Setting,要讓所有 service 都能正常運行真是一件讓人痛苦的事情。更多別提到你想加入一個臨時的 routing rules 做 testing 都要進入 ssh 到後台設置的麻煩( 在開源世界中,有一些替代方案或解決方案可解決這些問題。像 NPM 是 r/selfhost 上 Reddit 用戶最推薦的方案之一。然而,它已經快兩年沒更新了,而且聽說最新版本會弄壞很多東西。這就是為什麼我決定自己開發一個 Reverse Proxy 伺服器以解決自己未來可預見的「所有」問題。 這就是 Zoraxy 誕生的原因 Zoraxy 是一個以 Go 開發的 Reverse Proxy 伺服器。除了基本的功能外,還附了很多不同的工具和機能讓你輕易管理你的伺服器集群(當然也能用於 docker 了)。以下是一些簡單易懂的系統截圖: 登入後的主頁 一些 overview status Subdomain 設定 建立新的 Proxy Rules Proxy root (預設路由路徑) Certificates 重導向設置 存取管理 Uptime Monitor MDNS 與 IP scanner Web SSH 功能 用戶統計 登入界面 TCP Proxy (主要用來當遊戲伺服器路由,如 Minecraft Server) ZeroTier controller 有興趣了解更多或下載試用可以到 https://zoraxy.arozos.com/ 看看喔
CH552G 怎樣直接輸入中文到 Windows 上的應用程式?
CH552G 作為一款便宜好用的 USB HID 模擬晶片,我當然是想辦法讓他做到各種神奇功能的東西。而其中一個我很有興趣做的就是能直接輸出中文的鍵盤。 可是這樣問題又來了。到底要怎樣才能讓 CH552G 直接輸出中文呢?作為只有 8bit 的 E8051 處理器,根本沒辦法輸出中文不是嗎? 黑魔法:ALT + BIG5 碼 如果有一定年紀的 Windows 使用者,有玩過一些很早期的網絡遊戲的話應該都知道,早期的中文輸入法對各種遊戲和應用程式的支援很差,有時候即使是輸入法能抓到被遊戲 handle 的鍵盤輸入,也不一定能夠輸出字元到遊戲內的輸入框。這個時候就出現了一個神奇的輸入方法,就是在鍵盤上長按 ALT 然後在 keypad 上輸入該中文字對應的 big-5 碼,之後放開 ALT,中文字就出來了!? 然後我又花了幾天把所有 utf-8 跟 big-5 交雜的中文字轉成其對應的輸入用 DEC 碼 當然,在 Windows 10 之後,有不少應用程式(例如 wordpad)都開始轉用萬國碼 UTF-8,但是只要能夠背下兩邊的碼表的話理論上就能夠不透過任何中文輸入法輸入中文了喔? 那麼,我們讓 CH552G 代替我們按鍵盤不就行了嗎? 理論上是這樣沒錯,但是這裡又有一個問題了,就是 Keyboard_press 沒辦法按數字鍵盤啊??? 假設我們要輸入 「你」 好了。它對應的 big-5 和 utf-8 碼分別為 20320 ( 4F60 HEX) 跟 42817 ( A741 HEX),可是當你想著:這很簡單啊,只要 Keyboard_press(KEY_LEFT_CTRL); Keyboard_write("2"); Keyboard_write("0"); Keyboard_write("3"); Keyboard_write("2"); Keyboard_write("0"); Keyboard_release(KEY_LEFT_CTRL); 的時候,它卻輸出了 "20320" 到電腦上。 嗯?為甚麼會這樣? 原來是因為在 USB HID Keyboard 的定義裡面,數字鍵盤的數字跟你英文字上面那排的 hex code 是不一樣的原因。這個時候為了要轉換這堆數字,我寫了這樣的一個轉換 function,把數字的 char 轉換成 keypad 的 hex code (為了找這個我快花了 3 個晚上,累死) char PressNumericAsKeypad(char in){ int delayTime = 1; switch (in) { case '0': Keyboard_press('\352'); delay(delayTime); Keyboard_release('\352'); break; case '1': Keyboard_press('\341'); delay(delayTime); Keyboard_release('\341'); break; case '2': Keyboard_press('\342'); delay(delayTime); Keyboard_release('\342'); break; case '3': Keyboard_press('\343'); delay(delayTime); Keyboard_release('\343'); break; case '4': Keyboard_press('\344'); delay(delayTime); Keyboard_release('\344'); break; case '5': Keyboard_press('\345'); delay(delayTime); Keyboard_release('\345'); break; case '6': Keyboard_press('\346'); delay(delayTime); Keyboard_release('\346'); break; case '7': Keyboard_press('\347'); delay(delayTime); Keyboard_release('\347'); break; case '8': Keyboard_press('\350'); delay(delayTime); Keyboard_release('\350'); break; case '9': Keyboard_press('\351'); delay(delayTime); Keyboard_release('\351'); break; default: return in; break; } } 這樣我們就順利的把數字 char 換成 keypad 輸出的 hex code 了。之後就是再寫一個 wrapper function 把整個輸入中文字的流程更容易開發: //Pass…
Stable Diffusion, Counterfeit v2.5 跟 656408761
有在用 SD 生 waifu 的人對前兩個應該是滿熟悉的,可是最後那串數字是甚麼? 那是一個滿好看的 SEED 沒錯,這篇文章大概就像一些 Minecraft forum 一樣在分享好看的地圖,這篇 blog 是用來分享一個好看的 SEED。以下是我用來生這些圖的參數: positive weight: ((masterpiece,best quality)),1girl, solo, blue eyes, (indoor), (blue sky:1.9), long hair, ((white hair)), hoodie, shiny hair, pleated skirt, front view, high detail background, (sunlight: 1.1), happy face, smiling, look at viewer, (ahoge), ((hands in pocket:1.3)), streaked hair, hair ribbon, blurry background, close up, summer, green house, high tech, ((glass wall)), grass field, ((white cloud)) negative weight: ((nipple)), ((((ugly)))), (((duplicate))), ((morbid)), ((mutilated)), (((tranny))), (((trans))), (((trannsexual))), (hermaphrodite), [out of frame], extra fingers, mutated hands, ((poorly drawn hands)), ((poorly drawn face)), (((mutation))), (((deformed))), ((ugly)), blurry, ((bad anatomy)), (((bad proportions))), ((extra limbs)), cloned face, (((disfigured))). (((more than 2 nipples))). [[[adult]]], out of frame, ugly, extra limbs, (bad anatomy), gross proportions, (malformed limbs), ((missing arms)), ((missing legs)), (((extra arms))), (((extra legs))), mutated hands, (fused fingers), (too many fingers), (((long neck))), (((background))), ((((big breast)))), EasyNegative, extra fingers,fewer fingers, ((keyboard)), (door), Sampling method: DPM++ 2MSize: 1024 * 768Sampling Steps: 25CFG Scale: 7Seed: 656408761Variation seed: 3600373764 (或隨機,但是我都在這範圍附近)Variation strength: 0.3 以下為一些產出來好看的圖(部分經過 Photoshop 做微調整) 有興趣生類似感覺的圖的話歡迎抓來使用喔!
初嘗 CH552G 與 Macro-pad 鍵盤
在一段時間之前,我無意中發現了 CH552g 這一片超便宜的 Arduino IDE 相容開發板。由於它實在太冷門了,冷門到幾乎沒有用它的 DIY Project,所以我就來自己做一個當實驗了。 可是如果只把 CH552G 做成一個類似 arduino 這樣的開發板,我猜應該也不能引起甚麼 Makers 圈的關注,作為一個喜歡 reinvent the wheel 的開發者,我就想到一個能盡用這顆 IC 的功能的小 project -- 4 key macopads keyboard 甚麼是 Macropad Keyboard? Macro-pad (我也不知道中文是甚麼),簡單來說就是一堆快捷鍵,讓你在按下去的時候它幫你自動對電腦輸入一連串的按鍵動作。目標不一定是電腦,例如說也有可以控制 IoT 裝置的 macro-pad,也有可以配合 auto hotkey 控制軟體界面的 macro-pad 等等。但是我這裡做的是最基本的款式:hot-key type macropad 外面有很多類似的東西啊,你設計的有甚麼特別? 講到這個就有趣了。因為 customize mechanical keyboard 這東西是一個很特別的領域,就如迷你版的「HiFi 音響隨便看都上千上萬元一套」領域一樣,市場上有類似的東西價格都是一兩百港幣起跳的,貴的到幾千都有。不過他們貴的原因有很多,有的是用鋁合金電鍍外殼、有的是用上最貴的機械開關(軸)、有的有訂做的鍵帽、螢幕與 RGB 等等。可是作為一個 macropad,這些東西本來就只是 value-added 的附加品,不知道為甚麼弄著弄著就變成了成本最貴的東西(? 在移除了這些附加的東西之後,剩下來的就是鍵盤最基本的部分: 按鍵電路板MCU / Keyboard IC輸出接口 而這個 project 最特別的地方就是: 低成本 我做的這個 macropad 用了以下一大堆神奇的方法來節省成本: 使用更便宜的機械按鍵使用最便宜的 PCB 生產方案(3 HKD / pcs)使用 Mini USB 取代較常見的 type C 接口,省去兩顆 5.1K 電阻盡量減少零件種類(RLC 部件只使用了 10k 電阻跟 0.1uF 電容)以 CH552G 替代常用的 32u4 大部分外面的 DIY 鍵盤都是在用 32u4 作為控制器。這顆 MCU 畢竟是 Atmel 的,說貴不貴但是也不便宜。這顆 4 港幣左右的 CH552G 跟 32u4 一樣內置有 USB HID 裝置,所以能被電腦識別為鍵盤,同時間又因為它需要的外圍零件真的超級少,所以我們只要很簡單的這樣那樣就設計好板子了。 看著這個板子這麼空的時候我都懷疑自己是不是畫漏了零件 背面一樣零件都沒有,只有走線 如果你是不需要 MODE A / B 切換的話連那個物理開關也能省下,但是因為我打算平用來音樂控制器,在做 Youtube 影片時來當 Adobe PR 的 hotkey keyboard,在只有四個按鈕的設計下只好做 multiplex 了。 軟體方面使用了 CH55X Arduino 的 library 與一些 C code 來做到鍵盤機能 https://pastebin.com/Hb0AQzpY 底座 然後因為都做這麼完整了,那就順便幫它做一個鍵盤底座吧? 這軟體是我自家公司開發的 Aprint Editor 成品
AI 產圖與魔法 #淡淡杯
話說最近 FB 上出現了這麼一個有趣的比賽,但是作為技術系開發者,當然是要用最原始的 stable diffusion 來產,於是這就是作品: 魔法如下(Positive weight 跟 negative weight) ANIME GIRL, FEMININE,((PERFECT FACE)),((SEXY FACE)),((DETAILED PUPILS)).(ARTIST),ARTIST,ARTIST,(ARTIST). OIL PAINTING. ((NO BREAST)), SMIRK,LOOK AT VIEWER, (((WHITE HAIR))).(INTRICATE),long hair, asian, (loli), (HIGH DETAIL),SHARP, GREY EYES, 14, ((maid)), cherry blossom, ((sakura)), leaf, (flower), nature, ((blue sky)), white cloud, black cat ((nipple)), ((((ugly)))), (((duplicate))), ((morbid)), ((mutilated)), (((tranny))), (((trans))), (((trannsexual))), (hermaphrodite), [out of frame], extra fingers, mutated hands, ((poorly drawn hands)), ((poorly drawn face)), (((mutation))), (((deformed))), ((ugly)), blurry, ((bad anatomy)), (((bad proportions))), ((extra limbs)), cloned face, (((disfigured))). (((more than 2 nipples))). [[[adult]]], out of frame, ugly, extra limbs, (bad anatomy), gross proportions, (malformed limbs), ((missing arms)), ((missing legs)), (((extra arms))), (((extra legs))), mutated hands, (fused fingers), (too many fingers), (((long neck))), (((background))), ((((big breast)))), (((hand))) #淡如盃 技術細節 可能看到這裡的你會在想,到底 stable diffusion + pre-train model 跟外面的 midjourney 之類的差別在哪?雖然我也不清楚其他系統的做法,但是我猜的是他們也是基於一個 pre-train model 並加入一堆 preset 的 rule / theme 來讓它產出那模型的獨有風格。舉例說,上面的 negative weight 中,除了最後幾個(background)、(hand) 之類用作減少背景雜亂和手部生產錯誤的 negative weight 以外,其他基本上也就是固定的了。因此我猜可能其他的服務也是透過類似的方法來實現。 嘛當然,如果能避免直接出現手部(例如用 hands in pocket、hands out of frame 的 positive weight)的話那效果會更好。 手指與手套 加入黑色手套 (black glove) 不知道為甚麼,有時候好像也能改善手指數目和動作生成的問題(我猜可能只是看不見而已),以下是兩張例子: 色系與背景 特別強調背景的物品或色系看來有時候也會讓整體的繪圖質素有所提升(可能是因為通常背景畫得好的繪師,人物也畫得不錯?),例如說當我特別定義了 blue sky, white cloud, sunlight 等大自然的感覺的字眼之後,整個產出的氣氛也變得特別悠和 加入其他現代化的字眼如 future, glass wall, minimalist 之類的也可以做到類似效果 不過我覺得最特別的是加入了 (((hong kong))) 為背景所產出來的,不知道為甚麼有一種未來城市的感覺(?…
Golang 程序連續執行一個月之後一定會出錯之神奇原因及除錯
話說半年前我開發了一個叫 imusutm 的 Simple Up Time Monitor。它是一個很簡單的程式:每隔 5 分鐘去 ping 一次 json 設定檔案裡面的網址,然後把它 buffer 到 RAM。同時提供一個 RESTFUL API 給 php script 來 call 並回傳最近一天的狀態。 可是不知道為甚麼,這程式很固定每隔一個月就會出現全部斷線的狀態,連帶用這系統的 Telegram bot 也一律全部報錯 在無論如何都沒辦法在本地端 reproduce 之後,在上一個月我把所有 error 裡都加入了 error message print-out 來協助除錯。結果被我發現問題了: 2023/02/24 20:20:34 Get "{某個要 ping 的 IP 地址}": dial tcp {某個要 ping 的 IP 地址}: bind: An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full. 一看到這個我就明白了,原本是 socket 用光了。可是一台主機的 socket 有這麼多怎可能能全部佔用? 原來是忘記了 resp.Body.Close() 於是我去看整段 code 唯一有用到 socket 的部分:http.Get(url),發現忘記了寫 resp.Body.Close() 了(222 行是新加入的),所以難怪會出現這個問題。 可是,又為甚麼是大約一個月會出現一次? Windows 的 Dynamic Port 與 ArozOS Windows 的 dynamic port range 是由 49152 到 65535。雖然有一些間中會被佔用,但是大部分都是用完之後就會被釋放出來。這兩個數字相減之後便能得出 16384 個能用的 dynamic port。 至於為甚麼是一個月?因為 每小時有 12 個 5 分鐘 x 一天 24小時 x 30天 = 8640 個 connection,然後由於 ArozOS 使用的 Go net/http 會自動斷開,而這數字又差不多是可用 port 數的一半,再加上列表上又剛好只有兩個 connection 是能維持的,我好像猜到點甚麼的樣子(? 總括而言 相信加入了 resp.Body.Close() 之後就能解決 utm 不穩定的問題了,如果下一個月再出現類似的問題我還是整個砍掉重寫好了(畢竟這只是一個我在等上飛機時的小作品,出現這些奇怪的 bug 也不怎麼意外就是了)
ArozOS 的相容性存取模式
在開發 ArozOS 這個計劃的時候,其實大部分的時間我都不是用來寫功能性的東西,而是開發前端,以提升使用者體驗(UX)的東西。從網頁桌面到簡單易用的設定與管理系統,從 FTP 到 WEBDAV 接口等,都是讓不同的用戶及自己能在不同的裝置與環境下使用到自己的伺服器。然而自從 1.0 版 ArozOS 開始開發之後我們一直都還沒有放進去的,就是相容模式了。 新版的硬碟掛載界面 新版的檔案伺服器界面 從 Aroz Online Beta 起相容模式就一直是我們堅持的功能之一。其一是為了一些極端的使用裝置(例如 DSi 的瀏覽器、快譯通之類的嵌入式裝置)可以使用 ArozOS 為資料傳輸用之外,也可以用在一些很惡劣的網絡環境下,讓相容模式變成遠端使用 ArozOS 的最終手段。 AOB 下的相容登入模式 相容模式下只能勉強執行一些簡單的 WebApp 可是 AOB 的相容模式下真的沒辦法做甚麼,除了 Music 跟 Setting 幾個 WebApp 之外幾乎甚麼都沒辦法做(特別是連 File Manager 都開不了這點最讓我覺得奇怪),所以我猜當時開發相容模式就只是為了可以產生伺服器端的 session 然後用同一組 session 來存取伺服器上其他的服務而已。 ArozOS 2.0 的 相容模式 ArozOS 2.0 新加入的 Directory Server 相容存取模式 去到 ArozOS 2.0 之後,相容模式的登入界面也被直接改成有一定年代歷史的 Basic Auth 處理,也把界面盡量減少到只使用最基本的 HTML5 及顯示最基本的虛擬檔案系統層 ArozOS 2.0 的 file system abstraction ,以 compatibility mode 顯示 這樣的設計不但能相容最多的裝置,作業系統等,也能在極為惡劣的網絡環境下(Kbps 速度)存取到你放在伺服器的資料,對於在緊急需要下載個文件之類的還是有點用途(我猜) 如果你有一定年紀的話你會發現這界面好像在哪裡看過。沒錯,這是參考 Apache 的 list dir 界面設計的。簡單、直接的設計怎樣說還是參考前人設計為佳。 Apache 預設的 list dir 界面 結論:實用性有時候比技術重要 現在的前端都太複雜了,不是依靠 Virtual DOM 就是依賴一大堆 HTML5 attribute tags。有時候當你開發的系統是以實用性和高相容性為主的時候,不妨考慮一下以機能而非技術先行,採用 server side 直出 HTML 的做法還比較實際。
Marktext VS MDEditor 還是自己寫的好用
最近我在用 MarkText 來寫 Final Exam 的筆記,由於這是一門非常複雜的課,所以筆記也超級無敵的長。直到突然去到一個位置 MarkText 就開始出現一些怪怪的情況。例如說一按 Enter 就會自動在其他位置加入新項目之類的: 一看就知道又是開源項目的通病。這些小 bug 往往就是讓人覺得「開源的東西不好用啊」的部分。這也是為甚麼我在開發 ArozOS 系統的時候都特別注重這些細節的位置,東西不是生不出來就是一定要做得好用易上手的。 由於這軟件又增加了我對別人寫的 Markdown Editor 的不信任,所以我決定用回那個我使用多年,超級無敵穩定可靠的 WebApp:ArOZ Markdown Editor (現在叫 MDEditor,但是核心都是一樣的) ArozOS 2.008 的 MDEditor 跟 PDF Viewer ArOZ Online Beta LTS 的 WriterA 跟 PDF Viewer 用自己寫的東西的好處大概就是相信自己寫的東西夠穩定吧。說實話我現在已經開始發現到「 相信別人不如相信自己,相信自己不如戰勝自己。 」的道理。從 Beta 到現在這個編輯器還在而且還能夠在檔案系統虛擬化後能完全穩定運作,讓我能在今晚完成這份筆記,完全就是這句說話的例子啊(
ESP8266 讀取 SD 卡太慢?要試試全速 SPI 嗎?
我看到日本技術宅的 Blog ,覺得奇怪這裡為甚麼他可以在 SD.begin 後面設定一個指定的速度(? https://www.mgo-tec.com/blog-entry-esp8266-wroom-spi-speed-up.html 於是我跑去翻 ESP8266 Arduino Core 的源碼,原來 ESP8266 比起原生的 Arduino core 在 SD.begin function call 多了一個可選擇指定的 uint32_t 參數,預設是 SPI 一半速度(4 Mhz),但是如果你的 SD 卡夠快(例如說現在大部分 A1 Class 10 的卡)都可以上到 8Mhz (SPI Full Speed) 或以上(這裡日本部落格用的是 40Mhz,為了資料安全好孩子不要隨便超頻你的 SD 卡) https://github.com/esp8266/Arduino/blob/313b3c07ecccbe6fee24aa9fa447c4aed16ca499/libraries/SD/src/SD.h#L35 嘛不過 ESP8266 的 WiFi 速度極限也就 4Mbps,如果要用來做網頁伺服器的話 SPI 速度設定到全速(8Mhz)已經足夠盡用它的網絡速度了。 備注:如果要設定速度的話可以用 ESP8266 SD library 內預設的常數 uint32_t const SPI_FULL_SPEED = 8000000; uint32_t const SPI_HALF_SPEED = 4000000; uint32_t const SPI_QUARTER_SPEED = 2000000;