pdf-icon

Arduino Quick Start

2. Devices & Examples

6. Applications

StickS3 IR Infrared Transmit & Receive

StickS3 IR infrared transmit & receive related APIs and example programs.

Example

Compilation Requirements

  • M5Stack Board Manager version >= 3.2.5
  • Development board option = M5StickS3
  • M5Unified library version >= 0.2.12
  • M5GFX library version >= 0.2.18

Transmitter

cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
#include "M5Unified.h"
#include "driver/rmt_tx.h"
#include "driver/rmt_encoder.h"

#define IR_SEND_PIN    46      // GPIO pin connected to IR LED transmitter

// NEC protocol parameters
uint16_t address = 0x0000;     // NEC address (8-bit or 16-bit)
uint8_t  command = 0x55;       // NEC command byte
uint8_t  repeats = 0;          // Number of repeat frames (0 = no repeat)

rmt_channel_handle_t tx_chan = NULL;
rmt_encoder_handle_t copy_encoder = NULL;

// NEC protocol timing constants (microseconds)
#define NEC_HEADER_MARK     9000
#define NEC_HEADER_SPACE    4500
#define NEC_BIT_MARK        560
#define NEC_BIT_0_SPACE     560
#define NEC_BIT_1_SPACE     1690
#define NEC_REPEAT_MARK     9000
#define NEC_REPEAT_SPACE    2250

// IR carrier configuration
#define IR_CARRIER_FREQ_HZ  38000
#define IR_DUTY_CYCLE       0.33

// Function prototypes
void setup_rmt_tx();
bool sendNEC(uint16_t address, uint8_t command, uint8_t repeats);
void encodeNEC(uint32_t raw_data, rmt_symbol_word_t *symbols, size_t *symbol_count);
uint32_t NECRaw(uint16_t address, uint8_t command);

void setup() {
    M5.begin();
    Serial.begin(115200);

    // Display initialization
    M5.Display.setRotation(3);
    M5.Display.setTextFont(&fonts::FreeMonoBold9pt7b);
    M5.Display.clear();
    M5.Display.setCursor(0, 0);
    M5.Display.printf("StickS3 IR example");

    Serial.println("StickS3 IR example");

    // Initialize RMT TX channel
    setup_rmt_tx();

    Serial.printf("IR Send Pin: %d\n", IR_SEND_PIN);

    // Enable external power output for IR LED module
    M5.Power.setExtOutput(true, m5::ext_none);
    delay(100);
}

void loop() {
    // Build 32-bit NEC frame data
    uint32_t raw = NECRaw(address, command);

    Serial.printf("Send NEC: addr=0x%04X, cmd=0x%02X, raw=0x%08X\n", address, command, raw);

    // -------- Send NEC frame --------
    sendNEC(address, command, repeats);

    M5.Display.fillRect(0, 30, 240, 105, TFT_BLACK);
    M5.Display.setCursor(0, 30);
    M5.Display.printf("Send NEC:\n");
    M5.Display.printf(" addr=0x%04X\n", address);
    M5.Display.printf(" cmd =0x%02X\n", command);
    M5.Display.printf(" raw =0x%08X\n", raw);

    address += 0x0001;
    command += 0x01;
    repeats = 0;

    delay(2000);
}

// Initialize RMT TX channel
void setup_rmt_tx() {
    // Configure RMT TX channel
    rmt_tx_channel_config_t tx_chan_config = {
        .gpio_num = (gpio_num_t)IR_SEND_PIN,
        .clk_src = RMT_CLK_SRC_DEFAULT,
        .resolution_hz = 1000000, // 1 us per tick
        .mem_block_symbols = 64,
        .trans_queue_depth = 4,
        .flags = {
            .invert_out = false,
            .with_dma = false,
        }
    };
    ESP_ERROR_CHECK(rmt_new_tx_channel(&tx_chan_config, &tx_chan));

    // Configure 38kHz carrier wave for IR transmission
    rmt_carrier_config_t carrier_cfg = {
        .frequency_hz = IR_CARRIER_FREQ_HZ,
        .duty_cycle = IR_DUTY_CYCLE,
        .flags = {
            .polarity_active_low = false,
        }
    };
    ESP_ERROR_CHECK(rmt_apply_carrier(tx_chan, &carrier_cfg));

    // Create copy encoder for pre-encoded symbols
    rmt_copy_encoder_config_t encoder_config = {};
    ESP_ERROR_CHECK(rmt_new_copy_encoder(&encoder_config, &copy_encoder));

    // Enable TX channel
    ESP_ERROR_CHECK(rmt_enable(tx_chan));
}

