Arduino PulseWire Transceiver Library
Loading...
Searching...
No Matches
NRZCodec.h
1#pragma once
2#include "Codec.h"
3
4namespace pulsewire {
5
10class NRZCodec : public Codec {
11 public:
12 NRZCodec(uint8_t stopBits = 1) : _stopBits(stopBits) {}
13
14 NRZCodec(Preamble& preambleDetector, uint8_t stopBits = 1)
15 : Codec(preambleDetector), _stopBits(stopBits) {}
16
17 CodecEnum getCodecType() const override { return CodecEnum::NRZ; }
18
19 bool getIdleLevel() { return true; }
20
21 void setStopBits(uint8_t stopBits) { _stopBits = stopBits; }
22
23 uint8_t getStopBits() const { return _stopBits; }
24
25 bool begin(uint32_t bitFrequencyHz) override {
26 if (_preamble == &_defaultPreamble) {
27 _defaultPreamble.clear();
28 // setup default preamble: alternating edges at full bit period, ending
29 // with a HIGH level to match NRZ idle state
30 uint32_t bp = 1000000UL / bitFrequencyHz;
31 _defaultPreamble.addEdge(false, bp); // single HIGH idle edge
32 _defaultPreamble.addEdge(true, bp); // single HIGH idle edge
33 }
34
35 return Codec::begin(bitFrequencyHz);
36 }
37
38 size_t encode(uint8_t byte, Vector<OutputEdge>& output) override {
39 size_t edgeCount = 0;
40
41 // Start bit (LOW)
42 OutputEdge start;
43 start.level = false;
44 start.pulseUs = _bitPeriodUs;
45 output.push_back(start);
46 ++edgeCount;
47
48 // Data bits (LSB first)
49 for (int bit = 0; bit < 8; ++bit) {
50 OutputEdge data;
51 data.level = (byte & (1 << bit)) != 0;
52 data.pulseUs = _bitPeriodUs;
53 output.push_back(data);
54 ++edgeCount;
55 }
56
57 // Stop bits (HIGH)
58 for (uint8_t s = 0; s < _stopBits; ++s) {
59 OutputEdge stop;
60 stop.level = true;
61 stop.pulseUs = _bitPeriodUs;
62 output.push_back(stop);
63 ++edgeCount;
64 }
65
66 return edgeCount;
67 }
68
69 bool decodeEdge(uint32_t durationUs, bool level, uint8_t& result) override {
70 // Filter idle gaps — full reset
71 // uint32_t maxDuration = _bitPeriodUs * getEdgeCount() * 2;
72 // if (durationUs > maxDuration) {
73 // reset();
74 // return false;
75 // }
76
77 // Split long pulses into individual bit-period edges
78 int count = (durationUs + _bitPeriodUs / 2) / _bitPeriodUs;
79 if (count < 1) count = 1;
80 if (count > (int)getEdgeCount()) count = getEdgeCount();
81
82 bool valid = false;
83 for (int i = 0; i < count; ++i) {
84 if (Codec::decodeEdge(_bitPeriodUs, level, result)) {
85 valid = true;
86 }
87 }
88 return valid;
89 }
90
91 bool decodeByte(Vector<OutputEdge>& edges, uint8_t& result) override {
92 if (edges.size() < 1 + 8 + _stopBits) return false;
93 bool valid = true;
94 if (edges[0].level != false) return false; // Start bit
95
96 uint8_t byte = 0;
97 for (int i = 0; i < 8; ++i) {
98 if (edges[i + 1].level) byte |= (1 << i);
99 }
100
101 // Check stop bits
102 for (int s = 0; s < _stopBits; ++s) {
103 if (edges[9 + s].level != true) valid = false;
104 }
105
106 result = byte;
107 return valid;
108 }
109
110 size_t getEdgeCount() const override { return 1 + 8 + _stopBits; }
111
112 int getEndOfFrameDelayUs() override { return getEdgeCount() + 1 * _bitPeriodUs; }
113
114 protected:
115 uint8_t _stopBits;
116
117 // Implementation of pure virtual function bitMatch
118 bool bitMatch(uint32_t duration, bool bit) const {
119 uint32_t expectedDuration = _bitPeriodUs;
120 return (duration >= expectedDuration - (_bitPeriodUs / 2)) &&
121 (duration <= expectedDuration + (_bitPeriodUs / 2));
122 }
123};
124
125} // 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
NRZ (Non-Return-to-Zero) codec for serial-like encoding/decoding with start/stop bit framing.
Definition NRZCodec.h:10
int getEndOfFrameDelayUs() override
Provide the end of frame delay in microseconds for this protocol, used by RX driver to.
Definition NRZCodec.h:112
CodecEnum getCodecType() const override
instance.
Definition NRZCodec.h:17
size_t getEdgeCount() const override
Get the number of protocol symbols (bits, pulses, etc.) per encoded byte.
Definition NRZCodec.h:110
size_t encode(uint8_t byte, Vector< OutputEdge > &output) override
Fill output vector with protocol-specific OutputSpec(s) for a byte.
Definition NRZCodec.h:38
bool decodeByte(Vector< OutputEdge > &edges, uint8_t &result) override
Decode edges into a byte.
Definition NRZCodec.h:91
bool decodeEdge(uint32_t durationUs, bool level, uint8_t &result) override
Edge-based decoding for protocol-agnostic RX drivers.
Definition NRZCodec.h:69
bool begin(uint32_t bitFrequencyHz) override
initialization method for codecs that require setup before use (e.g., loading PIO programs,...
Definition NRZCodec.h:25
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