Avionics
Core avionics package for CURE flight computers
Loading...
Searching...
No Matches
Telemetry.h
Go to the documentation of this file.
1#ifndef TELEMETRY_H
2#define TELEMETRY_H
3
4#include <array>
5#include <cstddef>
6#include <cstdint>
7#include <cstring>
8
9#include "ArduinoHAL.h"
11
27
28namespace TelemetryFmt {
29
31constexpr std::size_t kPacketCapacity = 120;
32
34constexpr std::size_t kSyncZeros = 3;
35
37constexpr std::size_t kU32Bytes = 4;
38
40constexpr std::size_t kStartByteIndex = kSyncZeros; // 3
41constexpr std::size_t kTimestampIndex = kStartByteIndex + 1; // 4
42constexpr std::size_t kPacketCounterIndex = kTimestampIndex + kU32Bytes; // 8
43constexpr std::size_t kHeaderBytes = kSyncZeros + 1 + kU32Bytes + kU32Bytes; // 12 (CHANGED from 8 to 12)
44
46constexpr std::size_t kEndMarkerBytes = kSyncZeros + 1;
47
49constexpr std::uint8_t kStartByteValue = 51;
50
52constexpr std::uint8_t kEndByteValue = 52;
53
55constexpr std::size_t kBytesIn32Bit = 4;
56constexpr unsigned kBitsPerByte = 8;
57constexpr std::uint8_t kAllOnesByte = 0xFF;
58
60static_assert(sizeof(std::uint32_t) == 4, "Expected 32-bit uint32_t");
61static_assert(sizeof(float) == 4, "Expected 32-bit float");
62
66inline void write_u32_be(std::uint8_t* dst, std::uint32_t v) {
67
68 for (std::size_t i = 0; i < kBytesIn32Bit; ++i) {
69 const unsigned shift = static_cast<unsigned>((kBytesIn32Bit - 1 - i) * kBitsPerByte);
70 dst[i] = static_cast<std::uint8_t>(v >> shift);
71 }
72}
73
74
80inline std::uint16_t hz_to_period_ms(std::uint16_t hz) {
81 return (hz == 0) ? 1000u
82 : static_cast<std::uint16_t>((1000u + hz - 1u) / hz);
83}
84
85} // namespace TelemetryFmt
86
87// Backwards-compatible names if existing code uses START_BYTE / END_BYTE.
88static const std::uint8_t START_BYTE = TelemetryFmt::kStartByteValue;
89static const std::uint8_t END_BYTE = TelemetryFmt::kEndByteValue;
90
106 // --- Payload configuration ---
107
110
113
115 // Shall not be changed after construction
116 // Used to iterate over multiSDH
117 const std::size_t multiSDHLength;
118
120 std::uint8_t multiSDHDataLabel;
121
122 // --- Scheduling state ---
123
125 std::uint16_t periodMs;
126
128 std::uint32_t lastSentTimestamp;
129
135 SendableSensorData(SensorDataHandler* sdh, std::uint16_t sendFrequencyHz)
136 : singleSDH(sdh),
137 multiSDH(0),
140 periodMs(TelemetryFmt::hz_to_period_ms(sendFrequencyHz)),
142
149 template <std::size_t M>
150 SendableSensorData(const std::array<SensorDataHandler*, M>& sdhList,
151 std::uint8_t label,
152 std::uint16_t sendFrequencyHz)
153 : singleSDH(0),
154 multiSDH(sdhList.data()),
156 multiSDHDataLabel(label),
157 periodMs(TelemetryFmt::hz_to_period_ms(sendFrequencyHz)),
159
163 bool shouldBeSent(std::uint32_t now) const {
164 return (now - lastSentTimestamp) >= periodMs;
165 }
166
170 void markWasSent(std::uint32_t now) {
171 lastSentTimestamp = now;
172 }
173
175 bool isSingle() const { return singleSDH != 0; }
176
178 bool isMulti() const { return (multiSDH != 0) && (multiSDHLength != 0); }
179};
180
193public:
194
199 template <std::size_t N>
200 Telemetry(const std::array<SendableSensorData*, N>& streams,
201 Stream& rfdSerialConnection)
202 : streams(streams.data()),
203 streamCount(N),
204 rfdSerialConnection(rfdSerialConnection),
205 nextEmptyPacketIndex(0),
206 packet{} {}
207
212 bool tick(std::uint32_t currentTimeMs);
213
214private:
215 // Packet building helpers
216 void preparePacket(std::uint32_t timestamp);
217 void addSingleSDHToPacket(SensorDataHandler* sdh);
218 void addSSDToPacket(SendableSensorData* ssd);
219 void setPacketToZero();
220 void addEndMarker();
221
222 // Non-owning view of the stream list
223 SendableSensorData* const* streams;
224
225 // Number of streams in the list
226 // Shall not be changed after construction
227 // Used to iterate over streams
228 const std::size_t streamCount;
229
230 // Output
231 Stream& rfdSerialConnection;
232
233 // Packet state
234 std::uint32_t packetCounter = 0;
235 std::size_t nextEmptyPacketIndex;
236 std::array<std::uint8_t, TelemetryFmt::kPacketCapacity> packet;
237};
238
239#endif
Buffers sensor samples and forwards them to an IDataSaver at a controlled rate.
bool tick(std::uint32_t currentTimeMs)
Call every loop to send due telemetry streams.
Definition Telemetry.cpp:80
Telemetry(const std::array< SendableSensorData *, N > &streams, Stream &rfdSerialConnection)
Construct from std::array (convenient and compile-time sized). The std::array must outlive the Teleme...
Definition Telemetry.h:200
std::uint16_t hz_to_period_ms(std::uint16_t hz)
Convert frequency (Hz) to period (ms), using integer math.
Definition Telemetry.h:80
constexpr std::size_t kStartByteIndex
Definition Telemetry.h:40
constexpr unsigned kBitsPerByte
Definition Telemetry.h:56
constexpr std::size_t kPacketCapacity
Definition Telemetry.h:31
constexpr std::uint8_t kStartByteValue
Definition Telemetry.h:49
constexpr std::size_t kPacketCounterIndex
Definition Telemetry.h:42
constexpr std::uint8_t kAllOnesByte
Definition Telemetry.h:57
void write_u32_be(std::uint8_t *dst, std::uint32_t v)
Write a 32-bit value in big-endian order to dst[0..3].
Definition Telemetry.h:66
constexpr std::size_t kSyncZeros
Definition Telemetry.h:34
constexpr std::size_t kEndMarkerBytes
Definition Telemetry.h:46
constexpr std::size_t kBytesIn32Bit
Definition Telemetry.h:55
constexpr std::size_t kHeaderBytes
Definition Telemetry.h:43
constexpr std::uint8_t kEndByteValue
Definition Telemetry.h:52
constexpr std::size_t kTimestampIndex
Definition Telemetry.h:41
constexpr std::size_t kU32Bytes
Definition Telemetry.h:37
Declares one telemetry "stream" to include in packets.
Definition Telemetry.h:105
std::uint32_t lastSentTimestamp
Definition Telemetry.h:128
void markWasSent(std::uint32_t now)
Update internal state after sending.
Definition Telemetry.h:170
const std::size_t multiSDHLength
Definition Telemetry.h:117
bool isMulti() const
Convenience: true if configured as a multi SDH stream.
Definition Telemetry.h:178
bool isSingle() const
Convenience: true if configured as a single SDH stream.
Definition Telemetry.h:175
bool shouldBeSent(std::uint32_t now) const
Return true if enough time has elapsed such that this stream wants to be sent again.
Definition Telemetry.h:163
std::uint16_t periodMs
Definition Telemetry.h:125
std::uint8_t multiSDHDataLabel
Definition Telemetry.h:120
SendableSensorData(const std::array< SensorDataHandler *, M > &sdhList, std::uint8_t label, std::uint16_t sendFrequencyHz)
Create a multi SDH stream from a std::array.
Definition Telemetry.h:150
SensorDataHandler *const * multiSDH
Definition Telemetry.h:112
SendableSensorData(SensorDataHandler *sdh, std::uint16_t sendFrequencyHz)
Create a single SDH stream.
Definition Telemetry.h:135
SensorDataHandler * singleSDH
Definition Telemetry.h:109