原文首發於IterNull Blog,作者為IterNull,原文鏈接地址:http://blog.iternull.com/posts/2017/02/02/Decoding-Remote-Control-Signals.html
我們平常對遙控器信號的截取、分析、重放,一般用得都是 SDR 設備,常見的有 R820T2+RTL2832U, CC1111EMK, Yardstick One, HackRF One ……
其中 R820T2+RTL2832U 電視棒是最廉價的 SDR 設備,35 人民幣左右就能得到,其余的都是比較昂貴的設備。不過使用電視棒你只能接收信號,不能發送信號。
這里我們使用更廉價的設備(Arduino + 315 or 433 MHz 超再生模塊)來實現對常見固定碼遙控器信號的分析與重放。
常見型號的 Arduino 開發板都可以支持,無線模塊建議不同頻段的多買幾對,價格也不貴。
1、接收/解碼信號
這里我們使用 RC Switch 庫接收和解碼信號。
1.1 安裝 RC Switch 庫
打開 Arduino IDE ,在選項欄 項目 > 加載庫 > 管理庫 里打開庫管理器,搜索 rc switch
並安裝它。
1.2 連接 Arduino 和接收模塊
使用數據線連接 Arduino 到電腦,並在 Arduino IDE 里選擇對應的板和端口號。
1.3 上傳代碼
打開信號接收的示例代碼。在選項欄 文件 > 示例 > rc-switch > ReceiveDemo_Simple
/* Simple example for receiving https://github.com/sui77/rc-switch/ */ #include <RCSwitch.h> RCSwitch mySwitch = RCSwitch(); void setup() { Serial.begin(9600); mySwitch.enableReceive(0); // Receiver on interrupt 0 => that is pin #2 } void loop() { if (mySwitch.available()) { int value = mySwitch.getReceivedValue(); if (value == 0) { Serial.print("Unknown encoding"); } else { Serial.print("Received "); Serial.print( mySwitch.getReceivedValue() ); Serial.print(" / "); Serial.print( mySwitch.getReceivedBitlength() ); Serial.print("bit "); Serial.print("Protocol: "); Serial.println( mySwitch.getReceivedProtocol() ); } mySwitch.resetAvailable(); } }
點擊上傳,上傳代碼到 Arduino
想要注意的一點,在 void setup()
里有一行代碼是定義數據接收的針腳的,不同的 Arduino 版本針腳不一樣,如果接錯線會導致 Arduino 沒法正常工作,具體可以參考 Arduino 的文檔。
ySwitch.enableReceive(0); // Receiver on interrupt 0 => that is pin #2
1.4 查看信號解碼
打開串口監視器。在選項欄 工具 > 串口監視器 或者按快捷鍵 Ctrl + Shift + M
然后你可以按下遙控器,Arduino 會解碼它,並在串口監視器上顯示出你按下的按鍵所發送的代碼。
2、重放信號
當你知道了信號的代碼后你就可以對它進行信號的重放。
2.1 連接 Arduino 和發送模塊
2.2 修改示例代碼
打開信號發送的示例代碼。在選項欄 文件 > 示例 > rc-switch > SendDemo
示例代碼里有好幾種發送選項,和好幾個被注釋的發送參數。
這里我們使用十進制的發送方式。
/* Example for different sending methods https://github.com/sui77/rc-switch/ */ #include <RCSwitch.h> RCSwitch mySwitch = RCSwitch(); void setup() { Serial.begin(9600); // Transmitter is connected to Arduino Pin #10 mySwitch.enableTransmit(10); // Optional set pulse length. // mySwitch.setPulseLength(320); // Optional set protocol (default is 1, will work for most outlets) // mySwitch.setProtocol(2); // Optional set number of transmission repetitions. // mySwitch.setRepeatTransmit(15); } void loop() { /* See Example: TypeA_WithDIPSwitches */ /* mySwitch.switchOn("11111", "00010"); delay(1000); mySwitch.switchOff("11111", "00010"); delay(1000); */ /* Same switch as above, but using decimal code */ mySwitch.send(5393, 24); // 5393 表示發送的信號代碼, 24 表示數據長度。 delay(1000); // 暫停 1000 毫秒后再執行下一行代碼。 mySwitch.send(5396, 24); delay(1000); /* Same switch as above, but using binary code */ /* mySwitch.send("000000000001010100010001"); delay(1000); mySwitch.send("000000000001010100010100"); delay(1000); */ /* Same switch as above, but tri-state code */ /* mySwitch.sendTriState("00000FFF0F0F"); delay(1000); mySwitch.sendTriState("00000FFF0FF0"); delay(1000); */ delay(20000); }
2.3 上傳代碼
代碼上傳完成后會一直向外發送信號。
3、可能遇到的問題
1、串口監視器沒有顯示,不能正常接收信號。
導致出現正在錯誤的情況有很多,比如打開的端口錯誤、接收模塊與 Arduino 的連接錯誤、遙控器和接收模塊不是同一個頻段的……
2、發送的信號正常但被遙控的設備沒響應。
遇到這種情況你需要使用 RC Switch 庫的 ReceiveDemo_Advanced 示例代碼進行接收和解碼信號,其中有一個 PulseLength
字段,RC Switch 庫默認的值是 320
,而常見的遙控器是 185
你需要修改發送代碼的 mySwitch.setPulseLength(185);
參數。
- RC Switch: https://github.com/sui77/rc-switch