Android紅外遙控開發(fā)實(shí)踐

一、簡介

隨著科技進(jìn)步,手機(jī)逐漸融入了我們的生活。通過在手機(jī)中內(nèi)置紅外發(fā)射器,手機(jī)可以模擬各種遙控器的操作,實(shí)現(xiàn)對不同家電設(shè)備的控制。在電視精靈的Android版本中,也支持了紅外遙控器功能,實(shí)現(xiàn)對移動(dòng)高清機(jī)頂盒的遙控操作,提升了用戶手機(jī)控制大屏的體驗(yàn)。紅外遙控器的具體樣式,如下圖1所示,基本涵蓋了用戶日常操作指令。

紅外遙控是一種古老而實(shí)用的技術(shù),它是利用紅外線的特性來傳遞信息。紅外線是一種不可見光,具有較強(qiáng)的穿透力和方向性。在紅外遙控中,發(fā)射器會(huì)將控制指令編碼成特定的紅外信號,并通過發(fā)射二極管將其發(fā)射出去。當(dāng)這些紅外信號到達(dá)接收設(shè)備時(shí),接收設(shè)備中的紅外接收器會(huì)將其接收并解碼,從而執(zhí)行相應(yīng)的操作。接下來,本文將詳細(xì)介紹一下紅外系統(tǒng)的實(shí)現(xiàn)原理,并以電視精靈紅外遙控為例,介紹如何在Android系統(tǒng)上開發(fā)紅外遙控功能。


圖1 電視精靈紅外遙控g

二、紅外遙控原理

2.1 紅外系統(tǒng)

紅外遙控系統(tǒng)通常由紅外發(fā)射器和紅外接收器組成。紅外發(fā)射器將控制信號轉(zhuǎn)換為紅外光信號發(fā)射出去,而紅外接收器則接收這些紅外光信號,并將其轉(zhuǎn)換回電信號,從而實(shí)現(xiàn)對設(shè)備的控制。紅外遙控系統(tǒng)發(fā)送和接收的主要組成部分,如下圖所示。

圖2 紅外系統(tǒng)組成結(jié)構(gòu)

發(fā)送端:

  1. 指令輸入:用戶通過遙控器上的按鍵輸入控制指令。

  2. 編碼:將指令編碼為紅外信號格式。

  3. 調(diào)制:使用特定的調(diào)制方式,將編碼后的信號與載波進(jìn)行調(diào)制。

  4. 紅外發(fā)射:通過紅外發(fā)射二極管將調(diào)制后的紅外信號發(fā)射出去。

接收端:

  1. 紅外接收:紅外接收二極管接收紅外信號。

  2. 解調(diào):對接收的信號進(jìn)行解調(diào),還原出編碼信息。

  3. 解碼:將解碼后的信息轉(zhuǎn)換為具體的控制指令。

  4. 指令執(zhí)行:根據(jù)接收到的控制指令,執(zhí)行相應(yīng)的操作,如控制家電設(shè)備的開關(guān)、調(diào)節(jié)等。

2.2 紅外編碼

紅外遙控器發(fā)射的信號由一串“0”和“1”的二進(jìn)制代碼組成,不同的芯片對“0”和“1”的編碼有所不同,通常有曼徹斯特 (Manchester) 編碼和脈沖寬度編碼 (PWM)。

2.2.1 曼徹斯特編碼(Manchester Encoding)

  • 原理:曼徹斯特編碼是一種雙相編碼,通過電平的高低轉(zhuǎn)換來表示“0”或“1”。每位中間的電平轉(zhuǎn)換既表示了數(shù)據(jù)代碼,也作為定時(shí)信號使用。

  • 特點(diǎn):

    • 每位數(shù)據(jù)都有一個(gè)電平跳變,位中間的跳變既作時(shí)鐘信號,又作數(shù)據(jù)信號。

    • 數(shù)據(jù)傳輸速率是調(diào)制速率的1/2,因?yàn)槊總€(gè)碼元都被調(diào)制成兩個(gè)電平。

    • 編碼效率約為50%,因?yàn)槊總€(gè)時(shí)鐘位都必須有一次變化。

