ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
somfy_rts_protocol.cpp
Go to the documentation of this file.
2#include "esphome/core/log.h"
3
4namespace esphome::remote_base {
5
6// Timings from https://pushstack.wordpress.com/somfy-rts-protocol/
7static constexpr uint8_t FRAME_SIZE_IN_BYTES = 7;
8static constexpr uint16_t HALF_BIT_US = 604;
9
10static constexpr uint16_t WAKEUP_HIGH_US = 9415;
11static constexpr uint32_t WAKEUP_LOW_US = 89565;
12
13static constexpr uint16_t HW_SYNC_US = 2560;
14
15static constexpr uint16_t SW_SYNC_HIGH_US = 4550;
16static constexpr uint16_t SW_SYNC_LOW_US = HALF_BIT_US;
17
18// Wakeup, two hardware syncs and a software sync (8), two entries per bit (112)
19static constexpr uint32_t FRAME_ENTRIES = 8 + FRAME_SIZE_IN_BYTES * 8 * 2;
20
22 dst->reserve(FRAME_ENTRIES);
24 dst->item(WAKEUP_HIGH_US, WAKEUP_LOW_US);
25 dst->item(HW_SYNC_US, HW_SYNC_US);
26 dst->item(HW_SYNC_US, HW_SYNC_US);
27 dst->item(SW_SYNC_HIGH_US, SW_SYNC_LOW_US);
28
29 uint8_t frame[FRAME_SIZE_IN_BYTES];
30 // Some non standard remotes put the control nibble in the key byte and send 0xF in the control nibble
31 if (data.control_in_key) {
32 frame[0] = (data.key & 0xF0) | (data.control & 0x0F);
33 frame[1] = 0xF0;
34 } else {
35 frame[0] = data.key;
36 frame[1] = (data.control & 0x0F) << 4;
37 }
38 frame[2] = data.rolling_code >> 8;
39 frame[3] = data.rolling_code;
40 frame[4] = data.address >> 16;
41 frame[5] = data.address >> 8;
42 frame[6] = data.address;
43
44 uint8_t crc = 0;
45 for (uint8_t data_byte : frame) {
46 crc ^= (data_byte >> 4) ^ (data_byte & 0xF);
47 }
48 frame[1] |= (crc & 0x0F);
49
50 for (uint8_t i = 1; i < FRAME_SIZE_IN_BYTES; i++) {
51 frame[i] ^= frame[i - 1];
52 }
53
54 // Manchester, MSB first: a 1 is space then mark, a 0 is mark then space. Frames repeat with
55 // the 30 ms gap through the action's repeat option, not inside the frame.
56 for (uint8_t data_byte : frame) {
57 for (int8_t y = 7; y >= 0; y--) {
58 if (data_byte & (1 << y)) {
59 dst->space(HALF_BIT_US);
60 dst->mark(HALF_BIT_US);
61 } else {
62 dst->mark(HALF_BIT_US);
63 dst->space(HALF_BIT_US);
64 }
65 }
66 }
67}
68
69} // namespace esphome::remote_base
void set_carrier_frequency(uint32_t carrier_frequency)
Definition remote_base.h:31
void item(uint32_t mark, uint32_t space)
Definition remote_base.h:26
void encode(RemoteTransmitData *dst, const SomfyRtsData &data)
static void uint32_t
uint16_t y
Definition tt21100.cpp:6