/*
 * Send NEC IR frame via RMT.
 *
 * @param address NEC address (8-bit or 16-bit)
 * @param command NEC command byte
 * @param repeats Number of repeat frames to send
 *
 * @return true if transmission successful
 */
bool sendNEC(uint16_t address, uint8_t command, uint8_t repeats) {
    // Build 32-bit NEC raw data
    uint32_t raw = NECRaw(address, command);

    // Buffer for RMT symbols
    rmt_symbol_word_t symbols[68]; // Header + 32 bits + ending mark
    size_t symbol_count = 0;

    encodeNEC(raw, symbols, &symbol_count);

    // RMT transmit configuration
    rmt_transmit_config_t tx_config = {
        .loop_count = 0,
        .flags = {
            .eot_level = 0,
        }
    };

    // Transmit the frame
    esp_err_t ret = rmt_transmit(tx_chan, copy_encoder, symbols,
                                  symbol_count * sizeof(rmt_symbol_word_t),
                                  &tx_config);

    if (ret == ESP_OK) {
        // Wait for transmission completion
        ret = rmt_tx_wait_all_done(tx_chan, 1000);
    }

    // Send repeat frames if requested
    for (int i = 0; i < repeats; i++) {
        delay(108); // NEC repeat frame interval

        // TODO: Implement repeat frame
        // Repeat frame: 9ms mark + 2.25ms space + 560us mark
    }

    return (ret == ESP_OK);
}

/*
 * Encode NEC protocol data into RMT symbols.
 *
 * @param raw_data     32-bit NEC frame data
 * @param symbols      Output buffer for RMT symbols
 * @param symbol_count Number of symbols generated
 */
void encodeNEC(uint32_t raw_data, rmt_symbol_word_t *symbols, size_t *symbol_count) {
    size_t idx = 0;

    // NEC header: ~9 ms mark + ~4.5 ms space
    symbols[idx].duration0 = NEC_HEADER_MARK;
    symbols[idx].level0 = 1;
    symbols[idx].duration1 = NEC_HEADER_SPACE;
    symbols[idx].level1 = 0;
    idx++;

    // Encode 32 data bits (LSB first)
    for (int i = 0; i < 32; i++) {
        // Mark duration: always 560 us
        symbols[idx].duration0 = NEC_BIT_MARK;
        symbols[idx].level0 = 1;

        // Space duration distinguishes logic 0 and logic 1
        if (raw_data & (1UL << i)) {
            symbols[idx].duration1 = NEC_BIT_1_SPACE; // Logic 1: 1690 us
        } else {
            symbols[idx].duration1 = NEC_BIT_0_SPACE; // Logic 0: 560 us
        }
        symbols[idx].level1 = 0;
        idx++;
    }

    // Ending mark: 560 us
    symbols[idx].duration0 = NEC_BIT_MARK;
    symbols[idx].level0 = 1;
    symbols[idx].duration1 = 0;
    symbols[idx].level1 = 0;
    idx++;

    *symbol_count = idx;
}

/*
 * Build 32-bit NEC raw data from address and command.
 *
 * NEC frame format (LSB first):
 *   bit  0-15 : Address field (8-bit + inverse, or full 16-bit)
 *   bit 16-23 : Command byte
 *   bit 24-31 : Inverse of command byte
 *
 * @param address NEC address (8-bit with auto-inverse, or 16-bit extended)
 * @param command NEC command byte
 *
 * @return 32-bit NEC raw data ready for encoding
 */
