-
Notifications
You must be signed in to change notification settings - Fork 839
/
Copy pathir_Multibrackets.cpp
115 lines (103 loc) · 4.14 KB
/
ir_Multibrackets.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Copyright 2020 David Conran
/// @file
/// @brief Support for Multibrackets protocols.
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1103
/// @see http://info.multibrackets.com/data/common/manuals/4500_code.pdf
// Supports:
// Brand: Multibrackets, Model: Motorized Swing mount large - 4500
#include "IRrecv.h"
#include "IRsend.h"
const uint16_t kMultibracketsTick = 5000; // uSeconds
const uint16_t kMultibracketsHdrMark = 3 * kMultibracketsTick; // uSeconds
const uint16_t kMultibracketsFooterSpace = 6 * kMultibracketsTick; // uSeconds
const uint8_t kMultibracketsTolerance = 5; // Percent
const uint16_t kMultibracketsFreq = 38000; // Hertz
#if SEND_MULTIBRACKETS
/// Send a Multibrackets formatted message.
/// Status: BETA / Appears to be working.
/// @param[in] data The message to be sent.
/// @param[in] nbits The number of bits of message to be sent.
/// @param[in] repeat The number of times the command is to be repeated.
void IRsend::sendMultibrackets(uint64_t data, uint16_t nbits, uint16_t repeat) {
enableIROut(kMultibracketsFreq);
for (uint16_t r = 0; r <= repeat; r++) {
uint16_t bits = nbits;
// Header
mark(kMultibracketsHdrMark);
// Data
// Send 0's until we get down to a bit size we can actually manage.
while (bits > sizeof(data) * 8) {
space(kMultibracketsTick);
bits--;
}
// Send the supplied data.
for (uint64_t mask = 1ULL << (bits - 1); mask; mask >>= 1)
if (data & mask) // Send a 1
mark(kMultibracketsTick);
else // Send a 0
space(kMultibracketsTick);
// Footer
space(kMultibracketsFooterSpace);
}
}
#endif // SEND_MULTIBRACKETS
#if DECODE_MULTIBRACKETS
/// Decode the Multibrackets message.
/// Status: BETA / Appears to be working.
/// @param[in,out] results Ptr to the data to decode & where to store the result
/// @param[in] offset The starting index to use when attempting to decode the
/// raw data. Typically/Defaults to kStartOffset.
/// @param[in] nbits The number of data bits to expect.
/// @param[in] strict Flag indicating if we should perform strict matching.
/// @return True if it can decode it, false if it can't.
bool IRrecv::decodeMultibrackets(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
// Compliance
if (strict && nbits != kMultibracketsBits)
return false; // Doesn't match our protocol defn.
// Check there is enough unprocessed buffer left.
if (results->rawlen < offset) return false;
// Header
int32_t remaining = *(results->rawbuf + offset);
if (!matchAtLeast(remaining, kMultibracketsHdrMark, kMultibracketsTolerance))
return false;
remaining -= (kMultibracketsHdrMark / kRawTick); // Remove the header.
// We are done with the header. Onto the data.
bool bit = true;
uint16_t bitsSoFar = 0;
uint64_t data = 0;
// Keep going till we run out of message or expected bits.
while (offset <= results->rawlen && bitsSoFar < nbits) {
// Have we finished processing this rawbuf value yet?
if (remaining <= 0) { // No more possible "bits" left in this value.
// Invert the bit for next time, and move along the rawbuf.
bit = !bit;
offset++;
// Load the next data point if there is one.
if (offset <= results->rawlen) remaining = *(results->rawbuf + offset);
} else { // Look for more bits in this entry.
if (matchAtLeast(remaining, kMultibracketsTick,
kMultibracketsTolerance)) { // There is!
data <<= 1;
data += bit;
bitsSoFar++;
}
remaining -= (kMultibracketsTick / kRawTick); // Remove the "bit".
}
}
// Compliance
if (bitsSoFar != nbits) return false;
// Footer
if (results->rawlen <= offset && !matchAtLeast(*(results->rawbuf + offset),
kMultibracketsFooterSpace,
kMultibracketsTolerance))
return false;
// Success
results->decode_type = decode_type_t::MULTIBRACKETS;
results->value = data;
results->bits = nbits;
results->address = 0;
results->command = 0;
return true;
}
#endif // DECODE_MULTIBRACKETS