2#include "codecs/PulseDistanceCodec.h"
3#include "codecs/PulseWidthCodec.h"
4#include "codecs/ManchesterCodec.h"
5#include "codecs/NRZCodec.h"
7#include "codecs/Codec.h"
8#include "tools/Vector.h"
14enum class IRProtocolEnum {
43const char* toStr(IRProtocolEnum protocol) {
45 case IRProtocolEnum::Custom:
47 case IRProtocolEnum::NEC:
49 case IRProtocolEnum::NEC16:
51 case IRProtocolEnum::NEC42:
53 case IRProtocolEnum::Sony:
55 case IRProtocolEnum::RC5:
57 case IRProtocolEnum::RC6:
59 case IRProtocolEnum::Denon:
61 case IRProtocolEnum::JVC:
63 case IRProtocolEnum::Sharp:
65 case IRProtocolEnum::Kaseikyo:
67 case IRProtocolEnum::Samsung:
69 case IRProtocolEnum::Samsung48:
71 case IRProtocolEnum::Whynter:
73 case IRProtocolEnum::Apple:
75 case IRProtocolEnum::Onkyo:
77 case IRProtocolEnum::Matsushita:
79 case IRProtocolEnum::Grundig:
81 case IRProtocolEnum::SiemensGigaset:
82 return "Siemens Gigaset";
83 case IRProtocolEnum::Nokia:
85 case IRProtocolEnum::Thomson:
87 case IRProtocolEnum::Telefunken:
89 case IRProtocolEnum::Technics:
91 case IRProtocolEnum::Manchester:
128 size_t dataLength, uint32_t shortPulse, uint32_t longPulse,
133 _shortPulseUs(shortPulse),
134 _longPulseUs(longPulse),
135 _toleranceUs(tolerance),
136 _codecType(codecType),
141 if (_codec !=
nullptr) {
149 uint32_t shortPulse, uint32_t longPulse, uint32_t tolerance,
151 CodecEnum codecType = CodecEnum::PulseDistance) {
155 _shortPulseUs = shortPulse;
156 _longPulseUs = longPulse;
157 _toleranceUs = tolerance;
159 for (
const auto& edge : edges) {
160 _edges.push_back(edge);
166 _proto = other._proto;
167 _frequency = other._frequency;
168 _dataLength = other._dataLength;
169 _shortPulseUs = other._shortPulseUs;
170 _longPulseUs = other._longPulseUs;
171 _toleranceUs = other._toleranceUs;
172 _codecType = other._codecType;
174 for (
const auto& edge : other._edges) {
175 _edges.push_back(edge);
182 const char* name()
const {
return toStr(_proto); }
187 for (
auto& edge : _edges) {
190 return _edges.size();
195 virtual uint32_t
frequency()
const {
return _frequency; }
206 if (_codec ==
nullptr) {
207 switch (_codecType) {
208 case CodecEnum::PulseDistance:
211 case CodecEnum::PulseWidth:
214 case CodecEnum::Manchester:
229 IRProtocolEnum _proto = IRProtocolEnum::Unknown;
230 Codec* _codec =
nullptr;
232 uint32_t _frequency = 38000;
233 size_t _dataLength = 4;
235 uint32_t _shortPulseUs = 560;
236 uint32_t _longPulseUs = 1690;
237 uint32_t _toleranceUs = 200;
238 std::vector<OutputEdge> _edges;
239 CodecEnum _codecType;
242static IRProtocol IRProtocolNEC(IRProtocolEnum::NEC, CodecEnum::PulseDistance,
243 38000, 32, 560, 1690, 200,
244 {{
true, 9000}, {
false, 4500}});
245static IRProtocol IRProtocolNEC16(IRProtocolEnum::NEC16, CodecEnum::PulseDistance,
246 38000, 16, 560, 1690, 200,
247 {{
true, 9000}, {
false, 2250}});
248static IRProtocol IRProtocolNEC42(IRProtocolEnum::NEC42, CodecEnum::PulseDistance,
249 38000, 42, 560, 1690, 200,
250 {{
true, 9000}, {
false, 4500}, {
true, 562}, {
false, 562}});
251static IRProtocol IRProtocolSony(IRProtocolEnum::Sony, CodecEnum::PulseWidth,
252 40000, 12, 600, 1200, 200,
254static IRProtocol IRProtocolSamsung(IRProtocolEnum::Samsung, CodecEnum::PulseDistance,
255 38000, 32, 560, 1690, 200,
256 {{
true, 4500}, {
false, 4500}});
257static IRProtocol IRProtocolSamsung48(IRProtocolEnum::Samsung48, CodecEnum::PulseDistance,
258 38000, 48, 560, 1690, 200,
259 {{
true, 4800}, {
false, 4800}});
260static IRProtocol IRProtocolWhynter(IRProtocolEnum::Whynter, CodecEnum::PulseDistance,
261 38000, 32, 560, 1690, 200,
262 {{
true, 2850}, {
false, 2850}});
263static IRProtocol IRProtocolApple(IRProtocolEnum::Apple, CodecEnum::PulseDistance,
264 38000, 32, 560, 1690, 200,
265 {{
true, 9000}, {
false, 4500}});
266static IRProtocol IRProtocolOnkyo(IRProtocolEnum::Onkyo, CodecEnum::PulseDistance,
267 38000, 32, 560, 1690, 200,
268 {{
true, 9000}, {
false, 4500}});
269static IRProtocol IRProtocolMatsushita(IRProtocolEnum::Matsushita, CodecEnum::PulseDistance,
270 37900, 48, 432, 1296, 200,
271 {{
true, 3456}, {
false, 1728}});
272static IRProtocol IRProtocolGrundig(IRProtocolEnum::Grundig, CodecEnum::Manchester,
273 38000, 24, 560, 1690, 200,
274 {{
true, 2600}, {
false, 600}});
275static IRProtocol IRProtocolSiemensGigaset(IRProtocolEnum::SiemensGigaset, CodecEnum::Manchester,
276 38000, 32, 560, 1690, 200,
277 {{
true, 9000}, {
false, 4500}});
278static IRProtocol IRProtocolNokia(IRProtocolEnum::Nokia, CodecEnum::Manchester,
279 38000, 32, 560, 1690, 200,
280 {{
true, 4500}, {
false, 4500}});
281static IRProtocol IRProtocolThomson(IRProtocolEnum::Thomson, CodecEnum::Manchester,
282 38000, 24, 560, 1690, 200,
283 {{
true, 2600}, {
false, 600}});
284static IRProtocol IRProtocolTelefunken(IRProtocolEnum::Telefunken, CodecEnum::Manchester,
285 38000, 24, 560, 1690, 200,
286 {{
true, 2600}, {
false, 600}});
287static IRProtocol IRProtocolTechnics(IRProtocolEnum::Technics, CodecEnum::Manchester,
288 37900, 48, 432, 1296, 200,
289 {{
true, 3456}, {
false, 1728}});
290static IRProtocol IRProtocolJVC(IRProtocolEnum::JVC, CodecEnum::PulseDistance,
291 38000, 32, 525, 1575, 200,
292 {{
true, 8400}, {
false, 4200}});
293static IRProtocol IRProtocolSharp(IRProtocolEnum::Sharp, CodecEnum::PulseDistance,
294 38000, 32, 320, 1600, 200,
295 {{
true, 3200}, {
false, 1600}});
296static IRProtocol IRProtocolKaseikyo(IRProtocolEnum::Kaseikyo, CodecEnum::PulseDistance,
297 37900, 48, 432, 1296, 200,
298 {{
true, 3456}, {
false, 1728}});
299static IRProtocol IRProtocolDenon(IRProtocolEnum::Denon, CodecEnum::PulseDistance,
300 38000, 24, 425, 1275, 200,
301 {{
true, 2600}, {
false, 500}});
319 _preambles.push_back(&IRProtocolNEC);
320 _preambles.push_back(&IRProtocolNEC16);
321 _preambles.push_back(&IRProtocolNEC42);
322 _preambles.push_back(&IRProtocolSony);
323 _preambles.push_back(&IRProtocolSamsung);
324 _preambles.push_back(&IRProtocolSamsung48);
325 _preambles.push_back(&IRProtocolWhynter);
326 _preambles.push_back(&IRProtocolApple);
327 _preambles.push_back(&IRProtocolOnkyo);
328 _preambles.push_back(&IRProtocolMatsushita);
329 _preambles.push_back(&IRProtocolGrundig);
330 _preambles.push_back(&IRProtocolSiemensGigaset);
331 _preambles.push_back(&IRProtocolNokia);
332 _preambles.push_back(&IRProtocolThomson);
333 _preambles.push_back(&IRProtocolTelefunken);
334 _preambles.push_back(&IRProtocolTechnics);
335 _preambles.push_back(&IRProtocolJVC);
336 _preambles.push_back(&IRProtocolSharp);
337 _preambles.push_back(&IRProtocolKaseikyo);
338 _preambles.push_back(&IRProtocolDenon);
341 setActualProtocol(defaultInfo);
359 uint32_t shortPulse, uint32_t longPulse, uint32_t tolerance,
360 Vector<OutputEdge> edges) {
366 for (
size_t i = 0;
i < _preambles.
size(); ++
i) {
368 IRProtocolEnum _proto = _preambles[
i]->getProtocolID();
369 if (_callback) _callback(_proto, *_preambles[
i], _ref);
389 for (
size_t i = 0;
i < _preambles.
size(); ++
i) {
391 return *_preambles[
i];
400 for (
size_t i = 0;
i < _preambles.
size(); ++
i) {
402 _preambles[
i] = &protocol;
409 void setActualProtocol(IRProtocol& proto) {
411 if (_preambles[0] != &proto) {
412 _preambles.insert(_preambles.
begin(), _refInfo);
417 IRProtocol* _refInfo = &IRProtocolNEC;
418 Vector<IRProtocol*> _preambles;
419 void (*_callback)(IRProtocolEnum, IRProtocol&,
void* ref) =
nullptr;
420 void* _ref =
nullptr;
Abstract base class for IR protocol encoding and decoding.
IRMultiProtocol: Handles detection and delegation for multiple IR protocols.
IRProtocol & getProtocol() const
Provides the active protocol.
IRProtocol & getProtocolByID(IRProtocolEnum proto) const
Provides a protocol by its enum ID, or a default if not found.
uint32_t toleranceUs() const
Tolerance in microseconds for pulse duration matching during detection.
size_t preambleLength() const override
Returns the number of edges in the preamble.
void setCallback(void(*callback)(IRProtocolEnum, IRProtocol &, void *ref), void *ref)
uint32_t frequency() const
Returns the carrier frequency in Hz.
size_t dataLength() const
Returns the expected data length in bytes (not including preamble)
uint32_t shortPulseUs() const
Returns the duration of the short pulse in microseconds.
uint32_t longPulseUs() const
Returns the duration of the long pulse in microseconds.
int getEdges(Vector< OutputEdge > &output) const override
Returns the preamble edges for this protocol.
IRProtocolEnum getProtocolID() const override
Returns the protocol enum identifier for this IR protocol.
bool detect(const OutputEdge &edge) override
Detects if the incoming edge matches the expected preamble pattern.
IRProtocol: Represents a specific IR protocol with all its parameters.
virtual Codec & codec()
Provides the codec associated with this protocol.
virtual size_t preambleLength() const override
Returns the number of edges in the preamble.
void begin(IRProtocolEnum proto, uint32_t frequency, size_t dataLength, uint32_t shortPulse, uint32_t longPulse, uint32_t tolerance, Vector< OutputEdge > edges, CodecEnum codecType=CodecEnum::PulseDistance)
Set all fields for this IR protocol, including preamble edges.
void copyFrom(const IRProtocol &other)
Copy all fields from another IRProtocol instance.
virtual size_t dataLength() const
Returns the expected data length in bytes (not including preamble)
virtual uint32_t frequency() const
Returns the carrier frequency in Hz.
virtual int getEdges(Vector< OutputEdge > &output) const override
Returns the preamble edges for this protocol.
virtual IRProtocolEnum getProtocolID() const
Returns the protocol enum identifier for this IR protocol.
virtual uint32_t shortPulseUs() const
Returns the duration of the short pulse in microseconds.
virtual uint32_t toleranceUs() const
Tolerance in microseconds for pulse duration matching during detection.
virtual uint32_t longPulseUs() const
Returns the duration of the long pulse in microseconds.
Manchester encoding/decoding utility class for IR communication.
NRZ (Non-Return-to-Zero) codec for serial-like encoding/decoding with start/stop bit framing.
Abstract base class for preamble detection and generation.
Pulse-distance encoding/decoding utility class for IR communication.
Pulse-width encoding/decoding utility class for IR communication.
Small, header-only vector replacement for non-STL environments.
iterator begin()
Iterator to first element.
void clear()
Remove all elements.
void push_back(const T &value)
Add element to end of vector.
size_t size() const
Number of elements in vector.
Specifies a single IR signal segment for protocol-agnostic transmission.