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 上, 用數位像機確認: