1. 程式人生 > >Android開發筆記(一百六十五)利用紅外發射遙控電器

Android開發筆記(一百六十五)利用紅外發射遙控電器

紅外遙控是一種無線控制技術,它具有功耗小、成本低、易實現等諸多優點,因而被各種電子裝置特別是家用電器廣泛採用,像日常生活中的電視遙控器、空調遙控器等等基本都採用紅外遙控技術。
不過遙控器並不都是紅外遙控,也可能是射頻遙控。紅外遙控使用近紅外光線(頻率只有幾萬赫茲)作為遙控光源,而射頻遙控使用超高頻電磁波(頻率高達幾億赫茲)作為訊號載體。紅外遙控器的頂部,有的鑲嵌一個或多個小燈泡,有的是一小片黑色蓋子,這個黑蓋子對紅外線來說可是透明的,只是人的肉眼看不穿它。射頻遙控器的頂部,有的突出一根天線,有的啥都沒有(其實發射器包在蓋子裡面)。紅外遙控器帶著燈泡就像一支手電筒,紅外光照到哪裡,哪裡的電器才會接收響應,這決定了紅外遙控的三個特性:
1、遙控器要對準電器才有反應。要是手電筒沒照到這兒,那肯定是黑乎乎的;
2、遙控器不能距離電器太遠,最好是五米之內。這也好理解,手電筒離得遠了,照到物體上的光線都變暗了;
3、遙控器與電器之間不能有障礙物。你能想象手電筒發出來的燈光會穿透牆壁嗎?
而射頻遙控器正好與紅外的特性相反,它採用超高頻電磁波,所以訊號是四散開的不具備方向性,並且射頻訊號的有效距離可以長達數十米,末了射頻訊號還能輕鬆穿透非金屬的障礙物。紅外遙控和射頻遙控的不同特性決定了它們各自擅長的領域,紅外遙控看似侷限很多,其實正適用於家用電器,否則每個人隔著牆還能遙控鄰居家的電器,這可怎麼得了;射頻遙控的強大抗干擾能力,更適用於一些專業的電子裝置。因為紅外遙控更貼近日常生活,所以人民大眾購買的智慧手機,自然配置的是紅外遙控了(有的手機可能沒裝紅外發射器)。
聽起來裝了紅外發射器的手機,可以拿來當遙控器使用,還能一部手機遙控許多家電,這不是什麼天方夜譚噢,接下來看看如何在App開發中運用紅外遙控技術。

首先要在App工程的AndroidManifest.xml中補充紅外許可權配置,具體的配置例子見下:
    <!-- 紅外遙控 -->
    <uses-permission android:name="android.permission.TRANSMIT_IR" />
    <!-- 僅在支援紅外的裝置上執行 -->
    <uses-feature android:name="android.hardware.ConsumerIrManager" android:required="true" />
其次在程式碼中初始化紅外遙控的管理器,注意紅外遙控功能從Android4.4之後才開始支援。紅外遙控對應的管理類名叫ConsumerIrManager,它的常用方法主要有三個,分別說明如下:
hasIrEmitter : 檢查裝置是否擁有紅外發射器。返回true表示有,返回false表示沒有。
getCarrierFrequencies : 獲得可用的載波頻率範圍。
transmit : 發射紅外訊號。第一個引數為訊號頻率,單位赫茲(Hz),家用電器的紅外頻率通常使用38000Hz;第二個引數為整型陣列形式的訊號格式。
下面是紅外遙控管理器的初始化程式碼例子:
    private ConsumerIrManager cim;
    private void initInfrared() {
        // 獲取系統的紅外遙控服務
        cim = (ConsumerIrManager) getSystemService(Context.CONSUMER_IR_SERVICE);
        if (!cim.hasIrEmitter()) {
            tv_infrared.setText("當前手機不支援紅外遙控");
        }
    }
最後準備發射遙控訊號之時呼叫transmit方法就好了。