uint32_t NECRaw(uint16_t address, uint8_t command) {
    uint16_t nec_addr;

    // Standard NEC: 8-bit address + inverse byte
    if (address <= 0x00FF) {
        uint8_t addr8 = address & 0xFF;
        nec_addr = ((uint16_t)(~addr8) << 8) | addr8;
    }
    // Extended NEC: full 16-bit address
    else {
        nec_addr = address;
    }

    // Assemble 32-bit NEC frame
    uint32_t raw = 0;
    raw |= (uint32_t)nec_addr;            // Address field
    raw |= (uint32_t)command << 16;       // Command byte
    raw |= (uint32_t)(~command) << 24;    // Inverted command byte

    return raw;
}

Receiver

Note
1. The infrared receiving and decoding of StickS3 must use the ESP32 RMT peripheral and does not support receiving and decoding via GPIO method.
2. When using the StickS3 IR receiving function, you need to disable the speaker amplifier (i.e., M5.Speaker.end(); in the code below or use the related APIs of M5PM1 SPK APM section), otherwise it will not receive correctly.
3. During the infrared transmission and reception process, the transmitter is required to face the receiver as much as possible, and the distance requirement is greater than 30cm, too close may cause reception abnormalities.
cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
#include "M5Unified.h"
#include "driver/rmt_rx.h"

#define IR_RECEIVE_PIN 42

rmt_channel_handle_t rx_chan = NULL;
static rmt_symbol_word_t rx_raw_symbols[64]; // Buffer for received RMT symbols
static volatile bool rx_done = false;
static size_t rx_symbol_num = 0; // Number of symbols received in last RX transaction

// Function prototypes
bool rmt_rx_done_callback(rmt_channel_handle_t channel, const rmt_rx_done_event_data_t *edata, void *user_data);
void setup_rmt_rx();
void start_rmt_receive();
bool decodeNEC(rmt_symbol_word_t *rx_raw_symbols, uint32_t *out_raw, bool *out_repeat);

void setup() {
    M5.begin();
    M5.Speaker.end();// Disable speaker amp to avoid IR RX interference
    Serial.begin(115200);

    // Display initialization
    M5.Display.setRotation(3);
    M5.Display.setFont(&fonts::FreeMonoBold9pt7b);
    M5.Display.clear();
    M5.Display.println("StickS3 IR example");
    M5.Display.setCursor(0, 30);
    M5.Display.println("Waiting for NEC...");

    setup_rmt_rx();      // Initialize RMT RX channel and register RX Done callback
    start_rmt_receive(); // Start first RMT receive operation

    // Enable external power output for IR receiver module
    M5.Power.setExtOutput(true, m5::ext_none);
}

void loop() {
    M5.update();
    
    // Check if a complete IR frame has been received
    if (rx_done) {
        rx_done = false;

        uint32_t rx_data = 0;
        bool repeat_frame = false;

        bool valid = decodeNEC(rx_raw_symbols, &rx_data, &repeat_frame);

        if (repeat_frame) {
            Serial.println("NEC Repeat Frame");
            M5.Display.fillRect(0, 30, 240, 105, TFT_BLACK);
            M5.Display.setCursor(0, 30);
            M5.Display.setTextColor(YELLOW);
            M5.Display.println("NEC Repeat");
        }
        else if (valid) {
            uint16_t rx_addr = rx_data & 0xFFFF;
            uint8_t  rx_cmd  = (rx_data >> 16) & 0xFF;
            Serial.printf(
                "Received NEC: Addr: 0x%04X, Cmd: 0x%02X, Raw: 0x%08X\n",
                rx_addr, rx_cmd, rx_data
            );

            M5.Display.fillRect(0, 30, 240, 105, TFT_BLACK);
            M5.Display.setCursor(0, 30);
            M5.Display.setTextColor(GREEN);
            M5.Display.printf("Received NEC:\n");
            M5.Display.printf("Addr: 0x%04X\n", rx_addr);
            M5.Display.printf("Cmd:  0x%02X\n", rx_cmd);
            M5.Display.printf("Raw:  0x%08X\n", rx_data);
        }
        else {
            Serial.println("Signal received, but not a valid NEC frame.");
        }
        // Re-arm RMT RX to receive the next IR frame
        start_rmt_receive();
    }

    delay(10);
    M5.Display.setTextColor(WHITE);
}

