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 // Differential Manchester: each bit is two pulses, but encoding depends on
30 // previous level
31 size_t encodeBit(bool bit, Vector<OutputEdge>& output) override {
32 OutputEdge first, second;
33
34 if (bit) {
35 // No transition at start, transition in middle
36 first.level = _lastLevelEncode;
37 first.pulseUs = _bitPeriodUs / 2;
38 _lastLevelEncode = !_lastLevelEncode;
39 second.level = _lastLevelEncode;
40 second.pulseUs = _bitPeriodUs / 2;
41 } else {
42 // Transition at start, transition in middle
43 _lastLevelEncode = !_lastLevelEncode;
44 first.level = _lastLevelEncode;
45 first.pulseUs = _bitPeriodUs / 2;
46 _lastLevelEncode = !_lastLevelEncode;
47 second.level = _lastLevelEncode;
48 second.pulseUs = _bitPeriodUs / 2;
49 }
50 output.push_back(first);
51 output.push_back(second);
52 return 2;
53 }
54
55 bool decodeByte(Vector<OutputEdge>& edges, uint8_t& result) override {
56 // Defensive: check edge count
57 if (edges.size() != getEdgeCount()) return false;
58 uint8_t& byte = result;
59 byte = 0;
60
61 // MSB first: bit 7 is first
62 for (int i = 0; i < 8; ++i) {
63 bool b0 = edges[i * 2].level;
64 bool b1 = edges[i * 2 + 1].level;
65
66 // Differential Manchester: transition at start = 0, no transition = 1
67 bool transitionAtStart = (b0 != _lastLevelDecode);
68 if (!transitionAtStart) {
69 byte |= (1 << (7 - i));
70 }
71 // Update lastLevel for next bit (end of this bit period)
72 _lastLevelDecode = b1;
73 }
74 // Update _lastLevel for next decode
75 return true;
76 }
77
78 void reset() override {
79 ManchesterCodec::reset();
80 _lastLevelEncode = getIdleLevel();
81 _lastLevelDecode = getIdleLevel();
82 }
83
84 bool getIdleLevel() const override {
85 return false; // Idle state is LOW
86 }
87
88 protected:
89 bool _lastLevelEncode = false;
90 bool _lastLevelDecode = false;
91};
92
93} // namespace pulsewire
Differential Manchester encoding/decoding utility class for IR communication.
size_t encodeBit(bool bit, Vector< OutputEdge > &output) override
Fill output vector with protocol-specific OutputSpec(s) for a bit.
bool getIdleLevel() const override
Provides the initial ldle state (low or hith)
bool decodeByte(Vector< OutputEdge > &edges, uint8_t &result) override
Decode edges into a byte.
CodecEnum getCodecType() const override
instance.
bool begin(uint32_t bitFrequencyHz) override
initialization method for codecs that require setup before use (e.g., loading PIO programs,...
Manchester encoding/decoding utility class for IR communication.
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