ESPHome 2026.6.0-dev
Loading...
Searching...
No Matches
byronsx_protocol.cpp
Go to the documentation of this file.
1#include "byronsx_protocol.h"
2#include "esphome/core/log.h"
3
4#include <cinttypes>
5
6namespace esphome::remote_base {
7
8static const char *const TAG = "remote.byronsx";
9
10static constexpr uint32_t BIT_TIME_US = 333;
11static constexpr uint8_t NBITS_ADDRESS = 8;
12static constexpr uint8_t NBITS_COMMAND = 4;
13static constexpr uint8_t NBITS_START_BIT = 1;
14static constexpr uint8_t NBITS_DATA = NBITS_ADDRESS + NBITS_COMMAND /*+ NBITS_COMMAND*/;
15
16/*
17ByronSX Protocol
18Each transmitted packet appears to consist of thirteen bits of PWM encoded
19data. Each bit period of aprox 1ms consists of a transmitter OFF period
20followed by a transmitter ON period. The 'on' and 'off' periods are either
21short (approx 332us) or long (664us).
22
23A short 'off' followed by a long 'on' represents a '1' bit.
24A long 'off' followed by a short 'on' represents a '0' bit.
25
26A the beginning of each packet is and initial 'off' period of approx 5.6ms
27followed by a short 'on'.
28
29The data payload consists of twelve bits which appear to be an eight bit
30address floowied by a 4 bit chime number.
31
32SAAAAAAAACCCC
33
34Whese:
35S = the initial short start pulse
36A = The eight address bits
37C - The four chime bits
38
39--------------------
40
41I have also used 'RFLink' software (RLink Firmware Version: 1.1 Revision: 48)
42to capture these packets, eg:
43
4420;19;Byron;ID=004f;SWITCH=02;CMD=ON;CHIME=02;
45
46This module transmits and interprets packets in the same way as RFLink.
47
48marshn
49
50*/
51
53 uint32_t out_data = 0x0;
54
55 ESP_LOGD(TAG, "Send ByronSX: address=%04x command=%03x", data.address, data.command);
56
57 out_data = data.address;
58 out_data <<= NBITS_COMMAND;
59 out_data |= data.command;
60
61 ESP_LOGV(TAG, "Send ByronSX: out_data %03" PRIx32, out_data);
62
63 // Initial Mark start bit
64 dst->mark(1 * BIT_TIME_US);
65
66 for (uint32_t mask = 1UL << (NBITS_DATA - 1); mask != 0; mask >>= 1) {
67 if (out_data & mask) {
68 dst->space(2 * BIT_TIME_US);
69 dst->mark(1 * BIT_TIME_US);
70 } else {
71 dst->space(1 * BIT_TIME_US);
72 dst->mark(2 * BIT_TIME_US);
73 }
74 }
75 // final space at end of packet
76 dst->space(17 * BIT_TIME_US);
77}
78
80 ByronSXData out{
81 .address = 0,
82 .command = 0,
83 };
84
85 if (src.size() != (NBITS_DATA + NBITS_START_BIT) * 2) {
86 return {};
87 }
88
89 // Skip start bit
90 if (!src.expect_mark(BIT_TIME_US)) {
91 return {};
92 }
93
94 ESP_LOGVV(TAG,
95 "%3" PRId32 ": %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32
96 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32
97 " %" PRId32 " %" PRId32 " %" PRId32,
98 src.size(), src.peek(0), src.peek(1), src.peek(2), src.peek(3), src.peek(4), src.peek(5), src.peek(6),
99 src.peek(7), src.peek(8), src.peek(9), src.peek(10), src.peek(11), src.peek(12), src.peek(13), src.peek(14),
100 src.peek(15), src.peek(16), src.peek(17), src.peek(18), src.peek(19));
101
102 ESP_LOGVV(TAG, " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32, src.peek(20),
103 src.peek(21), src.peek(22), src.peek(23), src.peek(24), src.peek(25));
104
105 // Read data bits
106 uint32_t out_data = 0;
107 int8_t bit = NBITS_DATA;
108 while (--bit >= 0) {
109 if (src.expect_space(2 * BIT_TIME_US) && src.expect_mark(BIT_TIME_US)) {
110 out_data |= 1 << bit;
111 } else if (src.expect_space(BIT_TIME_US) && src.expect_mark(2 * BIT_TIME_US)) {
112 out_data |= 0 << bit;
113 } else {
114 ESP_LOGV(TAG, "Decode ByronSX: Fail 2, %2d %08" PRIx32, bit, out_data);
115 return {};
116 }
117 ESP_LOGVV(TAG, "Decode ByronSX: Data, %2d %08" PRIx32, bit, out_data);
118 }
119
120 // last bit followed by a long space
121 if (!src.peek_space_at_least(BIT_TIME_US)) {
122 ESP_LOGV(TAG, "Decode ByronSX: Fail 4 ");
123 return {};
124 }
125
126 out.command = (uint8_t) (out_data & 0xF);
127 out_data >>= NBITS_COMMAND;
128 out.address = (uint16_t) (out_data & 0xFF);
129
130 return out;
131}
132
134 ESP_LOGD(TAG, "Received ByronSX: address=0x%08X, command=0x%02x", data.address, data.command);
135}
136
137} // namespace esphome::remote_base
void dump(const ByronSXData &data) override
optional< ByronSXData > decode(RemoteReceiveData src) override
void encode(RemoteTransmitData *dst, const ByronSXData &data) override
const void * src
Definition hal.h:64
static void uint32_t