果真如此簡單嗎?當然不是,這裡面的玄機全在transmit方法的訊號格式引數上面。想一想,家電有很多種,每種家電又有好幾個品牌,便是房間裡的某個家電,遙控器上也有數排的按鍵。這麼算下來,訊號格式的各種組合都數不清了,普通開發者又不是電器廠商的內部人員,要想破解這些電器的紅外訊號編碼,那可真是比登天還難。
手工破解固然不容易,卻也並非沒有辦法,現在有一種紅外遙控器的解碼儀,可到淘寶上面購買。這個解碼儀能夠分析常見家電的紅外遙控訊號,下面兩種除外:
1、空調遙控器,空調的控制比較複雜,光光溫度就可能調節十幾次,難以破解。
2、燈光遙控器,燈本身發光發熱,同時也會散發大量紅外線,勢必對外部的紅外訊號造成嚴重干擾;所以燈只能採取射頻遙控器。
紅外解碼儀是家電維修人員的必備儀器,常用於檢測遙控器能否正常工作,開發者為了讓手機實現遙控功能,也要利用解碼儀捕捉每個按鍵對應的紅外訊號。接下來以掃地機器人的遙控解碼為例,介紹如何通過解碼儀獲取對應的紅外遙控指令。
先將掃地機器人的遙控器對準解碼儀正面的紅外接收視窗,按下遙控器上的clean鍵(開始掃地/停止掃地),此時解碼儀的分析結果如下圖所示:

從上圖可見,clean鍵的紅外訊號由三部分組成,分別是使用者碼4055、資料碼44、電路61212。其中使用者碼錶示廠商代號,每個廠家都有自己的唯一代號;資料碼錶示按鍵的編號,不同的資料碼代表不同的按鍵;電路格式表示紅外訊號的編碼協議,每種協議都有專門的指令格式。比如說電路61212表示的是NEC6121協議,該協議的紅外訊號編碼格式為:引導碼+使用者碼+資料碼+資料反碼+結束碼,其中引導碼和結束碼都是固定的,資料反碼由資料碼按位取反得來,真正變化的只有使用者碼和資料碼。
然而解碼儀獲得的使用者碼和資料碼並不能直接寫在程式碼中,因為液晶屏上的編碼其實是十六進位制數,需要轉換為二進位制數才行。例如使用者碼4055,對應的二進位制數為0100 0000 0101 0101;資料碼44,對應的二進位制數為0100 0100,按位取反得到資料反碼的二進位制數為1011 1011。
可是前述的transmit方法,引數要傳遞整型陣列形式的訊號,並不是二進位制數,這意味著二進位制數還得轉換成整型陣列。那麼整型數組裡面存放的到底是些什麼資料呢?這就要從數位電路中的電平說起了。電平是“電壓平臺”的簡稱,指的是電路中某一點電壓的高低狀態,在數位電路中常用高電平表示“1”,用低電平表示“0”。遙控器發射紅外訊號之時,通過“560微秒低電平+1680微秒高電平”代表“1”,通過“560微秒低電平+560微秒低電平”代表“0”。於是編寫Android程式碼的時候,使用“560,1680”表示二進位制的1,使用“560,560”表示二進位制的0,此處的560和1680只是大概的數值,也可使用580、600替換560,或者使用1600、1650替換1680。
根據數位電路的電平規則,使用者碼4055對應的二進位制數為0100 0000 0101 0101,轉換成電平訊號就變成了“560,560, 560,1680, 560,560, 560,560, 560,560, 560,560, 560,560, 560,560, 560,560, 560,1680, 560,560, 560,1680, 560,560, 560,1680, 560,560, 560,1680, ”,資料碼44及其資料反碼的電平訊號依此類推。再加上NEC協議固定的引導碼“9000,4500”,以及結束碼“560,20000”,即可得出前面clean鍵的紅外訊號整型陣列,具體的陣列數值如下所示:
int[] pattern = {9000,4500, // 開頭兩個數字表示引導碼
    // 下面兩行表示使用者碼
    560,560, 560,1680, 560,560, 560,560, 560,560, 560,560, 560,560, 560,560,
    560,560, 560,1680, 560,560, 560,1680, 560,560, 560,1680, 560,560, 560,1680,
    // 下面一行表示資料碼
    560,560, 560,1680, 560,560, 560,560, 560,560, 560,1680, 560,560, 560,560,
    // 下面一行表示資料反碼
    560,1680, 560,560, 560,1680, 560,1680, 560,1680, 560,560, 560,1680, 560,1680,
    560,20000}; // 末尾兩個數字表示結束碼
