長按開關的超簡單電路
這是一個基於 EC190708 方案的,可以做到長按三秒輸出 HIGH、再長按三秒輸出 LOW 的神奇功能。以下是出處所提及的電路圖: 出自: https://www.youtube.com/watch?v=Ppm9qWKcTe8 我是覺得連 0.1uF 的部分都可以直接省下就是了(畢竟現在很多電供裡面都有內置電容)
JavaScript 顯示時間的例子
因為間中要用到每次都要去 Stack Overflow 抓有點麻煩所以就直接記下來了: new Date().toLocaleDateString() > 2022/1/30 new Date().toLocaleString(undefined, {year: 'numeric', month: '2-digit', day: '2-digit', weekday:"long", hour: '2-digit', hour12: false, minute:'2-digit', second:'2-digit'}) > 2022年01月30日 星期日 01:05:48 new Date().toLocaleDateString('en-US', {year: 'numeric', month: '2-digit', day: '2-digit'}) > 01/30/2022 new Date().toLocaleDateString('en-ZA') > 2022/01/30 new Date().toLocaleDateString('en-CA') > 2022-01-30 new Date().toLocaleString("en-US", {timeZone: "America/New_York"}) > 1/29/2022, 12:05:48 PM new Date().toLocaleString("en-US", {hour: '2-digit', hour12: false, timeZone: "America/New_York"}) > 12
使用 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 輸入到模擬器)
KIOXIA 32GB EXCERIA Micro SD 卡跑分
嗯,就大概這樣… 嘛,對於一張 36HKD 的卡來說不能要求太高吧(?)
3D 打印新手懶人包
見間唔中都有人會入坑試下玩 3D 打印,作為已經玩咗 3D 打印 4 - 5 年嘅 Maker,我就係呢到寫個懶人包方便大家搵野。有問題或者補充歡迎下面留言多多指教 【家用 3D 打印機分類】 3D Printer 有好多種,一般最多人用嘅家用機係 FDM 同 DLP ,以下係一啲你可能聽過嘅例子: FDM Puras i3、Tiny Boy (港產)、P 仔(港產)、Creality Ender 系列、AnyCubic Mega 系列 DLP AnyCubic Photon / NOVA、Creality LD 而你可能會以為佢係 DLP 但係其實佢係 SLA 嘅 FORMLABS Form 系列就唔係包括係上面個表入面 【揀邊種機好?】 你要考慮幾點 你打算印啲咩(結構 / 工程件?機械類模型?公仔?)你需要幾精細 / 想印幾快?你 budget 幾多? 基本上就可以大概知道你應該買邊種機。總括黎講,如果你: 只係打算印啲簡單模型表面光唔光滑唔緊要,最緊要硬正同埋印得快(整下一啲外殼、支撐或者功能性嘅野)想印完即刻用得,唔洗過水、等佢固化 你就可以去買 FDM 嘅機型;但係如果你 打算印一啲好精細嘅模型表面一定要光滑,打印件唔諗住會食力你屋企有個空氣流通嘅位置放部機唔介意印完之後要過水 / 用酒精處理、再放入 UV 燈箱照光做固化 你可以去買 DLP / SLA 嘅機型。 【要用咩軟件?】 3D 打印個過程大概係咁: 你用建模軟件畫一個 3D 模型你將個模型匯出到合適嘅格式(stl / obj)匯入去切片軟件匯出一個部 3D 打印機食到嘅指令檔(gcode / x3g)將個 file 放入去 SD 卡 / 電腦用 USB 線連接部 3D printer 開始打印 所以,係一般情況之下你會學用到兩套軟件(除咗一啲有 build in slicing 嘅 3D modeling engine,呢個後話)。如果你想學,下面呢個 list 你可以選擇一個適合自己嘅試下用。(帶 ✨ 號係香港本地嘅 startup 公司 / Makers 開發嘅產品 / 服務) 【建模 軟件】 帶 🔼 號係指呢個模型係以2D extrusion 變 3D 嘅模式建模,因為要經常 2D 3D 轉黎轉去,一開始唔習慣可能會成日畫錯野 / 搞錯方向〔新手向〕 Draw23D (小學 - 初中,用作將圖片變成 2.5D 的網上工具) ✨ http://www.draw23d.com aPrint Editor (初中 - 高中,帶雲端切片的 3D 建模工具) ✨ https://aprint.io/editor/ TinkerCAD (小學 - 初中,但無法直接匯出 Gcode,需要使用其他切片軟件切完個模型先印到)https://www.tinkercad.com/ Fusion 360 (高中或以上,比較完整嘅一個建模軟件)🔼 〔專業用〕Autodesk Inventor (有學生版免費)🔼 SketchUp (通常用黎畫建築圖)🔼 Blender (功能多到痴線,但係用得熟基本上乜都做到) ZBrush (畫公仔用,呢個我唔熟) 【切片軟件】 呢個通常跟機,特別係一啲用 custom protocol 嘅機型(例如 MakerBot 同埋 FlashForge),但係一般人嘅選擇通常係: 〔雲端切片〕 IceSL (一個超簡單的雲切片軟件)https://icesl.loria.fr/ aPrint Editor (係「列印」則欄有得直接 export Gcode 檔案) https://aprint.io/editor/ OctoPrint (需要自己買部 Pi 返黎…
Powerman v6 – 由 Micro USB 升級為 type C 的方法
話說我在一年前完成了一塊叫 Powerman v5r2 的一體式鋰電池充放管理板。它使用 IP5306 來對聚合物鋰電池進行 5V 2A 的充電和 5V 2A 升壓輸出。後來我也有放到 Tindie 上面賣,大約 65港幣一塊。 正面 背面 可是最近因為之前一次性生產的 100 塊存量即將見底,所以在準備下一批的生產過程。而在使用這充電板來做 STEM 套件的時候也收到不少的使用者意見,其中一個不時會聽到的是「不能用 type C 充電嗎?」 就是這樣,就讓我來設計一個能夠使用 type C 充電的設計吧! 要升級成 type C 聽上去很簡單,可是 Raspberry Pi 3 在升級到 4 的 type C 的時候出現過很嚴重的問題(有的甚至把充電器燒壞),所以我們就來看看當時 Pi 4 的初版是怎樣設計的: 這是 Raspberry Pi 4 初代的設計 你看到它 CC1 跟 CC2 是共用一對 5.1K 電阻,可是根據 USB C 的規格書,實際上的做法應該是這樣 由於我們不需要 5V 以上的電壓,我們只需要很簡單的用兩個 5.1K 電阻(Rd 位置) 分別連接 CC1 跟 CC2 再接地就好。 經過一大堆 re-route 之後,我的 Powerman v5 就成功升級成有 type C 的 powerman v6 了
Babylon.js ExtrudeShape 匯出成 STL 之後出現不正常 face data 的解決方案
在開發 aPrint 系統的時候,其中一個功能是使用 CSG 把兩個 Mesh 組合成一個容器。可是在組合匯出之後卻出現 face data 重疊的情況(也有人會把它叫做 z-fighting 或是 invalid normal ) 在 Windows 的 3D viewer 中可以看到全部面都有一些問題 這個我研究了一段時間,發現這是跟 extrude 模型的時候的設定有關。一般來說,為了避免模型在背面出現破圖,所以在 render 的時候也會把 rendering face 設成雙面。以下為其中一個例子 BABYLON.MeshBuilder.ExtrudeShape("container-outerwall", { shape: externalBorder, path: [extrusionStart,extrusionEnd], cap: BABYLON.Mesh.CAP_ALL, sideOrientation: BABYLON.Mesh.DOUBLESIDE }, scene); 可是這樣在 CSG 處理的時候卻會出現問題,我懷疑是與 Mesh.CAPALL 的設定有關,可是我並沒有深入研究是不是 CAP_ALL 設定了之後就不能使用 DOUBLESIDE 的設定。 然而在把sideOrientation 改成 FONTSIDE 之後問題就解決了。 BABYLON.MeshBuilder.ExtrudeShape("container-outerwall", { shape: externalBorder, path: [extrusionStart,extrusionEnd], cap: BABYLON.Mesh.CAP_ALL, sideOrientation: BABYLON.Mesh.FRONTSIDE }, scene); 所以結論就是如果你要進行 CSG 操作的話 sideOrientation 不要設成 DOUBLESIDE 就對了。
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…
Refused to execute script from ‘xxx’ because its MIME type (‘text/plain’) is not executable.
Go 在 Windows 10 上使用 File Server 傳送 JavaScript 的時候間中會出現這個錯誤,網上的其中一個解決方法是更改系統 register 讓 Windows 把 JavaScript 辨認為 text/javascript。然而如果你不想透過更改系統設定的方法解決的話你也可以透過編程方法解決。 使用 Router 來手動設定正確的 Mime Type func mrouter(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if filepath.Ext(r.RequestURI) == ".js" { //Requesting a js file w.Header().Add("Content-Type", "text/javascript") h.ServeHTTP(w, r) } else { h.ServeHTTP(w, r) } }) } 使用方法如下 fs := http.FileServer(http.Dir("./web")) http.Handle("/", mrouter(fs)) 這樣便修好了
目前第 5 頁,共有 12 頁