Skip to content

Concepts First

  • IR remote control: encodes "0/1" into modulated infrared pulses; the receiver converts the light back into electrical signals.
  • NEC protocol: the most common IR encoding — one frame is 32 bits = address + inverted address + command + inverted command.
  • Receive/transmit: on BL616/BL618 the example mainly receives (TEST_IR_RX); transmit is compiled only on chips like BL618DG.

Example Overview

This page is based on the ir_nec example in the official Bouffalo SDK (examples/peripherals/ir/ir_nec), which demonstrates NEC-protocol IR reception:

  • Initializes the IR receiver (bflb_ir_rx_init, NEC mode), enables reception, and blocks until data arrives;
  • Prints the bit count and the 32-bit value of a received NEC frame;
  • Chips such as BL618DG also support IR transmit (TEST_IR_TX), so two boards can do a loopback test.
  • Sibling examples (examples/peripherals/ir/): ir_rc5 (RC5 protocol), ir_swm / ir_swm_int (software protocol/interrupt).

Operation Steps

1
Prepare the Hardware

On BL616/BL618 the example mainly runs in receive mode (TEST_IR_RX): connect an IR receiver to the IR RX pin (see board_ir_gpio_init()), VCC to 3.3V, GND to GND. Prepare an NEC-protocol IR remote.

2
Enter the Example Directory

Open a terminal and enter the IR example directory (prerequisite: set up the environment as in Quick Start (Linux) or Windows):

cd examples/peripherals/ir/ir_nec
3
Build the Project

Run the build command. The Ai-M62 (BL616) and Ai-M61 (BL618) belong to the same series, so both use bl616:

make CHIP=bl616 BOARD=bl616dk
4
Flash the Firmware

Connect the board with a USB cable, hold the BOOT button (IO2 on the Ai-M61-32S-Kit), briefly press EN/RST to enter download mode, then flash (replace the serial port with the one on your computer):

make flash CHIP=bl616 COMX=/dev/ttyUSB0
5
Run and Verify

Open a serial tool (baud rate 2000000). Point the IR remote at the receiver and press a key; the serial port prints Receive bit: 32, value: 0x..., the received 32-bit NEC code.

Code Execution Flow

The complete execution flow from startup to running is shown below (loop arrows mean repeated execution):

APIs Used by the Example

bflb_device_get_by_name("irrx")

Gets the IR receiver device handle ("irtx" for the transmitter).

Parameters:

  • name: device name, "irrx" receive / "irtx" transmit

Return: struct bflb_device_s * device handle

bflb_ir_rx_init(irrx, config)

Initializes the IR receiver. In struct bflb_ir_rx_config_s: rx_mode = IR_RX_NEC, input_inverse = true, deglitch_enable = false.

Parameters:

  • irrx: receiver device handle
  • config: pointer to the config struct

Return: 0 on success; negative error code on failure

bflb_ir_rx_enable(irrx, true)

Enables/disables IR reception.

Parameters:

  • irrx: receiver device handle
  • enable: true enable / false disable

Return: none

bflb_ir_receive(irrx, &rx_data)

Blocks until one IR frame is received.

Parameters:

  • irrx: receiver device handle
  • rx_data: uint64_t * output data

Return: number of valid bits (32 for NEC)

Complete Code

The complete source below matches the effect described on this page. It is based on the official example (examples/peripherals/ir/ir_nec); the LED pins are adapted to the Ai-M61/62-32S-Kit onboard RGB LED. Collapsed by default, click to expand:

📜 Click to expand ir_nec/main.c full code
c
#include "bflb_ir.h"
#include "board.h"

#if defined(BL602) || defined(BL702) || defined(BL702L) || defined(BL618DG)
#define TEST_IR_TX
#endif

#if defined(BL602) || defined(BL702) || defined(BL616) || defined(BL618DG) || defined(BL616CL)
#define TEST_IR_RX
#endif

#ifdef TEST_IR_TX
struct bflb_device_s *irtx;
#endif
#ifdef TEST_IR_RX
struct bflb_device_s *irrx;
#endif

/* main */
int main(void)
{
    board_init();

    printf("IR NEC case:\r\n");

    board_ir_gpio_init();

#ifdef TEST_IR_TX
    uint32_t tx_buffer[1] = { 0xE916FF00 };
    struct bflb_ir_tx_config_s tx_cfg;

    irtx = bflb_device_get_by_name("irtx");

    /* TX init */
    tx_cfg.tx_mode = IR_TX_NEC;
    bflb_ir_tx_init(irtx, &tx_cfg);
#endif

#ifdef TEST_IR_RX
    uint64_t rx_data;
    uint8_t rx_len;
    struct bflb_ir_rx_config_s rx_cfg;

    irrx = bflb_device_get_by_name("irrx");

    /* RX init */
    rx_cfg.rx_mode = IR_RX_NEC;
    rx_cfg.input_inverse = true;
    rx_cfg.deglitch_enable = false;
    bflb_ir_rx_init(irrx, &rx_cfg);

    /* Enable rx, wait for sending */
    bflb_ir_rx_enable(irrx, true);
#endif

#ifdef TEST_IR_TX
    /* Send */
    bflb_ir_send(irtx, tx_buffer, 1);
    printf("Send 0x%08lx\r\n", tx_buffer[0]);
#endif

#ifdef TEST_IR_RX
    /* Receive */
    rx_len = bflb_ir_receive(irrx, &rx_data);

#ifdef TEST_IR_TX
    /* Check data received */
    if (rx_data != tx_buffer[0]) {
        printf("Data error! receive bit: %d, value: 0x%016lx\r\n", rx_len, rx_data);
    } else {
        printf("Received correctly. receive bit: %d, value: 0x%016lx\r\n", rx_len, rx_data);
    }
#else
    printf("Receive bit: %d, value: 0x%016lx\r\n", rx_len, rx_data);
#endif
#endif

    printf("end\r\n");

    while (1) {
    }
}

FAQ

Nothing is printed when pressing the remote

Check the receiver wiring (signal pin, VCC 3.3V, shared ground) and make sure the remote uses NEC protocol; RC5/RC6 etc. are not parsed by this example.

The printed value does not match the key

The NEC code contains address + command + inverted code, and mappings differ per remote. Check that the value is stable, or use a remote with known NEC codes.

I want to test transmit

Transmit is compiled only on chips like BL618DG (TEST_IR_TX); standard Ai-M61/62 modules (BL616/BL618) enable reception only.

Have questions?

For any other questions, visit the unified Q&A and discussion board: Ai-Thinker Discussions

Released under the MIT License. Build Time 2026-09-11 14:52:23