crankyoldgit / IRremoteESP8266

Infrared remote library for ESP8266/ESP32: send and receive infrared signals with multiple protocols. Based on: https://github.com/shirriff/Arduino-IRremote/
GNU Lesser General Public License v2.1
2.84k stars 810 forks source link

`sendNEC()` function has no NEC redundant bits implemented #2043

Closed StachRedeker closed 8 months ago

StachRedeker commented 8 months ago

Version/revision of the library used

2.8.6

Describe the bug

The sendNEC() function does not follow the protocol guidelines as referenced on the linked NEC protocol website, i.e. https://www.sbprojects.net/knowledge/ir/nec.php. Although the timings are properly taken into account, the needed redundancy is not. The logical inverse of the command is not sent, but instead left as all zeroes. And the actual command is placed at the end of the packet, whereas the inverse command is expected to be placed there.

To reproduce & expected behaviour

Use sendNEC(1) or sendNEC(13). According to the above protocol website, one would expect an NEC packet with the address field undefined, then the payload (00000001) and (00001101), respectively, and then the inverse of the payload. The expected packets therefore are:

Address Logical inverse of address Command Logical inverse of command
xxxxxxxx yyyyyyyy 00000001 11111110
xxxxxxxx yyyyyyyy 00001101 11110010

I hooked up my oscilloscope to the direct output of an ESP32 and recorded the following packets:

packets_plot

As can be seen, the timing is correct and the pulse burst is also present. However, the logical inverse of the commands is not transmitted. Instead, the packet contents are just placed at the end of the packet and the rest of the packet is filled with zeroes. This causes incompatibilities with decoders that do strictly follow the NEC protocol.

crankyoldgit commented 8 months ago

Hey @StachRedeker due to backward compatibility with the original IRremote library, the way sendNEC() won't be changed. It also means sendNEC() can send more than plain/simple/boring NEC messages. The data used & returned by sendNEC() and decodeNEC() are not the same data as the NEC protocol's address & command values per manufacturer tables etc. To convert, you will need to use the encodeNEC() function. See: https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/classIRsend.html#ab2e1ce918e4e06b955c3d2a089ce189c

Per your example, you'd use: sendNEC(encodeNEC(0,1)); & sendNEC(encodeNEC(0,13));