esp_hal

Module rmt

Source
Available on crate feature unstable only.
Expand description

§Remote Control Peripheral (RMT)

§Overview

The RMT (Remote Control) module is designed to send and receive infrared remote control signals. A variety of remote control protocols can be encoded/decoded via software based on the RMT module. The RMT module converts pulse codes stored in the module’s built-in RAM into output signals, or converts input signals into pulse codes and stores them in RAM. In addition, the RMT module optionally modulates its output signals with a carrier wave, or optionally demodulates and filters its input signals.

Typically, the RMT peripheral can be used in the following scenarios:

  • Transmit or receive infrared signals, with any IR protocols, e.g., NEC
  • General-purpose sequence generator
  • Transmit signals in a hardware-controlled loop, with a finite or infinite number of times
  • Modulate the carrier to the output signal or demodulate the carrier from the input signal

§Channels

There are 8 channels, each of them can be either receiver or transmitter.

For more information, please refer to the ESP-IDF documentation

§Configuration

Each TX/RX channel has the same functionality controlled by a dedicated set of registers and is able to independently transmit or receive data. TX channels are indicated by n which is used as a placeholder for the channel number, and by m for RX channels.

§Examples

§Initialization

let freq = 80.MHz();
let rmt = Rmt::new(peripherals.RMT, freq).unwrap();
let mut channel = rmt
    .channel0
    .configure(
        peripherals.GPIO1,
        TxChannelConfig {
            clk_divider: 1,
            idle_output_level: false,
            idle_output: false,
            carrier_modulation: false,
            carrier_high: 1,
            carrier_low: 1,
            carrier_level: false,
        },
    )
    .unwrap();

§TX operation


// Configure frequency based on chip type
let freq = 80.MHz();
let rmt = Rmt::new(peripherals.RMT, freq).unwrap();

let tx_config = TxChannelConfig {
    clk_divider: 255,
    ..TxChannelConfig::default()
};

let mut channel = rmt
    .channel0
    .configure(peripherals.GPIO4, tx_config)
    .unwrap();

let delay = Delay::new();

let mut data = [PulseCode::new(true, 200, false, 50); 20];
data[data.len() - 2] = PulseCode::new(true, 3000, false, 500);
data[data.len() - 1] = PulseCode::empty();

loop {
    let transaction = channel.transmit(&data).unwrap();
    channel = transaction.wait().unwrap();
    delay.delay_millis(500);
}

§RX operation


const WIDTH: usize = 80;

let mut out = Output::new(peripherals.GPIO5, Level::Low);

// Configure frequency based on chip type
let freq = 80.MHz();
let rmt = Rmt::new(peripherals.RMT, freq).unwrap();

let rx_config = RxChannelConfig {
    clk_divider: 1,
    idle_threshold: 10000,
    ..RxChannelConfig::default()
};
let mut channel = rmt.channel0.configure(peripherals.GPIO4, rx_config).unwrap();
let delay = Delay::new();
let mut data: [u32; 48] = [PulseCode::empty(); 48];

loop {
    for x in data.iter_mut() {
        x.reset()
    }

    let transaction = channel.receive(&mut data).unwrap();

    // Simulate input
    for i in 0u32..5u32 {
        out.set_high();
        delay.delay_micros(i * 10 + 20);
        out.set_low();
        delay.delay_micros(i * 20 + 20);
    }

    match transaction.wait() {
        Ok(channel_res) => {
            channel = channel_res;
            let mut total = 0usize;
            for entry in &data[..data.len()] {
                if entry.length1() == 0 {
                    break;
                }
                total += entry.length1() as usize;

                if entry.length2() == 0 {
                    break;
                }
                total += entry.length2() as usize;
            }

            for entry in &data[..data.len()] {
                if entry.length1() == 0 {
                    break;
                }

                let count = WIDTH / (total / entry.length1() as usize);
                let c = if entry.level1() { '-' } else { '_' };
                for _ in 0..count + 1 {
                    print!("{}", c);
                }

                if entry.length2() == 0 {
                    break;
                }

                let count = WIDTH / (total / entry.length2() as usize);
                let c = if entry.level2() { '-' } else { '_' };
                for _ in 0..count + 1 {
                    print!("{}", c);
                }
            }

            println!();
        }
        Err((_err, channel_res)) => {
            channel = channel_res;
        }
    }

    delay.delay_millis(1500);
}

Note: on ESP32 and ESP32-S2 you cannot specify a base frequency other than 80 MHz

Structs§

Enums§

Traits§