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
4 channels, Channel<0> and Channel<1> hardcoded for transmitting signals and Channel<2> and Channel<3> hardcoded for receiving signals.
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 = Rate::from_mhz(80);
let rmt = Rmt::new(peripherals.RMT, freq)?;
let mut channel = rmt.channel0.configure_tx(
    peripherals.GPIO1,
    TxChannelConfig::default()
        .with_clk_divider(1)
        .with_idle_output_level(Level::Low)
        .with_idle_output(false)
        .with_carrier_modulation(false)
        .with_carrier_high(1)
        .with_carrier_low(1)
        .with_carrier_level(Level::Low),
)?;§TX operation
// Configure frequency based on chip type
let freq = Rate::from_mhz(80);
let rmt = Rmt::new(peripherals.RMT, freq)?;
let tx_config = TxChannelConfig::default().with_clk_divider(255);
let mut channel = rmt.channel0.configure_tx(peripherals.GPIO4, tx_config)?;
let delay = Delay::new();
let mut data = [PulseCode::new(Level::High, 200, Level::Low, 50); 20];
data[data.len() - 2] = PulseCode::new(Level::High, 3000, Level::Low, 500);
data[data.len() - 1] = PulseCode::end_marker();
loop {
    let transaction = channel.transmit(&data)?;
    channel = transaction.wait()?;
    delay.delay_millis(500);
}§RX operation
const WIDTH: usize = 80;
let mut out = Output::new(peripherals.GPIO5, Level::Low, OutputConfig::default());
// Configure frequency based on chip type
let freq = Rate::from_mhz(80);
let rmt = Rmt::new(peripherals.RMT, freq)?;
let rx_config = RxChannelConfig::default()
    .with_clk_divider(1)
    .with_idle_threshold(10000);
let mut channel = rmt.channel2.configure_rx(peripherals.GPIO4, rx_config)?;
let delay = Delay::new();
let mut data: [PulseCode; 48] = [PulseCode::default(); 48];
loop {
    for x in data.iter_mut() {
        x.reset()
    }
    let transaction = channel.receive(&mut data)?;
    // 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((symbol_count, channel_res)) => {
            channel = channel_res;
            let mut total = 0usize;
            for entry in &data[..symbol_count] {
                if entry.length1() == 0 {
                    break;
                }
                total += entry.length1() as usize;
                if entry.length2() == 0 {
                    break;
                }
                total += entry.length2() as usize;
            }
            for entry in &data[..symbol_count] {
                if entry.length1() == 0 {
                    break;
                }
                let count = WIDTH / (total / entry.length1() as usize);
                let c = match entry.level1() {
                    Level::High => '-',
                    Level::Low => '_',
                };
                for _ in 0..count + 1 {
                    print!("{}", c);
                }
                if entry.length2() == 0 {
                    break;
                }
                let count = WIDTH / (total / entry.length2() as usize);
                let c = match entry.level2() {
                    Level::High => '-',
                    Level::Low => '_',
                };
                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§
- Channel
- RMT Channel
- ChannelCreator 
- RMT Channel Creator
- ContinuousTxTransaction 
- An in-progress continuous TX transaction
- PulseCode 
- Convenience newtype to work with pulse codes.
- Rmt
- RMT Instance
- Rx
- Marker for a channel capable of/configured for receive operations
- RxChannelConfig 
- Channel configuration for RX channels
- RxTransaction
- RX transaction instance
- SingleShot TxTransaction 
- An in-progress transaction for a single shot TX transaction.
- Tx
- Marker for a channel capable of/configured for transmit operations
- TxChannelConfig 
- Channel configuration for TX channels
Enums§
Constants§
- CHANNEL_RAM_ SIZE 
- Per-channel size of the RMT hardware buffer (number of PulseCodes).
- HAS_RX_ WRAP 
- Whether the channel supports wrapping rx (wrapping tx is supported on all devices)
- MAX_RX_ IDLE_ THRESHOLD 
- The largest valid value for RxChannelConfig::with_idle_threshold.
- MAX_TX_ LOOPCOUNT 
- The largest valid value for loopcounts in LoopMode.
Traits§
- Direction
- A trait implemented by the RxandTxmarker structs.
- RxChannelCreator 
- Creates a RX channel
- TxChannelCreator 
- Creates a TX channel