Arduino PulseWire Transceiver Library
Loading...
Searching...
No Matches
PulseDistanceCodec.h
1#pragma once
2
3#include <stddef.h>
4#include <stdint.h>
5
6#include "Codec.h"
7#include "pulse/tools/Vector.h"
8
9namespace pulsewire {
10
22class PulseDistanceCodec : public Codec {
23 public:
24 PulseDistanceCodec() = default;
25
26 PulseDistanceCodec(Preamble& detector, uint32_t toleranceUs = 0,
27 uint32_t shortPulseUs = 0, uint32_t longPulseUs = 0)
28 : Codec(detector),
29 _shortPulseUs(shortPulseUs),
30 _longPulseUs(longPulseUs),
31 _toleranceUs(toleranceUs) {}
32
33 // used by ir
34 void init(Preamble& detector, uint32_t shortPulseUs = 0,
35 uint32_t longPulseUs = 0, uint32_t toleranceUs = 0) {
36 setPreamble(detector);
37 _shortPulseUs = shortPulseUs;
38 _longPulseUs = longPulseUs;
39 _toleranceUs = toleranceUs;
40 }
41
42 bool begin(uint32_t bitFrequencyHz) override {
43 Codec::begin(bitFrequencyHz);
44 if (_shortPulseUs == 0) _shortPulseUs = 1000000UL / (bitFrequencyHz * 2);
45 if (_longPulseUs == 0) _longPulseUs = 1000000UL / (bitFrequencyHz / 2);
46 if (_toleranceUs == 0) _toleranceUs = _bitPeriodUs * 0.4;
47
48 _inFrame = false;
49
50 return true;
51 }
52
60 size_t encodeBit(bool bit, Vector<OutputEdge>& output) override {
61 OutputEdge pulse, space;
62 pulse.level = false;
63 pulse.pulseUs = bit ? _longPulseUs : _shortPulseUs;
64 space.level = true;
65 space.pulseUs = _shortPulseUs;
66
67 output.push_back(pulse);
68 output.push_back(space);
69 return 2;
70 }
71
72 size_t getEdgeCount() const override { return 16; }
73
74 int getEndOfFrameDelayUs() override { return 2 * _longPulseUs; }
75
76 CodecEnum getCodecType() const override { return CodecEnum::PulseDistance; }
77
78 bool getIdleLevel() { return true; }
79
80 protected:
81 uint32_t _shortPulseUs = 0;
82 uint32_t _longPulseUs = 0;
83 uint32_t _toleranceUs = 0;
84
85 bool decodeByte(Vector<OutputEdge>& edges, uint8_t& result) override {
86 if (edges.size() < 16) {
87 Logger::error("Not enough edges to decode byte: %d", edges.size());
88 return false;
89 }
90 uint8_t byte = 0;
91 int bit = 0;
92 for (auto& edge : edges) {
93 // only consider low edges
94 if (edge.level == false) {
95 if (bitMatch(edge.pulseUs, true)) {
96 byte |= (1 << (7 - bit));
97 } else if (bitMatch(edge.pulseUs, false)) {
98 // bit is 0
99 } else {
100 Logger::error("Invalid pulse duration for bit %d: %d us", bit,
101 edge.pulseUs);
102 }
103 bit++;
104 }
105 }
106 result = byte;
107 return true;
108 }
109
110 bool bitMatch(uint32_t duration, bool bit) const {
111 uint32_t expected = bit ? _longPulseUs : _shortPulseUs;
112 bool rc = (duration >= expected - _toleranceUs &&
113 duration <= expected + _toleranceUs);
115 "Bit match for bit %d: duration=%d, expected=%d, tolerance=%d, "
116 "match=%s",
117 bit ? 1 : 0, duration, expected, _toleranceUs, rc ? "YES" : "NO");
118 return rc;
119 }
120};
121
122} // namespace pulsewire
Abstract base class for IR protocol encoding and decoding.
Definition Codec.h:41
virtual bool begin(uint32_t bitFrequencyHz)
initialization method for codecs that require setup before use (e.g., loading PIO programs,...
Definition Codec.h:56
void setPreamble(Preamble &preamble)
Set the Preamble Detector object.
Definition Codec.h:84
static void debug(const char *format,...)
Log a debug message with formatting.
Definition Logger.h:82
static void error(const char *format,...)
Log an error message with formatting.
Definition Logger.h:37
Abstract base class for preamble detection and generation.
Definition Preamble.h:40
Pulse-distance encoding/decoding utility class for IR communication.
CodecEnum getCodecType() const override
instance.
bool decodeByte(Vector< OutputEdge > &edges, uint8_t &result) override
Decode edges into a byte.
size_t encodeBit(bool bit, Vector< OutputEdge > &output) override
Fill output vector with PulseDistance OutputSpec(s) for a bit.
bool begin(uint32_t bitFrequencyHz) override
initialization method for codecs that require setup before use (e.g., loading PIO programs,...
void init(Preamble &detector, uint32_t shortPulseUs=0, uint32_t longPulseUs=0, uint32_t toleranceUs=0)
size_t getEdgeCount() const override
Get the number of protocol symbols (bits, pulses, etc.) per encoded byte.
int getEndOfFrameDelayUs() override
Provide the end of frame delay in microseconds for this protocol, used by RX driver to.
Small, header-only vector replacement for non-STL environments.
Definition Vector.h:29
void push_back(const T &value)
Add element to end of vector.
Definition Vector.h:92
size_t size() const
Number of elements in vector.
Definition Vector.h:116
Specifies a single IR signal segment for protocol-agnostic transmission.
Definition Preamble.h:23