Skip to content

[esp32_rmt] Updates for IDF 5+#7770

Merged
kbx81 merged 72 commits into
esphome:devfrom
swoboda1337:rmt_driver
Dec 19, 2024
Merged

[esp32_rmt] Updates for IDF 5+#7770
kbx81 merged 72 commits into
esphome:devfrom
swoboda1337:rmt_driver

Conversation

@swoboda1337
Copy link
Copy Markdown
Member

@swoboda1337 swoboda1337 commented Nov 14, 2024

What does this implement/fix?

Newer versions of the framework have a new RMT driver:

The legacy RMT driver is deprecated, please use driver/rmt_tx.h and/or driver/rmt_rx.h

One big difference is the user cannot choose the RMT channel. Will simplify the esphome code as there is no need to coordinate between components as its all done in the driver.

Newer driver has a number of other advantages:

  • Proper support for rx/tx on a single gpio, add "one_wire: true" in remote_transmitter to use this feature.
  • Previous driver would drop most rx data in high noise environments rendering it useless, new driver performs very well.
  • DMA support on newer chips like s3: add "with_dma: true" in remote_transmitter or remote_receiver.
  • Boards like C3 are limited to a single hw memory buffer, the previous driver can only read a max of 128 values. Even with all 8 buffers on other chips the max length was only 1024. The newer driver on newer chips reads continuously in a ping-pong fashion. To use this set max_length in remote_receiver to the desired length.

Remote code and led code have been updated to support both versions of the RMT driver. Arduino doesn't support the newer drivers yet. We have to support both drivers for a while.

Note neopixelbus also used RMT but it doesn't work with IDF anyways so it wont be a problem.

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Code quality improvements to existing code or addition of tests
  • Other

Related issue or feature (if applicable):

Pull request in esphome-docs with documentation (if applicable):

Test Environment

  • ESP32
  • ESP32 IDF
  • ESP8266
  • RP2040
  • BK72xx
  • RTL87xx

Example entry for config.yaml:

latest:

    external_components:
      - source: github://pr#7770
        components: [ remote_base, remote_receiver, remote_transmitter, esp32_rmt, esp32_rmt_led_strip ]
        refresh: 5min

if you are not on the lastest dev and get c6 config errors:

    external_components:
      - source: github://esphome/esphome@94befe126bc952785994ddf8dcfd15e9c3c3ff23
        components: [ remote_base, remote_receiver, remote_transmitter, esp32_rmt, esp32_rmt_led_strip ]
        refresh: 5min

Checklist:

  • The code change is tested and works locally.
  • Tests have been added to verify that the new code works (under tests/ folder).

If user exposed functionality or configuration variables are added/changed:

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Nov 14, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 53.77%. Comparing base (4d8b5ed) to head (c6f25dc).
Report is 1819 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #7770      +/-   ##
==========================================
+ Coverage   53.70%   53.77%   +0.06%     
==========================================
  Files          50       50              
  Lines        9408     9840     +432     
  Branches     1654     1361     -293     
==========================================
+ Hits         5053     5291     +238     
- Misses       4056     4223     +167     
- Partials      299      326      +27     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@swoboda1337
Copy link
Copy Markdown
Member Author

Have not tested this on arduino only on idf. Not sure if/when this would get merged but at least there is a working proof of concept.

@fightforlife
Copy link
Copy Markdown
Contributor

fightforlife commented Nov 15, 2024

I tried to use this PR in conjuction with the CC1101 PR #6300 .

external_components:
  - source: github://pr#6300
    components: [ cc1101 ]
  - source: github://pr#7770
    components: [ remote_base, remote_receiver, remote_transmitter ]

esp32:
  board: esp32doit-devkit-v1
  variant: esp32
  framework:
    type: esp-idf
    version: 5.3.1
    platform_version: 6.8.1

I get the following error, is this expected?

[08:41:13][C][remote_receiver.esp32:083]: Remote Receiver:
[08:41:13][C][remote_receiver.esp32:084]:   Pin: GPIO4
[08:41:13][C][remote_receiver.esp32:089]:   RMT memory blocks: 3
[08:41:13][C][remote_receiver.esp32:090]:   Clock divider: 80
[08:41:13][C][remote_receiver.esp32:091]:   Tolerance: 80%
[08:41:13][C][remote_receiver.esp32:093]:   Filter out pulses shorter than: 20 us
[08:41:13][C][remote_receiver.esp32:094]:   Signal is done after 20000 us of no changes
[08:41:13][E][remote_receiver.esp32:096]: Configuring RMT driver failed: ESP_ERR_NOT_SUPPORTED (in rmt_receive)
[08:41:13][E][component:082]:   Component remote_receiver is marked FAILED

@gabest11
Copy link
Copy Markdown
Contributor

gabest11 commented Nov 15, 2024

Arduino won't compile, no drivers/rmt_rx/tx.h there. My first test subject was a c3, same error, cannot allocate rmt for the receiver.

