顯示具有 IR 標籤的文章。 顯示所有文章
顯示具有 IR 標籤的文章。 顯示所有文章

2016年2月29日 星期一

[Arduino] 完整抓取 凱擘 kbro 遙控器紅外線原碼並發出重新發出以控制機上盒

再次與 kbro 凱擘機上盒遙控器搏鬥:


先講結果, kbro 遙控器發射出來的 IR code 頻率為 38 kHz, 是 XMP protocol  (應該是). IRremote/IRLib 抓取 IR 碼因為 bug 所以中間會斷掉, 沒有辦法抓到完整的碼, 需要將 IR receiver 接到 Arduino 的 interrupt pin 抓才能抓到完整的碼.

如果你不想看以下落落長的過程, 只想用 Arduino IRremote 發射已經抓出來的完整 kbro 凱擘機上盒遙控器碼. 請直接服用以下 sketch:

IRsendKbro.ino : 測試程式, 已寫入所有 kbro raw code, unmark 之後可以測試遙控機上盒.

LfPanasonic2KbroIRtransf.ino: 將 Sony LF-Box1 發出的 Panasonic CATV(1)碼轉為凱擘碼的 IR 轉換器. (請參考這篇)

其實說搏鬥也很可笑, 在台灣應該很多人知道凱擘使用的紅外線碼, 但是網路上能找到的資訊很少, 而且相當分散, 用 Arduino 的 IRremote 或 IRLib (也是基於 IRremote) 都無法解譯 kbro 機上盒遙控器碼, 更無法用Arduino去發射 IR 碼來控制機上盒, 也找不到人有寫這塊.

這次找到時間重新解析 kbro 的 IR 碼, 讓我一個外行人搞懂更多關於 IR 的事情, 就算很蠢走了歪路, 最後結果得到滿意的答案, 還是很開心.

在一年多前寫的一篇 [Arduino] 用 IRrepeater 抓取 kbro 凱擘遙控器的 IR raw code , 當時利用 repeater 程式抓取 kbro 凱擘機上盒遙控器碼, 利用 Arduino 發射 raw code 對應於自己家中的機上盒是可以用的, 但後來發現僅限於我家中那個機上盒, 拿到長輩家比較舊的凱擘機上盒就完全無效. 令人相當苦惱.

抓取紅外線發射頻率

對一個外行人來說, 遇到謎樣的紅外線碼, 首先上網找一下. 以前菜鳥剛弄紅外線時買的紅外線接收器就是光華商場買來就用. 雖然商家有講型號, 並且上網找了 datasheet. 但買了就用從來沒有關心過接收器的真正功能.

從網路上找一下, 發現最基本的就是紅外線接收器有分不同的頻率, 有 36, 38, 40 kHz ... 等等的發射頻率. 最常見的是 38 kHz. 首先我先懷疑到凱擘可能使用的頻率不是常見的頻率:



參考了 CY's Tech Talk 的 1.4.3 IR Receiver Components and Schematics , CY是 IRLib 的作者. 參考 CY 的blog上網買了 TSOP38236 (36 kHz), TSOP38256 (56 kHz) 和  TSMP58000 這幾種. 關於買特定型號的電子零件和光華商場買有不同, 要找到能夠小量買的商家不容易, 起碼以我一個外行人去找不好找. 後來仍是到淘寶找店家買. 可以小量大約十個以內但是運費就省不了. 十個對我來說還是太多了, 但沒辦法.

終於等到這幾種 IR receiver 寄到來抓凱擘遙控碼, 很不幸, 俺運氣沒那麼好. 用 IRremote 或 IRLib 抓出來的 raw code, 用 Arduino 發出來仍舊不能控制凱擘機上盒. 不過用一併買回來的 TSMP58000 搭配 CY 的 IRLib 中的 IRfreq.ino 來抓取遙控碼的頻率:

在 Arduino mini pro 用的 interrupt pin 是 pin 2:

IRfreq.ino 一開始會印出 pin 腳:

測試了幾支不同的遙控器, 可以看到它印出遙控器發出的頻率, (38) 那個就是凱擘遙控器的頻率:

TSMP58000 是 IR learner 而不是 IR receiver. 一般的 IR receiver 的封裝中會帶有 bandpass filter 調諧到特定的頻率, 例如: 36 kHz, 38 kHz:

但是 TSMP58000 則沒有 bandpass filter, 所以會讀取到更原始的 raw code. 根據 CY 的說法是可以用 TSMP58000 去取得 raw code, 但是會需要比一般 IR receiver 更多的記憶體. 所以他只把 TSMP58000 這樣的 IR learner 拿來偵測控制碼的頻率.

問題是, 外行人的我滿心認為一定是 kbro 使用有別於一般 38 kHz 頻率, 例如: 40 kHz, 是我用錯 IR receiver 所以造成抓取 raw code 失敗. 但用 IRfreq.ino 一抓, 可惡的 kbro 白色遙控器發出來的頻率居然是非常標準的 38 kHz, 為此相當沮喪的卡關了一陣子. <=== 事實上得知頻率仍是很重要的事.

查知 kbro 機上盒疑似使用XMP

OK, 卡了幾天關之後, 灰心的我還是上網碰碰運氣, 之前其實就知道網路上的 slingbox 社群有流傳支援 kbro 的設定檔. 但是我都是 download 到 binary 的檔案, 打開當然是編碼過, 人類不懂的二元檔. 卡關那幾天心血來潮就找了它的原始 slingbox 檔來看, 它被發布在著名的 JP1 remotes 網站上. 這個網站是一些 IR 遙控器愛好者分享資訊網站, 其中就有 slingbox 使用的 kbro 凱擘機上盒控制檔:

RMDU Remotemaster source file for the Kbro Hyundai Digital Technology digital set top box (DSTB).
http://www.hifi-remote.com/forums/dload.php?action=file&file_id=8399Kbro Hyundai Digital Technology digital set top box (DSTB) (1).rmdu

上面這個檔案是原始檔(免費註冊登入JP1 remotes 後能取得), 用來產出真正 slingbox 使用的 binary 檔. 原始檔是人類可以看懂的, 可以看到下面的字眼:

Description=Kbro Hyundai Digital Technology digital set top box (DSTB)
Remote.name=Slingbox with UEI RV Chip
Remote.signature=BINRV
DeviceType=Cable
DeviceIndex=1
SetupCode=2010
Protocol=01 6C
Protocol.name=XMP (Slingbox)
Protocol.variantName=JP1Slingbox
ProtocolParms=88 16 null 0 0
FixedData=1B 0F 44 58 1F 00 40
Function.0.name=power
Function.0.hex=0F

可以看到 protocol  是 01 6C, 名稱為XMP, google 一查確實有這樣的 IR protocol, 再查, 發現國外也有 cable TV 公司使用這樣的碼, 而且用 Arduino 去解析並產出 XMP 碼並不成功. 找了數個文章都沒有看到 XMP 和 Arudino IRremote 合作的線索. 但皇天不負苦心人, 找到一個對我很重要的一篇 Arduino forum 的討論: Reading IR signals from Comcast XR2 remote

這篇討論由 robertanthony02 發動, 他也是想用 Arduino parser XMP 不成功. 討論的前兩頁給我幾個以前不知道的線索, 首先, IR receiver 是有對於 XMP 比較建議的型號, 也就是說比較著名ㄧ點的 IR receiver 的型號(通常也會貴一些), 它的 datasheet 是有建議針對哪種 protocol 比較友善的 receiver:

所以依據網路找到的 datasheet 建議我又上網買了 TSOP38338, 這個 IR receiver 被推薦使用在 XMP 上. 買來用用看. 結果到貨後滿心歡喜的用 IRremote 一弄, 當場又囧了, 沒錯! 抓出來的 raw code 居然仍無法使用!

至此, 第二次進入卡關. 又花了幾百塊買 TSOP38338, 重點是沒有得到新的突破, 再次令我沮喪...

AnalysIR 的 Arduino_Record_Long_AirConditioner_Infrared_Signals_10 sketch

所幸天公伯沒有把門堵死, 累積走過的一切仍有收穫, 在 Reading IR signals from Comcast XR2 remote 討論串中, 前兩頁中 robertanthony02 和 AnalysIR 兩人的討論非常重要.

AnalysIR 就是 AnalysIR 這個軟體專案的開發者, AnalysIR 是一個可以搭配數種開發板, 包含 Arduino, 將截獲的 IR code 在 PC 上繪製成圖形, 也就是軟體示波器. 個人非商用版本很便宜, $10 美金約 $300 台幣上下, 和一個硬體示波器的價格比便宜太多了. 如果只是應用在 IR 場合不想花大錢買硬體示波器的話 AnalysIR是滿不錯的選擇.

在討論中, AnalysIR 他提供給 robertanthony02 一個很重要的 sketch 來進行抓取 IR code 的任務. 這個 sketch 叫做 Arduino_Record_Long_AirConditioner_Infrared_Signals_10.txt, 這個 sketch 最早被 AnalysIR 發表在 Air Conditioners: Recording long Infrared Remote control signals with Arduino 這篇文章中.

這時候發生令我振奮的結果, 沒錯! AnalysIR 的 sketch 可以用, 搭配 TSOP38338 抓出來的 raw code 可以控制我手上有的兩個外型不同的凱擘機上盒.

AnalysIR 的 sketch 跳過了 IRremote, 將 IR receiver 接到 interrupt pin 去抓取 raw code. 這個程式本來是用來對付一些冷氣機的遙控器, 因為這些遙控器所發出的 code 特別長, 而 IRremote 的 buffer 有 100 的長度限制, 所以他做了這個 sketch 來抓. 剛好它也繞過了我遇到的問題. 後面分所抓出來的凱擘 IR code, 它的長度是 71 並不是因為太長超過 buffer 無法抓取, 而是發現另一個 IRremote 的問題.

總之, AnalysIR 的 sketch 讓我順利的抓出 kbro 機上盒的 raw code, 我放置在本文後的附錄, 我只抓了用來選台的一些按鍵. 搭配我的 IR translator 和 LF-Box1 使用. 至於其他的按鍵同好們可以用相同的 sketch 抓取. 我測試過不只 TSOP38338 (XMP首選) 可以抓出來, 用光華商場買的 38 kHz IR receiver 也可以抓出來沒問題.

利用抓出來的 raw code, 我修改了做給 Sony LF-Box1 用的 IR code 轉換器, 把它發出的 Panasonic code 轉為 kbro cable box 的 code, 這樣 LF-Box1 可以遙控 kbro box. 程式碼在此: LfPanasonic2KbroIRtransf.ino, 稍有經驗的人應該可以看出程式中的問題來, 在最後一段會說怎麼處理.

我還寫了一個簡單的 sketch, 將所有抓出來的 kbro raw code 都放進去: IRsendKbro.ino, 可以用來測試.

IRremote/IRLib 無法適應 XMP protocol

事實上在找到 AnalysIR 的  sketch 之前, 我花了一些時間 trace IRremote/IRLib 的原始碼. 因為從邏輯上來說 IRremote 雖然沒有支援 XMP protocol, 但是直接從 ISR 抓出來的 raw code 應該要可以使用, 但事實上沒辦法用. 所以 IRremote 中抓 raw code 的算法肯定有問題.

不過我沒有貴鬆鬆的示波器, 也沒買 AnalysIR, 所以沒有對照組可以用來抓 IRremote 的問題. 但是找到 AnalysIR 的 sketch 之後, 分析抓出來的 kbro raw code 就瞭解了一些事情.

首先, AnalysIR 的 sketch 抓出來完整的 raw code 長度為 71, 而我以前用 IRrepeator 抓出來的長度是 17, 很明顯 IRremote 抓出來的長度少了很多. 判斷不是被錯誤過濾掉就是誤判了結束點.

再以抓出來的 channel+ 按鈕為例:

Raw: (71) 224, 892, 224, 2252, 224, 752, 224, 2796, 228, 1292, 232, 1292, 224, 1432, 232, 1836, 228, 14264, 228, 888, 228, 1024, 228, 748, 232, 744, 232, 748, 232, 2512, 236, 744, 224, 752, 228, 15468, 280, 840, 232, 2244, 232, 744, 224, 2792, 228, 1296, 232, 1288, 228, 1432, 228, 1836, 228, 14268, 224, 892, 224, 2112, 224, 1844, 220, 756, 224, 752, 228, 2520, 228, 748, 228, 752, 228

IR LED 亮是 mark, 暗是 space. 它是 mark, space, mark space... 這樣一直排下去, 可以發現其中有抓出特別長的間隔時間, 就是我上面紅色標出來的數字. 以這個數字為間隔可以發現很長的間隔出現之前, 其他的 mark, space 數字一共剛好就是17, 就是我以前抓的長度. 至此可以推斷出來 IRremote 判斷 IR code 結尾是有問題的. 過長的時間間隔會造成 IRremote 的誤判, 誤以為整個 raw code 結束了.

這時候繼續 trace IRremote, 發現了癥結點在 IRremoteInt.h 和 IRremote.cpp (其實也沒幾個檔案):

Arduino-IRremote/IRremote.cpp

Arduino-IRremote/IRremoteInt.h  // Minimum gap between IR transmissions
                                        #define _GAP            5000
                                        #define GAP_TICKS       (_GAP/USECPERTICK)
    Arduino-IRremote/IRremoteInt.h  // microseconds per clock interrupt tick
                                                           #define USECPERTICK    50

可以看到 IRremote 是 state machine 的設計, 以一些研判條件來推進整個 parser process 的 state.

if (irparams.timer > GAP_TICKS) {
        irparams.rcvstate = STATE_STOP;
}

當抓出來的 ir timer 小於 GAP_TICKS 的 ticks 數量, 代表要將 IR receiver 的狀態推進到 STATE_STOP, 而 GAP_TICKS 則是從 _GAP 5000  算出來, 5000 的單位是 microseconds , 這相當小, 是 10 的 -6 次方. 所以是 0.005 秒. 而上面的紅色數字為 14264, 15468 14268, 明顯都大於 5000 這個數字.

所以我刻意加大 _GAP, 加大到 20000, 可以處理一部分上面的 timer gap, 抓出更長一些的 raw code. 可是很奇特的是, 從數字上去計算, 應該比抓出來的數字例如 15468 稍微大一點就可以避免誤判, 但實際測試出來卻不是這樣, _GAP 必須要大上很多才行, 這點我目前也不明白, 應該還有什麼東西拖延到實際的 ticks 數字.

總之 IRremote 的 _GAP 不修改的話, 是肯定會對 XMP protocol 造成結束碼的誤判. 未來如果要想為 IRremote 添加 XMP 支援, 則這個問題不能忽略.

用 PROGMEM 解決 raw code 陣列過大問題

第一個版本 LF-Box1 遙控 kbro box 程式碼: LfPanasonic2KbroIRtransf.ino, 前面有提到出了問題. 由於抓出來的 kbro raw code 很大, 每個按鈕有 71 個 unsigned int (Arduino 上是 2 bytes) 的大小, 實際一用發現當整個 arrary 很大的時候, 會造成 sketch 上載成功但是無法運作. 這個問題大約卡了一天, 後來找到這個文件 Dean Camera's "GCC and the PROGMEM Attribute", 它的說明相當清楚, 問題就是出在實行時期 Arduino 會將使用到的陣列由 ROM 拷貝到 RAM, 如果 array 太大就會把 RAM 塞爆, 造成程式無法執行.

我使用的 Arduino mini pro 內帶 32KB Flash memory (ROM), 2KB SRAM (RAM), SRAM就是執行時期能用的記憶體大小. AVR-GCC在起始的時候會將用到的 array 從用來存放程式的ROM拷貝到 RAM 中執行, 這樣速度會比較快, 但是 array 加上執行時期用掉的其他空間不能大於 2KB.

我們在 upload sketch 到 Arduino 上時, Arduino IDE 上顯示的大小是 32 KB 的 ROM, 而不是執行時期的 RAM, 請注意.

所以我實際遇到的狀況發現陣列存放 12 個 kbro raw code 時 sketch 就無法執行. 細算一下:
    71 * 2 (bytes) = 142 (bytes)
    142 * 12 =  1704 (bytes) <=== 很接近 2KB

若包含其他執行時期的 heap, stack 的消耗, 很容易就把只有 2KB 的 RAM 撐爆. 葉難 的 Arduino:關於記憶體之二三事 文章有佷漂亮的圖片可以參考.

那怎麼避免這樣的狀況呢? 可以利用 PROGMEM 變數屬性告訴 AVR-GCC 將該陣列保留在 ROM 中不要copy到 RAM 中. 而是利用 memory_P 在要用的時候 copy 到我預先在 RAM 中宣告好的 buffer, 再把 IR raw code 發出去. 修正版本在此: LfPanasonic2KbroIRtransf.ino

修正過後原本的靈異現象就不再出現, 而且可以放下更多的 kbro raw code.

最後

終於能夠順利抓出 kbro 凱擘機上盒的遙控碼, 而且用 IRremote 重新播放出去. 雖然 IRremote 沒有辦法 parser XMP protocol, 但總算是可以發出 raw code. 未來若有時間有空閒可以將 XMP 的 parser 添加到 IRremote, 但這時候示波器就很必要了.



附錄:

 kbro 遙控器 Raw data 完整版 (已拿掉第一個 code, 長度為 71):
Caputure by Arduino_Record_Long_AirConditioner_Infrared_Signals_10

CHANNEL UP:
Raw: (71) 224, 892, 224, 2252, 224, 752, 224, 2796, 228, 1292, 232, 1292, 224, 1432, 232, 1836, 228, 14264, 228, 888, 228, 1024, 228, 748, 232, 744, 232, 748, 232, 2512, 236, 744, 224, 752, 228, 15468, 280, 840, 232, 2244, 232, 744, 224, 2792, 228, 1296, 232, 1288, 228, 1432, 228, 1836, 228, 14268, 224, 892, 224, 2112, 224, 1844, 220, 756, 224, 752, 228, 2520, 228, 748, 228, 752, 228