/*
 * RMT RX Done callback.
 *
 * Called in ISR context when a complete RX transaction finishes.
 *
 * @param channel   RMT channel handle
 * @param edata     RX event data containing symbol buffer and count
 * @param user_data User context pointer (unused)
 *
 * @return true to request deferred processing after ISR
 */
bool rmt_rx_done_callback( rmt_channel_handle_t channel, const rmt_rx_done_event_data_t *edata, void *user_data) {
    rx_symbol_num = edata->num_symbols;
    rx_done = true;
    return true; // Return true to allow post-ISR task scheduling
}

// Initialize RMT RX channel
void setup_rmt_rx() {
    rmt_rx_channel_config_t rx_chan_config = {
        .gpio_num = (gpio_num_t)IR_RECEIVE_PIN,
        .clk_src = RMT_CLK_SRC_DEFAULT,
        .resolution_hz = 1000000, // 1 us per tick
        .mem_block_symbols = 128,
    };
    ESP_ERROR_CHECK(rmt_new_rx_channel(&rx_chan_config, &rx_chan));
    rmt_rx_event_callbacks_t cbs = {
        .on_recv_done = rmt_rx_done_callback,
    };
    ESP_ERROR_CHECK(rmt_rx_register_event_callbacks(rx_chan, &cbs, NULL));
    ESP_ERROR_CHECK(rmt_enable(rx_chan));
}

// Start an RMT receive operation
void start_rmt_receive() {
    rmt_receive_config_t receive_config = {
        .signal_range_min_ns = 1000,
        .signal_range_max_ns = 20000000
    };

    ESP_ERROR_CHECK(rmt_receive(rx_chan, rx_raw_symbols, sizeof(rx_raw_symbols), &receive_config));
}

/*
 * Decode a NEC IR frame from RMT symbols.
 *
 * @param rx_raw_symbols Pointer to RMT RX symbol buffer
 * @param out_raw        Decoded 32-bit NEC raw data (LSB first)
 * @param out_repeat     Set to true if a NEC repeat frame is detected
 *
 * @return true if a valid NEC data frame is decoded
 */
bool decodeNEC(rmt_symbol_word_t *rx_raw_symbols, uint32_t *out_raw, bool *out_repeat) {

    *out_raw = 0;
    *out_repeat = false;

    uint32_t header_low  = rx_raw_symbols[0].duration0;
    uint32_t header_high = rx_raw_symbols[0].duration1;

    // Standard NEC header: ~9 ms LOW + ~4.5 ms HIGH
    if (header_low > 8000 && header_high > 4000) {
        // Valid NEC header, continue decoding
    }
    // NEC repeat frame: ~9 ms LOW + ~2.25 ms HIGH
    else if (header_low > 8000 &&
             header_high > 2000 &&
             header_high < 3000) {
        *out_repeat = true;
        return false;
    }
    else {
        return false;
    }

    // Decode 32 NEC data bits (LSB first)
    for (int i = 0; i < 32; i++) {
        uint32_t mark  = rx_raw_symbols[i + 1].duration0;
        uint32_t space = rx_raw_symbols[i + 1].duration1;

        // NEC mark duration should be ~560 us
        if (mark < 300 || mark > 800) {
            return false;
        }

        // Space duration distinguishes logic 0 and logic 1
        if (space > 1000) {
            *out_raw |= (1UL << i);
        }
    }

    // Verify command byte and its inverse
    uint8_t cmd     = (*out_raw >> 16) & 0xFF;
    uint8_t cmd_inv = (*out_raw >> 24) & 0xFF;

    if ((cmd ^ cmd_inv) != 0xFF) {
        return false;
    }

    return true;
}

The transmitter and receiver run on separate StickS3 devices. The transmitter sends an NEC infrared signal every two seconds. After receiving the signal, the receiver displays the address and command on both the serial port and the screen.

Note
1. The reflective surface on the right side is not shown in the image below. In practical use, it is recommended to use a reflective surface to reflect the infrared signal from the transmitter to the receiver for optimal reception.
2. When the user code (Address) does not exceed 0x00FF, the transmitter sends the infrared signal in the NEC standard format. In this case, the address field is composed of 8-bit user code and its inverse. The address parsed by the receiver is not exactly the same as the transmitter. Conversely, when the user code exceeds 0x00FF, the transmitter sends the infrared signal in the NEC extended format. In this case, the address field is the complete 16-bit user code, and the address parsed by the receiver is consistent with the transmitter.

