ESP32開発ノート(3)ソースコードの例12_IR_Rev_RMT RMTを使用して赤外線リモコンの受信とデコード(NECエンコード)を実現する

開発ボード購入リンク

https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.50111deb2Ij1As&ft=t&id=626366733674


Windows
ソースコード例をビルドするための開発ボード開発環境の概要
    0_Helloバグ(ESP_LOGXおよびprintf)     プロジェクトテンプレート/印刷デバッグ出力
    1_LED                                                     LEDオンおよびオフ制御       
    2_LED_Task                                           使用タスクモードLEDを制御
    3_LEDC_PWM LEDCを                                       使用してLEDを制御して呼吸光効果を達成
    4_ADC_LightR                                       ADCを使用して感光性を読み取る光感知を実現するための抵抗
    5_KEY_Short_Long                               ボタンの長押しと短押しによる
    6_TouchPad_Interrupt                           静電容量式タッチ割り込みによる
    7_WS2812_RMT                                   RGB_LED虹色の変更の例
    8_DHT11_RMTによる                                     RMTの使用によるDHT11温度および湿度センサーの読み取り
    9_SPI_SDCard                                     SPIバスTFカードファイルシステムを使用して、例示的な実施
    10_IIC_ADXL345を                                 角度ADXL345加速度を読み取るためのIICバスを使用してセンサー
    11_IIC_AT24C02は                                  小容量データストレージを実現するためにIICバス・テストを使用
    (NEC符号化)12_IR_Rev_RMT RMTは、赤外線リモコン受信機のデコーダを使用して実装
    13_IR_Send_RMT赤外線データ伝送RMTを使用して実装しました(NEC)
    14_WIFI_Scan近くのWIFI信号スキャンの例
    15_WIFI_APソフトAP 作成例    
    16_WIFI_AP_TCP_Server
    ソフトAPモードでのTCPサーバーの実装17_WIFI_AP_TCP_Client ソフトAPモードでのTCPクライアントの実装
    18_WIFI_AP_UDPソフトAPモードでのUDP通信の実装
    19_WIFI_STA STAステーションモデルの作成
    20_WIFI_STA_TCP_Server
    ステーションモードでのTCPサーバーの実装STA
    21_WIFI_STA_TCP_Client ステーションモードでのTCPクライアントの実装STA 22_WIFI_STA_UDPステーションモードでのUDP通信の実装STA
    23_LVGL_Test LVGLグラフィックライブラリの簡単な例

赤外線入門

遠隔制御技術は遠隔制御技術とも呼ばれ、制御対象の遠隔制御の実現を指し、産業制御、航空宇宙、および家電製品の分野で広く使用されています。

赤外線リモートコントロールは、ワイヤレスの非接触制御技術です。強力な干渉防止機能、信頼性の高い情報伝送、低消費電力、低コスト、簡単な実現などの大きな利点があります。多くの電子機器、特に家電製品で広く使用されており、ますます人気が高まっています。コンピュータや携帯電話システムで広く使用されています。

        赤外線は赤外光波とも呼ばれ、電磁スペクトルでは、光波の波長範囲は0.01um〜1000umです。波長によって可視光と不可視光に分けられ、波長0.38um〜0.76umの光波が可視光となり、赤・オレンジ・黄・緑・青・青・紫の7色になります。0.01um〜0.38umの光波の光波は紫外光(線)であり、0.76um〜1000umの波長の光波は赤外光(線)です。赤外光は波長域により近赤外、中赤外、遠赤外、極赤外の4種類に分類されます。赤外線リモコンは、近赤外線を使用して、0.76um〜1.5umの波長のリモコンコマンドを送信します。赤外線発光デバイス(赤外線発光管)および赤外線受信デバイス(フォトダイオード、トライオード、フォトセル)のピーク波長は一般に0.8um〜0.94umであるため、リモートコントロール光源として近赤外線が使用されます。近赤外線帯域では、 2つのスペクトルは正確に一致し、よく一致し、より高い伝送効率と信頼性を得ることができます

