esphome / issues

Issue Tracker for ESPHome
https://esphome.io/
290 stars 36 forks source link

Remote Receiver truncates long signals #1037

Closed albertofustinoni closed 4 years ago

albertofustinoni commented 4 years ago

Operating environment/Installation (Hass.io/Docker/pip/etc.):

pip

ESP (ESP32/ESP8266, Board/Sonoff):

ESP32

Affected component:

Remote Receiver

Description of problem:

Problem-relevant YAML-configuration entries:

remote_receiver:
  pin:
    number: GPIO18
    inverted: yes
  dump: raw
  filter: 300us
  buffer_size: 65536

Logs (if applicable):

PASTE DEBUG LOG HERE

I am attempting to use the remote receiver on an ESP32 to dump codes for a couple of AC units, both of which use the Panasonic protocol, however:

According to the the findings of a reverse engineering effort (which match my own observations when decoding the partial raw dumps), the signals can be up to 216 bit long after decoding.

Can this be fixed?

glmnet commented 4 years ago

Esphome will understand the code ends once the transmitter is idle by default 10ms. Check idle config and increase it.

albertofustinoni commented 4 years ago

I tried upping the idle time in config, but to no effect. Here is what I have right now

remote_receiver:
  pin:
    number: GPIO18
    inverted: yes
  dump: all
  #filter: 200.0us
  idle: 100ms
  buffer_size: 64kb

And here is what the log says

[15:37:49][C][remote_receiver.esp32:055]:   Pin: GPIO18 (Mode: INPUT, INVERTED)
[15:37:49][C][remote_receiver.esp32:060]:   Channel: 0
[15:37:49][C][remote_receiver.esp32:061]:   Clock divider: 80
[15:37:49][C][remote_receiver.esp32:062]:   Tolerance: 25%
[15:37:49][C][remote_receiver.esp32:063]:   Filter out pulses shorter than: 50 us
[15:37:49][C][remote_receiver.esp32:064]:   Signal is done after 100000 us of no changes
glmnet commented 4 years ago

Are you trying to decode an ac ir code?

What makes you believe you are not getting the full code? I’ve seen the message you deleted in my email. It seems to be a full message but esphome splits into several log lines because it will otherwise overflow the log buffer space (or any other cosmetic like that)

albertofustinoni commented 4 years ago

I deleted the other message because after reading the source code more I understood the print on line 28 was not an error but, as you said, a single read being written to multiple lines.

As for why I believe I am only getting the beginning of messages

glmnet commented 4 years ago

Even though what you are trying to accomplish makes sense, ESPHome is not the best tool for this.

If you are not trusting the signal you are decoding other than just believing in what other web sites says you can also try other decoding tools which you trust and then compare them with ESPHome, that way, if they are different, a better diagnostic could be made.

IRRemoteESP8266 is a good project for this, it already includes the panasonic for AC protocols so you can even check if you remote is compatible with it.

OttoWinter commented 4 years ago

ESPHome only reports what the ESP32 remote peripheral (through the esp-idf APIs) responds.

I have some protocols that I use myself that definitely have much longer codes than what you have here, and those work fine for me.

For eliminating causes, I'd suggest you try to capture the IR raw codes with another project like IRRemoteESP8266 first to see if it's an error elsewhere.

puuu commented 4 years ago

I can confirm this behaviour.

The following error message also appears ones on the serial console:

[16:43:49]E (12383) rmt: RMT[1] ERR
[16:43:49]E (12384) rmt: status: 0x13040080

I hit this issue when I implemented the receiver part of the daikin (IR AC protocol) component esphome/esphome#1001. The signal frame of the daikin protocol is 306 marks and spaces (152 bit) long. If I want to check the checksum, I have to read all the pulses. This works well on an esp8266. But, I only get 128 marks and spaces on an esp32 and I need at least 130 to be able to determine the fan and swing mode.

The problem seems to be the RMT implementation. If I increase rmt.mem_block_num in remote_receiver_esp32.cpp to 3, it works fine. So the RMT receiver can only receive as much data as fit in one RMT memory block, independent from the ring buffer size.

IMHO, since this seems to be a limitation of the esp32 rmt support, we need a way to configure rmt.mem_block_num. Or better an interrupt-based implementation (as on the esp8266 platform) as an alternative.

glmnet commented 4 years ago

This is interesting findings!!

IMHO, since this seems to be a limitation of the esp32 rmt support, we need a way to configure rmt.mem_block_num. Or better an interrupt-based implementation (as on the esp8266 platform) as an alternative.

just to put clear, I though we prefer the inner ESP32 "hardware" based decoding or something like that as it should be better than ESP8266's, so no "better an interrupt based"? Does it make sense to configure the rmt.mem_block_num as a function of the capture block length?

puuu commented 4 years ago

Ok, @glmnet, then define 'better'. For the transmitter, there is no doubt that the RMT solution is better, since it is not blocking. But for receive, a real comparison needs to be made. An interrupt solution can be very efficient and is a typical implementation. In addition, we would not depend on proprietary code that we cannot fix, and we can provide a more resource-efficient (especially memory) solution.

However, see pull request esphome/esphome#1002 for an attempt to make rmt.mem_block_num configurable.

glmnet commented 4 years ago

Sorry for late reply...

I am with you. I really don’t know much about rmt but makes sense to keep using transmitter and have our own soft receiver. Also I don’t see problems with the transmitter implementation (I use esp8266 only) however I just wanted to remind the word of Otto saying that the RC stuff works much “better” on the ESP32

I’d like to add that I don’t like much current implementation, the “silence” at the end as a means for detecting end of reception does not work well for all protocols, also this made almost imposible to implement a feature I’ve tried which will tell you the repeat interval between the codes.

It works in the end but it can be reviewed and improved. Unfortunately I forgot about the ideas I had in mind back then.