CHANNEL DOWN:
Raw: (71) 224, 892, 232, 2244, 232, 744, 232, 2788, 224, 1296, 228, 1296, 232, 1424, 228, 1840, 224, 14268, 232, 884, 232, 880, 224, 756, 224, 752, 228, 752, 224, 2656, 228, 752, 228, 748, 232, 15464, 232, 884, 232, 2244, 228, 748, 232, 2788, 232, 1288, 228, 1296, 228, 1428, 224, 1844, 232, 14260, 228, 888, 228, 1972, 228, 1840, 224, 752, 228, 748, 228, 2656, 228, 748, 232, 748, 232

POWER
Raw: (71) 228, 892, 224, 2248, 228, 752, 224, 2792, 228, 1296, 232, 1288, 228, 1432, 232, 1832, 228, 14268, 232, 880, 224, 756, 308, 668, 312, 668, 228, 748, 228, 2792, 228, 748, 232, 748, 232, 15420, 224, 896, 232, 2240, 232, 748, 232, 2784, 224, 1300, 228, 1292, 232, 1428, 224, 1840, 224, 14268, 232, 884, 232, 1832, 232, 1836, 224, 752, 228, 752, 228, 2788, 232, 748, 228, 748, 232

ONE 1:
Raw: (71) 232, 888, 232, 2244, 220, 756, 228, 2788, 232, 1292, 224, 1300, 224, 1432, 232, 1836, 224, 14268, 228, 888, 284, 2596, 224, 756, 228, 748, 232, 748, 224, 888, 232, 748, 224, 752, 232, 15412, 228, 888, 232, 2244, 224, 752, 232, 2788, 232, 1288, 228, 1296, 228, 1428, 232, 1836, 224, 14268, 232, 884, 220, 1572, 228, 1840, 228, 752, 220, 756, 228, 884, 224, 756, 228, 748, 232,

TWO 2:
Raw: (71) 232, 888, 232, 2240, 228, 752, 228, 2788, 224, 1300, 228, 1292, 232, 1428, 224, 1840, 232, 14264, 224, 892, 224, 2520, 232, 748, 224, 752, 232, 748, 224, 1024, 228, 752, 220, 756, 228, 15452, 224, 892, 228, 2248, 228, 748, 228, 2792, 228, 1292, 224, 1300, 224, 1432, 232, 1836, 224, 14268, 232, 884, 224, 1436, 224, 1840, 232, 744, 228, 752, 228, 1020, 224, 756, 228, 748, 224

THREE 3:
Raw: (71) 232, 888, 232, 2240, 224, 756, 228, 2788, 232, 1292, 224, 1296, 232, 1428, 224, 1844, 224, 14268, 232, 884, 224, 2384, 232, 748, 224, 752, 228, 752, 304, 1080, 228, 752, 232, 744, 228, 15444, 224, 896, 224, 2248, 232, 748, 224, 2792, 228, 1296, 232, 1288, 224, 1436, 228, 1836, 224, 14272, 228, 884, 224, 1300, 224, 1840, 232, 748, 224, 752, 232, 1156, 224, 752, 312, 664, 224

FOUR 4:
Raw: (71) 224, 896, 224, 2248, 228, 752, 316, 2700, 224, 1300, 228, 1292, 224, 1436, 228, 1840, 228, 14264, 308, 808, 228, 2244, 224, 756, 228, 748, 232, 744, 228, 1296, 232, 748, 224, 752, 316, 15356, 228, 888, 232, 2244, 224, 752, 312, 2708, 232, 1288, 228, 1296, 228, 1432, 224, 1840, 228, 14268, 232, 880, 228, 1160, 228, 1836, 224, 752, 316, 664, 308, 1212, 232, 748, 224, 752, 228

FIVE 5:
Raw: (71) 224, 896, 220, 2252, 228, 752, 228, 2788, 224, 1300, 228, 1292, 224, 1436, 224, 1840, 232, 14264, 224, 892, 228, 2108, 224, 752, 232, 748, 224, 752, 312, 1348, 232, 748, 308, 668, 316, 15360, 228, 892, 228, 2244, 232, 748, 224, 2792, 228, 1296, 232, 1292, 224, 1432, 232, 1836, 224, 14268, 228, 888, 224, 1024, 228, 1840, 232, 744, 228, 752, 232, 1424, 224, 756, 228, 748, 224

SIX 6:
Raw: (71) 224, 892, 224, 2252, 228, 748, 232, 2788, 224, 1296, 232, 1292, 224, 1432, 228, 1840, 232, 14260, 228, 888, 232, 1972, 224, 752, 232, 748, 224, 752, 228, 1568, 220, 756, 228, 752, 220, 15420, 232, 888, 232, 2240, 228, 752, 228, 2788, 224, 1300, 228, 1292, 232, 1428, 224, 1840, 232, 14264, 224, 888, 232, 884, 224, 1844, 228, 748, 232, 744, 228, 1568, 232, 748, 224, 752, 232

SEVEN 7:
Raw: (71) 224, 892, 224, 2252, 228, 748, 224, 2796, 224, 1296, 232, 1292, 228, 1428, 228, 1840, 232, 14264, 224, 888, 232, 1836, 224, 752, 312, 668, 304, 672, 312, 1616, 236, 744, 312, 664, 316, 15344, 224, 892, 224, 2252, 228, 748, 236, 2784, 224, 1296, 232, 1292, 224, 1432, 228, 1840, 220, 14272, 232, 884, 232, 748, 224, 1840, 232, 748, 224, 752, 312, 1616, 224, 756, 228, 752, 220

EIGHT 8:
Raw: (71) 232, 884, 224, 2252, 228, 752, 228, 2788, 224, 1296, 232, 1292, 224, 1432, 228, 1840, 232, 14264, 224, 888, 232, 1700, 224, 752, 228, 752, 304, 672, 312, 1756, 228, 748, 228, 752, 228, 15428, 224, 896, 220, 2252, 228, 752, 228, 2788, 224, 1300, 228, 1292, 224, 1436, 224, 1840, 232, 14264, 224, 888, 232, 2788, 232, 1832, 228, 752, 232, 744, 228, 1840, 228, 748, 308, 620, 344

NINE 9:
Raw: (71) 232, 888, 232, 2240, 224, 756, 228, 2788, 224, 1300, 224, 1296, 232, 1428, 224, 1840, 228, 14268, 224, 888, 228, 1568, 232, 744, 312, 668, 312, 664, 312, 1892, 228, 748, 224, 756, 312, 15384, 232, 888, 228, 2248, 220, 756, 228, 2788, 232, 1292, 224, 1300, 228, 1428, 224, 1844, 224, 14268, 232, 884, 224, 2660, 228, 1836, 232, 744, 228, 752, 316, 1884, 228, 752, 228, 748, 224

ZERO 0:
Raw: (71) 224, 896, 224, 2248, 228, 752, 232, 2784, 228, 1296, 228, 1292, 224, 1436, 228, 1836, 232, 14264, 224, 892, 228, 2788, 236, 744, 228, 748, 232, 748, 224, 752, 232, 748, 224, 752, 232, 15424, 232, 888, 224, 2252, 224, 752, 232, 2784, 228, 1296, 228, 1292, 232, 1428, 224, 1840, 232, 14264, 224, 892, 228, 1700, 224, 1844, 224, 752, 316, 664, 224, 752, 232, 744, 228, 752, 228

OK:
Raw: (107) 228, 888, 232, 2244, 220, 756, 312, 2708, 228, 1292, 224, 1300, 228, 1428, 224, 1844, 228, 14264, 232, 884, 224, 1844, 228, 748, 224, 756, 228, 1020, 232, 1428, 224, 752, 232, 748, 224, 65180, 232, 888, 232, 2244, 220, 756, 228, 2788, 232, 1292, 228, 1292, 232, 1428, 224, 1844, 228, 14264, 232, 884, 224, 752, 232, 1836, 224, 752, 232, 1020, 224, 1436, 224, 752, 232, 744, 228, 16028, 228, 888, 232, 2244, 220, 756, 312, 2704, 224, 1300, 228, 1292, 232, 1428, 224, 1844, 228, 14264, 224, 892, 228, 748, 308, 1760, 224, 752, 232, 1020, 224, 1436, 228, 748, 224, 752, 228

RETURN:
Raw: (71) 224, 896, 220, 2252, 228, 752, 232, 2784, 224, 1300, 228, 1292, 224, 1436, 224, 1840, 232, 14264, 224, 888, 232, 1292, 224, 752, 232, 748, 224, 1028, 224, 1976, 232, 748, 224, 752, 228, 15520, 224, 892, 228, 2248, 228, 748, 228, 2792, 228, 1292, 224, 1300, 228, 1428, 232, 1836, 232, 14260, 232, 884, 224, 2384, 228, 1840, 232, 744, 228, 1024, 232, 1972, 220, 756, 228, 748, 224