実際の通信分野では、送信される信号は一般に周波数スペクトルが広く、比較的低い周波数範囲にエネルギーが多く分布するため、ベースバンド信号と呼ばれ、チャネルでの直接送信には適していません。 。伝送を容易にし、干渉防止能力を改善し、帯域幅を効果的に利用するには、通常、信号を、信号変調と呼ばれる、チャネルと伝送のノイズ特性に適した周波数範囲に変調する必要があります。通信システムの受信側では、受信した信号を復調して元のベースバンド信号を復元する必要があります。コミュニケーションの原則のこの部分の内容を理解できます。

  通常使用している赤外線リモコンの赤外線通信は、通常38K程度のキャリアで変調されていますので、以下にその原理をご紹介しますので、送信部の原理を見てみましょう。

  変調:送信される信号を使用して高周波信号の振幅、位相、周波数、およびその他のパラメータを制御するプロセス。つまり、ある信号を使用して別の信号をロードするプロセス。たとえば、赤外線リモコン信号を送信する場合、図に示すように、まず38Kで変調されます。

元の信号は送信したいデータ「0」ビットまたはデータ「1」ビットであり、いわゆる38Kキャリアは周波数38Kの方形波信号であり、変調信​​号は送信する最終波形です。38Kキャリアの制御はオリジナルの信号を使用しており、データが「0」の場合は38Kキャリアを予約なしで送出し、データが「1」の場合はキャリア信号を送出しません。上図に示す変調後の信号波形。

次の図は、波形のNECコードの波形タイミングを示しています

NECコード化波形の完全なセグメント

赤外線レシーバーには多くの種類があります。開発ボードで使用される赤外線レシーバーはKMS183です。統合された赤外線レシーバーは、キャリア赤外線信号を高レベル信号と低レベル信号にデコードできます。これは、MCUが赤外線コマンドを解析するのに便利です(下図を参照)。

RMTの概要

RMT(リモートコントロール)モジュールドライバーを使用して、赤外線リモートコントロール信号を送受信できます。RMTモジュールの柔軟性により、ドライバーは他の多くのタイプの信号の生成または受信にも使用できます。

信号は一連のパルスで構成されており、RMTトランスミッターによって値のリストに基づいて生成されます。これらの値は、パルス幅とバイナリレベルを定義します。以下を参照してください。送信機は、搬送波を提供し、提供されたパルスで変調することもできます。

変調図を送信:

受信機では、一連のパルスがパルス持続時間とバイナリレベルを含む値のリストにデコードされます。フィルターを適用して、入力信号から高周波ノイズを除去できます。

受信変調図:

1.ハードウェア設計/原理

開発ボードの回路図を確認します。KMS183統合赤外線レシーバーの信号ピンがメインコントロールのGPIO35ピンに接続され、赤外線放射ピンがメインコントロールのGPIO7ピンに接続されています。上記のRMTと赤外線の紹介に従って続行できます。コードが書かれています。

2.プログラムの設計

最初に必要なヘッダーファイルを引用します

// IR_Rre Example

#include <stdio.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "IR_Rev.h"
#include <esp_log.h>
#include "driver/rmt.h"

デフォルトでは、開発ボードはNEC赤外線エンコードをデコードします。これは最も一般的な赤外線エンコードでもあります。テレビやセットトップボックスなどの他の小型アプライアンスのリモートコントロールでテストできます。エンコードを変更する必要がある場合は、コードのエンコードタイミングを変更するだけで済みます。ワンクリック

NEC赤外線デコードタイミング

#define NEC_BITS          32
#define NEC_HDR_MARK    9000
#define NEC_HDR_SPACE   4500
#define NEC_BIT_MARK     560
#define NEC_ONE_SPACE   1690
#define NEC_ZERO_SPACE   560
#define NEC_RPT_SPACE   2250

ピン定義と主な機能

const static char *TAG = "IR_Rre Demo";


#define RECV_PIN		35	// 一体化红外接收头GPIO
uint8_t command = 0;		// 接收到的ENC红外指令
void app_main()
{
	ESP_LOGI(TAG, "APP Start......");

	IRrecvInit(RECV_PIN, 3);
	while(1){
		command = IRrecvReadIR();
		if (command != 0){
			printf("IR Command is 0x%02X\n", command);
		}
	}
}

赤外線デコードRMT初期化

void IRrecvInit(uint8_t pin, uint8_t port)
{
	IRrecv_Pin = pin;
	IRrecv_Chanel = port;
	rmt_config_t config;
	config.rmt_mode = RMT_MODE_RX;
	config.clk_div = CLK_DIV;
	config.channel = (rmt_channel_t)IRrecv_Chanel;
	config.gpio_num = (gpio_num_t)IRrecv_Pin;
	config.mem_block_num = 2;
	config.rx_config.filter_en = 1;
	config.rx_config.filter_ticks_thresh = 100;
	config.rx_config.idle_threshold = TICK_10_US * 100 * 20;
	ESP_ERROR_CHECK(rmt_config(&config));
	ESP_ERROR_CHECK(rmt_driver_install(config.channel, 5000, 0));
	rmt_get_ringbuf_handle(config.channel, &ringBuf);
	rmt_rx_start(config.channel, 1);
}

