Arduino PulseWire Transceiver Library
Loading...
Searching...
No Matches
DifferentialManchesterCodec.h
1#pragma once
2#include "ManchesterCodec.h"
3
4namespace pulsewire {
5
15 public:
16 DifferentialManchesterCodec(Preamble& preambleDetector)
17 : ManchesterCodec(preambleDetector) {}
18
19 bool begin(uint32_t bitFrequencyHz) override {
20 _lastLevelEncode = getIdleLevel();
21 return ManchesterCodec::begin(bitFrequencyHz);
22 }
23
24 CodecEnum getCodecType() const override {
25 return CodecEnum::DifferentialManchester;
26 }
27
28 protected:
29 bool _lastLevelEncode = false;
30 bool _lastLevelDecode = false;
31
32 // Differential Manchester: each bit is two pulses, but encoding depends on
33 // previous level
34 size_t encodeBit(bool bit, Vector<OutputEdge>& output) {
35 OutputEdge first, second;
36
37 if (bit) {
38 // No transition at start, transition in middle
39 first.level = _lastLevelEncode;
40 first.pulseUs = _bitPeriodUs / 2;
41 _lastLevelEncode = !_lastLevelEncode;
42 second.level = _lastLevelEncode;
43 second.pulseUs = _bitPeriodUs / 2;
44 } else {
45 // Transition at start, transition in middle
46 _lastLevelEncode = !_lastLevelEncode;
47 first.level = _lastLevelEncode;
48 first.pulseUs = _bitPeriodUs / 2;
49 _lastLevelEncode = !_lastLevelEncode;
50 second.level = _lastLevelEncode;
51 second.pulseUs = _bitPeriodUs / 2;
52 }
53 output.push_back(first);
54 output.push_back(second);
55 return 2;
56 }
57
58 bool decodeByte(Vector<OutputEdge>& edges, uint8_t& result) {
59 // Defensive: check edge count
60 if (edges.size() != getEdgeCount()) return false;
61 uint8_t& byte = result;
62 byte = 0;
63
64 // MSB first: bit 7 is first
65 for (int i = 0; i < 8; ++i) {
66 bool b0 = edges[i * 2].level;
67 bool b1 = edges[i * 2 + 1].level;
68
69 // Differential Manchester: transition at start = 0, no transition = 1
70 bool transitionAtStart = (b0 != _lastLevelDecode);
71 if (!transitionAtStart) {
72 byte |= (1 << (7 - i));
73 }
74 // Update lastLevel for next bit (end of this bit period)
75 _lastLevelDecode = b1;
76 }
77 // Update _lastLevel for next decode
78 return true;
79 }
80
81 void reset() override {
83 _lastLevelEncode = getIdleLevel();
84 _lastLevelDecode = getIdleLevel();
85 }
86
87 bool getIdleLevel() const override {
88 return false; // Idle state is LOW
89 }
90
91};
92
93} // namespace pulsewire
virtual void reset()
Reset the internal state of the codec.
Definition Codec.h:84
Differential Manchester encoding/decoding utility class for IR communication.
bool begin(uint32_t bitFrequencyHz) override
initialization method for codecs that require setup before use (e.g., loading PIO programs,...
void reset() override
Reset the internal state of the codec.
bool getIdleLevel() const override
Provides the initial ldle state (low or hith)
Manchester encoding/decoding utility class for IR communication.
bool begin(uint32_t bitFrequencyHz) override
initialization method for codecs that require setup before use (e.g., loading PIO programs,...
size_t getEdgeCount() const override
Get the number of edges used to encode a byte (16 for Manchester).
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
Specifies a single IR signal segment for protocol-agnostic transmission.
Definition Preamble.h:23