一個能夠發送和接收紅外線訊號的庫。
可作為 Arduino 庫“IRremote”使用。
? Google翻譯
支援的紅外線協議
特徵
4.x 版本的新功能
3.x 版本的新功能
將 2.x 程式轉換為 4.x 版本
如何將舊的 MSB 前 32 位 IR 資料代碼轉換為新的 LSB 前 32 位 IR 資料代碼
使用舊教學的 3.x 版本時發生錯誤
繼續使用 2.x
為什麼 *.hpp 而不是 *.cpp
使用新的 *.hpp 文件
教學
指定 IR 代碼的 3 種方法
IR接收器引腳排列
接收IR碼
免責聲明
其他庫,可能涵蓋這些協議
協定=PULSE_DISTANCE
協議=未知
如何處理 IRremote 不支援的協議
解碼IR資料結構
協議不明確
不同協定的RAM使用情況
處理未知協議
發送紅外線代碼
公共 IR 代碼資料庫列表
發送 IRDB IR 代碼
發送圖釘
微型 NEC 接收器和發送器
FAST協議
常見問題與提示
在analogWrite()或tone()之後或在運轉馬達之後接收停止
接收設定溢出標誌
Neopixel、FastLed 等問題
無法與其他函式庫一起使用/編譯
多個 IR 接收器和發送器實例
增加發送輸出訊號的強度
最低 CPU 時脈頻率
Bang & Olufsen 協議
該庫的範例
WOKWI 線上範例
機器人小車的紅外線控制
問題和討論
該函式庫的編譯選項/宏
使用 Arduino IDE 更改包含 (*.h) 文件
使用 Sloeber IDE 修改編譯選項
支援的主機板
定時器和引腳使用
與其他函式庫和 Arduino 指令(例如tone()和analogWrite())不相容
用於發送的硬體 PWM 訊號生成
為什麼我們要使用 30% 的佔空比來發送
我們如何解碼訊號
NEC 編碼圖
5個Arduino IR接收庫快速對比
歷史
有用的連結
貢獻者
執照
版權
NEC / Onkyo / Apple
Denon / Sharp
Panasonic / Kaseikyo
JVC
LG
RC5
RC6
Samsung
Sony
Universal Pulse Distance
Universal Pulse Width
Universal Pulse Distance Width
Hash
Pronto
BoseWave
Bang & Olufsen
Lego
FAST
Whynter
MagiQuest
可以透過在#include <IRremote.hpp>
行之前定義巨集來關閉和開啟協議,如下所示:
#define DECODE_NEC//#define DECODE_DENON#include <IRremote.hpp>
很多教學和範例。
積極維護。
允許接收和發送原始定時資料。
由於 4.3 IrSender.begin(DISABLE_LED_FEEDBACK)
將不再起作用,請改用IrSender.begin(DISABLE_LED_FEEDBACK, 0)
。
新增了新的通用脈衝距離/脈衝寬度/脈衝距離寬度解碼器,涵蓋了許多以前未知的協定。
列印如何透過IrReceiver.printIRSendUsage(&Serial)
發送接收到的命令的程式碼。
對於 32 位元平台,RawData 類型現在是 64 位,因此與先前的 32 位元平台相比, decodedIRData.decodedRawData
可以包含更多協定的完整幀資訊。
收到命令後回調- 一旦收到訊息,它就會呼叫您的程式碼。
改進了PULSE_DISTANCE
+ PULSE_WIDTH
協定的處理。
新的 FAST 協議。
使用printIRSendUsage()
自動列印對應的發送函數。
您必須將#define DECODE_DISTANCE
替換為#define DECODE_DISTANCE_WIDTH
(僅當您明確啟用此解碼器時)。
參數bool hasStopBit
不再需要並被刪除,例如對於函數sendPulseDistanceWidth()
。
任何引腳都可用於接收,如果未定義SEND_PWM_BY_TIMER
也可用於傳送。
可以啟動回饋 LED 以進行發送/接收。
提供 8/16 位元 **命令值以及 16 位元位址和協定號用於解碼(而不是舊的 32 位元值)。
協議值符合協議標準。
NEC、Panasonic、Sony、Samsung 和 JVC 解碼並先發送 LSB。
支援Universal Distance協議,涵蓋了許多以前未知的協議。
與tone()庫相容。請參閱 ReceiveDemo 範例。
同時發送和接收。請參閱 SendAndReceive 範例。
支援更多平台。
允許產生非 PWM 訊號,僅模擬低電平有效接收器訊號,以便直接連接到現有接收設備,而無需使用 IR。
簡單的協定配置,直接在原始碼中。
減少記憶體佔用並縮短解碼時間。
包含一個非常小的 NEC 專用解碼器,不需要任何計時器資源。
-> 5 個 Arduino IR 函式庫的功能比較。
從3.1版本開始,用於發送的PWM的生成由軟體完成,從而節省了硬體定時器並允許任意輸出引腳用於發送。
如果您使用不使用-flto
標誌進行編譯的(舊)Arduino 核心,並且在編譯期間收到有關 begin() 的錯誤訊息,則可以啟動 IRRemote.h 中的#define SUPPRESS_ERROR_MESSAGE_FOR_BEGIN
行。
新增了IRreceiver和IRsender對象,無需定義即可使用它們,就像眾所周知的 Arduino Serial物件一樣。
只要刪除行IRrecv IrReceiver(IR_RECEIVE_PIN);
和/或IRsend IrSender;
在您的程式中,並替換所有出現的IRrecv.
或irrecv.
與IrReceiver
並用IrSender
取代所有IRsend
或irsend
。
由於解碼後的值現在位於IrReceiver.decodedIRData
中,而不再位於results
中,因此請刪除decode_results results
行或類似行。
與 Serial 物件一樣,在 setup() 中呼叫IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK)
或IrReceiver.begin(IR_RECEIVE_PIN, DISABLE_LED_FEEDBACK)
而不是IrReceiver.enableIRIn()
irrecv.enableIRIn()
如需發送,請呼叫IrSender.begin();
在設定()中。
如果未定義 IR_SEND_PIN(在#include <IRremote.hpp>
行之前),則必須使用例如IrSender.begin(3, ENABLE_LED_FEEDBACK, USE_DEFAULT_FEEDBACK_LED_PIN);
舊的decode(decode_results *aResults)
函數被簡單的decode()
取代。因此,如果您有一條語句if(irrecv.decode(&results))
將其替換為if (IrReceiver.decode())
。
解碼結果現在位於IrReceiver.decodedIRData
中,不再位於results
中,因此將任何出現的results.value
和results.decode_type
(及類似的)替換為IrReceiver.decodedIRData.decodedRawData
和IrReceiver.decodedIRData.protocol
。
溢出、重複和其他標誌現在位於IrReceiver.receivedIRData.flags
中。
很少使用: results.rawbuf
和results.rawlen
必須替換為IrReceiver.decodedIRData.rawDataPtr->rawbuf
和IrReceiver.decodedIRData.rawDataPtr->rawlen
。
NEC、Panasonic、Sony、Samsung 和 JVC 5 個協定已先轉換為 LSB。用於傳送舊 MSB 資料的傳送函數已重新命名為sendNECMSB
、 sendSamsungMSB()
、 sendSonyMSB()
和sendJVCMSB()
。舊的sendSAMSUNG()
和sendSony()
MSB 函數仍然可用。 sendPanasonic()
函數的舊 MSB 版本已被刪除,因為它存在無人識別的錯誤,因此假定從未使用過。
有關將 MSB 代碼轉換為 LSB 的信息,請參閱下文。
#include <IRremote.h>#define RECV_PIN 2IRrecv irrecv(RECV_PIN); 解碼結果結果;void setup() { … 串列.開始(115200); // 建立串列通訊 irrecv.enableIRIn(); // 啟動接收器}void Loop() { if (irrecv.decode(&results)) { Serial.println(結果.值, HEX); … irrecv.resume(); // 接收下一個值 } … }
#include <IRremote.hpp>#define IR_RECEIVE_PIN 2void setup() { … 串列.開始(115200); // // 建立串列埠通信 IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // 啟動接收器}void Loop() { if (IrReceiver.decode()) { Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX); // 列印“舊”原始數據 IrReceiver.printIRResultShort(&Serial); // 一行列印完整接收到的數據 IrReceiver.printIRSendUsage(&Serial); // 列印傳送此資料所需的語句 … IrReceiver.resume(); // 允許接收下一個值 } … }
對於NEC、Panasonic、Sony、Samsung 和 JVC的新解碼器,結果IrReceiver.decodedIRData.decodedRawData
現在是LSB-first ,正如這些協議的定義所示!
要將其中一種轉換為另一種,必須反轉位元組/半位元組位置,然後反轉每個位元組/半位元組的所有位元位置,或將其寫入二進位字串並反轉/鏡像它。
範例: 0xCB 34 01 02
0x20 10 43 BC
半位元組反轉後
每個半位元組位元反轉後的0x40 80 2C D3
0->0 1->8 2->4 3->C 4->2 5->A 6->6 7->E 8->1 9->9 A->5 B->D C->3 D->B E->7 F->F
0xCB340102
是二進位1100 1011 0011 0100 0000 0001 0000 0010
。
0x40802CD3
是二進位0100 0000 1000 0000 0010 1100 1101 0011
。
如果向後(從右到左)讀取第一個二進位序列,您將得到第二個序列。為此,您可以使用bitreverseOneByte()
或bitreverse32Bit()
。
可以使用sendNECMSB()
、 sendSonyMSB()
、 sendSamsungMSB()
、 sendJVCMSB()
來傳送舊的 MSB 程式碼而不轉換。
如果您遇到舊教程程式碼(包括IRremote.h
而不是IRremote.hpp
的錯誤,只需嘗試回滾到版本 2.4.0。
您的程式碼很可能會運行,並且您不會錯過新功能。
考慮為您的專案使用原始 2.4 版本 2017 或最後一個向後相容的 2.8 版本。
它可能就足夠了,並且可以完美地處理 32 位元 IR 程式碼。
如果這不適合您的情況,請放心,4.x 至少會嘗試向後相容,因此您的舊範例應該仍然可以正常工作。
僅以下解碼器可用:
NEC
Denon
Panasonic
JVC
LG
RC5
RC6
Samsung
Sony
irrecv.decode(&results)
的呼叫使用舊的 MSB First 解碼器(如 2.x 中),並在results.value
中設定 32 位元程式碼。
無需解碼為更有意義(恆定)的 8/16 位元位址和 8 位元命令。
每個 *.cpp 檔案都是透過呼叫專用於該 cpp 檔案的編譯器來單獨編譯的。這些呼叫由 IDE/make 系統管理。在 Arduino IDE 中,當您按一下「驗證」或「上傳」時,就會執行呼叫。
現在 Arduino 的問題是:
如何為所有 *.cpp 檔案設定編譯選項,尤其是使用的函式庫?
Sloeber 或 PlatformIO 等 IDE 透過允許為每個專案指定一組選項來支援這一點。他們在每次編譯器呼叫時都會添加這些選項,例如-DTRACE
。
但Arduino缺少這個功能。因此,解決方法不是單獨編譯所有原始程式碼,而是透過將它們包含在原始程式碼中將它們連接到一個巨大的原始檔案中。
這是透過例如#include "IRremote.hpp"
完成的。
但為什麼不#include "IRremote.cpp"
呢?
嘗試一下,您會看到大量錯誤,因為 *.cpp 文件的每個函數現在都編譯了兩次,第一次編譯巨大的文件,第二次單獨編譯 *.cpp 文件,如上所述。
因此,不再可能使用擴展名cpp ,一種解決方案是使用hpp作為擴展名,以表明它是包含的 *.cpp 檔案。
其他所有擴充(例如cinclude)都可以,但hpp似乎是常識。
為了更輕鬆地支援編譯選項,您必須在主程式(又稱帶有 setup() 和 Loop() 的 *.ino 檔案)中使用語句#include <IRremote.hpp>
而不是#include <IRremote.h>
。
在所有其他文件中,您必須使用以下內容,以防止multiple definitions
連結器錯誤:
#define USE_IRREMOTE_HPP_AS_PLAIN_INCLUDE#include <IRremote.hpp>
確保主程式中的所有巨集都在#include <IRremote.hpp>
之前定義。
否則,以下巨集肯定會被預設值覆蓋:
RAW_BUFFER_LENGTH
IR_SEND_PIN
SEND_PWM_BY_TIMER
DroneBot Workshop 對 IR 遙控器和 IRremote 庫進行了非常詳細的介紹。
有 3 種不同的方式來指定特定的 IR 代碼。
每個標記/脈衝和脈衝之間的間隔/距離的時序在清單或陣列中指定。這可以指定所有 IR 程式碼,但需要大量記憶體並且根本不可讀。這種定時陣列的一種正式定義(包括頻率和重複的規範)是Pronto格式。
使用較低的時間分辨率可以節省記憶體。對於 IRremote,您可以使用 50 µs 分辨率,透過使用位元組值而不是 int16 值,將記憶體需求減半。為了接收目的,您可以使用由decodeHash()
解碼器提供的時間雜湊值。
有 3 種主要的編碼方案對二進位位元流/十六進位值進行編碼:
PULSE_DISTANCE
。脈衝之間的距離決定了位元值。這總是需要一個停止位!例如 NEC 和 KASEIKYO 協議。對於大多數協定來說,脈衝寬度是恆定的。
PULSE_WIDTH
。脈衝的寬度決定了位值,脈衝距離是恆定的。這不需要停止位!唯一已知的例子是 SONY 協議。
相位/曼徹斯特編碼。脈衝/暫停轉換(相位)相對於時脈的時間決定了位元值。例如 RC5 和 RC6 協定。
相位編碼具有恆定的位元長度, PULSE_DISTANCE
具有恆定的脈衝寬度,而PULSE_WIDTH
則沒有恆定的位元長度!
使用非恆定脈衝寬度編碼的PULSE_DISTANCE
的一個眾所周知的範例是RS232 串列編碼。這裡使用非恆定脈衝寬度來實現恆定的位元長度。
大多數紅外線訊號都有一個特殊的標頭來幫助設定接收器電路的自動增益。該標頭不是編碼的一部分,但通常對於特殊協議很重要,因此必須是可重現的。
請注意,有些代碼使用PULSE_DISTANCE
編碼,其中不只一個二進位 0/1 被放入脈衝/暫停組合中。這需要 2 種以上不同的脈衝或暫停長度組合。 HobToHood 協議使用這樣的編碼。
使用編碼方案將 IR 代碼的規範簡化為位元流/十六進位值,預設為 LSB 以及標頭、0 和 1 的脈衝/暫停時序。這些方案不能在此位元流上放置任何語義,如位址、命令或校驗和。
有一些常見協定直接在 IRremote 中實作。它們指定頻率、標頭、0 和 1 的時序以及其他值,如校驗和、重複距離、重複編碼、位元切換等。指定IR 代碼的命令。這樣可以節省記憶體且可讀性很高。位址通常也是恆定的,這進一步減少了記憶體需求。
Adafruit 紅外線感測器教程
在您的程式中,您可以使用以下命令檢查是否已完全接收 IR 訊框:
if (IrReceiver.decode()) {}
這也對接收到的資料進行解碼。
成功解碼後,IR 資料包含在 IRData 結構中,可用作IrReceiver.decodedIRData
。
結構 IRData { 解碼類型_t 協定; // UNKNOWN、NEC、SONY、RC5、PULSE_DISTANCE、... uint16_t 地址; // 解碼後的位址 uint16_t 指令; // 解碼後的指令 uint16_t extra; // 用於 Kaseikyo 未知供應商 ID。用於解碼距離協定的刻度。 uint16_t 位數; // 接收的資料位數(位址 + 指令 + 奇偶校驗) - 決定協定長度(如果可能有不同的長度)。 uint8_t 標誌; // IRDATA_FLAGS_IS_REPEAT、IRDATA_FLAGS_WAS_OVERFLOW 等。 IRRawDataType 解碼的RawData; // 最多 32 位元(32 位元 CPU 架構為 64 位元)解碼原始數據,用於 sendRaw 函數。 uint32_t 解碼的RawDataArray[RAW_DATA_ARRAY_SIZE]; // 32 位元解碼後的原始數據,用於傳送功能。 irparams_struct *rawDataPtr; // 要解碼的原始時序資料的指標。主要是接收ISR填充的資料緩衝區。
這是標誌欄位中包含的標誌清單。
使用例如if(IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)
檢查它。
旗幟名稱 | 描述 |
---|---|
IRDATA_FLAGS_IS_REPEAT | 前一幀之間的間隙小於重複預期的最大間隙。 !!!我們不檢查更改的命令或位址,因為幾乎不可能在大約 100 毫秒內按下遙控器上的 2 個不同按鈕! |
IRDATA_FLAGS_IS_AUTO_REPEAT | 當前重複幀是重複幀,總是在常規幀之後發送並且無法避免。僅指定用於 DENON 和 LEGO 協定。 |
IRDATA_FLAGS_PARITY_FAILED | 目前(自動重複)幀違反奇偶校驗。 |
IRDATA_FLAGS_TOGGLE_BIT | 如果設定了 RC5 或 RC6 切換位,則設定該值。 |
IRDATA_FLAGS_EXTRA_INFO | 位址和資料中未包含額外資訊(例如,Kaseikyo 未知供應商 ID 或解碼的RawDataArray 中)。 |
IRDATA_FLAGS_WAS_OVERFLOW | 指定的RAW_BUFFER_LENGTH 標記和空格過多。為了避免無休止的溢出標記,在這種情況下 irparams.rawlen 設定為 0。 |
IRDATA_FLAGS_IS_MSB_FIRST | 該值主要由(已知)協議決定。 |
自動 myRawdata= IrReceiver.decodedIRData.decodedRawData;
此處描述了IrReceiver.decodedIRData.flags
的定義。
IrReceiver.printIRResultShort(&Serial);
IrReceiver.printIRResultRawFormatted(&Serial, true);`
原始資料取決於 Arduino 定時器相對於接收到的訊號的內部狀態,因此每次可能會略有不同。 (分辨率問題)。解碼後的值是解釋後的值,可以容忍如此微小的差異!
IrReceiver.printIRSendUsage(&Serial);
NEC協定定義為8位元位址和8位元指令。但實體位址和資料欄位都是 16 位元寬。額外的 8 位元用於發送反轉位址或奇偶校驗指令。
擴展的NEC協定對16位元位址使用額外的8位元位址奇偶校驗位,從而停用位址的奇偶校驗。
ONKYO 協定再使用位址和指令的附加 8 個奇偶校驗位元來表示 16 位元位址和指令。
如果奇偶校驗正確,解碼器會將 16 位元值減少為 8 位元值。如果奇偶校驗不正確,則假定沒有奇偶校驗錯誤,但假設擴展 NEC 或擴展 NEC 協議,則將這些值視為無奇偶校驗的 16 位元值。
但現在當我們想要接收例如16 位元位址 0x00FF 或 0x32CD 時,我們遇到了問題!解碼器將此解釋為具有正確奇偶校驗 0xFF / 0xCD 的 NEC 8 位元位址 0x00 / 0x32,並將其減少為 0x00 / 0x32。
處理此問題的一種方法是使用#define DECODE_ONKYO
強製程式庫始終使用 ONKYO 協定解釋。另一種方法是檢查IrReceiver.decodedIRData.protocol
是否是 NEC 而不是 ONKYO,並手動恢復奇偶校驗減少。
長按時, NEC 協定不會重複其幀,而是發送一個特殊的短重複幀。這樣可以輕鬆區分長按和重複按,並節省一些電池電量。這種行為對於 NEC 及其衍生協議(例如 LG 和 Samsung)來說非常獨特。
當然,也有一些遠端控制系統,使用 NEC 協議,但僅在長按時重複第一幀,而不是發送特殊的短重複幀。我們將此命名為NEC2協議,並透過sendNEC2()
發送。
但要小心,NEC2 協定只能在第一幀之後且長按時才能被 NEC 庫解碼器偵測到!
長按時, SamsungLG 協定不會重複其幀,而是發送特殊的短重複幀。
RAW_BUFFER_LENGTH
決定解碼前儲存接收到的 IR 定時資料的位元組緩衝區的長度。
對於高達 48 位元的標準協定來說, 100就足夠了,其中 1 位元由一個標記和一個空格組成。我們總是需要額外的 4 個字節,1 個位元組用於初始間隙,2 個位元組用於標頭,1 個位元組用於停止位元。
48位元協定有 PANASONIC、KASEIKYO、SAMSUNG48、RC6。
NEC、SAMSUNG、WHYNTER、SONY(20)、LG(28) 等32位元協定需要緩衝區長度為 68 。
BOSEWAVE、DENON、FAST、JVC、LEGO_PF、RC5、SONY(12 或 15)等16位元協定需要緩衝區長度為 36 。
MAGIQUEST 所需的緩衝區長度為112 。
空調通常發送更長的協定資料流,最多 750 位元。
如果RECORD_GAP_MICROS
確定的記錄間隙從預設的 8 ms 變更為超過 20 ms,則緩衝區不再是位元組,而是 uint16_t 緩衝區,需要兩倍的 RAM。
該庫旨在適合資源水平相對較低的 MCU 內部,並旨在作為庫與其他也需要 MCU 資源才能運行的其他應用程式一起工作。
使用ReceiveDemo 範例列印有關 IR 協定的所有資訊。
ReceiveDump 範例為您提供了更多信息,但由於列印資訊所需的時間,重複檢測效果不佳。
如果該庫似乎不支援您的協議,您可以嘗試 IRMP 庫,它尤其對曼徹斯特協議支援得更好。
對於空調,您可以嘗試 IRremoteESP8266 庫,它支援一組令人印象深刻的協定和大量空調,並且也可以在 ESP32 上運行。
Raw-IR-decoder-for-Arduino 不是一個庫,而是一個 arduino 範例草圖,它提供了許多解碼方法,尤其是空調協定。這些協定的發送可以透過 Arduino 庫 HeatpumpIR 來完成。
如果你得到這樣的東西:
PULSE_DISTANCE: HeaderMarkMicros=8900 HeaderSpaceMicros=4450 MarkMicros=550 OneSpaceMicros=1700 ZeroSpaceMicros=600 NumberOfBits=56 0x43D8613C 0x3BC3BC
那麼你就有了一個由56 位元組成的代碼,它可能來自空調遙控器。
您可以使用sendPulseDistanceWidth()
發送它。
uint32_t tRawData[] = { 0xB02002, 0xA010 }; IrSender.sendPulseDistance(38, 3450, 1700, 450, 1250, 450, 400, &tRawData[0], 48, false, 0, 0);
您可以透過呼叫sendPulseDistanceWidthData()
兩次來傳送它,一次用於前 32 位,下一次用於其餘 24 位。
PULSE_DISTANCE
/ PULSE_WIDTH
解碼器僅將定時流解碼為儲存為十六進位值的位元流。這些解碼器不能在此位元流上放置任何語義,如位址、命令或校驗和。但比特流比定時流更具可讀性。預設情況下,此位元流首先讀取 LSB 。如果LSB不適合進一步研究,可以在這裡更改。
如果 RAM 不超過 2k,解碼器僅接受最多 2500 微秒的標記或空間持續時間以節省 RAM 空間,否則它接受最多 10 毫秒的持續時間。
如果您看到類似Protocol=UNKNOWN Hash=0x13BD886C 35 bits received
內容,則表示您在解碼協定時遇到問題,或協定不受支援。
如果收到的位數為奇數,則您的接收器電路可能有問題。可能是因為紅外線訊號太弱。
如果您看到像+ 600,- 600 + 550,- 150 + 200,- 100 + 750,- 550
這樣的時序,那麼一個450 µs 的空間被分成兩個150 和100 µs 的空間,其間有200 µs的尖峰/誤差訊號。可能是因為接收器有缺陷或與附近的另一個發光源結合時訊號較弱。
如果您看到像+ 500,- 550 + 450,- 550 + 450,- 500 + 500,-1550
這樣的計時,那麼標記通常比空格短,因此MARK_EXCESS_MICROS
(在您的 ino 文件中指定)應該為負數以補償這一點在解碼時。
如果您看到Protocol=UNKNOWN Hash=0x0 1 bits received
,則可能是初始標記之後的空格比RECORD_GAP_MICROS
長。在一些 LG 空調協議中觀察到了這一點。在 .ino 檔案中的#include <IRremote.hpp>
行之前使用一行重試,例如#define RECORD_GAP_MICROS 12000
。
要查看更多資訊來支援您查找 UNKNOWN 協定的原因,您必須在 IRremoteInt.h 中啟用//#define DEBUG
行。
如果您不知道您的紅外線發射器使用哪種協議,您有多種選擇。
只需使用哈希值來決定接收到哪個命令。請參閱 SimpleReceiverForHashCodes 範例。
使用 IRreceiveDemo 範例或 IRreceiveDump 範例轉儲 IR 時序。然後,您可以使用 SendRawDemo 範例重現/傳送該計時。
IRMP AllProtocol 範例列印40 個受支援協定之一的協定和資料。可以使用相同的庫來發送此程式碼。
如果您手邊有更大的 Arduino 板(> 100 kByte 程式記憶體),您可以嘗試 Arduino 庫 DecodeIR 的 IRremoteDecode 範例。
使用 IrScrutinizer。它可以透過匯出為「Arduino Raw」來自動為您的協定產生發送草圖。它支援 IRremote、舊的 IRLib 和 Infrared4Arduino。
如果您手邊有一個可以產生您想要使用的 IR 程式碼的裝置(又稱為 IR 遙控器),建議使用 ReceiveDemo 範例接收程式碼,該範例將在串列輸出上告訴您如何傳送它們。
Protocol=LG Address=0x2 Command=0x3434 Raw-Data=0x23434E 28 bits MSB first Send with: IrSender.sendLG(0x2, 0x3434, <numberOfRepeats>);
您會發現地址是一個常數,並且命令有時會被合理地分組。
如果您不確定用於傳送的重複次數, 3是一個很好的起點。如果這有效,您可以稍後檢查較低的值。
如果啟用了DECODE_DISTANCE_WIDTH
,則printIRSendUsage()
列印的程式碼在 8 位元和 32 位元平台上會有所不同,因此最好在與傳送程式相同的平台上執行接收程式。
如果合理的話,所有發送功能都支援重複發送。重複幀按照協議確定的固定週期發送。例如,對於 NEC,從開始到開始為 110 毫秒。
請記住,在最後發送的標記之後沒有延遲。如果您自己處理重複幀的發送,則必須在重複幀之前插入合理的延遲才能正確解碼。
可以使用sendNECMSB()
、 sendSonyMSB()
、 sendSamsungMSB()
、 sendJVCMSB()
來傳送舊的 MSB 程式碼而不轉換。
Flipper-IRDB 資料庫中的程式碼轉換起來非常簡單,因為它們也使用位址/命令方案。
協議匹配為 NECext -> NECext(或 Onkyo)、Samsung32 -> Samsung、SIRC20 -> Sony(20 位元)等。
irdb 資料庫中找到的程式碼指定了一個裝置、一個子裝置和一個函數。大多數時候,設備和子設備可以作為位址參數的高位元組和低字節,而函數是具有位址、命令和重複計數參數的新結構化函數的命令參數,例如IrSender.sendNEC((device << 8) | subdevice, 0x19, 2)
.
可以在 IR 協定的 IRP 定義檔中找到精確的映射。 “D”和“S”表示設備和子設備,“F”表示功能。
任何引腳都可以選擇作為發送引腳,因為 PWM 訊號預設是透過軟體位元連動產生的,因為SEND_PWM_BY_TIMER
未啟動。
在ESP32上,ledc 通道 0 用於產生 IR PWM。
如果指定了IR_SEND_PIN
(作為 c 巨集),則會減少程式大小並改善 AVR 的傳送時序。如果您想要使用變數來指定傳送引腳,例如使用setSendPin(uint8_t aSendPinNumber)
,則必須停用此IR_SEND_PIN
巨集。然後您可以在發送 IR 幀之前隨時更改發送引腳。另請參閱此程式庫的編譯選項/巨集。
http://www.harctoolbox.org/IR-resources.html
Flipper IRDB 資料庫
翻轉解碼 | 紅外線遙控解碼 |
---|---|
三星32 | 三星 |
日本電氣公司 | 日本電氣公司 |
NECext | 安橋 |
<起始位元><供應商ID:16><供應商ID奇偶校驗:4><流派1:4><流派2:4><指令:10><ID:2><奇偶校驗:8 ><停止位> ID 是位址的 MSB。 地址:8A 02 20 00 命令:56 03 00 00 ->紅外線遠端: 位址0x6A8,發送Panasonic(02 20)和指令0x35 | <起始位元><VendorID:16><VendorID奇偶校驗:4><位址:12><指令:8><VendorID奇偶校驗、位址與指令的奇偶校驗:8><停止位元> |
對於僅需要 NEC、NEC 變體或 FAST(見下文)協議的應用,包含一個特殊的接收器/發送器,其代碼大小非常小,為 500 字節,並且不需要任何定時器。
TinyReceiver 接收器不像 IRremote 那樣每 50 µs 對輸入進行一次取樣,而是使用引腳變更中斷進行動態解碼,這限制了協定的選擇。
在每次層級變更時,層級和自上次變更以來的時間用於增量解碼協定。
有了這個工作原理,我們就不能像IRremote那樣等待超時然後解碼協定了。
相反,我們需要知道哪個是協議的最後一位(級別更改)來進行最終解碼以及調用可選的用戶提供的回調函數handleTinyReceivedIRData()
。
這意味著,我們需要了解協議中的位數,從而了解協議(系列)。
查看 TinyReceiver 和 IRDispatcherDemo 範例。
請注意包含TinyIRReceiver.hpp
或TinyIRSender.hpp
而不是IRremote.hpp
。
//#define USE_ONKYO_PROTOCOL // 與NEC 類似,但將16 位元位址和指令分別視為一個16 位元值,而不是8 位元正常值和8 位元反轉值。不是NEC / ONKYO#include "TinyIRReceiver.hpp"void setup() { initPCIInterruptForTinyReceiver(); // 在 IR 輸入訊號變更時啟用中斷產生}void Loop() { if (TinyReceiverDecode()) { printTinyReceiverResultMinimal(&Serial); } // 不需要resume() :-)}
#include "TinyIRSender.hpp"void setup() { sendNEC(3, 0, 11, 2); // 在接腳 3 上傳送位址 0 和指令 11,重複 2 次。
可以在這裡找到另一個支援更多協定的微型接收器和發送器。
FAST 協議是一種專有的修改後的 JVC 協議,無地址、具有奇偶校驗且具有較短的標頭。它的目的是對在另一塊板上發送協定幀的事件做出快速回應。 FAST 的發送時間為 21 ms ,發送週期為 50 ms 。它具有用於錯誤檢測的完整 8 位元奇偶校驗。
位元時序就像 JVC
標頭較短,3156 µs 與 12500 µs
無位址和 16 位元數據,解釋為 8 位元命令和 8 位元反轉命令,導致固定協定長度為 (6 + (16 * 3) + 1) * 526 = 55 * 526 = 28930 微秒或 29 毫秒。
重複作為完整幀發送,但周期為 50 毫秒/距離為 21 毫秒。
#define IR_SEND_PIN 3#include <IRremote.hpp>void setup() { sendFAST(11, 2); // 在接腳 3 上傳送指令 11,重複 2 次。
#define USE_FAST_PROTOCOL // 使用 FAST 協定。無位址和 16 位元數據,解釋為 8 位元指令和 8 位元反轉指令#include "TinyIRSender.hpp"void setup() { sendFAST(3, 11, 2); // 在接腳 3 上傳送指令 11,重複 2 次。
FAST協定可以透過IRremote和TinyIRReceiver接收。
50 µs 的接收器採樣間隔由定時器產生。在許多板上,這必須是硬體定時器。在一些有軟體定時器的闆卡上,使用軟體定時器。
請注意,用於接收的硬體定時器不應用於analogWrite()
。
特別是馬達控制經常使用analogWrite()
函數,因此如果在此處指示的引腳上使用,將停止接收。
在 Uno 和其他 AVR 板上,接收器計時器與音訊計時器相同。因此,接收將在tone()
指令之後停止。請參閱 ReceiveDemo 範例如何處理它,即如何使用IrReceiver.restartTimer()
。
如果RAW_BUFFER_LENGTH
對於協定的所有標記和空間來說太小,則設定標誌IRDATA_FLAGS_WAS_OVERFLOW
。這可能發生在長協議幀上,例如來自空調的協議幀。如果RECORD_GAP_MICROS
小於一幀和第三個重複幀之間的實際間隙,則也可能發生這種情況,從而將兩者解釋為一個連續幀。最好的方法就是放棄時間,看看哪個理由成立。
當您使用Neopixels (又稱 WS2811/WS2812/WS2812B)或其他阻塞中斷時間較長(> 50 µs)的程式庫時,IRremote 將無法正常運作。
無論您使用 Adafruit Neopixel lib 還是 FastLED,許多低階 CPU(例如基本 Arduino)上的中斷都會停用超過 50 µs。反過來,這會在需要時停止 IR 中斷處理程序的運作。另請參閱此視頻。
一種解決方法是等待 IR 接收器空閒,然後再使用if (IrReceiver.isIdle()) { strip.show();}
發送 Neopixel 資料。
這至少可以防止中斷正在運行的紅外線傳輸,並且(取決於 Neopixel 的更新速率)可能會很好地工作。
在更強大的處理器上還有一些其他解決方案,請參閱 Marc MERLIN 的此頁面
只有當您停用IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
行時,另一個函式庫才會運作/編譯。 。
這通常是由於定時器資源與其他庫發生衝突。請看下文。
此函式庫僅支援每個 CPU 一個 IR 接收器和一個 IR 發送器物件(IRrecv 和 IRsend)。
然而,由於發送是一個串行任務,您可以使用setSendPin()
來切換要發送的引腳,從而模擬多個發送者。
接收器使用特殊的定時器觸發功能,每 50 µs 從一個引腳讀取數位紅外線訊號值。
因此,必須將多個紅外線接收器的輸出引腳連接在一起才能使用多個紅外線接收器。 IR 接收器模組內部使用 NPN 電晶體作為輸出設備,只需一個 30k 電阻連接到 VCC。這基本上是一個“集電極開路”,允許多個輸出引腳連接到一個 Arduino 輸入引腳。
但是,請記住,來自其中一個接收器的任何微弱/受干擾的訊號也會幹擾來自另一個接收器的良好訊號。
免費增加紅外線功率的最佳方法是串聯使用 2 或 3 個紅外線二極體。一個二極體在 20 mA 時需要 1.2 V 電壓,在 100 mA 時需要 1.5 V 電壓,因此您可以為最多 3 個二極體提供 5 V 輸出。
若要使用 1.2 V 和 20 mA 以及 5 V 電源為2 個二極體供電,請將電阻器設定為:(5 V - 2.4 V) -> 2.6 V / 20 mA = 130 Ω 。
對於3 個二極體,需要 1.4 V/20 mA = 70 Ω 。
由於AVR 引腳的損耗,實際電流可能會更低。例如,20 mA 時為 0.3 V。
如果不需要超過20mA的電流,則無需使用外部電晶體(至少對於AVR晶片而言)。
在我的 Arduino Nano 上,我總是使用 100 Ω 串聯電阻和一個 IR LED ?。
對於接收,最小 CPU 時脈頻率為 4 MHz ,因為 50 µs 定時器 ISR(中斷服務例程)在 16 MHz ATmega 上大約需要 12 µs。
TinyReceiver 不需要輪詢,運作頻率為 1 MHz。
對於發送,預設軟體產生的 PWM 在以 8 MHz 運行的 AVR 上存在問題。 PWM 頻率約為 30 kHz,而不是 38 kHz,RC6 不可靠。您可以透過#define SEND_PWM_BY_TIMER
切換到定時器 PWM 產生。
預設情況下,Bang & Olufsen 協定解碼器未啟用,即如果 #define DECODE_<XYZ>
未明確啟用任何協定。它必須始終透過#define DECODE_BEO
明確啟用。這是因為它的IR 傳輸頻率為 455 kHz ,因此需要不同的接收器硬體 (TSOP7000)。
由於產生 455 kHz PWM 訊號目前僅針對SEND_PWM_BY_TIMER
實現,因此僅當定義了SEND_PWM_BY_TIMER
或USE_NO_SEND_PWM
時,傳送才有效。
有關詳細信息,請參閱 ir_BangOlufsen.hpp。
這些範例位於檔案 > 範例 > 自訂庫/IRremote 中的範例。
為了讓範例適合 ATtiny85 和 ATtiny88 的 8K 快閃記憶體,此 CPU 需要 Arduino 函式庫 ATtinySerialOut。
另請參閱 DroneBot Workshop SimpleReceiver 和 SimpleSender。
SimpleReceiver和SimpleSender範例是一個很好的起點。一個簡單的例子可以用 WOKWI 在線測試。
SimpleReceiverForHashCodes僅使用雜湊解碼器。它將所有長度超過 6 的 IR 幀轉換為 32 位元雜湊碼,從而能夠接收未知協定。
請參閱:http://www.righto.com/2010/01/using-任-remotes-with-arduino.html
如果程式碼大小或計時器使用很重要,請查看這些範例。
TinyReceiver範例使用TinyIRReceiver庫,該庫只能接收 NEC、Extend NEC、ONKYO 和 FAST 協議,但不需要任何定時器。他們使用引腳更改中斷進行動態解碼,這就是為什麼協議選擇受到限制的原因。
TinyReceiver可以用WOKWI線上測試。
TinySender範例使用TinyIRSender函式庫,只能傳送 NEC、ONKYO 和 FAST 協定。
它以標準格式發送 NEC 協定代碼,具有 8 位元位址和 8 位元命令,如 SimpleSender 範例中所示。它可以選擇使用擴展 NEC、ONKYO 和 FAST 協定進行發送。與 SimpleSender 相比,節省 780 位元組程式記憶體和 26 位元組 RAM,SimpleSender 的功能相同,但使用 IRRemote 函式庫(因此更加靈活)。
如果協定不是 NEC 且程式碼大小很重要,請查看此範例。
ReceiveDemo 接收所有協議,並使用 Arduinotone() 函數在收到的每個資料包上產生蜂鳴聲。
偵測到長按一個紅外線按鈕(接收一個指令的多次重複)。
AllProtocolsOnLCD 另外在 1602 LCD 上顯示簡短結果。 LCD 可以並行或序列連接 (I2C)。
透過將偵錯引腳接地,您可以強制列印每個幀的原始值。調試引腳的引腳編號在設定期間列印,因為它取決於板和 LCD 連接類型。
此範例也作為如何一起使用 IRremote 和tone() 的範例。
接收所有協定並以不同風格(包括 Pronto 格式)轉儲接收到的訊號。由於列印需要很長時間,重複訊號可能會被跳過或解釋為未知。
至少發送一次所有可用協定。
發送時演示接收。
按下按鈕時記錄並回放最後接收到的紅外線訊號。已知協定的IR幀由適當的協定編碼器發送。 UNKNOWN
協定幀作為原始資料儲存並使用sendRaw()
發送。
嘗試使用通用DistanceWidth 解碼器解碼每個 IR 幀,儲存資料並在按下按鈕時使用sendPulseDistanceWidthFromArray()
發送資料。
如果 RAM 不超過 2k,解碼器僅接受最多 2500 微秒的標記或空間持續時間以節省 RAM 空間,否則它接受最多 10 毫秒的持續時間。
距離寬度協定儲存資料需要17個位元組。 ReceiveAndSend 範例需要 16 個位元組用於已知協定數據,37 個位元組用於egNEC 協定的原始資料。
用作紅外線遠端巨集擴展器。接收 Samsung32 協定並在接收指定的輸入幀時,它會發送多個 Samsung32 幀,並在其間有適當的延遲。這是我的舊三星 H5273 電視的Netflix 金鑰模擬。
用於為不同的 IR 程式碼呼叫程式的不同函數的框架。
用遙控器控制繼電器(連接到輸出引腳)。
使用者定義類別的範例,它本身使用 IRremote 中的 IRrecv 類別。
傳送由串列輸入控制的 LG 空調 IR 代碼的範例。
只需使用函數bool Aircondition_LG::sendCommandAndParameter(char aCommand, int aParameter)
您就可以透過任何其他命令來源控制空調。
文件acLG.h包含 LG 空調 IR 協議的命令文件。基於 LG AKB73315611 遙控器的逆向工程。
IReceiverTimingAnalysis 可以使用 WOKWI 進行線上測試。
接收和發送 AEG/Elektrolux Hob2Hood 協定的範例。
此範例分析 IR 接收器模組傳送的訊號。值可用於確定接收訊號的穩定性以及用於確定協定的提示。
它還計算MARK_EXCESS_MICROS
值,該值是 IR 接收器模組引入的標記(脈衝)持續時間的擴展。
可以用 WOKWI 線上測試。在仿真運行時按一下接收器以指定各個 NEC IR 代碼。
ReceiveDemo + SendDemo 在一個程式中。發送時演示接收。在這裡您可以看到接收器輸出(藍色)與紅外線二極體輸入(黃色)之間的延遲。
簡易接收器
透過 IR 鍵 5 進行簡單切換
小接收器
接收時序分析
帶有 LCD 輸出和開關語句的接收器
Arduino PWMMotorControl 庫的此範例使用 IRremote 庫控制機器人汽車的基本功能。
它控制2個PWM馬達通道,每個通道2個馬達。
在這裡您可以找到汽車組裝和代碼的說明。
IR_RobotCar,帶有插入擴充板的 TL1838 紅外線接收器。
在沒有先測試一些範例之前,不要提出問題!
如果您遇到問題,請發布顯示此問題的 MCVE(最小完整可驗證範例)。我的經驗是,大多數時候你會在創建這個 MCVE 時發現問題?
使用程式碼區塊;當我們可以閱讀您的程式碼時,它可以幫助我們為您提供幫助!
要根據不同的要求自訂庫,可以使用一些編譯選項/巨集。
這些巨集必須在程式中的#include <IRremote.hpp>
行之前定義才能生效。
透過啟用/停用它們來修改它們,或更改值(如果適用)。
姓名 | 預設值 | 描述 |
---|---|---|
RAW_BUFFER_LENGTH | 200 | 原始輸入 uint16_t 緩衝區的緩衝區大小。一定要均勻!如果太小,將設置溢出標誌。對於高達 48 位元的常規協議,100 就足夠了,但對於大多數空調協議,需要高達 750 的值。使用 ReceiveDump 範例尋找符合您要求的最小值。值 200 需要 200 位元組 RAM。 |
EXCLUDE_UNIVERSAL_PROTOCOLS | 殘障人士 | 從decode() 中排除脈衝距離寬度協定的通用解碼器和decodeHash(所有協定的特殊解碼器)。最多可節省 1000 位元組程式記憶體。 |
DECODE_<Protocol name> | 全部 | 選擇要解碼的單一協定。您可以指定多個協定。看這裡 |
DECODE_STRICT_CHECKS | 殘障人士 | 檢查協定時序所需的其他特性,例如常數標記協定的標記長度,其中空間長度決定位元值。需要最多 194 個位元組的程式記憶體。 |
IR_REMOTE_DISABLE_RECEIVE_COMPLETE_CALLBACK | 殘障人士 | 最多可保存 60 位元組程式記憶體和 2 位元組 RAM。 |
MARK_EXCESS_MICROS | 20 | MARK_EXCESS_MICROS 在解碼前從所有標記中減去並添加到所有空格中,以補償不同紅外線接收模組的訊號形成。 |
RECORD_GAP_MICROS | 5000 | IR 傳輸之間的最小間隙,用於偵測協定的結束。 必須大於協議的任何空間,例如 4500 µs 的 NEC 標頭空間。 必須小於命令與重複之間的任何間隙;例如,索尼的重傳間隙約為 24 毫秒。 請記住,這是接收命令結束和解碼開始之間的延遲。 |
DISTANCE_WIDTH_DECODER_DURATION_ARRAY_SIZE | 如果 RAM <= 2k,則為 50,否則為 200 | 值 200 允許解碼長達 10 ms 的標記或空間持續時間。 |
IR_INPUT_IS_ACTIVE_HIGH | 殘障人士 | 如果您使用具有高電平有效輸出訊號的 RF 接收器,請啟用它。 |
IR_SEND_PIN | 殘障人士 | 如果指定,它會減少程式大小並改善 AVR 的發送時序。如果您想要使用變數來指定傳送引腳,例如使用setSendPin(uint8_t aSendPinNumber) ,則不得在來源中使用/停用此巨集。 |
SEND_PWM_BY_TIMER | 殘障人士 | 停用軟體中的載波 PWM 產生並使用硬體 PWM(透過計時器)。具有更精確的 PWM 產生的優點,特別是佔空比
展開
相關應用
爲您推薦
相關資訊
全部
|