ESP32 的 IDF 內已經有紅外線收發器(Infrared Transceiver)範例程式,可以直接使用,RMT (Remote Control)模塊有8個通道,編號為 0 到 7,每個通道都有寄存器、存儲器塊和數據發送器之類的組件,應用是很簡單。
ESP32 紅外線接收器發射器製作 |
自我測試:
將 GPIO TX 引腳連接到 GPIO RX 引腳以進行信號傳輸。
tx_task 任務在沒有載波禁用的情況下發送 NEC 數據。
通過紅外 LED 測試:
我們需要使用載波啟用發射器來廣播紅外線。
當使用紅外 LED 測試時,接收器通常處於低電平有效狀態。
基本實施步驟:
創建包含以下基本組件的數據包(NEC項):
標題部分是一個脈衝前導碼,持續 9ms,後面是 4.5ms 的間隔,總傳輸時間是 13.5ms。
數據部分是 4個字節(32位),後面是首先傳遞最低加權位的標題。 其中,從低到高轉的字節為:字節 1 是字節地址,字節 2 是反轉字節 1,字節 3 是主命令部分,字節 4 由字節 3 反轉。 結束是一個持續 0.56ms 的脈衝。
注意 :
在數據部分:
位 1 由持續約 0.56ms 的脈衝表示,之後是 1.69ms 間隔,總傳輸時間為 2.25ms。
位 0 由 0.56ms 的脈衝長度表示,之後是 0.56ms 的延遲,總傳輸時間為 1.12ms。
使用 struct rmt_config_t 參數初始化 RMT TX 和 RX 模塊 。
繼續發送數據包並將消息顯示在屏幕。
接收數據包,分析數據並打印到屏幕,然後釋放緩衝區。
ESP32 紅外線接收器發射器程式 IO 設定:
// 紅外線接收器發射器設定
#define RMT_TX_CHANNEL 1 /*!< RMT channel for transmitter */
#define RMT_TX_GPIO_NUM 18
/*!< GPIO number for transmitter signal */
#define RMT_RX_CHANNEL 0 /*!< RMT channel for receiver */
#define RMT_RX_GPIO_NUM 17
/*!< GPIO number for receiver */
#define RMT_CLK_DIV 100
/*!< RMT counter clock divider */
|
ESP32 紅外線發射器程式:
static void rmt_example_nec_tx_task()
{
vTaskDelay(10);
nec_tx_init();
esp_log_level_set(NEC_TAG, ESP_LOG_INFO);
int
channel = RMT_TX_CHANNEL;
uint16_t cmd = 0x0;
uint16_t addr = 0x11;
int
nec_tx_num = RMT_TX_DATA_NUM;
for(;;)
{
ESP_LOGI(NEC_TAG, "RMT TX DATA");
size_t size = (sizeof(rmt_item32_t) * NEC_DATA_ITEM_NUM * nec_tx_num);
//each item represent a cycle of waveform.
rmt_item32_t* item = (rmt_item32_t*) malloc(size);
int
item_num = NEC_DATA_ITEM_NUM * nec_tx_num;
memset((void*) item, 0, size);
int
i, offset = 0;
while(1) {
//To build a series of waveforms.
i = nec_build_items(channel, item + offset, item_num - offset,
((~addr) << 8) | addr, cmd);
if(i < 0) {
break;
}
cmd++;
addr++;
offset += i;
}
//To send data according to the waveform items.
rmt_write_items(channel, item, item_num, true);
//Wait until sending is done.
rmt_wait_tx_done(channel, portMAX_DELAY);
//before we free the data, make sure sending is already done.
free(item);
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
vTaskDelete(NULL);
}
|
ESP32 紅外線接收器程式:
static void rmt_example_nec_rx_task()
{
int channel = RMT_RX_CHANNEL;
nec_rx_init();
RingbufHandle_t rb = NULL;
rmt_get_ringbuf_handle(channel, &rb);
rmt_rx_start(channel, 1);
while(rb) {
size_t rx_size = 0;
//try to receive data from ringbuffer.
//RMT driver will push all the data it receives to its ringbuffer.
//We just need to parse the value and return the spaces of ringbuffer.
rmt_item32_t* item = (rmt_item32_t*) xRingbufferReceive(rb,
&rx_size, 1000);
if(item) {
uint16_t rmt_addr;
uint16_t rmt_cmd;
int offset = 0;
while(1) {
//parse data value from ringbuffer.
int res = nec_parse_items(item + offset, rx_size / 4 - offset,
&rmt_addr, &rmt_cmd);
ESP_LOGI(NEC_TAG, "RX Ret=%d", res);
if(res > 0) {
offset += res + 1;
ESP_LOGI(NEC_TAG,
"RMT RCV --- addr: 0x%04x cmd: 0x%04x", rmt_addr, rmt_cmd);
sprintf(dsp_buffer, "addr: 0x%04x",rmt_addr);
ili9341_hspi_String(dsp_buffer,
0, 90, 4, ILI9341_BLUE, ILI9341_GREEN);
sprintf(dsp_buffer, "cmd:
0x%04x", rmt_cmd);
ili9341_hspi_String(dsp_buffer,
0,120, 4, ILI9341_BLUE, ILI9341_GREEN);
} else {
break;
}
}
//after parsing the data, return spaces to ringbuffer.
vRingbufferReturnItem(rb, (void*) item);
}
else {
break;
}
}
|
操作系統:Windows 7 64-bit 版本
開發環境:AiThinker05 版本
原程碼: ESP32 ESP-IDF V3.0rc1
程式: DIY-ESP32-022-IR_01_IDF_TXRX-20181104
ESP32 紅外線接收器發射器程式運行中 |
ESP32 紅外線接收器發射器程式接收顯示 |
ESP32 紅外線接收器發射器程式串口輸出 |
※ DIY - ESP32:ESP32 紅外線接收器發射器電路(三十三)
※ DIY - ESP32:ESP32 RMT API 函數介紹(三十五)
※ DIY - ESP32:ESP32 RMT API 函數(三十六)
※ DIY - ESP32:ESP32 RMT API 函數結構件及其它(三十七)
2018年 11月 21日 天氣報告
氣溫:23.8度 @ 21:20
相對濕度:百分之 74%
天氣:微雨
沒有留言:
張貼留言