i/PINFO:
Raw: (71) 224, 892, 228, 2248, 228, 748, 224, 2796, 224, 1296, 232, 1292, 224, 1432, 228, 1840, 228, 14268, 228, 884, 224, 1164, 228, 748, 224, 756, 224, 1024, 232, 2108, 224, 752, 228, 748, 228, 15464, 224, 896, 224, 2248, 228, 752, 232, 2784, 224, 1300, 280, 1240, 232, 1428, 224, 1840, 228, 14268, 228, 884, 224, 2252, 224, 1840, 232, 748, 224, 1028, 224, 2112, 232, 744, 228, 752, 228

2016年2月13日 星期六

[Locationfree] 製作紅外線遙控轉換器 IR translator LF-BOX1 Panasonic CATV/DVD 轉 Tivo

上一篇 [Arduino] 製作紅外線遙控轉換器 IR translate Panasonic 電漿電視轉 Kbro 凱擘 , 最近用同樣的原理製作了 LF-BOX1 的紅外線遙控轉換器, 把 LF-BOX1 所發出的 Panasonic CATV(1)/DVD(1) 紅外線碼轉換為 Tivo 紅外線遙控碼, 這樣可以讓 LF-BOX1/LF-PK20 的組合遙控原本不支援的 Tivo.

首先簡單說明一下 Sony LF-BOX1 和 LF-PK20 日版之間的使用關係, Locationfree LF-PK20 是 server 端, 可以將 AV 端子輸出的器材轉換成為網路串流, 讓使用者透過 Intranet 或 Internet 看電視. 由於 LF-PK20 是 server 端, 所以需要一個 client 端, 通常是安裝在 Windows 上的 Locationfree player 軟體. 除此之外, 對於日版 LF-PK20 (只有日版)還有另一種選擇就是 LF-BOX1 這樣的專屬 client 端設備, 它可以透過網路連接遠端的 LF-PK20 server, 並且透過 AV 端子輸出到電視上, 達成遠端看電視的目的. LF-BOX1 也是在 LAN 下輸出畫質最好的一個 Locationfree client.

連接關係是這樣:

Video Output path:
set-top box (ex. Tivo or Kbro) ---[AV]---> LF-PK20 ---[LAN/WAN]---> LF-BOX1 ---> TV

User IR Input path:
User press remote ---> LF-BOX1 ---[LAN/WAN]---> LF-PK20 ---> set-top box (ex: Tivo or Kbro)

事實上, LF-BOX1 中內建有和 Tivo 很接近的遙控碼可以使用, 但有缺點就是上下鍵會吐兩次 IR code 造成 Tivo 選節目的時候一次跳兩格, 相當惱人. 而且也不支援 Tivo 的數字鍵選台. 所以想透過製作紅外線遙控轉換器把某個 LF-BOX1 內建發出的 IR code 轉換成為 Tivo 紅外線碼. 這樣在遠端就可以遙控 Tivo 選擇節目或者選台.

IR 遙控路徑變成這樣:
User press remote ---> LF-BOX1 ---[LAN/WAN]---> LF-PK20 ---> Arduino IR Translator  ---> set-top box (ex: Tivo or Kbro)

我製作的 Arduino 轉換器就是串接在 server 端的 LF-PK20 和 LF-PK20 附帶的 IR 發送器 (IR emitter) 之間. 它的構造就是 IR Detector + IR Emitter.

轉換作用像這樣:

LF-BOX1 ---> LF-PK20 --- [Panasonic DVD(1) code] ---> Arduino IR Translator ---> [Tivo code]

我在 LF-BOX1 上面選擇的遙控碼為 松下 CATV(1) 和 DVD(1), 我曾試過 Sony 的 IR code, 但發現 Arduino 的 IRremote library 讀取 Sony IR code 作出的 hash code 會有碰撞的狀況, 也就是數個按鈕可能會抓到同一個 hash code, 造成無法判斷使用者按了哪個鍵. 另外, 使用 Sony 的過程有發現當 IR detector 和 IR emitter 寫在同一支程式中, 像我現在的應用就是需要同時使用 detector 和 emitter, 則 IRremote 寫出來的程式所發出的 IR code 會失敗. 至於原因我並沒有探究, 總之改為抓 Panasonic code 就 OK 了.

下面就是把 LF-BOX1 中的遙控碼設定為 Panasonic (松下) CATV(1) 另外次遙控器設定為 DVD(1). 會 mapping 兩組的原因是因為有時候給家中其他人使用如果不需要太複雜太多的功能, 用 CATV(1) 就可以了, 如果需要遙控或者快轉等功能則 DVD(1) 的按鍵比較多:


先用麵包板測試一下 LF-BOX1 的 IR emitter 座的腳位定義, 也就是故意將 LF-BOX1 附贈的 IR emitter 接到 Arduino 上面, 利用 Arduino 透過它發送 IR code, 如果用數位像機看到 IR LED 有亮起來, 就代表可以控制:

OK, 透過數位像機可以看到紅光, 代表 IR LED 有亮起來:

立體聲腳座的定義, 靠外側黑色是接地, 內側紅色是供電:

知道腳位定義後, 以相同的腳位把一顆 IR LED 焊接到立體聲座上:

另外這此我使用的 IR detector 是 VS-1838B:

我的 IR detector 接到 Arduino pin 12, IR emitter 接到 pin 3 (IRremote 的預設). 並且用一個零件盒裝起來. 當然要記得開三個洞, 一個給 IR LED, 一個 IR emitter, 然後是供電的 USB:

IR LED, 這端接到 LF-BOX1 上的 IR emitter 座:

近照部分電路與 USB 取電座:

硬體這樣就完成了. 原始的 LF-PK20 配置像下圖. 它附帶的 IR emitter 直接接到 IR 座. 事實上它可以接兩個 emitter, emitter 也可以自己做:


改為把我做的 IR translator 接到 LF-PK20 上, 然後 IR emitter 接到自製的 IR translator 上. 別接錯孔, 接錯動不了:

近照:

另一個方向, USB還沒有接電:

IR LED 端近照:

整體:

硬體這樣就完成了. 軟體部分已上傳 github:
https://github.com/smallbeetw/arduinosketch/commit/75a61430bfcdfcc47470b8a4cee575e6e0c1d2cf

下面是另一個試作品, 這個試作品是沒有用黑盒子把電路裝起來, 直接做了一個 IR LED 和 立體聲公頭 焊接在一起的 IR emitter, 插到 LF-PK20 上發射 IR code, 然後用另一個裸露的電路板接收, 這個做法堪用但比較差, 原因是因為接收器可能會接收一般其他遙控器的 IR code, 這樣比較耗電.

下面組圖就不解釋了, 有需要就參考著做, 只要腳位弄對, 插到 LF-PK20 上就可以使用. 我沒有串電阻, 如果需要可以串上;

注意腳位, 黑的接 LED 短腳, 紅的接 LED 長腳:



完成後插到 LF-PK20 上, 用數位像機確認:

2015年3月30日 星期一

[Arduino] ThinkPad x61 IR UltraBase DOCK - 添加IR遙控功能 (圖多, 文囉唆)







* 一開始...
這裡先說好, 小弟不是電子科系出身, 對電子零件焊接還有Arduino都是初學, 弄得醜就請各位專家砲小力一點...

hm... 事情是這樣的, 我家有台可以用skype打視訊電話的 smart TV, 現在很多的 smart TV都有這個功能. 但是舊一點的液晶電視就沒辦法打skype. 用 smart TV打skype有個好處就是用電視遙控器按OK就可以接通來電, 起碼我的電視設計是這樣, 比起用電腦打skype操作上方便很多, one button搞定.

那... 舊的液晶電視想要能夠one button接skype怎麼辦呢? 很顯然要掛一台電腦到電視上面, 然後要'訓練'家裡的電視遙控器去接skype來電. 我有台x61s, 就用這個裝skype接到電視上面, x61s省電輕薄又安靜, 滿適合當HTPC, 但是要怎麼讓電腦能收遙控器的 IR訊號呢?

我很直覺就到拍賣上去買了所謂的 HTPC 遙控器, 就是一個透過 USB 接頭接上電腦的 IR 接收器, 然後一併帶個遙控器, 在Windows 下還要裝 IR 軟體. 如下圖:

 
IR軟體可以透過設定去下很多軟體的hotkey, 看起來滿完美, 不過有缺點:
 a. 加上電視一共需要使用兩個遙控器, 我家的老爸老媽一定搞不懂哪個控制哪個.
 b. 好, 基於a.缺點, 那我就想直接使用TV的遙控器去接skype, '理論上'設定Windows 下的 IR軟體就可以了, 不幸的是, 測過 IR 軟體無法抓到我家的 panasonic 遙控器的 code, 我也不懂怎麼改 Windows 下的 code.
 c. 使用 USB 型的 IR receiver 有個原生的缺點, 就是無法幫關掉的電腦開機, 得要手動去開, 再不然就是電腦要一直開著.
