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