接著在App程式碼中代入上述的訊號格式陣列,即呼叫transmit方法傳遞格式引數,示例如下:
    // 普通家電的紅外發射頻率一般為38KHz
    cim.transmit(38000, pattern);
執行測試App,卻發現不管讓手機發送多少次的紅外訊號,掃地機器人都呆若木雞,絲毫沒有反應。這是咋回事?奧祕在於NEC協議只規定了大體上的編碼規則,實際的遙控器訊號在整體規則內略有調整。之前提到的解碼儀,既是家電售後的檢測儀器,也可作為App開發者的除錯工具。拿起手機對準解碼儀正面的接收視窗,點選按鈕傳送紅外訊號,解碼儀同步顯示分析後的訊號資料,如下圖所示:

由上圖可知,此時手機發出的紅外訊號符合NEC6121協議,只不過使用者碼變成了02AA,資料碼變成了22。把這兩個碼數翻譯成二進位制,則使用者碼02AA轉為0000 0010 1010 1010,資料碼22轉為0010 0010。回頭比較遙控器的解碼資料,遙控器發出的使用者碼4055對應0100 0000 0101 0101,資料碼44對應0100 0100。看起來手機與遙控器的訊號區別,應當是每兩個十六進位制數先轉為二進位制數,然後倒過來排列,也就是所謂的逆序編碼。
找到問題的癥結便好辦了,數學上有負負得正,編碼則有逆逆得順。既然4055逆序編碼後變為02AA,那麼02AA逆序編碼後必為4055,於是再次構造使用者碼02AA以及資料碼22的電平訊號,更改後的紅外訊號資料如下所示:
int[] pattern = {9000,4500, // 開頭兩個數字表示引導碼
    // 下面兩行表示使用者碼
    560,560, 560,560, 560,560, 560,560, 560,560, 560,560, 560,1680, 560,560,
    560,1680, 560,560, 560,1680, 560,560, 560,1680, 560,560, 560,1680, 560,560,
    // 下面一行表示資料碼
    560,560, 560,560, 560,1680, 560,560, 560,560, 560,560, 560,1680, 560,560,
    // 下面一行表示資料反碼
    560,1680, 560,1680, 560,560, 560,1680, 560,1680, 560,1680, 560,560, 560,1680,
    560,20000}; // 末尾兩個數字表示結束碼
重新編譯執行測試App,手機依舊對準解碼儀,然後點選按鈕發射紅外訊號,解碼儀終於正常顯示使用者碼4055、資料碼44了。這時再將手機對準掃地機器人,點擊發射按鈕,機器人居然轉動起來了耶。至此遙控器clean鍵的紅外編碼正式破解完成,其它按鍵乃至其它家電遙控器的紅外訊號編碼,均可通過解碼儀破譯得到。
當然,以上的紅外訊號解析辦法,僅限於編碼規則廣泛公開的NEC協議。對於其它格式未知的電路協議,只能藉助於更專業的微控制器來分析,話說開發者拿起電路板,一邊做電工,一邊做碼農,其樂也融融。採用紅外遙控的家電種類與品牌都很繁多,前人已經對它們做了不少的訊號破譯工作,這些已知的紅外訊號資料詳見網址http://www.remotecentral.com/cgi-bin/codes/,裡面包括各大國外家電品牌的訊號編碼,有興趣的讀者可參考。


點此檢視Android開發筆記的完整目錄


