最近在做乙個智慧型家居的專案,其核心部分是使用紅外遙控各種家電,包括電視,風扇,空調等等。在製作學習型紅外遙控的過程中,遇到了許多問題,也頗有感悟,特此記錄下來與大家分享。
紅外線傳送不同於一般的資料傳輸協議,在此與串列埠比較說明。
串列埠是最簡單的資料傳輸協議,學過微控制器的人都知道,微控制器通過串列埠傳送協議時,其傳送的波形是一系列高低變化的電平(這不是廢話嗎?)。
一般串列埠一次傳送只能傳送1個位元組,即8個位的資料。若排除校驗位、其實為或是其他xx位,若是從最高位開始發,0101 0001b 這個資料的波形就是先低電平,後高電平,再低電平…. 一直到最低位傳送完畢(或者是校驗位)。以下是串列埠傳送的波形圖。
而紅外線的發射有兩種狀態,一種是載波訊號,另一種是空閒訊號。什麼是載波訊號?按照我最直觀的理解,載波訊號就是一組連續的,高頻率的方波。一般世面上的家電紅外線發射都是使用38khz頻率的載波,這個還牽扯到紅外線接收頭的問題,在後面接收端會提到。與載波訊號相對,空閒訊號就是一段連續的高電平或低電平。注意,是空閒訊號期間是不會發生波形變化的。
上面就是我在使用紅外線發射時相關io口輸出的高低電平變化,是不是奇怪為社麼有黑色的粗條。那就是載波訊號,一系列連續的高低電平變化,只不過頻率太高,電平跳變的線都擠在一起,成為了一根粗條。
而兩根粗條之間的間隔就是空閒訊號,有可能是高電平,也可能是低電平,一般沒什麼影響,只要其間不發生電平跳變就行。
不同的廠家有的紅外線傳送協議都不盡相同,但是都類似。例如nec協議,
按照nec協議,上面的波形圖傳送的資料就是 0000 0000b。另外,nec協議在正式資料傳送前還有個引導碼,先是9ms的載波,後是4.5ms的低電平。引導碼,顧名思義,就是告訴接受裝置我要開始傳送資料了,你做好準備接受。
當然這只是乙個特定的協議,你完全可以自己制定乙個協議,不過還要在接收端上也要根據這個協議進行接收。
微控制器的接收端是通過乙個紅外線接收頭來實現的。這個紅外線接收頭很神奇,能夠識別38khz的載波訊號與空閒訊號。
這是與之前相對應的接收端波形圖,可以看到,傳送的載波經紅外置收頭輸出成了低電平,空閒訊號輸出成了高電平。
那這就好辦了,之前我們不是說過紅外傳輸間有個協議嗎,只要我在接收端根據這個協議進行接收就行了,繼續拿nec作為例子說明:
當nec的引導碼傳送過來時,由於有載波訊號,紅外置收頭引腳輸出由高電平跳變為低電平。那麼只要我們設定乙個下降沿中斷就可以隨時地進行資料接收。而且,我們要檢測接受到的載波訊號和空閒訊號的持續時間是否與傳送的引導相同(都接近9ms和4.5ms),只有當通過了引導碼的檢驗後才能進行資料接收,否則直接結束接收,避免收到錯誤的資料。
資料的接受也是一樣,按照接收到高低電平的持續時間識別傳送過來的是1還是0。
下面貼上用使用nec協議作傳送和接收測試時相應引腳的波形圖,因為螢幕太小的緣故,只記錄到了引導碼+使用者碼。而nec剩餘的使用者反碼、按鍵碼和按鍵反碼都沒記錄到。
上面闡述了紅外收發的基本原理,然而若根據協議來制定接受協議與傳送協議,那麼世界上那麼多個廠家,那麼多種紅外協議,難道要沒種協議都寫乙個傳送接收函式嗎?這當然是不現實的,所以我們有了另一種思路。
既然紅外線是以波形的形式傳送出去的,只要兩段波形相同,那麼接受端才不會管你的程式是怎麼寫的,有沒有按照協議傳送呢,通通照收了再說。
所以,如果我們有了一種未知協議的遙控器發射裝置,我只需要拿個乙個紅外線接收器將你傳送的波形記錄下來(解碼),那不就學習到你的波形了嗎?怎麼記錄呢,可以參考一下nec協議接受端的操作。
基於nec協議的接受函式主要是檢測傳送過來的波形符不符合nec協議的標準。例如,引導碼的載波訊號是否為9ms,空閒是否為4.5ms,560us載波後的空閒是560us還是1.68ms。
換一種思路,假如我知不道究竟持續多久的載波+空閒才是正確的引導,但我能夠確定你傳送的訊號是準確的。那麼只要我將從你開始傳送(進入中斷後)的每一次的載波訊號的時間和空閒訊號的時間都儲存在乙個長度足夠的陣列裡,那麼當我想傳送一段和你相同的紅外編碼時,只要根據這個陣列裡的時間傳送載波訊號和空閒訊號即可,這樣即使我知道你的協議,但我照樣能發射出和你一樣的波形。
然而,這個方法的缺點就是需要犧牲空間,因為要使用陣列記錄每一次高電平低電平的時間,發射端紅外編碼協議越複雜,那麼儲存乙個這樣的紅外編碼需要的空間就越多。
我測試過nec協議和美的空調r51協議的波形,儲存乙個以nec編碼的紅外波形需要用到71個16位的整型空間,共142個位元組。而每存乙個r51協議的命令要用到200個16位整型的空間,即400位元組。要知道,像電視、風扇這種家電的紅外編碼還算簡潔,但對於空調來說,每乙個溫度對應的各種操作(例如開機,公升溫、降溫)的紅外編碼都不同,在不知道編碼規律單純記錄波形的情況下,這種方式對空間的消耗是巨大的。
上圖是我在測試美的空調r51協議編碼發射端時完整記錄的波形圖。
有木有注意到,r51的波形圖橫座標是以25ms為單位,之前nec是以2.5ms為單位,所以空調的波形資料佔那麼大的空間就不足為怪了。
學習型紅外遙控的原理基本是這些了。上面我只是介紹了這個實現這個功能的大概思路而忽略了實現過程。對於stm32這款微控制器,可以使用定時器pwm功能輸出38khz的載波訊號;測量高低電平持續時間,可以使用systick的精確延時來實現等等。
附上我製作學習型紅外時的除錯流程圖:
因為之前在51上做過nec的紅外遙控,所以直接使用了51板作為紅外發射端。
最後貼上源**位址,學習型紅外的功能都封裝好了,直接使用函式即可,不過要注意引腳的設定。
學習型紅外遙控原始碼
剛剛學會用git和github,越用越覺得爽,也希望大家有空也一起學學。有的地方寫的不夠好,希望大家多多指教。
stm32紅外遙控的外部中斷實現
花了整整兩天時間終於算是基本把紅外解碼搞明白了,其實並不是很難,用了兩天時間,說來慚愧啊,原因就是細節上的問題,不過最終總算找出問題來了。使用外部中斷來解碼,就先對外部中斷進行配置吧 void exti init rcc apb2enr 1 0 使用外部中斷要開afio復用時鐘,因為要用到用到它的暫...
STM32 紅外遙控器
紅外 原理 遙控器作為發射器,發射38khz的載波,接收器在接收到載波時為低電平 按照nec protocol的pwm,該協議的特點 1 8位位址和8位指令長度 2 位址和命令分兩次傳送,並有傳送位址和命令反碼,便於校驗,確保傳輸的準確 3 pwm脈衝位置調製,以發射紅外載波的占空比來表示 0 和 ...
STM32紅外遙控NEC協議
正點原子紅外遙控實驗 nec協議發出的一幀資料報括 同步 引導 碼,位址碼,位址反碼,控制碼,控制反碼,連發 重複 碼 其中位址碼,位址反碼,控制碼,控制反碼的邏輯 1 和邏輯 0 表示如下 邏輯 1 2.25ms 560us脈衝 1680us低電平 邏輯 0 1.125ms 560us脈衝 560...