HF-FDO2 Driver 0.1.0-dev
UART driver for PyroScience FDO2-G2 (data sheet v5 §4: #MOXY, #MRAW, #VERS)
Loading...
Searching...
No Matches
fdo2_types.hpp
Go to the documentation of this file.
1
13#pragma once
14
15#include <cmath>
16#include <cstdint>
17#include <string_view>
18
19namespace fdo2 {
20
22constexpr uint32_t kFdo2G2DefaultBaud = 19200U;
23
25constexpr uint32_t kFdo2G2PowerUpSettleMs = 1100U;
26
28enum class DriverError : uint8_t {
29 None = 0,
31 Timeout,
35};
36
37constexpr std::string_view ToString(DriverError e) noexcept {
38 switch (e) {
39 case DriverError::None: return "None";
40 case DriverError::InvalidParameter: return "InvalidParameter";
41 case DriverError::Timeout: return "Timeout";
42 case DriverError::BufferOverflow: return "BufferOverflow";
43 case DriverError::ProtocolError: return "ProtocolError";
44 case DriverError::DeviceError: return "DeviceError";
45 }
46 return "?";
47}
48
49template <typename T>
51 T value{};
53
54 constexpr bool ok() const noexcept { return error == DriverError::None; }
55 constexpr explicit operator bool() const noexcept { return ok(); }
56
57 static constexpr DriverResult success(T v) noexcept { return {v, DriverError::None}; }
58 static constexpr DriverResult failure(DriverError e) noexcept { return {T{}, e}; }
59};
60
61template <>
62struct DriverResult<void> {
64 constexpr bool ok() const noexcept { return error == DriverError::None; }
65 constexpr explicit operator bool() const noexcept { return ok(); }
66 static constexpr DriverResult success() noexcept { return {DriverError::None}; }
67 static constexpr DriverResult failure(DriverError e) noexcept { return {e}; }
68};
69
77 int32_t device_id{};
78 int32_t num_channels{};
80 int32_t sensor_types{};
81};
82
84constexpr double FirmwareRevisionToDouble(int32_t r) noexcept {
85 return static_cast<double>(r) * 0.01;
86}
87
95 int32_t o_raw{};
96 int32_t t_raw{};
97 uint32_t status_u32{};
98
99 double p_o2_hpa{};
100 double temp_c{};
101};
102
110 int32_t d_raw{};
111 int32_t i_raw{};
112 int32_t a_raw{};
113 int32_t p_raw{};
114 int32_t h_raw{};
115
116 double dphi_deg{};
119 double pressure_mbar{};
121};
122
123namespace moxy_status {
124
125constexpr uint32_t kWarnAutoAmpReduced = 1U << 0;
126constexpr uint32_t kFatalSignalTooLow = 1U << 1;
127constexpr uint32_t kFatalSignalTooHigh = 1U << 2;
128constexpr uint32_t kFatalRefTooLow = 1U << 3;
129constexpr uint32_t kFatalRefTooHigh = 1U << 4;
130constexpr uint32_t kFatalTempSensor = 1U << 5;
131constexpr uint32_t kWarnHumidityHigh = 1U << 7;
132constexpr uint32_t kErrPressureSensor = 1U << 9;
133constexpr uint32_t kErrHumiditySensor = 1U << 10;
134
135} // namespace moxy_status
136
138constexpr bool MoxyStatusOkForOxygen(uint32_t s) noexcept { return s <= 1U; }
139
140inline MoxyReading DecodeMoxy(int32_t o_raw, int32_t t_raw, uint32_t s) noexcept {
141 MoxyReading m{};
142 m.o_raw = o_raw;
143 m.t_raw = t_raw;
144 m.status_u32 = s;
145 m.p_o2_hpa = static_cast<double>(o_raw) * 1e-3;
146 m.temp_c = static_cast<double>(t_raw) * 1e-3;
147 return m;
148}
149
150inline MrawReading DecodeMraw(int32_t o_raw, int32_t t_raw, uint32_t s, int32_t d_raw,
151 int32_t i_raw, int32_t a_raw, int32_t p_raw,
152 int32_t h_raw) noexcept {
153 MrawReading r{};
154 static_cast<MoxyReading&>(r) = DecodeMoxy(o_raw, t_raw, s);
155 r.d_raw = d_raw;
156 r.i_raw = i_raw;
157 r.a_raw = a_raw;
158 r.p_raw = p_raw;
159 r.h_raw = h_raw;
160 r.dphi_deg = static_cast<double>(d_raw) * 1e-3;
161 r.signal_intensity_mv = static_cast<double>(i_raw) * 1e-3;
162 r.ambient_light_mv = static_cast<double>(a_raw) * 1e-3;
163 r.pressure_mbar = static_cast<double>(p_raw) * 1e-6;
164 r.rh_in_housing_pct = static_cast<double>(h_raw) * 1e-3;
165 return r;
166}
167
175inline double VolumePercentO2(double p_o2_hpa, double p_air_mbar) noexcept {
176 if (p_air_mbar <= 0.0 || !std::isfinite(p_air_mbar) || !std::isfinite(p_o2_hpa)) {
177 return 0.0;
178 }
179 return 100.0 * p_o2_hpa / p_air_mbar;
180}
181
182} // namespace fdo2
constexpr uint32_t kFatalRefTooHigh
Definition fdo2_types.hpp:129
constexpr uint32_t kWarnHumidityHigh
Definition fdo2_types.hpp:131
constexpr uint32_t kErrHumiditySensor
Definition fdo2_types.hpp:133
constexpr uint32_t kFatalRefTooLow
Definition fdo2_types.hpp:128
constexpr uint32_t kWarnAutoAmpReduced
Definition fdo2_types.hpp:125
constexpr uint32_t kFatalSignalTooHigh
Definition fdo2_types.hpp:127
constexpr uint32_t kFatalSignalTooLow
Definition fdo2_types.hpp:126
constexpr uint32_t kErrPressureSensor
Definition fdo2_types.hpp:132
constexpr uint32_t kFatalTempSensor
Definition fdo2_types.hpp:130
Definition fdo2.hpp:19
constexpr double FirmwareRevisionToDouble(int32_t r) noexcept
Definition fdo2_types.hpp:84
constexpr bool MoxyStatusOkForOxygen(uint32_t s) noexcept
Data sheet: normal operation implies S is 0 or 1 only.
Definition fdo2_types.hpp:138
MrawReading DecodeMraw(int32_t o_raw, int32_t t_raw, uint32_t s, int32_t d_raw, int32_t i_raw, int32_t a_raw, int32_t p_raw, int32_t h_raw) noexcept
Definition fdo2_types.hpp:150
constexpr std::string_view ToString(DriverError e) noexcept
Definition fdo2_types.hpp:37
constexpr uint32_t kFdo2G2DefaultBaud
Default UART speed after power-up per FDO2-G2 data sheet §4.
Definition fdo2_types.hpp:22
DriverError
Driver-level error codes (stable for logging / telemetry).
Definition fdo2_types.hpp:28
double VolumePercentO2(double p_o2_hpa, double p_air_mbar) noexcept
Volume % O₂ when p_air at the sensing membrane equals back-side pressure P.
Definition fdo2_types.hpp:175
MoxyReading DecodeMoxy(int32_t o_raw, int32_t t_raw, uint32_t s) noexcept
Definition fdo2_types.hpp:140
constexpr uint32_t kFdo2G2PowerUpSettleMs
Typical boot delay before the module accepts commands (data sheet: ~1 s).
Definition fdo2_types.hpp:25
static constexpr DriverResult success() noexcept
Definition fdo2_types.hpp:66
static constexpr DriverResult failure(DriverError e) noexcept
Definition fdo2_types.hpp:67
constexpr bool ok() const noexcept
Definition fdo2_types.hpp:64
Definition fdo2_types.hpp:50
constexpr bool ok() const noexcept
Definition fdo2_types.hpp:54
static constexpr DriverResult success(T v) noexcept
Definition fdo2_types.hpp:57
T value
Definition fdo2_types.hpp:51
static constexpr DriverResult failure(DriverError e) noexcept
Definition fdo2_types.hpp:58
DriverError error
Definition fdo2_types.hpp:52
Decoded #MOXY O T S sample (data sheet §4.3).
Definition fdo2_types.hpp:94
double p_o2_hpa
Partial pressure O₂ [hPa] = O × 10⁻³.
Definition fdo2_types.hpp:99
uint32_t status_u32
S as received.
Definition fdo2_types.hpp:97
int32_t t_raw
T as received (m°C).
Definition fdo2_types.hpp:96
int32_t o_raw
O as received (1e-3 hPa).
Definition fdo2_types.hpp:95
double temp_c
Temperature [°C] = T × 10⁻³.
Definition fdo2_types.hpp:100
Decoded #MRAW O T S D I A P H (data sheet §4.3).
Definition fdo2_types.hpp:109
int32_t i_raw
I (µV).
Definition fdo2_types.hpp:111
int32_t h_raw
H (mRH).
Definition fdo2_types.hpp:114
double dphi_deg
D × 10⁻³ degrees.
Definition fdo2_types.hpp:116
double rh_in_housing_pct
H × 10⁻³ RH.
Definition fdo2_types.hpp:120
double signal_intensity_mv
I × 10⁻³ mV.
Definition fdo2_types.hpp:117
double ambient_light_mv
A × 10⁻³ mV.
Definition fdo2_types.hpp:118
int32_t a_raw
A (µV).
Definition fdo2_types.hpp:112
int32_t d_raw
D (m°).
Definition fdo2_types.hpp:110
int32_t p_raw
P (µbar at connector / back side).
Definition fdo2_types.hpp:113
double pressure_mbar
P × 10⁻⁶ mbar (≈ hPa).
Definition fdo2_types.hpp:119
#VERS D N R S fields (FDO2-G2 data sheet §4.3).
Definition fdo2_types.hpp:76
int32_t num_channels
N (1 for FDO2-G2).
Definition fdo2_types.hpp:78
int32_t device_id
D (8 for FDO2-G2).
Definition fdo2_types.hpp:77
int32_t sensor_types
S bit mask: bit0 O2, bit1 temp housing, bit2 pressure, bit3 RH.
Definition fdo2_types.hpp:80
int32_t firmware_revision
R (e.g. 328 → 3.28).
Definition fdo2_types.hpp:79