STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
test_rtd_board.cpp
Go to the documentation of this file.
1// ESP32 RTD board conversion (fsw::calibration::rtd::rtd_board_adc_to_temp_c), as
2// calibration_service publishes it when a channel has no per-sensor calibration.
3//
4// The board drives excitation_ua through a Pt1000 and reads the voltage across it on a 32-bit ADC
5// (2^31 = adc_ref_voltage). The shipped settings ([calibration.rtd]) are 2.5 V, 1000 uA, R0 1000.
6//
7// Expected values come from the IEC 60751 curve evaluated here (temp_to_resistance_cvd, itself
8// pinned to the standard's Pt100 table in test_t7), never from the inverse under test.
9
10#include <cmath>
11#include <cstdint>
12#include <iostream>
13#include <string>
14
16
17using namespace fsw::calibration::rtd;
18
19static int g_failures = 0;
20
21static void check(bool ok, const std::string& what) {
22 std::cout << (ok ? " ok " : " FAIL ") << what << std::endl;
23 if (!ok)
24 g_failures++;
25}
26
27constexpr double kRef = 2.5, kUa = 1000.0, kR0 = 1000.0;
28
29/** The ADC code the board reports for an element at t_c. */
30static int32_t code_at(double t_c) {
31 CVDCoeffs c;
32 c.R0 = kR0;
33 const double volts = temp_to_resistance_cvd(t_c, c) * kUa * 1e-6;
34 return static_cast<int32_t>(std::llround(volts / kRef * 2147483648.0));
35}
36
37static double read(int32_t code) {
38 return rtd_board_adc_to_temp_c(code, kRef, kUa, kR0);
39}
40
41int main() {
42 std::cout << "=== ESP32 RTD board ===" << std::endl;
43
44 bool all_ok = true;
45 for (double t : {-196.0, -183.0, -150.0, -100.0, -40.0, 0.0, 25.0, 100.0, 300.0})
46 all_ok = all_ok && std::fabs(read(code_at(t)) - t) < 0.01;
47 check(all_ok, "reads the element's temperature from -196 C to 300 C within 0.01 C");
48
49 // The bug this replaces: the quadratic-only inverse dropped the C term below 0 C.
50 CVDCoeffs c;
51 c.R0 = kR0;
52 const double r_lox = temp_to_resistance_cvd(-183.0, c);
53 check(resistance_to_temp_cvd(r_lox, c) < -184.5,
54 "the old quadratic-only inverse read LOX about 1.8 C cold");
55 check(std::fabs(read(code_at(-183.0)) - -183.0) < 0.01, "the board now reads it at -183 C");
56 bool same = true;
57 for (double t : {0.5, 25.0, 300.0}) {
58 const int32_t code = code_at(t);
59 const double ohms = code / 2147483648.0 * kRef * 1e6 / kUa;
60 same = same && std::fabs(read(code) - resistance_to_temp_cvd(ohms, c)) < 1e-9;
61 }
62 check(same, "above 0 C the reading is unchanged (the quadratic is exact there)");
63
64 // Faults publish nothing.
65 check(std::isnan(read(2147483647)) && std::isnan(read(2147000000)),
66 "a saturated ADC (open element, ~395 C on the curve) is no reading");
67 check(std::isnan(read(0)) && std::isnan(read(1000)),
68 "a shorted element (~0 ohm, below -200 C) is no reading");
69 check(std::isnan(rtd_board_adc_to_temp_c(code_at(25.0), kRef, 0.0, kR0)),
70 "no excitation configured is no reading");
72 "above the standard's 850 C is no reading");
73
74 std::cout << (g_failures == 0 ? "PASSED" : "FAILED: " + std::to_string(g_failures))
75 << std::endl;
76 return g_failures == 0 ? 0 : 1;
77}
static bool ok
Definition flight_e2e.c:435
double resistance_to_temp_cvd(double resistance_ohms, const CVDCoeffs &cvd=CVDCoeffs{})
Convert resistance (Ω) to temperature (°C) using iterative CVD inverse.
double temp_to_resistance_cvd(double t_c, const CVDCoeffs &cvd=CVDCoeffs{})
Resistance (Ω) at temperature (°C), IEC 60751 Callendar-Van Dusen, the C term below 0 °C.
double rtd_board_adc_to_temp_c(int32_t adc_raw, double adc_ref_voltage, double excitation_ua, double r0_ohms)
An ESP32 RTD board's reading -> °C: the ADC code (2^31 = adc_ref_voltage) is the voltage across the e...
double resistance_to_temp_cvd_full(double resistance_ohms, const CVDCoeffs &cvd=CVDCoeffs{})
The full CVD inverse: exact above 0 °C (the quadratic), Newton on the C term below it.
static int g_failures
static double volts(uint32_t code)
Shunt volts for a code, as calibration_main's convert_hp_pt_to_pressure computes it.
constexpr double kUa
static int32_t code_at(double t_c)
The ADC code the board reports for an element at t_c.
static void check(bool ok, const std::string &what)
constexpr double kRef
static double read(int32_t code)
constexpr double kR0
int main()