我家的電視遙控器是這個:
 
 
So, 因為有上面幾個缺點 , 我在測過市售的產品無法抓到 panasonic code之後, 就自己試試看用 Teensy 寫程式進去抓抓看, 結果很幸運的, pansonic code 抓得到, 雖然無法 parser 出來是 panasonic code, 但是可以做出一個 hash code, 所以我就用 Teensy 做一個 IR receiver, 長像這樣:

 
Teensy 2.0 相當小:

 
Teensy網站這裡, 我使用的是2.0版Teensy, 它是相容於 Arduino 的一個 USB development board, 它雖然不像Arduino是open hardware, 但是 Teensy是很棒的小型 Arduino 的替代品, 它的大小和 Arduino mini差不多, 但是 Teensy內建了 USB Mini-B 的接頭而 Arduino mini卻沒有. 當然另一個原因是, 我的手上剛好有兩顆團購來的 Teensy($16鎂不含運), 當然就是用上去. Laughing
我做的第一代 IR receiver solution 可以解決 a. b. 兩個問題, 它可以收到 panasonic IR code 並且寫程式轉成 skype 的hotkey 去接 skype 影像電話. 基本上得到的操作行為OK, 但是並沒有解決 c. 問題, 就是電腦要一直開機.
 
* 拆!
在做第一代接收器之前, 就買了 x61 的 UltraBase DOCK本來想拿來用, 拍賣上很便宜, 不知為何才幾百元台幣:

 
當然用過x61 dock的人都知道, 有個 power button 在 dock 上面可以幫電腦開機 (廢話!) . 我本來很簡單的想法, 就是把dock上的power 線拉出來, 接到 teensy 上我就可以用 teensy去控制電腦開機.
拆任何東西前建議都照個相! 照完不廢話! 拆殼! dock上蓋螺絲拿掉, 脫掉上衣(羞~)之後看起來像這樣:

 
有看到右下角 power button, 紅黑兩條線 short 應該就是開機, 等於按下button:

 
但最重要的是, 看到 dock 靠左手腕的部份有個空間, 看起來是拿來裝小風扇用的, 好玩的是並沒有看到風扇的電源接頭:

 
這時候小笨腦興起念頭, 想說 teensy也滿小的, 應該塞得進去這個空間, 只要把電源和USB接上, 就可以將 IR receiver塞到 x61 UltraBase DOCK 中, 變成能夠收紅外線訊號並且發出key code控制電腦的 SMART DOCK !!!  HA HA HA... (陷入腦殘自嗨中~~)
結果對一個電子白痴來說, 這樣一試就是將近兩個月才完結, 多數是週末工作...            好了! 前情提要太長了, 開工!
一開始別猴急上手就是狂拆, 先瀏覽一下整個dock內貌:

 
左側是兩個 USB Type A 接口, 上邊dock後方從左邊看過來則有黃色的 power supply 接口, 兩個 USB, 還有其他 port.
我想的策略是盡量保留原本的接口能夠使用, 但是 Teensy無可避免的需要佔用一個 USB 接口作為發送 key code,比較可能就是選擇左側的兩個接口其中一個, 但是我不想把線拉到外面, 這樣會很醜沒有完整性, 所以我考慮從dock裡面接線. 
先列出大致需要做的工作:
 + power button  線需要拉出來給 Teensy做開機控制.
 +Teensy需要吃 5V 電源, 要找到電源. 這個電源從外面接進來就醜掉遜掉了,要想辦法從 dock 裡面找, 而且 Teensy 要 24 小時供電以便控制電腦開機, 而不是開了電腦才幫 Teensy 通電.
 + USB 的訊號線需要接到 Teensy 上面.
當時暫時想到上面三個工作, 當然後面發現不只是那麼簡單! Frown
 
* 拉出電源線開關
OK! 大致瀏覽過後, 先從原本就想拉出來的 power button 線下手, 反正要達成電腦開機功能這個工作是必需的:
 
 
上圖下方的那個接頭就是接到 power button, 只有紅黑兩條線, short 就等於是按下 power button. 我希望能夠保留手動按power button開機的功能, 所以就是從紅黑兩條線中間剝皮多接兩線出來給Teensy:
 
 
 
紅黑兩線剝皮後接另外兩條紅黑線出來,等於和power button 並聯, 原本的power button 還是可以使用. 這裡接線後我還在接線處焊接了, 避免斷掉:
 
 
接完長這樣:

 
其實我接了兩組出來, 原本是還想多做一個頭是讓 Dock 外的裝置也能控制開機, 後來並沒有用上.Over design...

 
如上圖, 線接出來後, 把x61放上去, 手動 short 紅黑兩條線, 可以看到x61開機, 證明可用.

 
然後, 避免短路, 用膠槍上膠! 其實用電火布(絕緣膠帶)比較方便, 只是當時我還沒買. Tongue out  上膠上得很醜, 叔叔是沒練過的, 小朋友不要學喔!
上完膠之後把接頭接回板上:

 
到此電源線拉出來了, 這個工作完成! 接下來是要在 dock 內找到 5V 電給 Teensy 使用, 而且這個 5V 電需要 always 通電.
 
* 接 5V 電
漸漸進入麻煩的地方了, Teensy和Arduino一樣都是吃5V電, 也可以吃3.3V, 但是Teensy用3.3V時脈會下降而且USB功能會關閉. 而我是做USB keyboard應用, 所以只能想辦法找5V電出來用.
 
 
重新檢視板子, 電路和零件密密麻麻, 不知如何下手找5V電, 就算找到以我的技術也很難把電線焊出來.
正面看起來沒辦法, 就拆板子吧! 除了板子正面的螺絲, 還有 dock 背板上每個port的螺絲都要卸下來, 板子才拿得下來:

 
死硬派! 剩下 USB port上兩個很細的螺絲, 比我手頭最細的十字起子還細:

 
翻了櫃子一下, 還好找到這個, 哈, 眼鏡行贈送用來鎖眼鏡螺絲的小起子:

 
很舊的小起子順利完成任務:

 
在所有的螺絲卸掉之後, 要把電路板拿起來前, 這裡特別提醒有兩個"壓縮感應器"(or 伸縮銷? 正確名稱不明)要注意不要弄掉了, 由於是表面黏著的關係它很容易和板子脫離. 我拆的時候就發生杯具, 差點脫落! 但是裝的時候就真的脫落了! 如果脫落別慌張, 要記得焊回去喔!
 
 
 
就是上圖那個咖啡色的東西, 它會有一個伸縮銷用來偵測 dock 的拉桿是否到位. 可能會影響開機(我沒在掉的時候測過).
 
 
在dock右邊靠鎖孔附近也有一個這樣的伸縮銷元件在板子背面, 要注意!
x61 UltraBase Dock被大卸八塊:
 
 
 
上邊的金屬蓋就是dock上可以置入cd-rom或第二顆硬碟那個空間的蓋子. 抱歉腳指入鏡傷眼...
 
 
上面是電路板的部分, 排線則是原本用來接到 cd-rom 或硬碟盒的排線. 屆時裝的時候要記得裝回去.
dock的電路板背面:
 
 
至此, 雖然翻到背面, 我還是找不到可以用的 5V 電源. 很直覺的會想要接 USB port 上的電源, 但是 dock 上的 USB 只有 x61開機的時候才會過電, 就算 BIOS 中開 ALWAYS ON USB, dock上的 USB port 還是沒有電. 從x61上去接也不合理, 因為我需要的是 24 小時都有的 5V 供電, 不可能因為 x61 從 dock 上拿起來就斷電.
那怎麼辦呢? 找不到 always enable 的 5V 電. 拿著電錶左量右量, 沒辦法, 只能從那個黃色的 AC adapter 接口去接電了:

 
 
用電表量過, 上面黃色座 有大小兩個ㄇ字型金屬, 包在外面那個比較大的ㄇ型是接地, 而小的裡面那個ㄇ字型是power, 電表量出來是穩定的 20.1V

 
 
如上圖, 我一開始的選擇是翻到板子背面去把接地(黑)和電源線(紅)焊出來. 選擇這個做法要注意, 因為印刷電路板表面有一層絕緣膠, 滿難焊得穩固, 我後來因為地線沒焊穩而發生杯具, 後來改從正面焊, 後面提到杯具時會講.
 

 
焊完後老樣子, 上膠! 但是要注意沒焊穩就算上膠也沒用.
施工到這裡, 我先轉個方向, 整理那個小風扇的座子, 那個風扇座太高會造成電路板放上去厚度太高, 所以一定是除之而後快:

 
 
上圖可以看到風扇座中間圓圈有兩個圓形黑色塑膠, 用來卡住整個風扇座跟dock底座, 我用小電鑽把這兩個黑色塑膠磨掉, 並且拆除 dock裡面那個黑色小音箱, 變成下圖:

 
 
已經磨兩個塑膠固定點, 這時候用手可以把風扇座鐵片拉起來:

 
 
這個圖更清楚怎麼拆, 在dock前方黑色那個其實是音箱, 有線接到板子上面.

 
 
用手一直反覆上下凹折, 就可以把風扇座折斷. 像上圖.
清掉之後像這樣:

 
 
把其他留下來的金屬部分整平, 將小音箱裝回去, 變成這樣:

 
 