__________________________________________________________________________
本文現已同步釋出到微信公眾號“老歐說安卓”,開啟微信掃一掃下面的二維碼,或者直接搜尋公眾號“老歐說安卓”新增關注,更快更方便地閱讀技術乾貨。

相關推薦

Android開發筆記一百利用紅外發射遙控電器

紅外遙控是一種無線控制技術,它具有功耗小、成本低、易實現等諸多優點,因而被各種電子裝置特別是家用電器廣泛採用,像日常生活中的電視遙控器、空調遙控器等等基本都採用紅外遙控技術。不過遙控器並不都是紅外遙控,也可能是射頻遙控。紅外遙控使用近紅外光線(頻率只有幾萬赫茲)作為遙控光源,

Android開發筆記一百休眠模式下的定時器控制

定時器AlarmManager常常用於需要週期性處理的場合,比如鬧鐘提醒、任務輪詢等等。並且定時器來源於系統服務,即使App已經不在運行了,也能收到定時器發出的廣播而被喚醒。似此迴光返照的神技,便遭到開發者的濫用,造成使用者手機充斥著各種殺不光程序,就算通過手機安全工具一再地

Android開發筆記一百H5通過WebView錄影上傳

前面的博文《Android開發筆記(一百五十二)H5通過WebView上傳圖片》介紹瞭如何拍照上傳給網頁,不料客戶又要求再加個攝像上傳給網頁。既然如此,那麼再探討一下如何實現這個攝像上傳的功能。與拍照上傳一樣,攝像上傳也要重寫WebChromeClient的openFileC

Android開發筆記一百文字輸入佈局TextInputLayout

文字輸入佈局TextInputLayoutTextInputLayout是MaterialDesign庫中對編輯框EditText進行增強的一個控制元件。眾所周知,EditText未輸入字元時,我們可以給它顯示預設的提示文字hint;可是一旦輸入字元,這個hint提示就消失了

Android開發筆記一百向量圖形與向量動畫

向量圖形VectorDrawable 與水波圖形RippleDrawable一樣,向量圖形VectorDrawable也是Android5.0之後新增的圖形類。向量圖不同於一般的圖形,它是由一系列幾何曲線構成的影象,這些曲線以數學上定義的座標點連線而成。具體到實現上,則需開

Android開發筆記一百工具欄ToolBar

Toolbar 在前面的博文《Android開發筆記(二十)頂部導航欄》中,我們學習了ActionBar的用法,可是ActionBar著實是不怎麼好用,比如文字風格不能定製、圖示不能定製,而且還存在低版本的相容性問題,所以實際開發中大家還是不傾向使用ActionBar。為此

Android開發筆記一百app省電方略

電源管理PowerManager PowerManager是Android的電源管理類,用於管理電源操作如睡眠、喚醒、重啟以及調節螢幕亮度等等。 PowerManager的物件從系統服務POWER_SERVICE中獲取,它的主要方法如下: goToSleep : 睡眠,即鎖

Android開發筆記一百約束佈局ConstraintLayout

約束佈局ConstraintLayout是Android Studio 2.2推出的新佈局,並從Android Studio 2.3開始成為預設佈局檔案的根佈局,由此可見Android官方對其寄予厚望,那麼約束佈局究竟具備哪些激動人心的特性呢?傳統的佈局如線性佈局Linear

Android開發筆記一百H5通過WebView上傳圖片

上一篇文章介紹了WebView與JS之間的資料互動,其實就是把字串傳來傳去,這對文字格式的資訊傳輸來說倒還湊合,倘若要傳輸圖片資訊就不管用了。所以,要想讓h5網頁支援從手機上傳圖片,還得另外想辦法,當然各版本的Android系統也都提供了相應的解決辦法。在Android 4.

Android開發筆記一百OpenGL的畫筆工具GL10

上一篇文章介紹了OpenGL繪製三維圖形的流程,其實沒有傳說中的那麼玄乎,只要放平常心把它當作一個普通控制元件就好了,接下來繼續介紹OpenGL具體的繪圖操作,這項工作得靠三維圖形的畫筆GL10來完成了。GL10作為三維空間的畫筆,它所描繪的三維物體卻要顯示在二維平面上,顯而