IR receive & echo-back

cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
#include "M5Unified.h"
#include "driver/rmt_rx.h"
#include "driver/rmt_tx.h"
#include "driver/rmt_encoder.h"

#define IR_RECEIVE_PIN 42
#define IR_SEND_PIN    46

rmt_channel_handle_t rx_chan = NULL;
rmt_channel_handle_t tx_chan = NULL;
rmt_encoder_handle_t copy_encoder = NULL;

static rmt_symbol_word_t rx_raw_symbols[256];
static volatile bool rx_done = false;
static size_t rx_symbol_num = 0;

#define IR_CARRIER_FREQ_HZ  38000
#define IR_DUTY_CYCLE       0.33

/* ================= Dump level data================= */
void dump_pulse_array(rmt_symbol_word_t *symbols, size_t count) {
    Serial.println("IR PULSE (us):(L0 | L1)");

    for (size_t i = 0; i < count; i++) {
        int32_t p0 = symbols[i].level0 ? symbols[i].duration0 : -symbols[i].duration0;
        int32_t p1 = symbols[i].level1 ? symbols[i].duration1 : -symbols[i].duration1;
        Serial.printf(" %d, %d\n", p0, p1);
    }
    Serial.println();
}

void dump_duration_array(rmt_symbol_word_t *symbols, size_t count) {
    Serial.println("IR DURATIONS (us):(L0 | L1)");

    for (size_t i = 0; i < count; i++) {
        Serial.printf(" %d, %d\n", symbols[i].duration0, symbols[i].duration1);
    }
    Serial.println();
}

void dump_raw_hex(rmt_symbol_word_t *symbols, size_t count) {
    Serial.println("IR RAW HEX:(L0 | L1)");

    for (size_t i = 0; i < count; i++) {
        Serial.printf(" %04X %04X\n", symbols[i].duration0, symbols[i].duration1);
    }
    Serial.println();
}

bool rmt_rx_done_callback(rmt_channel_handle_t, const rmt_rx_done_event_data_t *edata, void *) {
    rx_symbol_num = edata->num_symbols;
    rx_done = true;
    return true;
}

void setup_rmt_rx() {
    rmt_rx_channel_config_t rx_cfg = {
        .gpio_num = (gpio_num_t)IR_RECEIVE_PIN,
        .clk_src = RMT_CLK_SRC_DEFAULT,
        .resolution_hz = 1000000,
        .mem_block_symbols = 128,
    };

    if (rmt_new_rx_channel(&rx_cfg, &rx_chan) != ESP_OK) return;

    rmt_rx_event_callbacks_t cbs = {
        .on_recv_done = rmt_rx_done_callback,
    };

    rmt_rx_register_event_callbacks(rx_chan, &cbs, NULL);
    rmt_enable(rx_chan);
}

void start_rmt_receive() {
    rmt_receive_config_t cfg = {
        .signal_range_min_ns = 1000,
        .signal_range_max_ns = 20000000,
    };

    rmt_receive(rx_chan, rx_raw_symbols, sizeof(rx_raw_symbols), &cfg);
}

void setup_rmt_tx() {
    rmt_tx_channel_config_t tx_cfg = {
        .gpio_num = (gpio_num_t)IR_SEND_PIN,
        .clk_src = RMT_CLK_SRC_DEFAULT,
        .resolution_hz = 1000000,
        .mem_block_symbols = 128,
        .trans_queue_depth = 4,
    };

    rmt_new_tx_channel(&tx_cfg, &tx_chan);

    rmt_carrier_config_t carrier_cfg = {
        .frequency_hz = IR_CARRIER_FREQ_HZ,
        .duty_cycle = IR_DUTY_CYCLE,
    };

    rmt_apply_carrier(tx_chan, &carrier_cfg);

    rmt_copy_encoder_config_t enc_cfg = {};
    rmt_new_copy_encoder(&enc_cfg, &copy_encoder);

    rmt_enable(tx_chan);
}

