ArozOS 的多帳號切換系統原理
講到多帳戶切換系統,通常你只會在一些類似 AWS 或者 Google 那樣大規模的系統裡面才會看到,然而這並不是沒有原因的。因為有時候部分功能為了權限上的分別,不少人比起想要設定一個擁有多權限群組的用戶,反而會比較喜歡以帳戶的方式來使用不同權限群組的作業環境。 早在好幾十個版本之前,ArozOS 就可以建立不同的權限群組而且讓一個用戶加入不同的群組 單用戶多權限群組設計 原先的 ArozOS 採用多用戶多權限群組的設計,簡單來說就是每個用戶都可以加入一個或以上的權限群組,而這個用戶能做的事情和存取的儲存裝置就是 UNION of 所有的權限群組。假設群組 A 只能存取 A 的儲存池,群組 B 只能存取 B 的儲存池,那一個用戶加入了 A 和 B 的群組之後便能存取 A 和 B 兩個儲存池的資料,並在此中間自由移動和開啟檔案。 然而,不知道是不是這設計對於現代人來說太複雜了,很多人就是不會用,然後問我到底要怎樣才可以建立更多自用的使用者帳戶。建立之後他們又會來問到底要怎樣才可以把檔案在用戶之間移動,我就一整個(嗯??? 多用戶單權限群組設計 所以後來我在跟用戶訪談的時候,發現其實他們比較多在用多用戶單群組的用法。簡單來說,就是一個用戶只有一個權限群組,當他們想要存取另一個權限群組的資料的時候,他們便會登出原先帳戶並登入另一個帳戶。這用法通常是用來處理一些對外的服務(例如 www 的帳號來處理跟 web service 相關的檔案),但是用在 cloud desktop 上的這種要求我猜我應該是第一個 implement 的說? 所以為了體驗這種奇怪的使用方法,我特別在 test bench 上架了一個網站,讓 www 帳戶來保存檔案。 在 www 上架的一個 html file 然後就開始設計帳戶切換的邏輯。首先,一般的帳戶切換做法是使用 client side cookie / session 對每個帳戶進行登入,然後讓用戶可以自由切換在該 browser 上任何未過期的 login session。然而,在 ArozOS 上這有點不太可行 ArozOS 的 authentication 是基於 cookie 而非 localStorage。如果設計改了的話對一些依賴 legacy login API 的系統會帶來嚴重問題ArozOS 是網頁桌面系統,相比起其他網頁的 stateless 設計,ArozOS 的桌面是 stateful 的,而且整個狀態是儲存在伺服器端部分用戶在 ArozOS 上使用 oAuth / LDAP 作為登入認證伺服器,加上之後有打算加入 Cluster Authentication System 等伺服器端較複雜的結構,在客戶端上儲存登入狀態可能比較難做到跨伺服器間的 user state transfer 所以結合上述原因,我們最後採用了一個叫 Switchable Accounts Pool 的設計。 Switchable Accounts Pool (SAP) 是一個我們設計出來的實驗性東西。它的功能大概就是以一個 pool id 來對應一堆可以切換的帳戶,而這些帳戶又會有 main / secondary 的關系,讓帳戶的登出的時候在伺服器端對該瀏覽器的登入狀態進行切換。 一開始,當主帳戶登入的時候,一個在伺服器端的 SAP 便會被建立。Creator 的名字就會寫著是主帳戶的名字。之後,用戶可以透過登入 sub-account 以取得在這個 session 結束之前,可以不斷切換到 sub-account 的權利。 當 Sub account 登出的時候,由於 main account 的 session 仍存在,因此伺服器端會直接改寫 User 的 login cookie 到原先的 creator account。 而當 Main account (即 SAP 的 Creator)登出的時候,伺服器端便會直接 discard 整個 SAP 以保護其他 sub-account 的安全(非法透過登入 sub-account 以取得 main account 的存取權)。 在邏輯搞清楚之後,剩下的便是把功能寫出來了。這裡只是一點簡單的 Go programming,技術上沒甚麼特別的所以我就不再詳談。 網頁桌面上的可切換帳戶 新增帳戶的時候需要使用密碼登入,如果是近來切換過的而 session 沒過期可以透過伺服器端免密碼切換 在一些特殊情況下,例如說 main account 的 login session expire 但是 SAP 的 session 還沒 expire ,使用者便會在登入界面看到這樣的一個 popup,讓他可以快速回復之前登入過的…
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…
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 的做法還比較實際。
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;
在 Raspberry Pi Zero 2W 上設定 WiFi AP 作為 WiFi 中繼器
因為不知道為甚麼網上沒有 Raspberry Pi Zero 2W 以外接 WiFi USB 作為 WiFi 中繼器的教學,所以我就來自己研究出一個方法囉 材料 Raspberry Pi Zero 2WRaspberry Pi OS 用作 wlan1 的 USB WiFi 模組 安裝所需 Package sudo apt-get update sudo apt-get upgrade sudo apt-get install hostapd sudo apt-get install dnsmasq sudo systemctl stop hostapd sudo systemctl stop dnsmasq 設定網絡界面卡 sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.orig sudo nano /etc/dnsmasq.conf 寫入以下內容 interface=wlan1 dhcp-range=192.168.0.11,192.168.0.30,255.255.255.0,24h 固定 wlan1 的 IP 地址 sudo nano /etc/network/interfaces 把 source /etc/network/interfaces.d/* 加上 comment: #source /etc/network/interfaces.d/* 寫入以下內容 auto lo iface lo inet loopback auto wlan0 iface wlan0 inet dhcp allow-hotplug wlan1 iface wlan1 inet static address 192.168.0.10 netmask 255.255.255.0 broadcast 192.168.0.255 gateway 192.168.0.254 設定 Hostapd sudo nano /etc/hostapd/hostapd.conf 寫入以下內容(記得更新 WiFi 名稱與密碼) interface=wlan1 hw_mode=g channel=7 wmm_enabled=0 macaddr_acl=0 auth_algs=1 ignore_broadcast_ssid=0 wpa=2 wpa_key_mgmt=WPA-PSK wpa_pairwise=TKIP rsn_pairwise=CCMP ssid=[WiFi SSID 名稱] wpa_passphrase=[WIFI 密碼] 之後編輯預設設定 sudo nano /etc/default/hostapd 把原本的 #DAEMON_CONF="" 改成 DAEMON_CONF="/etc/hostapd/hostapd.conf" 設定 wlan1 -> wlan0 的 forwarding sudo nano /etc/sysctl.conf 把 #net.ipv4.ip_forward=1 改成 net.ipv4.ip_forward=1 新增 iptables 規則 如果你是用 Lite 版沒有 iptables 可以先透過以下指令安裝 sudo apt-get install iptables 然後輸入 sudo iptables -t nat -A POSTROUTING -o wlan1 -j MASQUERADE sudo sh -c "iptables-save > /etc/iptables.ipv4.nat" 編輯 rc.local 在啟動時自動應用規則 sudo nano…
Arduino 用在產品上太貴?有聽過 CH552G 嗎?
話說一個月前我在想到底有甚麼方法可以替 Raspberry Pi 增加一個 Analog Read 的功能,看了網上很多的教學和文章,大致上的方法就只有 用 ADC 透過 SPI 傳到 Raspberry Pi 的 GPIO用 USB 接一片 Arduino UNO 再透過 Serial 傳送讀取的資料 可是 ADC 需要接到 Raspberry Pi 的 3.3V GPIO,用來量 5V 的 Analog 電壓的話總覺得有點危險,要安全的話要加一片 LLC (Logic Level Converter,5V 轉 3.3V 的),需要的空間又會變更多,而且生產上來也不會特別便宜。 另外第二個方法比較安全(畢竟 USB 的 5V 是直接來自電供的,如果有短路電供會先斷開作保護),但是一片 Arduino (ATmega328)價格一點都不便宜,即使用較便宜的 ATtiny 44 也需要快 10 - 12 港幣一片,如果真的要量產起來一點都不比 ADC + LLC 便宜。 然後剛好我在研究 CH340 的各種版本時,在那間公司的網站不但發現到有一種 CH340 有內置晶振(不用外接,省掉焊接和零件的成本)而且還發現了一種新的 MCU 沒錯,這就是今天的主題:CH552G 於是我便隨便買來了一片開發板,來到之後長這樣,真的好小,跟我前女友的現任男友 ㄐㄐ 差不多大小。 CH552G 的好處在於以下幾點 內置 USB HID 控制器,不需要外接 USB to Serial 轉接晶片(如 CH340)5V Logic Level,可測電壓為 0 - 5v (對應 0 - 255,共 8bit 準確度)超級的便宜,大概 5.5 港幣就能買到一片(開發板也只是約 15 港幣一片) 使用 Arduino IDE 對它進行編程 https://github.com/DeqingSun/ch55xduino 上面是這次使用的 Arduino board definition。跟其他的第三方板子一樣,先把它給的 json 檔加入你的 Arduino 設定裡,再在 broad manager 找到 ch5xx 的板子把它加進去。 https://raw.githubusercontent.com/DeqingSun/ch55xduino/ch55xduino/package_ch55xduino_mcs51_index.json 對於全新的開發板,第一件事情就是先安裝 bootloader。詳情教學可以看 Github,但是對於 Windows 用戶在跟著 Github 教學前需要先為 CH552G 安裝 driver,不然在 Windows 內會顯示為不明裝置。其步驟為下: 下載 Zadig ,https://zadig.akeo.ie/按著在沒插電的開發板上的 PROG 按鈕(或「下載」按鈕)把開發板透過 USB 線連到電腦(注:不能鬆開按鈕)等待開發板在「裝置管理員」以「不明裝置」顯示之後才可鬆開打開 Zadig,點選 Unknown Device 1,選擇 Install Driver第 3 - 5 分鐘(可能更慢,看電腦規格)完成之後把開發板拔出,再重新插回去電腦裝置管理員會顯示為 COMX (我的話就是 COM7) 完成後的 Zadig 界面 安裝完 driver 的開發板,COM7 燒錄 Bootloader 在開發板寫程式的時候 bootloader 會順便送進去,所以這裡我們先要選好正確的板子(我這片是 CH552) Pin 的編號就是以開發板上寫的 x10 為準,例如說要控制 P3.0,pin number 則輸入 30,P3.2 則是 32 如此類推。因為我要順便測試 analogRead 跟 USB Serial,所以我把 blink 改成這樣 int val = 0;…
使用 Apache2 當 Reverse Proxy 伺服器
因為最近房東在沒經我同意之前在房間的網絡上遊加入了一台 NAT 路由器,所以原本架在我的房間裡的 ArozOS 伺服器就沒辦法在外面連線了。想了想,於是我想到了可以透過 zeroTier 和 Reverse Proxy 來使用我房間裡的伺服器,所以便開始研究怎樣可以弄到一台 Reverse Proxy 的伺服器。 網絡上很多人喜歡用 nginx 來當 RP伺服器,可是基於某些原因我並沒有太喜歡它所以我就選擇用 Apache2 了。首先,安裝 apache2 sudo apt-get update sudo apt-get install apache2 -y 然後就是編輯它的設定檔,加入你需要 proxy 的目標 sudo nano /etc/apache2/sites-available/000-default.conf NameVirtualHost *:80 <VirtualHost *:80> ServerName ixtw.hkwtc.com ProxyPass / http://{zerotier 的區網 ip}:8080/ ProxyPassReverse / http://{zerotier 的區網 ip}:8080/ </VirtualHost> <VirtualHost *:80> DocumentRoot /var/www/html </VirtualHost> 然後 Enable Proxy 插件並重啟 apache 2 sudo a2enmod proxy_http sudo systemctl restart apache2 可是,WebSocket 要求過不去欸? 這是因為要 proxy websocket 會需要額外的 module 去處理,首先啟用 wstunnel 跟 rewrite engine sudo a2enmod proxy_wstunnel sudo a2enmod rewrite sudo systemctl restart apache2 然後加入 RewriteCond 跟 RewriteRule <VirtualHost *:80> ServerName ixtw.hkwtc.org RewriteEngine On RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR] RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC] RewriteRule /(.*) ws://192.168.196.15:8082/$1 [P,QSA,L] ProxyPass / http://192.168.196.15:8082/ ProxyPassReverse / http://192.168.196.15:8082/ </VirtualHost> 最後再重啟一次 apache sudo systemctl restart apache2 這樣就完成了!
透過 Arduino 取得 UART HMI 螢幕頁面 ID 然後按需求轉頁
最近因為我在弄一個 60W 的 PD 充電器,然後想弄一個迷你的螢幕來顯示電池的資訊,所以我便選用了一個 2.2寸的 UART HMI 了。 2.2 寸的 UART HMI,比想像中要小一點 選 UART HMI 的原因有很多,網上也有很多文章教你怎樣選合適的螢幕,所以我就不細說了。簡單來說, UART HMI 是一種可以透過 Serial 來控制螢幕載入預先設計好的界面的一種人機界面。 發送指令到螢幕 HMISerial 是 Software Serial。以下 function 把 cmd 內的內容發到螢幕,如果 debugMode 被啟用,側會同步輸出到 hardware serial 上。 SoftwareSerial HMISerial(2, 3); // RX, TX //... void sendCommand(String cmd){ if (debugMode){ //Mirror output to serial Serial.print(cmd); Serial.write(0XFF); Serial.write(0XFF); Serial.write(0XFF); } HMISerial.print(cmd); HMISerial.write(0XFF); HMISerial.write(0XFF); HMISerial.write(0XFF); delay(50); } 使用例子: sendCommand("t0.txt=\"[info] MCU Connected\""); 取得現在 HMI 屏幕正在顯示的 Page ID 如果你把 sendme 指令發到屏幕,屏幕會回傳現在的 page ID 給你,它的回傳信號大約長這樣 66 01 FF FF FF 66 是這個指令的回傳碼,01 是現在的 page ID (即是 page 1),FF FF FF 側是傳送完成的意思,所以我們只需要在 Serial.read() 的時候抓到 0x66 就知道下一個一定是 page ID 了。 int getPageNumber(){ sendCommand("sendme"); bool nextReadIsPageNumber = false; while (HMISerial.available() > 0) { // read the incoming byte: incomingByte = HMISerial.read(); if (nextReadIsPageNumber){ //這是 page ID nextReadIsPageNumber = false; return incomingByte; } if (incomingByte == 0x66){ //下一個出現的 byte 就是 page ID 了 nextReadIsPageNumber = true; } } } 使用例子(檢查現在是否在 page 0(hex: 0x00)) currentPageNumber = getPageNumber(); if (currentPageNumber == 0x00){ //Do something } 成果(Arduino 透過 COM port 輸入到模擬器)
ArOZ Portable 主板開發計劃
說到 ArOZ Portable 計劃,這是一台可以放進口袋裡的迷你 ArozOS 伺服器。如果你沒看過的話現在的版本大約長這樣 最穩定版本的設計 可是如果你有機會把它拆開來看,你就會發現這版本其實是沒辦法量產的。因為裡面的線路長這樣 所以結論是:在真的量產之前我要先把它變成可以量產的設計。 ArOZ Portable 主板 通常說到電腦、手提電子裝置等等的東西第一個最基本的東西就是主板了。 這個計劃由 2016 年開始我就不斷在嘗試弄一塊主板來省略那堆亂七八糟的走線,可是每次都因為不同的原因而失敗。最大的原因可能是因為我還沒有焊接 小於 SOP 跟 0805 針腳的技術力吧,也有不少原因是當年的畫板技術還沒足夠讓我真的去自由發揮。 在這裡我就跟大家分享一下這幾年來我設計的 ArOZ Portable 主板(失敗品)吧 初代 ArOZ Portable 主板 第一代的 ArOZ Portable 主板 這一塊主板基本上就是一塊 FE1.1S USB Hub 晶片 + Micro SD 轉 USB 的晶片(用以代替外接的 USB 儲存裝置),但是當然這兩塊晶片的腳位都是 SSOP 的,而到現在我還是沒有合適的工具去焊接 SSOP 腳位,所以這板子當然是失敗了。 第二代主板 第二代的主板主要是把 SD 卡讀卡器移除,跟把充電電路放回進去。你在 U2 的位置能夠看到一個熟悉的 TP4056 layout,理論上是可以提供 5V 1A 的充電性能。但是唯一一個問題是這電路設計的時候沒考慮到 5V 升壓問題(而且還要畫完,在掉去生產前一刻才發現這問題),而大部分 USB 裝置必須要有 5V 供電才能運作,結果這板子也是不能用的。 第三代主板 在發現第二代這種低級錯誤之後第三代就換回去用移充的主板來供電了(右上的那個凹進去的位置),然後順便加粗了供電的走線和買了焊膏和熱風槍。雖然有成功焊出一兩塊,但是最後也是因為 FE1.1S 焊的良率太低而報廢(果然還是需要紅外線焗爐啊) 第四代 想著既然第三代都能有幾個 % 的成功率,那第四代也能碰碰運氣看看定 20塊板子有沒有一塊能成功吧?於是我把充電、升壓、USB Hub 等等全部放到一塊板子上面,結果良率太低全部焊完之後一塊正常運作的板子都沒有(# 第五代 「算了,還是 back to basic 好了。」用這種邏輯而畫的版子。只提供了最基本的電源、USB port 信號 routing 跟 USB Hub 的晶片,結果雖然有一點問題,但是加一點 patch wire 之後總比一大堆線要好。可是這體積,應該還能再小一點? 第六代 因為考慮到能不能把良率超低的 FE1.1S 找 OEM 進行焊接,然後以模組的形式插回到主板上而開發的板子。基本上與第五代的設計一樣,就是把 FE1.1S 的 footprint 換成了 2.54 針腳的插槽 可是後來這版本並沒有進行生產,因為問了才知道這麼少的生產量走一趟 OEM 貼片實在太貴了(比起買 USB hub 模組回來拆還要貴),所以就這樣這東西就放置了 1年多(由 fyp 開始到 grad 我都沒碰過這計劃) 第七代 在香港疫情爆得最厲害的時候因為在家裡沒事幹所以抽了點時間來設計這塊板子。這基本上是基於第七代的設計,但是把多餘的板子部分切走,讓它最小化方便安裝。可是沒進行生產的原因也是跟第七代一樣。另外你也能看到背面原本要放移充主板的位置被一塊 Powermanv5 代替。 主板背面,使用自家開發的 Powermanv5r2 主板代替移充主板,這樣就不用每做一台 ArOZ Portable 就犧牲一塊移充 背面用來供電跟充電的 Powermanv5r2,也是自家開發的其中一種通用模組,已經量產 https://www.tindie.com/products/tobychui/powerman-power-boost-lipo-charger-inoutput-5v-2a/ 第八代 經過這一年來不斷來回生產不同的 PCB 來做 STEM Kit 跟 了解了更多不同類型的晶片供應商,現在終於有技術可以重新回到這個 project 了。在幾個巧合的情況下才讓我有辦法設計到這塊板子: 在 twitter 看到有工程師分享一塊 SOP16 的 USB Hub 晶片:SL2.1A在拆移充時發現了一塊更便宜的充放管理晶片:HT4928我已經開發好 Powerman 跟 Powerloli 兩塊通用鋰電池充放管理板(內置升壓功能)終於理解 When in doubt, ground it out (有懷疑不知道它要連哪裡的時候,就把它接地吧)的道理 後面可以直接拉線到 Raspberry Pi Zero W 的 test pad 供電和 USB 接口 然後就是等 Power Loli v2 的樣品 PCB 回來,測試過沒問題之後就可以正式生產這塊第 八代的板子了。 8 May…
目前第 2 頁,共有 6 頁