Setting up RMT Devices

Setting up IR Devices

In this guide an infrared device will be set up with ESPHome. First, the remote code will be captured with an IR receiver module (like this one). We will use ESPHome’s dumping ability to output the decoded remote code directly.

Then we will set up a new remote transmitter with an infrared LED (like this one) to transmit the code when a button is pressed.

First, connect the infrared receiver module to a pin on your board and set up a remote_receiver instance:

remote_receiver:
  pin: GPIOXX
  dump: all

Compile and upload the code. While viewing the log output from the ESP, press a button on an infrared remote you want to capture (one at a time).

You should see log output like below:

# If the codec is known:
[D][remote.panasonic] Received Panasonic: address=0x4004 command=0x8140DFA2

# Or raw output if it's not known yet
# The values may fluctuate a bit, but as long as they're similar it's ok
[D][remote.raw] Received Raw: 4088, -1542, 1019, -510, 513, -1019, 510, -509, 511, -510, 1020,
[D][remote.raw]   -1020, 1022, -1019, 510, -509, 511, -510, 511, -509, 511, -510,
[D][remote.raw]   1020, -1019, 510, -511, 1020, -510, 512, -508, 510, -1020, 1022

If the codec is already implemented in ESPHome, you will see the decoded value directly - otherwise you will see the raw data dump (which you can use just as well). You have just successfully captured your first infrared code.

Now let’s use this information to emulate a button press from the ESP. First, wire up the IR diode to a new pin on the ESP and configure a global remote_transmitter instance:

remote_transmitter:
  pin: GPIOXX
  # Infrared remotes use a 50% carrier signal
  carrier_duty_percent: 50%

This will allow us to send any data we want via the IR LED. To replicate the codes we decoded earlier, create a new template button that sends the infrared code when triggered:

button:
  - platform: template
    name: Panasonic Power Button
    on_press:
      - remote_transmitter.transmit_panasonic:
          address: 0x4004
          command: 0x8140DFA2

# Or for raw code
button:
  - platform: template
    name: Raw Code Power Button
    on_press:
      - remote_transmitter.transmit_raw:
          carrier_frequency: 38kHz
          code: [4088, -1542, 1019, -510, 513, -1019, 510, -509, 511, -510, 1020,
                 -1020, 1022, -1019, 510, -509, 511, -510, 511, -509, 511, -510,
                 1020, -1019, 510, -511, 1020, -510, 512, -508, 510, -1020, 1022]

Recompile again, when you power up the device the next time you will see a new button in the frontend. Click on it and you should see the remote signal being transmitted. Done!

Setting up RF Devices

The remote_transmitter and remote_receiver components can also be used to send and receive 433MHz Radio Frequency (RF) signals. This guide will discuss setting up a 433MHz receiver to capture a device’s remote codes. After that we will set up a 433MHz transmitter to replicate the remote code with the press of a button in the frontend.

First, connect the RF module to a pin on the ESP and set up a remote_receiver instance:

remote_receiver:
  pin: GPIOXX
  dump: all
  # Settings to optimize recognition of RF devices
  tolerance: 50%
  filter: 250us
  idle: 4ms
  buffer_size: 2kb # only for ESP8266

Compile and upload the code. While viewing the log output from the ESP, press a button on an RF remote you want to capture (one at a time).

You should see log output like below:

# If the codec is known:
[D][remote.rc_switch] Received RCSwitch: protocol=2 data='100010000000000010111110'

# Or raw output if it's not known yet
# The values may fluctuate a bit, but as long as they're similar it's ok
[D][remote.raw] Received Raw: 4088, -1542, 1019, -510, 513, -1019, 510, -509, 511, -510, 1020,
[D][remote.raw]   -1020, 1022, -1019, 510, -509, 511, -510, 511, -509, 511, -510,
[D][remote.raw]   1020, -1019, 510, -511, 1020, -510, 512, -508, 510, -1020, 1022

ℹ️ Note

If the log output is flooded with “Received Raw” messages, you can also disable raw remote code reporting and rely on rc_switch to decode the values.

remote_receiver:
  pin: GPIOXX
  dump:
    - rc_switch
  ...
If the codec is already implemented in ESPHome, you will see the decoded value directly - otherwise you will see the raw data dump (which you can use just as well). You have just successfully captured your first RF code.

Now let’s use this information to emulate a button press from the ESP. First, wire up the RF transmitter to a new pin on the ESP and configure a global remote_transmitter instance:

remote_transmitter:
  pin: GPIOXX
  # RF uses a 100% carrier signal
  carrier_duty_percent: 100%

This will allow us to send any data we want via the RF transmitter. To replicate the codes we decoded earlier, create a new template button that sends the RF code when triggered:

button:
  - platform: template
    name: RF Power Button
    optimistic: true
    on_press:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '100010000000000010111110'
          protocol: 2
          repeat:
            times: 10
            wait_time: 0s

# Or for raw code
button:
  - platform: template
    name: Raw Code Power Button
    on_press:
      - remote_transmitter.transmit_raw:
          code: [4088, -1542, 1019, -510, 513, -1019, 510, -509, 511, -510, 1020,
                 -1020, 1022, -1019, 510, -509, 511, -510, 511, -509, 511, -510,
                 1020, -1019, 510, -511, 1020, -510, 512, -508, 510, -1020, 1022]

Recompile again, when you power up the device the next time you will see a new button in the frontend. Click on it and you should see the remote signal being transmitted. Done!

ℹ️ Note

Some devices require that the transmitted code be repeated for the signal to be picked up as valid. Also the interval between repetitions can be important. Check that the pace of repetition logs are consistent between the remote controller and the transmitter node. You can adjust the repeat: settings accordingly.

Rolling Codes

Some devices are using rolling codes, i.e. instead of one unique code, the buttons generate n different codes in a random manner. Good-natured receivers have a simple logic: the current code must differ from the previous one. In such a case, the n codes can be recorded by pressing each button several times and stored in a vector. The brennenstuhl remote for example uses four rolling codes for each button.The YAML below shows the transmitter for three buttons:


globals:
  # the code vectors of three buttons
- id: a_on
  type: std::vector<int>
  initial_value: '{ 0xbfcf6c, 0xbe821c, 0xb1d75c, 0xb593ac }'
- id: a_off
  type: std::vector<int>
  initial_value: '{ 0xbd2e2c, 0xb4ed8c, 0xb2b6bc, 0xb3017c }'
- id: b_on
  type: std::vector<int>
  initial_value: '{ 0xbb3535, 0xb87af5, 0xbca0e5, 0xba5c05 }'

script:
    # - select vector with bs_button
    # - lookup code from vector with idx
    # - call remote_transmitter
    # - update idx
  - id: bs_transmitter
    mode: single
    parameters: 
      bs_button: int
    then:
      - remote_transmitter.transmit_brennenstuhl:
          code: !lambda |-
            uint32_t code = 0;
            static int32_t idx = 0; // rolling index
            switch(bs_button) {
              case 10: { // A_ON
                code=id(a_on)[idx];
                break;
              }
              case 11: { // A_OFF
                code=id(a_off)[idx];
                break;
              }
              case 20: {  // B_ON
                code=id(b_on)[idx];
                break;
              }
            }
            idx = (idx + 1) & 3;
            return code;

# buttons for the GUI
button:
- platform: template
  name: "A ON"
  on_press:
    - lambda: id(bs_transmitter)->execute(10);
- platform: template
  name: "A OFF"
  on_press:
    - lambda: id(bs_transmitter)->execute(11);
- platform: template
  name: "B ON"
  on_press:
    - lambda: id(bs_transmitter)->execute(20);

See Also