[09:20:17][C][remote_receiver.esp32:033]: Setting up Remote Receiver...
[09:20:17][D][esp-idf:000]: E (274) rmt: rmt_rx_register_to_group(144): no free rx channels
[09:20:17]
[09:20:17][D][esp-idf:000]: E (274) rmt: rmt_new_rx_channel(213): register channel failed
[09:20:17]
[09:20:17][E][component:119]: Component remote_receiver was marked as failed.
[09:20:17][E][component:164]: Component remote_receiver set Error flag: unspecified
[09:20:17][C][remote_transmitter:013]: Setting up Remote Transmitter...
[09:20:17][D][esp-idf:000]: I (276) gpio: GPIO[3]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
[09:20:17]
[09:20:23][C][cc1101:206]: CC1101 partnum 00 version 14:
[09:20:23][C][cc1101:207]:   CC1101 CS Pin: GPIO10
[09:20:23][C][cc1101:209]:   CC1101 Bandwith: 200 KHz
[09:20:23][C][cc1101:210]:   CC1101 Frequency: 433920 KHz
[09:20:23][C][remote_receiver.esp32:083]: Remote Receiver:
[09:20:23][C][remote_receiver.esp32:084]:   Pin: GPIO4
[09:20:23][C][remote_receiver.esp32:089]:   RMT memory blocks: 3
[09:20:23][C][remote_receiver.esp32:090]:   Clock divider: 80
[09:20:23][C][remote_receiver.esp32:091]:   Tolerance: 50%
[09:20:23][C][remote_receiver.esp32:093]:   Filter out pulses shorter than: 250 us
[09:20:23][C][remote_receiver.esp32:094]:   Signal is done after 4000 us of no changes
[09:20:23][E][remote_receiver.esp32:096]: Configuring RMT driver failed: ESP_ERR_NOT_FOUND (in rmt_new_rx_channel)
[09:20:23][E][component:082]:   Component remote_receiver is marked FAILED
[09:20:23][C][remote_transmitter:018]: Remote Transmitter...
[09:20:23][C][remote_transmitter:019]:   RMT memory blocks: 1
[09:20:23][C][remote_transmitter:020]:   Clock divider: 80
[09:20:23][C][remote_transmitter:021]:   Pin: GPIO3

@gabest11
Copy link
Copy Markdown
Contributor

gabest11 commented Nov 15, 2024

I found this, something about 64 symbols.

http://esp32.io/viewtopic.php?t=28393

RMT memory blocks: 3

Definitely 3 times the limit.

Yep, memory_blocks: 1 and it works.

Needs some checks in __init__.py.

@gabest11
Copy link
Copy Markdown
Contributor

gabest11 commented Nov 15, 2024

S3 has a nice RGB led. There are three different components for WS2811, only esp32_rmt_led_strip compiles with esp-idf, and using the old rmt headers, it creates a conflict.

I cannot receive on the same pin, but two pin mode works. On C3, it worked both ways.

@fightforlife
Copy link
Copy Markdown
Contributor

memory_blocks: 1 in the receiver does not help for me.
Error seems to happen somewhere around here: https://github.com/swoboda1337/esphome/blob/25ce0ab4f3776d415c91c53869e8533ff35d976f/esphome/components/remote_receiver/remote_receiver_esp32.cpp#L72

[12:14:38][C][remote_receiver.esp32:083]: Remote Receiver:
[12:14:38][C][remote_receiver.esp32:084]:   Pin: GPIO4
[12:14:38][C][remote_receiver.esp32:089]:   RMT memory blocks: 1
[12:14:38][C][remote_receiver.esp32:090]:   Clock divider: 80
[12:14:38][C][remote_receiver.esp32:091]:   Tolerance: 25%
[12:14:38][C][remote_receiver.esp32:093]:   Filter out pulses shorter than: 50 us
[12:14:38][C][remote_receiver.esp32:094]:   Signal is done after 10000 us of no changes
[12:14:38][E][remote_receiver.esp32:096]: Configuring RMT driver failed: ESP_ERR_NOT_SUPPORTED (in rmt_receive)
[12:14:38][E][component:082]:   Component remote_receiver is marked FAILED

@gabest11
Copy link
Copy Markdown
Contributor

rmt_receive can't even return ESP_ERR_NOT_SUPPORTED according to the docs. There is a note though:

If you want this function to work even when the flash cache is disabled, please enable the CONFIG_RMT_RECV_FUNC_IN_IRAM option.

@swoboda1337
Copy link
Copy Markdown
Member Author

swoboda1337 commented Nov 15, 2024

S3 has a nice RGB led. There are three different components for WS2811, only esp32_rmt_led_strip compiles with esp-idf, and using the old rmt headers, it creates a conflict.

I cannot receive on the same pin, but two pin mode works. On C3, it worked both ways.

To use 1 pin mode you have to uncomment this, I have to add an option for it:

// TODO: add support for a rx/tx 1-wire gpio
// channel.flags.io_loop_back = 1;
// channel.flags.io_od_mode = 1;

I can do that today

