Arduino PulseWire Transceiver Library
Loading...
Searching...
No Matches
TxProtocol.h
1#pragma once
2#include <Arduino.h>
3
4#include "TransceiverConfig.h"
5#include "pulse/SignalBase.h"
6#include "pulse/TxDriver.h"
7#include "pulse/codecs/Codec.h"
8#include "pulse/tools/Logger.h"
9#include "pulse/tools/RingBuffer.h"
10#include "pulse/tools/Vector.h"
11
12namespace pulsewire {
13
19class DigitalSignal : public SignalBase {
20 public:
21 DigitalSignal() = default;
22
23 void setTxPin(uint8_t pin) override {
24 _pin = pin;
25 pinMode(_pin, OUTPUT);
26 digitalWrite(_pin, LOW);
27 }
28
29 void sendBit(bool bit) {
30 if (bit) {
31 digitalWrite(_pin, HIGH);
32 } else {
33 digitalWrite(_pin, LOW);
34 }
35 }
36};
37
44class ToneSignal : public SignalBase {
45 public:
46 ToneSignal(uint16_t freq = CARRIER_HZ) : _freq(freq) {}
47
48 void setFrequency(uint16_t freq) { _freq = freq; }
49 uint16_t getFrequency() const { return _freq; }
50
51 void setTxPin(uint8_t pin) {
52 _pin = pin;
53 pinMode(_pin, OUTPUT);
54 noTone(_pin);
55 }
56
57 void sendBit(bool bit) {
58 if (bit) {
59 tone(_pin, _freq);
60 } else {
61 noTone(_pin);
62 }
63 }
64
65 protected:
66 uint16_t _freq;
67};
68
69#if defined(HAS_SET_PMW_FREQUENCY1) || defined(HAS_SET_PMW_FREQUENCY2)
70
77class PWMSignal : public SignalBase {
78 public:
79 PWMSignal(uint32_t freq = CARRIER_HZ, uint8_t duty = 128)
80 : _freq(freq), _duty(duty) {}
81 void setTxPin(uint8_t pin) {
82 _pin = pin;
83 pinMode(_pin, OUTPUT);
84#if defined(HAS_SET_PMW_FREQUENCY1)
85 analogWriteFreq(_freq);
86#endif
87#if defined(HAS_SET_PMW_FREQUENCY2)
88 analogWriteFrequency(_pin, _freq);
89#endif
90 analogWrite(_pin, 0); // Start with output LOW
91 }
92 void sendBit(bool bit) override {
93 if (bit) {
94 analogWrite(_pin, _duty); // Enable PWM
95 } else {
96 analogWrite(_pin, 0); // Disable PWM (LOW)
97 }
98 }
99
100 protected:
101 uint32_t _freq;
102 uint8_t _duty;
103};
104
105#endif
106
126 public:
127 virtual bool begin(uint32_t bitFrequencyHz, Codec* p_codec, uint8_t pin) = 0;
128 virtual void setFrameSize(uint16_t size) = 0;
129 virtual void sendPreamble() = 0;
130 virtual void sendData(const uint8_t* data, uint8_t len) = 0;
131 virtual void sendEnd(bool& _useChecksum) = 0;
132 virtual bool isFrameClosed() const = 0;
133};
134
155 public:
163
171 TRACE();
172 _bitFrequencyHz = bitFrequencyHz;
173 _bitPeriod = 1000000UL / bitFrequencyHz; // Bit period in microseconds
174 this->_codec = p_codec;
175 this->_codec->begin(bitFrequencyHz);
176 return true;
177 }
178
184 TRACE();
185 Logger::debug("Setting frame size to %d", size);
187 }
188
196 if (_codec == nullptr) {
197 Logger::error("Codec pointer is null");
199 return;
200 }
201 if (p_signal == nullptr) {
202 Logger::error("SignalBase pointer is null");
204 return;
205 }
206 if (is_frame_closed) {
207 check_sum = 0; // Reset checksum at the start of a new frame
209 _codec->encodePreamble(_output_buffer);
210 is_frame_closed = false;
211 }
212 }
213
220 void sendData(const uint8_t* data, uint8_t len) {
221 if (_codec == nullptr) {
222 Logger::error("Codec pointer is null");
224 return;
225 }
226 if (p_signal == nullptr) {
227 Logger::error("SignalBase pointer is null");
229 return;
230 }
231 for (uint8_t i = 0; i < len; i++) {
232 check_sum += data[i];
233 _codec->encode(data[i], _output_buffer);
234 }
235 // Flush any pending encoder state (e.g., Miller pending duration)
237 for (const auto& spec : _output_buffer) {
238 p_signal->sendBit(spec.level);
239 delayUs(spec.pulseUs);
240 }
241 }
242
252 void sendEnd(bool& _useChecksum) {
253 if (_codec == nullptr) {
254 Logger::error("Codec pointer is null");
256 return;
257 }
258 if (p_signal == nullptr) {
259 Logger::error("SignalBase pointer is null");
261 return;
262 }
263 if (!is_frame_closed) {
264 // print checksum
265 if (_useChecksum) {
269 for (const auto& spec : _output_buffer) {
270 p_signal->sendBit(spec.level);
271 delayUs(spec.pulseUs);
272 }
273 }
274 check_sum = 0;
275
276 // Add a final delay to ensure we can recoginse the end of frame
277 // Ensure signal is in idle state
278 p_signal->sendBit(_codec->getIdleLevel());
280 delayUs(period);
281 is_frame_closed = true;
282 }
283 }
284
289 bool isFrameClosed() const { return is_frame_closed; }
290
291 protected:
293 bool is_frame_closed = true;
294 SignalBase* p_signal = nullptr;
297 Codec* _codec = nullptr;
298 uint16_t _bitFrequencyHz = 0;
299 uint16_t _bitPeriod = 0;
300
301 inline void delayUs(uint32_t us) {
302#if USE_RAW_DELAY
304#else
305 uint32_t ms = us / 1000;
307 delay(ms);
311#endif
312 }
313}; // end of TxDriverArduino
314
315} // end of namespace pulsewire
Abstract base class for IR protocol encoding and decoding.
Definition Codec.h:53
virtual size_t encode(uint8_t byte, Vector< OutputEdge > &output)=0
Fill output vector with protocol-specific OutputSpec(s) for a byte.
virtual int getEndOfFrameDelayUs()=0
virtual bool getIdleLevel() const
Provides the initial ldle state (low or hith)
Definition Codec.h:127
virtual size_t flushEncoder(Vector< OutputEdge > &output)
Flush any pending encoder state at end of frame.
Definition Codec.h:185
virtual bool begin(uint32_t bitFrequencyHz)
initialization method for codecs that require setup before use (e.g., loading PIO programs,...
Definition Codec.h:70
Digital output signal implementation using digitalWrite.
Definition TxProtocol.h:19
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
PWM-modulated output signal implementation using analogWrite and analogWriteFrequency.
Definition TxProtocol.h:77
Abstract base class for signal output.
Definition SignalBase.h:11
Tone-modulated output signal implementation using tone().
Definition TxProtocol.h:44
Generic implementation that is supported by all Arduino cores.
Definition TxProtocol.h:154
Codec * _codec
Pointer to the codec used for encoding data.
Definition TxProtocol.h:297
void sendPreamble()
Sends the preamble for the transmission.
Definition TxProtocol.h:195
TxProtocolGeneric(SignalBase *p_signal)
Constructs a TxProtocolGeneric instance with the specified signal implementation.
Definition TxProtocol.h:162
uint8_t check_sum
Checksum for data integrity.
Definition TxProtocol.h:292
bool is_frame_closed
Indicates whether the frame is closed.
Definition TxProtocol.h:293
void sendData(const uint8_t *data, uint8_t len)
Encodes and transmits the data.
Definition TxProtocol.h:220
SignalBase * p_signal
Pointer to the signal implementation.
Definition TxProtocol.h:294
bool isFrameClosed() const
Checks whether the transmission frame is closed.
Definition TxProtocol.h:289
bool begin(uint32_t bitFrequencyHz, Codec *p_codec, uint8_t pin)
Initializes the protocol with the specified codec and transmission pin.
Definition TxProtocol.h:170
void setFrameSize(uint16_t size)
Configures the size of the data to be transmitted.
Definition TxProtocol.h:183
void sendEnd(bool &_useChecksum)
Sends the end signal for the transmission.
Definition TxProtocol.h:252
Vector< OutputEdge > _output_buffer
Buffer for storing encoded signal edges.
Definition TxProtocol.h:296
Abstract base class for defining transmission protocols.
Definition TxProtocol.h:125
Small, header-only vector replacement for non-STL environments.
Definition Vector.h:29
void clear()
Remove all elements.
Definition Vector.h:120
void reserve(size_t cap)
Reserve space for at least cap elements.
Definition Vector.h:157