2018年11月21日 星期三

DIY - ESP32:ESP32 紅外線接收器發射器程式(三十四)

DIY - ESP32:ESP32 紅外線接收器發射器程式(三十四):

ESP32 的 IDF 內已經有紅外線收發器(Infrared Transceiver)範例程式,可以直接使用,RMT (Remote Control)模塊有8個通道,編號為 0 到 7,每個通道都有寄存器、存儲器塊和數據發送器之類的組件,應用是很簡單。

ESP32 紅外線接收器發射器製作
RMT 模塊可以通過 2 種方法進行測試:

自我測試:
將 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%
天氣:微雨

沒有留言:

張貼留言