Arduino PulseWire Transceiver Library
Loading...
Searching...
No Matches
TxProtocol.h
1#pragma once
2#include <Arduino.h>
3
4#include "pulse/codecs/Codec.h"
5#include "pulse/tools/RingBuffer.h"
6#include "pulse/SignalBase.h"
7#include "TransceiverConfig.h"
8#include "pulse/TxDriver.h"
9#include "pulse/tools/Logger.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(uint16_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, bool isDelayAfterFrame) = 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 // for (const auto& spec : _output_buffer) {
211 // p_signal->sendBit(spec.level);
212 // delayUs(spec.pulseUs);
213 // }
214 is_frame_closed = false;
215 }
216 }
217
224 void sendData(const uint8_t* data, uint8_t len) {
225 if (_codec == nullptr) {
226 Logger::error("Codec pointer is null");
228 return;
229 }
230 if (p_signal == nullptr) {
231 Logger::error("SignalBase pointer is null");
233 return;
234 }
235 for (uint8_t i = 0; i < len; i++) {
236 check_sum += data[i];
237 _codec->encode(data[i], _output_buffer);
238 }
239 for (const auto& spec : _output_buffer) {
240 p_signal->sendBit(spec.level);
241 delayUs(spec.pulseUs);
242 }
243 }
244
254 void sendEnd(bool& _useChecksum, bool isDelayAfterFrame) {
255 if (_codec == nullptr) {
256 Logger::error("Codec pointer is null");
258 return;
259 }
260 if (p_signal == nullptr) {
261 Logger::error("SignalBase pointer is null");
263 return;
264 }
265 if (!is_frame_closed) {
266 // print checksum
267 if (_useChecksum) {
270 for (const auto& spec : _output_buffer) {
271 p_signal->sendBit(spec.level);
272 delayUs(spec.pulseUs);
273 }
274 }
275 check_sum = 0;
276
277 // Add a final delay to ensure we can recoginse the end of frame
278 if (isDelayAfterFrame) {
279 // Ensure signal is in idle state
280 p_signal->sendBit(_codec->getIdleLevel());
282 delayUs(period);
283 }
284 is_frame_closed = true;
285 }
286 }
287
292 bool isFrameClosed() const { return is_frame_closed; }
293
294 protected:
296 bool is_frame_closed = true;
297 SignalBase* p_signal = nullptr;
300 Codec* _codec = nullptr;
301 uint16_t _bitFrequencyHz = 0;
302 uint16_t _bitPeriod = 0;
303
304 inline void delayUs(uint32_t us) {
305#if USE_RAW_DELAY
307#else
308 uint32_t ms = us / 1000;
310 delay(ms);
314#endif
315 }
316}; // end of TxDriverArduino
317
318} // end of namespace pulsewire
Abstract base class for IR protocol encoding and decoding.
Definition Codec.h:41
virtual size_t encode(uint8_t byte, Vector< OutputEdge > &output)
Fill output vector with protocol-specific OutputSpec(s) for a byte.
Definition Codec.h:162
virtual bool begin(uint32_t bitFrequencyHz)
initialization method for codecs that require setup before use (e.g., loading PIO programs,...
Definition Codec.h:56
virtual int getEndOfFrameDelayUs()=0
Provide the end of frame delay in microseconds for this protocol, used by RX driver to.
virtual bool getIdleLevel() const
Provides the initial ldle state (low or hith)
Definition Codec.h:208
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:300
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 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:295
bool is_frame_closed
Indicates whether the frame is closed.
Definition TxProtocol.h:296
void sendData(const uint8_t *data, uint8_t len)
Encodes and transmits the data.
Definition TxProtocol.h:224
SignalBase * p_signal
Pointer to the signal implementation.
Definition TxProtocol.h:297
bool isFrameClosed() const
Checks whether the transmission frame is closed.
Definition TxProtocol.h:292
void setFrameSize(uint16_t size)
Configures the size of the data to be transmitted.
Definition TxProtocol.h:183
Vector< OutputEdge > _output_buffer
Buffer for storing encoded signal edges.
Definition TxProtocol.h:299
void sendEnd(bool &_useChecksum, bool isDelayAfterFrame)
Sends the end signal for the transmission.
Definition TxProtocol.h:254
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