Android開發筆記一百利用GL10描繪點、線、面

上一篇文章介紹了GL10的常用方法,包括如何設定顏色、如何指定座標系、如何調整鏡頭引數、如何挪動觀測方位等等,不過這些方法只是繪圖前的準備工作,真正描繪點、線、面的製圖工作並未涉及,那麼本文就來談談如何利用GL10進行實際的三維繪圖操作。首先在三維座標系中,每個點都有x、y、

Android開發筆記一百四十三任務排程JobScheduler

任務排程App除了通過螢幕向用戶展示可互動的介面元素之外,還經常需要在後臺做些背地裡做的事情,比如說精密計算、檔案下載、統計分析、資料匯入、狀態監控等等,這些使用者看不到的事一般放在Service中處理。然而有時候我們希望在特定情況下再啟動事務,比如說延遲若干時間之後,或者等

Pro Android學習筆記:聯絡人API3:聯絡人資料

聯絡人資訊 檢視reference中android.provider.ContactsContract.CommonDataKinds可以知道該版本的Android API聯絡人中帶有哪些資訊。在API level 19中,我們看到有以下的資訊: 而各個資訊,例如Email,又有著他的結構,我們可以繼續

Android開發筆記攝像頭拍照

相機Camera Camera是直接操作攝像頭硬體的工具類。常用的方法如下: getNumberOfCameras : 獲取本機的攝像頭數目 open : 開啟攝像頭,預設開啟後置攝像頭。如果有多個攝像頭,那麼open(0)表示開啟後置攝像頭,open(1)表示開啟前置攝像

Android開發筆記手機資料庫Realm

Realm應用背景 Android自帶的SQLite資料庫,在多數場合能夠滿足我們的需求,但隨著app廣泛使用,SQLite也暴露了幾個不足之處: 1、開發者編碼比較麻煩,而且還要求開發者具備SQL語法知識; 2、SQLite預設沒有加密功能,手機一旦丟失容易導致資料庫被破解; 3、SQLite底層採用ja

OpenCV開發筆記:紅胖子8分鐘帶你深入瞭解ORB特徵點圖文並茂+淺顯易懂+程式原始碼

若該文為原創文章,未經允許不得轉載原博主部落格地址:https://blog.csdn.net/qq21497936原博主部落格導航:https://blog.csdn.net/qq21497936/article/details/102478062本文章部落格地址:https://blog.csdn.ne

一百Android O wpa_supplicant初始化學習—— retrieveIfacePtr 流程探討

前言:一直想梳理下WiFi在supplicant的連線流程,但是初始化流程梳理的千瘡八孔,少了前置步驟很難梳理。先看下一個基礎的介面retrieveIfacePtr流程。   1.目標介面 sta_iface.cpp /** * Retrieve the underl

Android開發筆記圖片快取演算法

ImageCache 由於手機流量有限,又要加快app的執行效率,因此好的app都有做圖片快取。圖片快取說起來簡單,做起來就用到很多知識點,可算是集Android技術之大全了。只要理解圖片快取的演算法,並加以實踐把它做好,我覺得差不多可以懂半個Android的開發。快取策略

Android開發筆記Runnable介面實現多執行緒

Runnable概述 Runnable介面可宣告一連串的事務,常用於多執行緒處理。但是實現Runnable介面並不意味著開啟了一個新執行緒,只是定義了接下來要做的事情,至於說這些事情要在主執行緒處理,還是在分執行緒處理,那得看我們在哪裡執行Runnable例項。如果在Han

Android開發筆記使用Properties讀寫屬性值

Properties概述 Java中的配置檔案常為.properties檔案,而Properties類便是讀寫此類檔案的工具。屬性檔案有兩種格式,一種是文字格式,其內容是“鍵=值”的形式,文字註釋資訊可以用"#"來註釋。另一種是XML格式,鍵值對遵循XML規範,Androi