赤外線コードを受け取る

uint8_t IRrecvReadIR(void)
{
	size_t itemSize;
	uint8_t command = 0;
	rmt_item32_t* item = (rmt_item32_t*) xRingbufferReceive((RingbufHandle_t)ringBuf, (size_t *)&itemSize, (TickType_t)portMAX_DELAY);
	int numItems = itemSize / sizeof(rmt_item32_t);
	int i;
	rmt_item32_t *p = item;
	for (i=0; i<numItems; i++) {
		p++;
	}
	command = IRrecvDecode(item, numItems);
	vRingbufferReturnItem(ringBuf, (void*) item);
	return command;
}

受信したレベル配列を赤外線エンコード機能にデコードします


uint8_t IRrecvDecode(rmt_item32_t *data, int numItems)
{
	printf("IRrecvDecode->Levels Count:%d   Start Decode.....\n", numItems*2);
	// 检查协议头,9ms/4.5ms,检查误差300us
	if(!IRrecvIsInRange(data[0], NEC_HDR_MARK, NEC_HDR_SPACE, 300)){
		uint32_t lowValue = data[0].duration0 * 10 / TICK_10_US;
		uint32_t highValue = data[0].duration1 * 10 / TICK_10_US;
		printf("IRrecvIsInRange->Error   lowValue %d	highValue %d\n", lowValue,highValue);
		return 0;
	}
	int i;
	uint8_t address = 0, notAddress = 0, command = 0, notCommand = 0;
	int accumCounter = 0;
	uint8_t accumValue = 0;
	for(i=1; i<numItems; i++){// 第1组为协议头,从第2组开始
		if(IRrecvIS0(data[i])){// 检查是否为0
			accumValue = accumValue >> 1;
		}else if(IRrecvIS1(data[i])){// 检查是否为1
			accumValue = (accumValue >> 1) | 0x80;
		}
		if(accumCounter == 7){// 检查了8Bit
			accumCounter = 0;
			if(i==8){
				address = accumValue;		// 第1字节为地址
			}else if (i==16){
				notAddress = accumValue;	// 第2字节为地址取反
			}else if (i==24){
				command = accumValue;		// 第3字节是命令
			}else if (i==32){
				notCommand = accumValue;	// 第4字节是命令取反
			}
			accumValue = 0;
		}else{
			accumCounter++;
		}
	}
	// 检查取反数据是否正确
	if(address != (notAddress ^ 0xff)){
		printf("IRrecvDecode->Address Overturn Check Error   address %02X	notAddress %02X\n", address,notAddress);
		return 0;
	}
	if(command != (notCommand ^ 0xff)){
		printf("IRrecvDecode->Command Overturn Check Error   command %02X	notCommand %02X\n", command,notCommand);
		return 0;
	}
	return command;
}

受信タイミングに偏りがあるので判断

//高低电平结构体,低电平检测时长,高电平检测时长,公差
bool IRrecvIsInRange(rmt_item32_t item, int lowDuration, int highDuration, int tolerance)
{
	uint32_t lowValue = item.duration0 * 10 / TICK_10_US;
	uint32_t highValue = item.duration1 * 10 / TICK_10_US;
	if(lowValue<(lowDuration-tolerance)||lowValue>(lowDuration+tolerance)||(highValue!=0&&(highValue<(highDuration-tolerance)||highValue>(highDuration+tolerance))))
	{
		return false;
	}
	return true;
}

3、ダウンロードテスト

ESP-IDFコマンドプロンプトを開く

このプロジェクトディレクトリに入るcdコマンド

cd F:\ESP32_DevBoard_File\12_IR_Rev_RMT

コンピューターのデバイスマネージャーで開発ボードのシリアルポート番号を表示する

idf.py -p COM9フラッシュモニターを実行して、シリアルポート9からダウンロードして実行します。ポートを開き、デバイスのデバッグ情報を表示します。Ctrl+ cを押して操作を終了します。ホームリモコンを使用して、開発ボードの赤外線レシーバーに対していくつかのボタンを押し、シリアルポートの印刷を観察できます。 。

おすすめ

転載: blog.csdn.net/cnicfhnui/article/details/108508379