@swoboda1337
Copy link
Copy Markdown
Member Author

t_receive can't even return ESP_ERR_NOT_SUPPORTED according to the docs. There is a note though:

If you want this function to work even when the flash cache is disabled, please enable the CONFIG_RMT_RECV_FUNC_IN_IRAM option.

Maybe that is the problem, it always worked for me though. Not sure how to enable that.

@gabest11
Copy link
Copy Markdown
Contributor

Could this enable that option?

esp32:
  framework:
    sdkconfig_options:
      CONFIG_RMT_RECV_FUNC_IN_IRAM: y

@swoboda1337
Copy link
Copy Markdown
Member Author

swoboda1337 commented Nov 15, 2024

S3 has a nice RGB led. There are three different components for WS2811, only esp32_rmt_led_strip compiles with esp-idf, and using the old rmt headers, it creates a conflict.

I cannot receive on the same pin, but two pin mode works. On C3, it worked both ways.

You can add "one_wire: true" to remote transmitter and it should work now without modifying anything.

@swoboda1337
Copy link
Copy Markdown
Member Author

swoboda1337 commented Nov 15, 2024

Actually it cant be the iram thing, this happens in the setup function not the isr. It can only be channel, filter, idle or the buffer pointer. The channel was just created without an error. Maybe the buffer pointer is invalid? I don't know.

@swoboda1337
Copy link
Copy Markdown
Member Author

ESP_ERR_NOT_SUPPORTED

I pushed a new change can you try it again?

Comment thread tests/components/remote_receiver/test.esp32-ard.yaml Outdated
Comment thread tests/components/remote_transmitter/test.esp32-ard.yaml Outdated
@kbx81
Copy link
Copy Markdown
Member

kbx81 commented Dec 12, 2024

@swoboda1337 I hope you don't mind...I jumped in and pushed a few more changes to keep things moving along. 😇

@swoboda1337
Copy link
Copy Markdown
Member Author

swoboda1337 commented Dec 12, 2024

@swoboda1337 I hope you don't mind...I jumped in and pushed a few more changes to keep things moving along. 😇

Looks good thanks! I will look at the remaining things today. I finished the docs but want to give them a second read.

EDIT: done

kbx81
kbx81 previously approved these changes Dec 13, 2024
Copy link
Copy Markdown
Member

@kbx81 kbx81 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is it...I've been testing on both an ESP32 and a C3 and it seems to be good...thanks for all the work! 🍻

@swoboda1337
Copy link
Copy Markdown
Member Author

I created #7974 to update split default to work with C6 and H2. Right now those defaults aren't right. I can update them if that pr gets merged.

@icarome
Copy link
Copy Markdown

icarome commented Dec 17, 2024

Last 2 commits broke it for esp32dev board

@swoboda1337
Copy link
Copy Markdown
Member Author

swoboda1337 commented Dec 17, 2024

Last 2 commits broke it for esp32dev board

It didn't actually break it, there was another change made to core. If you build on dev it will should work. Not sure if there is a way to sync to a previous change with a pr + external components.

@swoboda1337
Copy link
Copy Markdown
Member Author

swoboda1337 commented Dec 18, 2024

Last 2 commits broke it for esp32dev board

Yes you should be to sync to a prev commit if you need to:

external_components:
  - source: github://esphome/esphome@94befe126bc952785994ddf8dcfd15e9c3c3ff23
    components: [ remote_base, remote_receiver, remote_transmitter, esp32_rmt, esp32_rmt_led_strip ]
    refresh: 5min

Copy link
Copy Markdown
Member

@kbx81 kbx81 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-tested & still working for me here. 😄

Copy link
Copy Markdown
Member

@kbx81 kbx81 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-tested & still working for me here. 😄

@kbx81 kbx81 merged commit 265b6ec into esphome:dev Dec 19, 2024
@Bjk8kds
Copy link
Copy Markdown

Bjk8kds commented Dec 19, 2024

Last 2 commits broke it for esp32dev board

Yes you should be to sync to a prev commit if you need to:

external_components:
  - source: github://esphome/esphome@94befe126bc952785994ddf8dcfd15e9c3c3ff23
    components: [ remote_base, remote_receiver, remote_transmitter, esp32_rmt, esp32_rmt_led_strip ]
    refresh: 5min

Thanks, this source works for me.
But if you are using esp-idf, you need to remove rmt_channel.
Esphome 2024.12.0

@swoboda1337
Copy link
Copy Markdown
Member Author

@kbx81 should mark this as breaking since rmt_channel, clock_divider and memory_blocks have been removed from IDF.

@kbx81
Copy link
Copy Markdown
Member

kbx81 commented Dec 19, 2024

Oh! I thought we did that... 🤦🏻

@github-actions github-actions Bot locked and limited conversation to collaborators Dec 22, 2024
@swoboda1337 swoboda1337 deleted the rmt_driver branch January 24, 2025 14:06
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The legacy RMT driver is deprecated, please use driver/rmt_tx.h and/or driver/rmt_rx.h

10 participants