Arduino PulseWire Transceiver Library
Loading...
Searching...
No Matches
ManchesterCodec.h
1#pragma once
2#include "assert.h"
3#include "pulse/SignalBase.h"
4#include "pulse/codecs/Codec.h"
5#include "pulse/tools/Vector.h"
6
7namespace pulsewire {
8
20class ManchesterCodec : public Codec {
21 public:
22 ManchesterCodec() = default;
23
24 ManchesterCodec(Preamble& preambleDetector) : Codec(preambleDetector) {}
25
26 CodecEnum getCodecType() const override { return CodecEnum::Manchester; }
27
28 bool begin(uint32_t bitFrequencyHz) override {
29 // Set up default preamble if still using the built-in one
30 if (_preamble == &_defaultPreamble) {
31 _defaultPreamble.clear();
32 uint32_t halfBit = (1000000UL / bitFrequencyHz) / 2;
33 _defaultPreamble.addEdge(true, halfBit); // single HIGH idle edge
34 }
35 return Codec::begin(bitFrequencyHz);
36 }
37
50 bool decodeEdge(uint32_t durationUs, bool level, uint8_t& result) override {
51 // // Filter idle gaps
52 // if (durationUs > _bitPeriodUs * 2) {
53 // reset();
54 // return false;
55 // }
56
57 int edgePeriod = 0.45f * _bitPeriodUs;
58 int edgeCount = durationUs / edgePeriod;
59 if (edgeCount < 1) edgeCount = 1;
60 if (edgeCount > 4) edgeCount = 4;
61 int avg_period = durationUs / edgeCount;
62
63 bool valid = false;
64 for (int i = 0; i < edgeCount; ++i) {
65 if (Codec::decodeEdge(avg_period, level, result)) {
66 valid = true;
67 }
68 }
69 return valid;
70 }
71
72 int getEndOfFrameDelayUs() override { return 16 * _bitPeriodUs; }
73
74 protected:
78 size_t getEdgeCount() const override { return 16; }
79
88 size_t encodeBit(bool bit, Vector<OutputEdge>& output) override {
89 // Manchester: each bit is two pulses
90 OutputEdge first, second;
91 if (bit) {
92 first.level = true; // HIGH
93 first.pulseUs = _bitPeriodUs / 2;
94 second.level = false; // LOW
95 second.pulseUs = _bitPeriodUs / 2;
96 } else {
97 first.level = false; // LOW
98 first.pulseUs = _bitPeriodUs / 2;
99 second.level = true; // HIGH
100 second.pulseUs = _bitPeriodUs / 2;
101 }
102 output.push_back(first);
103 output.push_back(second);
104 return 2;
105 }
106
107 bool decodeByte(Vector<OutputEdge>& edges, uint8_t& result) override {
108 assert(edges.size() == getEdgeCount());
109 bool valid = true;
110
111 uint8_t& byte = result;
112 byte = 0;
113
114 for (int i = 0; i < 8; ++i) {
115 bool b0 = edges[i * 2].level;
116 bool b1 = edges[i * 2 + 1].level;
117
118 if (b0 == 1 && b1 == 0) {
119 byte |= (1 << (7 - i)); // Set bit to 1
120 } else if (b0 == 0 && b1 == 1) {
121 // Bit is 0, do nothing
122 } else {
123 valid = false; // Invalid Manchester pair
124 Logger::error("Invalid Manchester pair at bit %d: b0=%d, b1=%d", i, b0,
125 b1);
126 break;
127 }
128 }
129
130 return valid;
131 }
132};
133
134} // namespace pulsewire
Abstract base class for IR protocol encoding and decoding.
Definition Codec.h:41
virtual bool decodeEdge(uint32_t durationUs, bool level, uint8_t &result)
Edge-based decoding for protocol-agnostic RX drivers.
Definition Codec.h:106
virtual bool begin(uint32_t bitFrequencyHz)
initialization method for codecs that require setup before use (e.g., loading PIO programs,...
Definition Codec.h:56
static void error(const char *format,...)
Log an error message with formatting.
Definition Logger.h:37
Manchester encoding/decoding utility class for IR communication.
bool decodeEdge(uint32_t durationUs, bool level, uint8_t &result) override
Decode incoming edges to reconstruct bytes. Handles multiple edges per bit for noise tolerance by ave...
size_t encodeBit(bool bit, Vector< OutputEdge > &output) override
Fill output vector with Manchester OutputSpec(s) for a bit.
bool decodeByte(Vector< OutputEdge > &edges, uint8_t &result) override
Decode edges into a byte.
int getEndOfFrameDelayUs() override
Provide the end of frame delay in microseconds for this protocol, used by RX driver to.
CodecEnum getCodecType() const override
instance.
size_t getEdgeCount() const override
Get the number of edges used to encode a byte (16 for Manchester).
bool begin(uint32_t bitFrequencyHz) override
initialization method for codecs that require setup before use (e.g., loading PIO programs,...
Abstract base class for preamble detection and generation.
Definition Preamble.h:40
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