ESPHome 2026.5.1
Loading...
Searching...
No Matches
magiquest_protocol.cpp
Go to the documentation of this file.
2#include "esphome/core/log.h"
3
4/* Based on protocol analysis from
5 * https://arduino-irremote.github.io/Arduino-IRremote/ir__MagiQuest_8cpp_source.html
6 */
7
8namespace esphome::remote_base {
9
10static const char *const TAG = "remote.magiquest";
11
12static constexpr uint32_t MAGIQUEST_UNIT = 288; // us
13static constexpr uint32_t MAGIQUEST_ONE_MARK = 2 * MAGIQUEST_UNIT;
14static constexpr uint32_t MAGIQUEST_ONE_SPACE = 2 * MAGIQUEST_UNIT;
15static constexpr uint32_t MAGIQUEST_ZERO_MARK = MAGIQUEST_UNIT;
16static constexpr uint32_t MAGIQUEST_ZERO_SPACE = 3 * MAGIQUEST_UNIT;
17
19 dst->reserve(101); // 2 start bits, 48 data bits, 1 stop bit
20 dst->set_carrier_frequency(38000);
21
22 // 2 start bits
23 dst->item(MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE);
24 dst->item(MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE);
25 for (uint32_t mask = 1 << 31; mask; mask >>= 1) {
26 if (data.wand_id & mask) {
27 dst->item(MAGIQUEST_ONE_MARK, MAGIQUEST_ONE_SPACE);
28 } else {
29 dst->item(MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE);
30 }
31 }
32
33 for (uint16_t mask = 1 << 15; mask; mask >>= 1) {
34 if (data.magnitude & mask) {
35 dst->item(MAGIQUEST_ONE_MARK, MAGIQUEST_ONE_SPACE);
36 } else {
37 dst->item(MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE);
38 }
39 }
40
41 dst->mark(MAGIQUEST_UNIT);
42}
43optional<MagiQuestData> MagiQuestProtocol::decode(RemoteReceiveData src) {
44 MagiQuestData data{
45 .magnitude = 0,
46 .wand_id = 0,
47 };
48 // Two start bits
49 if (!src.expect_item(MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE) ||
50 !src.expect_item(MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE)) {
51 return {};
52 }
53
54 for (uint32_t mask = 1 << 31; mask; mask >>= 1) {
55 if (src.expect_item(MAGIQUEST_ONE_MARK, MAGIQUEST_ONE_SPACE)) {
56 data.wand_id |= mask;
57 } else if (src.expect_item(MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE)) {
58 data.wand_id &= ~mask;
59 } else {
60 return {};
61 }
62 }
63
64 for (uint16_t mask = 1 << 15; mask; mask >>= 1) {
65 if (src.expect_item(MAGIQUEST_ONE_MARK, MAGIQUEST_ONE_SPACE)) {
66 data.magnitude |= mask;
67 } else if (src.expect_item(MAGIQUEST_ZERO_MARK, MAGIQUEST_ZERO_SPACE)) {
68 data.magnitude &= ~mask;
69 } else {
70 return {};
71 }
72 }
73
74 src.expect_mark(MAGIQUEST_UNIT);
75 return data;
76}
78 ESP_LOGI(TAG, "Received MagiQuest: wand_id=0x%08" PRIX32 ", magnitude=0x%04X", data.wand_id, data.magnitude);
79}
80
81} // namespace esphome::remote_base
void dump(const MagiQuestData &data) override
void encode(RemoteTransmitData *dst, const MagiQuestData &data) override
optional< MagiQuestData > decode(RemoteReceiveData src) override
bool expect_item(uint32_t mark, uint32_t space)
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