OK, 整理告一段落, 事實上這些事情都會花掉我數個小時, 而小弟我還需要幫忙家務和帶小孩, 所以並不是向各位看到的一直連續不停的做下來.
接下來回到 5V 電源, 如果各位看倌沒忘記, 我從AC座接出來的是 20.1V, 並不是 5V, 20V接到Teensy肯定立刻鳥了. 初學者的我只知道需要把 20V -> 5V, 但是不知道用什麼東西可以辦到, 後來上網查有一些降壓電路, 不過都滿貴的大約80 ~ 100元, 而且降壓電路都會自己有電路板, 這多出的電路板加上Teensy不可能塞到那個小空間. 後來我用'KIS-3R33 DC-DC 降壓模組', 在拍賣上跟動物園長買很便宜一個約10元. 這個模組據說原本用在電玩機器上, KIS-3R33內建一些穩壓電路和元件, 比起直接使用降壓IC穩定.
話說完, 開始用麵包板測測看:
 

 
20.1V直接接到 KIS-3R33 的 Vi 和 GND, 而在 Vo我有串上16V/15uf電容, 如果在它的 Vadj 和 GND之間沒有串電阻, 我測出來 default 輸出是 3.3V, 可是我要的是5V, 所以我開始用電阻排換電阻一個個試, 後來找到27K電阻, 串到 Vadj 和 GND 間, Vo就會輸出 5V.
下面是更清楚的圖, 用電表確定 KIS-3R33 輸出 5V之後, 用麵包板接到 Teensy上做測試:
 
 
 
上圖中我還接了 IR receiver, 測試結果 Teensy 正常可以跑. Teensy的電源可以有兩種方法接近去, 一種是走 mini USB 供電, 另一方法是用 external power, Teensy mini USB接頭左右兩邊的兩個pin, 一個是 GND, 另一個是 power, 可以參考上圖紅線和藍線. 不過切記 mini USB和 external power 不能同時供電, Teensy網站有特別提.
把x61放上去, 測試同時供電給 Teensy和 x61, 測個幾個小時看來沒問題:

 
 
接下來暫時放下降壓電路, 我需要裁切一塊能夠放到風扇空間的洞洞板:

 
 
上圖的洞洞板切得剛好, 但是還是稍微大一點, 後來rework把C, D, E 那個外框切掉. 
將底部的一些塑膠料磨掉, 後面發生悲劇時很快就發現這樣不夠:

 
 
準備好洞洞板之後, 開始把3R33降壓元件和電容焊上去, 下面是簡單的電路圖:

 
 
焊接時的樣子, 小老虎鉗很好用:
 

 
焊好之後把拉出來的 20.1V 電線也接上去:
 

 
背面:
 

 
下圖拉遠一點看, 電線是從板子下方接到洞洞板, 但是我後面有rework改從電路板上方接電源, 後面會提:


 
 
放進去的樣子, 當時粉開心啦! 但是很快就發生悲劇, 整個rework:
 

 
* 接上 USB 資料線
至此, 還沒發現即將發生的杯具, 繼續我的工作是接上 USB 資料線. 接上前要先搞清楚 USB 幾個 pin 的用途, 下面的照片翻拍自wikipedia:

 
 
一般的 USB port 是 Type A, 而 Teensy 上內建的是 Mini-B 這種類型, wikipedia 上有很清楚的說明: pin 1是power, pin 4是GND, pin 2 與 pin 3 是 data line. 之前有說, 當使用 external power supply的時候  mini USB 是不允許供電給 Teensy, 所以扣除 GND 和 power, 事實上我的Teensy只需要接上2, 3兩條線.
再留意上圖 mini USB 的定義, 有五條pin, 比標準的 USB 多了一個 pin, 事實上 1 和 5 仍是 power 和 GND, 而多出來的pin 4 在一般應用可以 ignore, 所以只要小心的接上 2, 3 pin 就可以了.
開始施工, 從光華商場買來 mini USB type B 的公頭:

 
 
mini-USB 頭很小, 不好焊接, 搬出放大鏡協助, 而且使用OK線, 很細(對初學者我來說啦):

 
 
焊好2, 3 pin, 上圖可以看到買來的 mini-USB 的第四pin本來就沒有接, 所以 ignore.
 

 
由於真的太細了, 怕說 short 到, 這時候用電表歐姆檔去量, 上圖電表顯示1代表電阻無限大, 代表兩條線沒有導通, 這樣是對的. 還順便量了一下 power 和 GND 和 2,3 data 線之間有沒有導通, 確定都沒有short到.
接下來是焊標準 USB port 那端, 在板上:
 

 
這個比 mini USB 那端好焊很多, 我是用電火布(買了)貼上把要焊的單心線固定一下.
 
* 接通電源 整平底座
焊好 USB 兩端之後, 跳tone一下, 來焊接排母讓Teensy可以插上洞洞板:
 
 
 
注意降壓元件的 Vo 和 GND 要接到排母上的 Vin 和 GND, 這樣電才會接到 Teensy. 更清楚的圖:
 

 
用兩支電線插到排母, 用電表量看看是不是 5V, 下圖照的時候沒有多餘的手去量, 不過確定是5V:

 
 
懷著發抖的心情, 開始把 Teensy 插到排母上面跑 demo, 看來運氣很好沒問題, 下圖LED燈亮代表 Teensy 程式有跑有過電:
 
 
 
漸漸的朝悲劇前進, 小笨腦開始發現了問題了...
 

 
如上圖, 沒錯, 就算是拿掉風扇座都還是太高, 不只是電源插座, 還有Teensy也太高, 少估算了 mini USB 座的高度.
不管了! 硬著頭皮放到dock裡面插電, Teensy燈亮, 起碼代表過電而且大小放得進去:
 

 
大圖來一張, 這時候 mini USB 頭還沒確實壓上去:
 

 
這時候大概已經知道過高了, 可見ME很重要, 勉強還是想掙扎一下, 開始整平底座:
 
 
 
用筆刀切除底座凸起的塑料: 

 
 
其實那個塑料很軟, 用筆刀切成一片片後一個個'推倒', 不常'推倒'的人可以推得很爽 :)

 
 
順便用斜口鉗把旁邊的塑膠柵欄剪掉一個, 準備作個立體接頭讓 IR receiver 接進來:
 

 
侧視圖:

 
 
可以注意到上圖, 這時侯仍未處理過高的問題, 想說先把 mini USB 頭接完再來評估怎麼 rework...
 
* 完成 mini USB 接頭
OK, 決定先把 mini USB做完, 確定接上 USB data line 可行, 再來想辦法處理過高的問題.
首先把 mini USB 公頭的上下蓋蓋上:

 
 
注意下圖的左側兩條接到 USB 3/4 pin 的藍白OK線, 我將OK線和mini USB 接頭拉到 dock 外面,  準備把x61接上 dock 測試是否能夠被作業系統抓到:

 
 
Ok, 將 x61 接上 dock 並且插上 AC power 通電. 下圖可以看到 Teensy 的燈亮著, 而且 x61 運作正常:
 

 
耶! 確定用外接電源並且只接 USB 3,4 data pin 可行, 觀看 x61 上的 dmesg, 可以確認 Teensy keyboard/mouse 已經被OS抓到了:
 

 
x61 同時還可以上網:

 
 
確定 work 之後, 用尖嘴鉗把 mini USB 公頭的上下蓋確定壓緊:
 

 
老樣子, 將 dock 內接標準 USB 這端上膠, 很顯然的, 這個 port 等於未來不給用. 至於這個 USB port 的 power 和 GND 未來會有大用, 可以解掉另一個後來遇到的悲劇:



將 mini USB 頭貼上電火布絕緣, 貼的位置就是插入Teensy之後外露的位置:

 
 
多測試總是對的, 壓完線貼完電火布之後再接上 x61 測一次, 這次還開了 Arduino IDE 確認有抓到 Teensy:

 
 
一樣, 因為OK線很細, 為了確保穩固, 在 mini USB 頭裡面灌膠! 膠槍真是好幫手!

 
 
把 Teensy 放到dock裡面, 並且將 power 和 mini USB 都接上Teensy:



來一張更遠的圖,可以看到藍色OK當時拉線拉太短了, 有點緊迫:



從 dock 後端往前照, 可以明顯見到power接頭和 mini USB 母座過高的狀況.



好了! 該面對的還是要面對...
 

* 杯具1 - 模組過高無法蓋上

先看一下目前的layout:


 
 
layout像上圖, 降壓模組 KIS-3R33 放在 Teensy 的前面, 當時的想法是可以讓 Teensy 左右兩側空間夠大, Teensy的mini USB接口可以剛好高過 KIS-3R33, 但是沒考量到模組過高的問題. 
Teensy mini USB 高度剛好高過 KIS-3R33 才能接上自己焊的 USB 線, 而 Teensy 的高度是來自於排母, 使用排母有一個好處是 Teensy 不用焊死, 未來可以方便拆下來. 但是現在面臨過高的問題也只有排母可以拿掉. 所以模組過高造成dock上蓋無法蓋下我的解法是:
 + 拿掉 Teensy 底下的排母, Teensy 直接焊死在洞洞板上.
 + 由於排母拿掉, Teensy 的高度變得比 KIS-3R33 矮, 所以 KIS-3R33 不能再擋在 Teensy 前面了, 需要將 Teensy 向前拉才能接到mini USB 線.
所以改 layout 如下

 
 