2.2.2 脈沖寬度編碼(PWM, Pulse Width Modulation)

  • 原理:脈沖寬度編碼以發(fā)射紅外載波的占空比代表“0”和“1”。一般通過固定發(fā)射紅外載波的時(shí)間,通過改變不發(fā)射載波的時(shí)間來改變占空比。

  • 特點(diǎn):

    • 節(jié)省能量,因?yàn)榘l(fā)射紅外載波的時(shí)間固定。

    • 解碼方便,通常包含引導(dǎo)碼以輔助解碼。

    • 不同芯片或制造商的PWM編碼可能有所不同。

2.2.3 脈沖寬度編碼舉例

家用電器使用的紅外遙控器絕大部分都是脈沖寬度編碼,例如常用的電視遙控器使用NEC upd6121芯片,其“0”為載波發(fā)射0.56ms,不發(fā)射0.56ms;其“1”為載波發(fā)射0.56ms,不發(fā)射1.68ms。如下圖所示:

圖3 脈沖電平
圖4 紅外編碼

2.3 紅外調(diào)制

在紅外通信中,將編碼后的二進(jìn)制信號調(diào)制成特定頻率(如38kHz)的間斷脈沖串是一個(gè)常見的做法。這種調(diào)制方式通常被稱為脈沖調(diào)制或載波調(diào)制。在這個(gè)過程中,原始的二進(jìn)制信號(由“0”和“1”組成)被用來控制一個(gè)高頻載波信號(如38kHz的脈沖信號)的開關(guān)狀態(tài)。

具體實(shí)現(xiàn)時(shí),二進(jìn)制信號中的“1”和“0”,分別由不同38kHz載波和低電平組成。如“0”為由 0.56ms 的 38kHz 載波和 0.56ms 的無載波低電平組合而成;“1”由 0.56ms 的 38kHz 載波和 1.69ms 的無載波低電平組合而成。這樣,原始的二進(jìn)制信號就被轉(zhuǎn)換成了一個(gè)間斷的脈沖串,其中每個(gè)脈沖都對應(yīng)于原始信號中的一個(gè)位。

如下圖所示,以下是一個(gè)簡化的描述,說明如何使用高低電平來控制紅外信號的調(diào)制:

  1. 原始二進(jìn)制信號:例如,我們有二進(jìn)制信號“0010”。

  2. 載波頻率:選擇38kHz作為載波頻率。

  3. 調(diào)制過程:

    1. 當(dāng)二進(jìn)制信號為“1”時(shí),生成一個(gè)由0.56ms 的 38kHz 載波和 1.69ms 的無載波低電平脈沖

    2. 當(dāng)二進(jìn)制信號為“0”時(shí),生成一個(gè)由0.56ms 的 38kHz 載波和 0.56ms 的無載波低電平脈沖。

圖5 載波調(diào)制

2.4 紅外解調(diào)

解調(diào)是調(diào)制的逆過程,是通過紅外接收管進(jìn)行接收的。其基本工作過程為:當(dāng)接收到調(diào)制信號時(shí),輸出高電平,否則輸出為低電平。

圖6 紅外解調(diào)

2.5 紅外解碼

解碼是將解調(diào)輸出的脈沖,還原為二進(jìn)制的“0”和“1”,得到二進(jìn)制的“0”,“1”序列,進(jìn)而通過編碼協(xié)議分析傳輸內(nèi)容所含的用戶碼和數(shù)據(jù)碼。

圖7 紅外解碼

三、開發(fā)實(shí)踐

3.1 Android紅外開發(fā)

截止目前,iphone手機(jī)內(nèi)部沒有配置紅外發(fā)射硬件,因此在iphone手機(jī)上是不支持紅外指令發(fā)射的。文中后續(xù)的開發(fā)介紹,以Android系統(tǒng)為基礎(chǔ)。

3.1.1 權(quán)限申請

在App工程的AndroidManifest.xml中補(bǔ)充紅外權(quán)限配置。

<!--紅外遙控-->
<uses-permission android:name="android.permission.TRANSMIT_IR" />
<!-- 是否僅在支持紅外的設(shè)備上運(yùn)行 -->
<uses-feature android:name="android.hardware.ConsumerIrManager" android:required="false" /> 

3.1.2 API調(diào)用

