开发板购买连接windows
https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.50111deb2Ij1As&ft=t&id=626366733674数组
开发板简介
开发环境搭建 windows
源码示例:
0_Hello Bug (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 使用IIC总线实现读取ADXL345角度加速度传感器
11_IIC_AT24C02 使用IIC总线实现小容量数据储存测试
12_IR_Rev_RMT 使用RMT实现红外遥控接收解码(NEC编码)
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 在站模式STA下实现TCP服务端
21_WIFI_STA_TCP_Client 在站模式STA下实现TCP客户端
22_WIFI_STA_UDP 在站模式STA下实现UDP通信
23_LVGL_Test LVGL图形库简单示例app
红外简介函数
远程遥控技术又称为遥控技术,是指实现对被控目标的遥远控制,在工业控制、航空航天、家电领域应用普遍。测试
红外遥控是一种无线、非接触控制技术,具备抗干扰能力强,信息传输可靠,功耗低,成本低,易实现等显著优势,被诸多电子设备特别是家用电器普遍采用,并愈来愈多的应用到计算机和手机系统中。ui
红外线又称红外光波,在电磁波谱中,光波的波长范围为0.01um~1000um。根据波长的不一样可分为可见光和不可见光,波长为0.38um~0.76um的光波可为可见光,依次为红、橙、黄、绿、青、蓝、紫七种颜色。光波为0.01um~0.38um的光波为紫外光(线),波长为0.76um~1000um的光波为红外光(线)。红外光按波长范围分为近红外、中红外、远红外、极红外4类。红外线遥控是利用近红外光传送遥控指令的,波长为0.76um~1.5um。用近红外做为遥控光源,是由于红外发射器件(红外发光管)与红外接收器件(光敏二极管、三极管及光电池)的发光与受光峰值波长通常为0.8um~0.94um,在近红外光波段内,两者的光谱正好重合,可以很好地匹配,能够得到较高的传输效率及较高的可靠性编码
在实际的通讯领域,发出来的信号通常有较宽的频谱,并且都是在比较低的频率段分布大量的能量,因此称之为基带信号,这种信号是不适合直接在信道中传输的。为便于传输、提升抗干扰能力和有效的利用带宽,一般须要将信号调制到适合信道和噪声特性的频率范围内进行传输,这就叫作信号调制。在通讯系统的接收端要对接收到的信号进行解调,恢复出原来的基带信号。这部分通讯原理的内容,你们了解一下便可。.net
咱们平时用到的红外遥控器里的红外通讯,一般是使用38K左右的载波进行调制的,下面我把原理大概给你们介绍一下,了解一下,先看发送部分原理。设计
调制:就是用待传送信号去控制某个高频信号的幅度、相位、频率等参量变化的过程,即用一个信号去装载另外一个信号。好比咱们的红外遥控信号要发送的时候,先通过38K调制,如图3d
原始信号就是咱们要发送的一个数据“0”位或者一位数据“1”位,而所谓38K载波就是频率为38K的方波信号,调制后信号就是最终咱们发射出去的波形。咱们使用原始信号来控制38K载波,当信号是数据“0”的时候,38K载波毫无保留的所有发送出去,当信号是数据“1”的时候,不发送任何载波信号。如上图中的调制后信号波形。
下图为波形中NEC编码中的波形时序
完整的一段NEC编码波形
红外接收头有不少型号,开发板所用的红外线接收器为KMS183,一体化红外接收头能够将载波红外信号解码为高低电平信号,方便单片机解析红外命令,以下图:
RMT简介
RMT(Remote Control)模块驱动程序可用于发送和接收红外遥控信号。 因为RMT模块的灵活性,该驱动程序还可用于生成或接收许多其余类型的信号。
信号由一系列脉冲组成,由RMT的发射器根据值列表生成。 这些值定义了脉冲持续时间和二进制电平,请参见下文。 发射器还能够提供载波,并使用提供的脉冲对其进行调制。
发送调制图示:
在接收器中,一系列脉冲被解码为包含脉冲持续时间和二进制电平的值列表。 能够应用滤波器以从输入信号中去除高频噪声。
接收调制图示:
查看开发板原理图,KMS183一体化红外接收头信号引脚链接在主控的GPIO35引脚上,红外发射脚接到主控的GPIO7引脚上,根据上文RMT和红外的介绍了解就能够进行代码的编写了。
先引用必要头文件
// 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; }
打开ESP-IDF Command Prompt
cd命令进入此工程目录
cd F:\ESP32_DevBoard_File\12_IR_Rev_RMT
查看电脑设备管理器中开发板的串口号
执行idf.py -p COM9 flash monitor从串口9下载并运行打开口显示设备调试信息 Ctrl+c退出运行,能够用家里的遥控器对着开发板上的红外接收头按几个按钮,观察串口打印。