改layout的過程對初學者的我來說很辛苦, 解焊兩邊總共24 pin的排母比焊上去還要痛苦. 解焊後再焊回去結果才是上圖, KIS-3R33 的位置沒有變, 只是換個方向, 但是 power 線和 GND 拉比較遠才能到 Teensy.
更遠一點的圖:

 
 
把 dock 上蓋蓋上, 少了排母高度已經能順利蓋上了:
 

 
近一點看:
 

 
下面這個圖可以看到 Teensy 亮燈, 供電正常:

 
 
全景俯瞰圖亮燈, 有做超過三天的 longrun 測試沒問題, 照片有點暗:

 
 
* 外加 Reset 按鈕與 LED 燈
OK! 花時間解決過高悲劇後, run 幾天測試後繼續邁進.
由於 Teensy 是裝在 dock 裡面, 所以按不到 reset button, 還好 Teensy 有 reset pin 可以自己外接一個 reset  button. 後面寫程式的時候我真的慶幸當時有裝這個button:
 

 
從光華源達買的小按鈕:
 

 
我不需要耳朵, 折起來節省空間:

 
 
把按鈕裝上去:

 
 
上圖已經可以看到加裝了 LED, 我使用雙色 LED, 亮綠光代表 KIS-3R33 通電正常, 所以只要 dock 插上 AC adapter 就是綠光恆亮. 另外紅色燈光是會發生在 Teensy 收到 IR code 之後執行程式的過程會亮, 可以用來 debug 用. LED 接線電路圖:
 

 
背面的焊接狀況, 這時候還沒有很複雜, 可以很清楚看到改 layout 的狀況:

 
 
先把電和 mini USB 接上, 看看 LED 燈狀況, 順便測一下 Linux 有沒有抓到 Teensy, 還可以測 reset button:

 
 
在 dock 上開孔, 讓 LED 燈可以有出口:

 
 
注意 dock 的上下蓋在前方是有重疊的, 所以上下兩個蓋子都要開孔, 安裝後像這樣:

 
 
先預貼一下下圖, 可以看到 reset 按鈕會靠到 dock 左側原本用來通風的柵欄, 可以用尖銳物像原子筆去戳它, 觸發 Teensy 做 reset 動作:


 
 
Reset按鈕和雙色 LED 燈後續給的幫助很大, 尤其是寫程式, 可以做 reset 動作而且 LED 協助 debug.
 
* 拉出 USB 電源線, 製作 IR receiver 接口
看到 title 會有點奇怪, 已經接了外接電源, 為什麼還要去動 USB 電源線? 原因是這樣: 由於我們已經佔用 dock 上的一個 USB port, 所以正常的使用上這個 port 已經固定是接到 Teensy 上面, 把任何其他的 USB 裝置插入這個 port 都是危險的, 所以我不允許其他人使用這個 port, 會用電火布貼起來.
既然會貼起來, 其實上面有 USB 1和4 pin, 就是電源線和 GND, 我的想法是可以拿來偵測插在 dock 上的 x61 是否真的開機, 所以整個製作過程到這邊決定把這兩條線拉出來備用. 後續寫程式的時候證明是用得上的, 還好有拉出來, 後面會講到妙處.
如下圖, 用斜口鉗剪斷 USB port 上面的 1 pin 和 4 pin, 注意盡量留多一點在板子上, 方便後續焊線出來:
 

 
像下圖一樣將 USB 的 5V power 和 GND 先焊接拉出來, 我用一般的單芯線, 紅色power, 黑色 GND.
老樣子, 上膠:

 
 
USB power拉線動作先到這邊, 後面遇到杯具的時候會講詳細些, 製作這個作品的當時也是先拉出來備用而已.
接下來是製作 IR receiver 的接口, 這個接口直接接到洞洞板上, 我的設計是放在 dock 左邊風扇柵欄那邊.
首先是材料, 我手邊剛好有剩下來的透明樂高 2x2 壁板, 其實應該要用黑色會比較搭. 另外就是三 pin 的立體耳機座, 從光華源達購得:

 
 
我本來想直接把樂高塞進dock, 但是太佔空間沒必要, 所以把樂高上下兩端切開, 只用中間的透明板, 其實家裏有找得到的塑膠板的可以, 切割比較麻煩些:

 
 
OK, 還是一樣出動好朋友膠槍, 黏得醜斃了, 叔叔是沒練過的小朋友不要學喔(還是用黑色好遮醜):

 
 
將紅黑白三條線焊到立體座上, 紅色 5V power, 黑色 GND, 白色 date 線, 後面壓的那個 3 pin 插頭是多此一舉, 只是佔空間而已, 後來我拿掉接頭直接焊到洞洞板上:

 
 
看到的成果像下圖, 這時候接頭還沒拿掉, 洞洞板上還有插座. 這個圖預先看到用來控制 dock 開關線的光耦合器有焊上去. 整體看起來很擠:

 
 
IR receiver 的電路:
 

 
接下來講光耦合器控制開關線的部份.
 
* 控制 Dock 電源開關
大家應該記得一開始的時候最早做的項目就是將 dock 上的電源開關拉出並聯線路, 將兩條線 short 之後就能開機. 現在要用 Teensy 模擬這個手動的 short 動作, 也等於是按下電源開關的動作來開機.
我一開始也不懂這個動作要用什麼樣的電子元件來製作, 只記得讀機械系有學過 Relay, 就是繼電器, 但是繼電器滿大的, 不太可能殺雞用牛刀, 況且也塞不進去洞洞板. 後來上網查了一陣子才了解這個東西可以用光耦合IC來做. 
 
我選用的是 TLP521 這顆光耦合 IC, 源達有賣. 我的電路如下:

 
 
 先用麵包板和電錶測試是否能用 Teensy 在收到 power 鍵的 IR code 時利用 TLP521 將電路導通(我已經寫了程式). 下圖電錶歐姆檔顯示1表示未導通(抱歉沒有第三支手可以按遙控器), 如果測試看到0代表 TLP521 已經將電路導通, 等於是 short:

 
 
上圖有個樂高做的小盒子, 裡面是 IR receiver, 在源達買到的是6038LM-5A這顆, IC reciever有 power, GND, data 三隻腳, 但是每種 IC receiver 三隻腳的排列不一樣, 請記得上網查datasheet或者問店家:
更近一點看接線, 串了一顆 220 歐姆的電阻在光耦合IC的 input 端, 用 Teensy 的 pin 去控制開關, 原理就像讓 LED 亮燈一樣:
 
  
 
俯視圖來一張:

 
 
OK, 下面這張圖之前已經貼過兩次了, 已經將光耦合器焊上去, dock 的 power 線也接上去, 就是光耦合器旁邊那個座:

 

下圖是我直接用電錶歐姆檔量測座上的 pin 是否能夠被光耦合器 short:
 
 
 
拉近一點看, 可以注意到我已經拿掉 IR receiver 的 pin 座來節省洞洞板的空間, 後來處理新的悲劇時發現這個保留空間的決定是對的:



OK, 第一次完成的成品像這樣, 其實後面遭遇悲劇rework之後也差不多是這樣, 只是還會多些東西(已經很擠了):



* 尾聲! 裝回去:

終於弄得差不多了! 鳥瞰全圖, 拍得有暗請見諒:



裝的時候注意左側的x61卸除拉桿不要拉到dock中我們的 USB 線或 power 線, 我是用電火布(絕緣膠帶)把線做固定, 才開始蓋上上蓋.

終於弄得差不多了, 將上蓋裝回去, 記得裝回去前連背板的螺絲都要鎖:



蓋上上蓋後要記得測試左側的x61卸除拉桿確實可以控制 dock 上的頂出銷, 這些頂出銷可以正常將x61頂起來以便卸除.

左側視圖, 密合度如同改裝前, 沒有過高.      對~ 我知道 IR 座粘得很醜~~:



當然要把x61裝上去開電腦, 確定 Teensy 有被作為一個 USB device 抓到:



直接就在 x61 上寫程式 program 裝在 dock 裡面的 Teensy:



程式寫入而且 reset 成功, 真的很開心 :D



* Teensy 程式與成果:

到這邊硬體部份已經全部完成了, 寫得真的累了, Teensy(程式就是Arduino啦!)程式的部份我就暫時不詳述了, 等有空再來寫軟體篇.

我的程式放在這個 git 位置: <git>

請自行拿去研究修改, 請特別注意我的 license  是 GPL 發佈, 想改的人請修改後也把程式 open source 出來, 謝謝!

下圖是我拿來配合的電視遙控器, 這個圖一開始出現過, 這邊給各位參考一下:



我在 Teensy 中寫 code 將上圖遙控器中的 IR code 對應到 dock 開機和 skype key code (我用XP版本), 可以用來把 x61 開機並且控制 skype 甚至其他例如看照片的程式, 只要程式可以用hotkey控制. 就算沒有hotkey, 還有最後手段: 使用錄製mouse操作路徑的程式, e.g. tinytask
Windows XP 上的 tinytask 可以錄製key和mouse動作並編成小執行檔, 我們可以用 shortcut 建立到桌面上然後設定 hotkey去執行這些mouse 動作, 最後teensy收到 IR code 之後發出hotkey組合鍵觸發動作就可以了.