紅外遙控功能從Android4.4之后才開始支持,對應(yīng)的管理類名叫ConsumerIrManager,常用的三個(gè)方法分別是:

  • 檢測設(shè)備是否支持紅外發(fā)射器
/**
* 返回true表示支持紅外發(fā)射,返回false表示不支持紅外發(fā)射
*/
public boolean hasIrEmitter()
  • 獲得紅外發(fā)射器可用的載波頻率范圍
/**
* 返回CarrierFrequencyRange類型數(shù)組,表示紅外發(fā)射器可用的載波頻率范圍
*/
public CarrierFrequencyRange[] getCarrierFrequencies()
  • 發(fā)射紅外信號
/**
* @param carrierFrequency 信號頻率,單位赫茲(Hz),家用電器的紅外頻率通常使用38000Hz
* @param pattern 整型數(shù)組形式的信號格式
*/
public void transmit(int carrierFrequency, int[] pattern)

3.1.3 碼值編碼

紅外編碼由“引導(dǎo)碼 + 用戶編碼(高八位)+ 用戶編碼(低八位)+ 鍵數(shù)據(jù)碼 + 鍵數(shù)據(jù)反碼 + 結(jié)束碼”組成,然后按照一定的編碼規(guī)則,合成數(shù)組的形式。以NEC6122協(xié)議舉例,引導(dǎo)碼固定為(9000 + 4500),結(jié)束碼固定為(560,20000)。不同遙控器差別主要在于用戶碼和數(shù)據(jù)碼,同一個(gè)遙控器的用戶碼是一樣的,不同按鍵有不同的碼值,碼值可以轉(zhuǎn)換出對應(yīng)的數(shù)據(jù)碼和數(shù)據(jù)反碼。

紅外鍵值

上述表格中列了NEC協(xié)議的幾個(gè)指令,下面以按鍵數(shù)字2進(jìn)行舉例。

數(shù)字按鍵2的十六進(jìn)制表示:

  • 用戶碼:0x08E6

  • 碼值:0x41

轉(zhuǎn)換為二進(jìn)制:

  • 用戶碼

    • 高八位:00001000(表示08)

    • 低八位:11100110(表示E6)

  • 數(shù)據(jù)碼

    • 原碼:01000001(表示41)

    • 反碼:10111110(41的反碼)

由于手機(jī)與遙控器的信號編碼有區(qū)別,需要逆序編碼。

逆序編碼:

  • 用戶碼

    • 高八位: 00010000

    • 低八位: 01100111

  • 數(shù)據(jù)碼

    • 原碼:10000010

    • 反碼:01111101

編碼轉(zhuǎn)換完成,通過transmit方法進(jìn)行發(fā)送。但是參數(shù)要傳遞整型數(shù)組形式的信號,并不是二進(jìn)制數(shù)而是電平信號數(shù)據(jù)。電平是電路中某一點(diǎn)電壓的高低狀態(tài),在數(shù)字電路中常用高電平表示“1”,用低電平表示“0”。根據(jù)上文可以看出,遙控器發(fā)射紅外信號之時(shí),通過“560us高電平+1690us低電平”代表“1”,通過“560us高電平+565us低電平”代表“0”。于是編寫Android代碼的時(shí)候,使用“560,1690”表示二進(jìn)制的1,使用“560,565”表示二進(jìn)制的0,具體數(shù)組值如下所示:

int[] patternForKey2 = {9000,4500, // 開頭兩個(gè)數(shù)字表示引導(dǎo)碼
// 下面兩行表示用戶碼: 00010000 01100111
560,565, 560,565, 560,565, 560,1690, 560,565, 560,565, 560,565, 560,565,560,565, 560,1690, 560,1690, 560,565, 560,565, 560,1690, 560,1690, 560,1690,
// 下面一行表示數(shù)據(jù)碼:10000010
560,1690, 560,565, 560,565, 560,565, 560,565, 560,565, 560,1690, 560,565,
// 下面一行表示數(shù)據(jù)反碼:01111101
560,565, 560,1690, 560,1690, 560,1690, 560,1690, 560,1690, 560,565, 560,1690,
560,20000}; // 末尾兩個(gè)數(shù)字表示結(jié)束碼

3.1.4 指令發(fā)送

