STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
T7Calibration.hpp
Go to the documentation of this file.
1#pragma once
2
3// How calibration_service sees a LabJack T7 channel: as one more PT / LC / TC, with the same uid,
4// store, models, captures and tares as an ESP32 sensor. Only where its data comes from differs.
5//
6// t7_bridge ── raw volts {0x26, (slot-1)*0x20 + ain} ──► calibration_service
7// ── cold junction °C {0x26, (slot-1)*0x20 + 0x0F} (TC boards) ──►
8// calibration_service ── calibrated {0x26, (slot-1)*0x20 + 0x10 + ain} ──► GUI
9//
10// The "ADC code" a T7 channel feeds the shared calibration machinery is its reading in
11// MICROVOLTS (t7_counts): an int32 like the ESP32 boards' codes, so captured points, cubic fits,
12// the robust learner and tares all work on it unchanged. 1 µV is 0.005 % of a 20 mV load-cell
13// span, 0.02 ‰ of a 5 V PT span and about 0.025 °C of a type K, so the rounding is not what
14// limits any of them. The cubic store tags these channels "uV"
15// (CubicCalibrationStore kRawUnitMicrovolts) so a fit never crosses between the two units.
16
17#include <array>
18#include <cstdint>
19#include <map>
20#include <optional>
21#include <string>
22#include <vector>
23
24#include "config/Config.hpp"
25
26namespace fsw {
27namespace t7 {
28
29/** Raw-table offset (within a slot's 32-entry block) of the cold-junction table: AIN15 does not
30 * exist on a T7, so the slot is free. Entity T7<slot>.CJC, field temperature_c. */
31constexpr uint8_t kCjcTableOffset = 0x0F;
32
33/** First logical calibration channel for T7 inputs. ESP32 boards use (slot-1)*10 + connector,
34 * at most 80; T7 inputs use 128 + (slot-1)*16 + ain (128..255), so the two cannot collide in
35 * PTCalibrationManager / SensorCalibrationManager. */
36constexpr uint8_t kT7LogicalBase = 128;
37
38/** Logical calibration channel for a T7 input. */
39uint8_t t7_logical_channel(uint8_t slot, uint8_t ain);
40
41/** uid of a T7 input: board_id * 100 + ain, the ESP32 scheme with the AIN as connector. */
42uint16_t t7_uid(int board_id, int ain);
43
44/** The calibration "ADC code" for a T7 reading: microvolts, rounded and clamped to int32. */
45int32_t t7_counts(double volts);
46
47/** Volts from a calibration code. */
48double t7_volts(double counts);
49
50/** Cold-junction table id for a slot. */
51std::array<uint8_t, 2> cjc_table_id(uint8_t slot);
52
53/** One T7 input as calibration sees it. */
55 std::string board_key; ///< "labjack_1" — the <board> in [calibration_model_<board>] etc.
56 int board_id = 0;
57 uint8_t slot = 0;
59 uint16_t uid = 0;
60 uint8_t logical_ch = 0;
61};
62
63/**
64 * Every PT / LC / TC input on every enabled T7, from config. VOLTAGE inputs are left out (they
65 * have nothing to calibrate). Built only from a config t7_bridge would accept: when
66 * Config::t7_errors is non-empty the map is empty, because the bridge is not streaming either.
67 */
69public:
70 T7CalibrationMap() = default;
71 explicit T7CalibrationMap(const config::Config& cfg);
72
73 const T7CalChannel* by_uid(uint16_t uid) const;
74 /** The input behind raw table {0x26, (slot-1)*0x20 + ain}, or nullptr. */
75 const T7CalChannel* by_table(uint8_t slot, uint8_t ain) const;
76 const std::vector<T7CalChannel>& all() const {
77 return channels_;
78 }
79 /** Slots with at least one TC (they publish a cold-junction table). */
80 std::vector<uint8_t> tc_slots() const;
81 /** Raw tables calibration_service subscribes to: every input above, plus each TC slot's CJC. */
82 std::vector<std::pair<uint8_t, uint8_t>> raw_tables() const;
83 bool empty() const {
84 return channels_.empty();
85 }
86
87private:
88 std::vector<T7CalChannel> channels_;
89 std::map<uint16_t, size_t> by_uid_;
90 std::map<std::pair<uint8_t, uint8_t>, size_t> by_table_;
91};
92
93} // namespace t7
94} // namespace fsw
std::map< uint16_t, size_t > by_uid_
const T7CalChannel * by_uid(uint16_t uid) const
std::vector< uint8_t > tc_slots() const
Slots with at least one TC (they publish a cold-junction table).
std::vector< T7CalChannel > channels_
std::map< std::pair< uint8_t, uint8_t >, size_t > by_table_
const std::vector< T7CalChannel > & all() const
std::vector< std::pair< uint8_t, uint8_t > > raw_tables() const
Raw tables calibration_service subscribes to: every input above, plus each TC slot's CJC.
const T7CalChannel * by_table(uint8_t slot, uint8_t ain) const
The input behind raw table {0x26, (slot-1)*0x20 + ain}, or nullptr.
static uint8_t board_id
Definition main.cpp:30
constexpr uint8_t kCjcTableOffset
Raw-table offset (within a slot's 32-entry block) of the cold-junction table: AIN15 does not exist on...
std::array< uint8_t, 2 > cjc_table_id(uint8_t slot)
Cold-junction table id for a slot.
int32_t t7_counts(double volts)
The calibration "ADC code" for a T7 reading: microvolts, rounded and clamped to int32.
double t7_volts(double counts)
Volts from a calibration code.
constexpr uint8_t kT7LogicalBase
First logical calibration channel for T7 inputs.
uint16_t t7_uid(int board_id, int ain)
uid of a T7 input: board_id * 100 + ain, the ESP32 scheme with the AIN as connector.
uint8_t t7_logical_channel(uint8_t slot, uint8_t ain)
Logical calibration channel for a T7 input.
Motorized ball valve position: raw ADC counts -> % open.
The whole parsed config.toml, restricted to what C++ consumes.
Definition Config.hpp:264
One streamed analog input.
Definition T7Config.hpp:37
One T7 input as calibration sees it.
config::T7Channel channel
std::string board_key
"labjack_1" — the <board> in [calibration_model_<board>] etc.
static double volts(uint32_t code)
Shunt volts for a code, as calibration_main's convert_hp_pt_to_pressure computes it.