我在實用上採行的策略是:
將x61隨著電視 power 開關同步, 然後選擇半夜四五點設定Thinkpad電源管理來一次自動睡眠,這個動作是避免因為接收器沒有接收power訊號造成和電視開機不同步, 所以選在半夜做一次reset.

另外我也曾經採用的策略是: 每天第一次按下電視遙控器 power 鍵會將x61開機, 當然同時這個動作也是打開電視, 也就是電視和x61同步都是開的, 然後我用 Thinkpad 的電源管理設定每天午夜自動S4 (suspend to Disk)休眠. 如果考量到不想讓x61一天開開關關好幾次可以用這樣的策略, 而且當天沒有人在家按電視, 也不會打開x61, 一方面沒人在家時也省電. 其實用S3 (suspend to RAM) 讓x61和電視完全同步也是不錯的選擇, 只是我沒那樣做.

show 兩段影片是最後的成果:



雖然 smart dock 已經完工, 但是不出所料, 產品上線後才是悲劇的開始. 我將成品放到父母家上線後遇到了兩次杯具, 分別編號為杯具2以及杯具3, 也跟著做了兩次 rework, 幸虧都解決了問題.

 

* 杯具2 - 20V電源接地線脫落

上線後run到第二天就出現問題了, 發現x61沒有開機, 而且 Teensy 接收 IR 之後沒有發出任何 key code. 只好重新打開最不想開的 dock 上蓋量量看, 發現原本拉出來的 power 和 GND 居然量不出電了:



但是直接量黃色的AC座, 可以量到20.1 V, 代表從板子背面焊出來的 power 和 GND 線有問題, 後來仔細查發現是 GND 脫落了:



決定不想拆板子重焊了, 由於在背面焊接也不好焊牢固, 決定廢掉原本的 power 線, 重新在正面焊, 就直接從 AC 座上面焊接出來, 像下圖:



更近一點的圖, 我從AC座的外側焊出 GND, 然後在內圈焊出紅色 power 線:



沒拆板 rework 的代價: BBQ, 還聞得到味道...



查了一下洞洞板上的 power 座發現也是鬆動了, 乾脆順便把 power 座也拆掉直接將 power 線焊到板上, 以免後續鬆掉又要開殼重作:



Rework後的全圖來一張, 照得有點暗, 但是可以看到電源線已經從板子正面直接拉到Teensy洞洞板上面:



OK, 解決問題, 應該可以過著幸福快樂的日子了吧!

想不到, 在兩天之後又發生x61沒有開機的狀況(我每天都有monitor那台x61是否有用skype自動上線), 讓我們繼續看下去...

 

* 杯具3 - USB data 無窮等待 USB host

上個問題解決之後, 持續了兩天, 很快的又遇到新的問題, 一樣是電視開機時x61開不了機, skype沒有自動上線, 這次的問題也是很麻煩, 因為發現和Arduino的 USB library 有關. 

之前有提到我的程式在 Teensy 接收到 IR code 之後執行動作的時候, 會將LED的紅色燈點亮, 執行過程幾秒鐘就會點亮LED幾秒, 可是當無法開機的狀況發生時, 檢查 dock 發現 LED 燈的紅色燈恆亮, 永遠不會掉下來成為綠燈. 這個原因出在我的應用是利用Teensy模擬 USB keyboard 發出 key code, 如果在 x61 沒有起來前就發出 key code 會造成 Teensy 一直卡在等待 USB host 把 command/date 收走而無法開機, 問題發生時手動把 x61 開機就可以看到綠燈恢復.

所以無可避免的需要知道 x61 是否已經開機, 如果開機才允許 Teensy 透過 USB 送出key code.

我曾嘗試使用 Arduino USB library 的 usb_configuration flag 去觀察 Teensy 是否已經被 x61 config, 但是發現 hibernet 的時候這個 flag 並不會作用. 所以仍無法得知 x61 的開機狀況. 所幸之前有將 dock 上的 USB power/GND 拉出來, 就決定使用這兩條線來得知 USB port 是否供電, 若 dock 上的 USB port 供電則代表 x61 已經開機, 可以送出 key code.

利用 Teensy 可以將 USB power line 拉到一個 pin 上, 通電時會把 pin 的 state 拉起來, 然後加一個 downside resistance 在 USB 未通電的時候可以把 state set 回去.這樣 Teensy 程式就可以得知是否 x61 已經開機, 等於是 USB host 起來可以開始收東西. 電路如下:



我先使用麵包板測看看拉出來的 USB power線是不是可以work, 故意接一個 LED 反應 USB 通電, 如果 Teensy 看到 pin 被拉起來, 就用程式把 LED 點亮, 這代表 Teensy 可以抓到 USB 的通電狀況:



另一個角度, 我把 USB power 接到 Teensy 的 pin 2:



簡單的測試程式:



下圖是之前接出來的 USB power 線, 我把它拉更長接到 Teensy:



麵包板測試影片, 可以看到關機後麵包板上LED熄滅:



焊好後的全景俯視圖:



細部, 抱歉這隻相機近照功能差, 但是可以勉強看到多一顆 downside 電阻:



洞洞板背面, 已經亂七八糟了:



在接上 USB power 後, 我修改 Teensy 程式去觀測是否 pin state 被拉起來, 如果還沒拉起來就不會送出 key code. 詳細請我 git 上的 code, 就不多解釋了.

 

* 工具們

文章最後show 一下幫忙我很多的工具們, 事實上工具比下圖多很多, 都是做這個專案的時候慢慢買齊的, 我是看作建立開發能量來買, 由於是偶爾用用所以多數買國產相當便宜;



不可缺的 40W 電烙鐵, 最便宜的, 做完這攤烙鐵頭也差不多要換了:



這裡特別感謝光華源達對初學者的協助, 尤其是他們請的兩位年輕人, 對於一個外行大叔能夠不吝指導, 感恩!

 

* 結束

結尾小弟提供建構雙向 skype HD 的一些經驗:

 + 需要確定你買的 webcam 支援 skype HD, 我用的是 Creative Live! Cam inPerson HD, 發文的同時應該已經有更便宜的選擇.  由於使用電視通話的時候使用者通常坐在沙發上, 和使用電腦的狀況不同, 距離麥克風更遠, 所以如果webcam內建麥克風陣列是最好, 我買的這隻有麥克風陣列, 但價格就...

 + CPU 需求大約需要 core 2 dual 1.7 MHz 以上, 2.2 MHz 應該很足夠, 如果只是單向 skype HD 當然對 CPU 需求更小. 我沒用 x61s 之前腦殘想要用 Eee PC去玩 skype HD, 看到 lag 的分格畫面當場冏掉. 至於RAM 大小我是沒遇到問題, 所以一般2G可能就夠了. 

 + 網路頻寬需求為上行 1.4 M, 所以上行 2M 會更夠用.

 + 我發文的時候已經有很多讓電視打 skype HD的產品出現, 除了原本就內建skype的 smart TV以外, 還有例如: 支援skype HD的藍光播放機, 更有直接將影像透過HDMI輸出到一般液晶電視的 webcam (等於是內建skype軟體的webcam). 所以希望架設 skype HD的人不一定要像我這樣做, 也可以選擇這些東西, 缺點是功能單純是打 skype HD而且價格不算便宜.

至於視訊通話的使用行為, 其實我本來是掛一個外接 USB 喇叭在 dock 上面, skype打進去的時候會響起來, 然後按 OK 可以用視訊通話接起來. 但是實際使用數個月發現就算是打視訊電話, 事前通常還是會先打普通電話, 講好之後電視再切到視訊, 因為沒有人希望穿得亂七八糟內褲亂走然後用視訊對話. 所以後來就把 dock 上的聲音輸出直接接到液晶電視上面去, 反正市話講好要視訊之後遙控器按OK就可以了.

另外回頭講到將Teensy塞到dock去控制電腦開機甚至驅動軟體行為這樣的應用, 不只像我一樣可使用IR控制, 還可以有其他的應用例如: 溫度或感光. 利用耗電極低的MCU來做一個前導, 去驅動PC開機做一些紀錄, 執行程式或其他動作, 都是可能的應用範圍.

目前我做的這個成品快樂使用中, 已經數個月了, 一切正常每天開關機服役, 老媽也很快學會接我打過去的視訊, 只要按遙控器OK鍵連老人也會用. 除了 skype HD視訊, 也用於看照片以及 Locationfree player.

以上大長篇, 謝謝收看!

 


* 迴響

+ 謝阿達 · 國立高雄應用科技大學

還真的是有夠努力的!! 5V 小弟有說就是27K電阻了~!! 另外~輸入電容~~別用那固態電容~ 因為耐壓只有16V 超過18V真的很容易爆的!!!

辛苦了!!

smallbee: 感謝阿達大指導, 確實小弟沒注意到輸入電容只能耐壓 16V, 只是現在機器已經上線, 這陣子小弟應該沒力再去拆修了, 就等它真的爆了再去收拾吧!
無論如何感謝提醒, 小弟會注意!