當(dāng)我們做好指令和數(shù)組值的映射,并選定信號頻率。在需要發(fā)射紅外信號處調(diào)用如下:

/**
 * 按下按鍵發(fā)射紅外信號
 */
 public void transmit() {
     ConsumerIrManagerApi.transmit(38000, patternForKey2);
 }

3.2 電視精靈紅外遙控實(shí)現(xiàn)

紅外遙控功能,已經(jīng)在電視精靈的Android版本中落地。為了保證用戶體驗(yàn)和功能的有效性,在開發(fā)過程中,我們考慮并解決了以下兩個(gè)問題:

  1. 電視精靈需要控制多種不同款的機(jī)頂盒,不同類型機(jī)頂盒,可能支持的紅外碼是不一樣的。

  2. 用戶快速點(diǎn)擊多個(gè)指令,如何確保指令不丟失?

針對如上兩個(gè)問題,對應(yīng)解決方案分別是:

  1. 根據(jù)綁定設(shè)備類型,動(dòng)態(tài)獲取紅外碼值。

  2. 提供指令隊(duì)列,防止指令丟失。

3.2.1 紅外碼值動(dòng)態(tài)獲取

紅外遙控為了兼容不同設(shè)備,采用了紅外碼值動(dòng)態(tài)下發(fā)的方式。主要流程如下圖所示:

  1. 應(yīng)用啟動(dòng)判斷當(dāng)前是否綁定設(shè)備,并發(fā)起紅外配置獲取請求,如果有設(shè)備則帶上設(shè)備相關(guān)信息。

  2. 紅外配置獲取成功,則使用云端配置信息初始化紅外遙控。

  3. 紅外配置獲取失敗,則使用本地兜底數(shù)據(jù)初始化紅外遙控。

圖8 紅外碼值動(dòng)態(tài)下發(fā)方案

3.2.2 指令隊(duì)列控制

當(dāng)用戶快速點(diǎn)擊紅外遙控時(shí),可能會(huì)導(dǎo)致部分指令丟失。為了確保每個(gè)指令在手機(jī)端都能得到處理,我們基于線程池框架,實(shí)現(xiàn)紅外操作指令的控制隊(duì)列,具體實(shí)現(xiàn)如下所示。

  1. 定義發(fā)碼線程池
private static ExecutorService executorService = Executors.newSingleThreadExecutor();
  1. 單線程發(fā)碼保證先后順序,確保每次只有一個(gè)指令在執(zhí)行
/**
 * 發(fā)射紅外信號
 * @param carrierFrequency 紅外頻率
 * @param pattern 紅外碼
 */
public void transmit(int carrierFrequency, int[] pattern) {
    executorService.submit(new Runnable() {
        @Override
        public void run() {
            if(consumerIrManager != null){
                consumerIrManager.transmit(carrierFrequency, pattern);
            }
        }
    });
}

四、總結(jié)

紅外遙控是一項(xiàng)非常實(shí)用的技術(shù),它讓我們能夠輕松地操控各種家電設(shè)備。紅外遙控具有操作簡單、成本相對較低等優(yōu)點(diǎn),在家庭和日常生活中得到了廣泛應(yīng)用。但它也存在一些不足之處,比如信號容易被阻擋、對角度有一定要求,且不同設(shè)備之間可能存在兼容性問題。盡管如此,紅外遙控依然是我們生活中不可或缺的一部分,它為我們帶來了便利,也見證了科技的發(fā)展與進(jìn)步。

參考文獻(xiàn)

  1. Android 紅外Uart數(shù)據(jù)發(fā)送APP開發(fā)_android紅外給設(shè)備寫信息-CSDN博客

  2. 紅外遙控及Android手機(jī)紅外遙控器開發(fā)

  3. Android 新增紅外遙控支持 安卓有紅外線遙控嗎_GhostLover的技術(shù)博客_51CTO博客

  4. android 紅外遙控器編碼接收 紅外遙控編碼原理_mob6454cc670f76的技術(shù)博客_51CTO博客

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,428評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,024評論 3 413
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,285評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,548評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,328評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,878評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,971評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,098評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,616評論 1 331
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,554評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,725評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,243評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 43,971評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,361評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,613評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,339評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,695評論 2 370

推薦閱讀更多精彩內(nèi)容