void send_raw_symbols(rmt_symbol_word_t *symbols, size_t count) {
    rmt_transmit_config_t cfg = { .loop_count = 0 };
    rmt_transmit( tx_chan, copy_encoder, symbols, count * sizeof(rmt_symbol_word_t), &cfg);
    rmt_tx_wait_all_done(tx_chan, 1000);
    Serial.printf("Transmit back OK!\n\n");
}

void setup() {
    M5.begin();
    M5.Speaker.end();// Disable speaker amp to avoid IR RX interference
    Serial.begin(115200);

    // Display initialization
    M5.Display.setRotation(3);
    M5.Display.setFont(&fonts::FreeMonoBold9pt7b);
    M5.Display.clear();
    M5.Display.println("StickS3 IR example");
    M5.Display.setCursor(0, 30);
    M5.Display.println("Waiting for NEC...");

    setup_rmt_rx();
    setup_rmt_tx();
    start_rmt_receive();

    // Enable external power output for IR receiver module
    M5.Power.setExtOutput(true, m5::ext_none);
}

void loop() {
    if (rx_done) {
        rx_done = false;

        Serial.printf("RX symbols num: %d\n", rx_symbol_num);
        dump_pulse_array(rx_raw_symbols, rx_symbol_num);
        dump_duration_array(rx_raw_symbols, rx_symbol_num);
        dump_raw_hex(rx_raw_symbols, rx_symbol_num);

        M5.Display.fillRect(0, 30, 240, 105, TFT_BLACK);
        M5.Display.setCursor(0, 30);
        M5.Display.setTextColor(GREEN);
        M5.Display.printf("Received!\nsymbols num: %d\nDetails see Serial", rx_symbol_num);

        send_raw_symbols(rx_raw_symbols, rx_symbol_num);
        start_rmt_receive();
    }
    delay(10);
}

After flashing the above sketch to a StickS3, each received IR frame is dumped to the serial port. It prints the level durations (in microseconds) of every symbol and a hex representation, then immediately retransmits the captured raw data over IR. You can verify the echo‑back by pointing a standard IR receiver at the StickS3.

Sample serial output:

RX symbols num: 34
IR PULSE (us):(L0 | L1)
 -9008, 4488
 -591, 568
 -538, 567
 -565, 567
 -536, 1700
 -563, 567
 -540, 1724
 -540, 1696
 -538, 1726
 -538, 1698
 -540, 1722
 -542, 1696
 -539, 591
 -540, 1697
 -538, 594
 -538, 566
 -566, 566
 -540, 1697
 -567, 564
 -538, 1699
 -565, 1698
 -541, 1696
 -567, 1695
 -540, 592
 -540, 564
 -538, 594
 -542, 1696
 -564, 566
 -540, 566
 -566, 565
 -538, 566
 -570, 1667
 -567, 1697
 -567, 0

IR DURATIONS (us):(L0 | L1)
 9008, 4488
 591, 568
 538, 567
 565, 567
 536, 1700
 563, 567
 540, 1724
 540, 1696
 538, 1726
 538, 1698
 540, 1722
 542, 1696
 539, 591
 540, 1697
 538, 594
 538, 566
 566, 566
 540, 1697
 567, 564
 538, 1699
 565, 1698
 541, 1696
 567, 1695
 540, 592
 540, 564
 538, 594
 542, 1696
 564, 566
 540, 566
 566, 565
 538, 566
 570, 1667
 567, 1697
 567, 0

IR RAW HEX:(L0 | L1)
 2330 1188
 024F 0238
 021A 0237
 0235 0237
 0218 06A4
 0233 0237
 021C 06BC
 021C 06A0
 021A 06BE
 021A 06A2
 021C 06BA
 021E 06A0
 021B 024F
 021C 06A1
 021A 0252
 021A 0236
 0236 0236
 021C 06A1
 0237 0234
 021A 06A3
 0235 06A2
 021D 06A0
 0237 069F
 021C 0250
 021C 0234
 021A 0252
 021E 06A0
 0234 0236
 021C 0236
 0236 0235
 021A 0236
 023A 0683
 0237 06A1
 0237 0000

Transmit back OK!
On This Page