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
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.
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_necRun the build command. The Ai-M62 (BL616) and Ai-M61 (BL618) belong to the same series, so both use bl616:
make CHIP=bl616 BOARD=bl616dkConnect 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/ttyUSB0Open 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 handleconfig: 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 handleenable:trueenable /falsedisable
Return: none
bflb_ir_receive(irrx, &rx_data)
Blocks until one IR frame is received.
Parameters:
irrx: receiver device handlerx_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
#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.
Related Best Practices
Have questions?
For any other questions, visit the unified Q&A and discussion board: Ai-Thinker Discussions

