ESPHome 2026.5.0b1
Loading...
Searching...
No Matches
nec_protocol.cpp
Go to the documentation of this file.
1#include "nec_protocol.h"
2#include "esphome/core/log.h"
3
4namespace esphome::remote_base {
5
6static const char *const TAG = "remote.nec";
7
8static constexpr uint32_t HEADER_HIGH_US = 9000;
9static constexpr uint32_t HEADER_LOW_US = 4500;
10static constexpr uint32_t BIT_HIGH_US = 560;
11static constexpr uint32_t BIT_ONE_LOW_US = 1690;
12static constexpr uint32_t BIT_ZERO_LOW_US = 560;
13
15 ESP_LOGD(TAG, "Sending NEC: address=0x%04X, command=0x%04X command_repeats=%d", data.address, data.command,
16 data.command_repeats);
17
18 dst->reserve(2 + 32 + 32 * data.command_repeats + 2);
19 dst->set_carrier_frequency(38000);
20
21 dst->item(HEADER_HIGH_US, HEADER_LOW_US);
22
23 for (uint16_t mask = 1; mask; mask <<= 1) {
24 if (data.address & mask) {
25 dst->item(BIT_HIGH_US, BIT_ONE_LOW_US);
26 } else {
27 dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US);
28 }
29 }
30
31 for (uint16_t repeats = 0; repeats < data.command_repeats; repeats++) {
32 for (uint16_t mask = 1; mask; mask <<= 1) {
33 if (data.command & mask) {
34 dst->item(BIT_HIGH_US, BIT_ONE_LOW_US);
35 } else {
36 dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US);
37 }
38 }
39 }
40
41 dst->mark(BIT_HIGH_US);
42}
43optional<NECData> NECProtocol::decode(RemoteReceiveData src) {
44 NECData data{
45 .address = 0,
46 .command = 0,
47 .command_repeats = 1,
48 };
49 if (!src.expect_item(HEADER_HIGH_US, HEADER_LOW_US))
50 return {};
51
52 for (uint16_t mask = 1; mask; mask <<= 1) {
53 if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) {
54 data.address |= mask;
55 } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) {
56 data.address &= ~mask;
57 } else {
58 return {};
59 }
60 }
61
62 for (uint16_t mask = 1; mask; mask <<= 1) {
63 if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) {
64 data.command |= mask;
65 } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) {
66 data.command &= ~mask;
67 } else {
68 return {};
69 }
70 }
71
72 while (src.peek_item(BIT_HIGH_US, BIT_ONE_LOW_US) || src.peek_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) {
73 uint16_t command = 0;
74 for (uint16_t mask = 1; mask; mask <<= 1) {
75 if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) {
76 command |= mask;
77 } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) {
78 command &= ~mask;
79 } else {
80 return {};
81 }
82 }
83
84 // Make sure the extra/repeated data matches original command
85 if (command != data.command) {
86 return {};
87 }
88
89 data.command_repeats += 1;
90 }
91
92 src.expect_mark(BIT_HIGH_US);
93 return data;
94}
95void NECProtocol::dump(const NECData &data) {
96 ESP_LOGI(TAG, "Received NEC: address=0x%04X, command=0x%04X command_repeats=%d", data.address, data.command,
97 data.command_repeats);
98}
99
100} // namespace esphome::remote_base
void dump(const NECData &data) override
void encode(RemoteTransmitData *dst, const NECData &data) override
optional< NECData > decode(RemoteReceiveData src) override
bool expect_item(uint32_t mark, uint32_t space)
bool peek_item(uint32_t mark, uint32_t space, uint32_t offset=0) const
Definition remote_base.h:70
void set_carrier_frequency(uint32_t carrier_frequency)
Definition remote_base.h:29
void item(uint32_t mark, uint32_t space)
Definition remote_base.h:24
static void uint32_t