Skip to content

Commit c9f3df2

Browse files
committed
Refactor ADC-backed sensors onto a shared base
1 parent 392e207 commit c9f3df2

12 files changed

Lines changed: 403 additions & 111 deletions

File tree

Inc/HALAL/Services/ADC/NewADC.hpp

Lines changed: 0 additions & 3 deletions
This file was deleted.

Inc/ST-LIB_LOW/ST-LIB_LOW.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
// #include "Sensors/Sensor/Sensor.hpp" // To be implemented when InputCapture is done
1616
#include "Sensors/DigitalSensor/DigitalSensor.hpp"
1717
#include "Sensors/SensorInterrupt/SensorInterrupt.hpp"
18-
#include "Sensors/LinearSensor/LinearSensor.hpp"
1918
#include "Sensors/LookupSensor/LookupSensor.hpp"
2019
#include "Sensors/EncoderSensor/NewEncoderSensor.hpp"
2120
// #include "Sensors/PWMSensor/PWMSensor.hpp" // To be implemented when InputCapture is done
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#pragma once
2+
3+
#include <algorithm>
4+
#include <cstddef>
5+
6+
#include "HALAL/Services/ADC/ADC.hpp"
7+
8+
namespace ST_LIB::Sensors {
9+
10+
inline constexpr float kDefaultADCReferenceVoltage = 3.3f;
11+
12+
template <class ValueType> class ADCValueSensor {
13+
protected:
14+
using ADCInstance = ST_LIB::ADCDomain::Instance;
15+
16+
constexpr ADCValueSensor() = default;
17+
constexpr ADCValueSensor(ADCInstance& adc, ValueType* value) : adc(&adc), value(value) {}
18+
19+
[[nodiscard]] bool is_configured() const { return adc != nullptr && value != nullptr; }
20+
21+
[[nodiscard]] float read_raw() const { return (adc == nullptr) ? 0.0f : adc->get_raw(); }
22+
23+
[[nodiscard]] float read_voltage(float vref = kDefaultADCReferenceVoltage) const {
24+
if (adc == nullptr) {
25+
return 0.0f;
26+
}
27+
return adc->get_value_from_raw(read_raw(), vref);
28+
}
29+
30+
[[nodiscard]] float normalized_raw() const {
31+
if (adc == nullptr) {
32+
return 0.0f;
33+
}
34+
35+
const float max_raw =
36+
static_cast<float>(ADCInstance::max_raw_for_resolution(adc->resolution));
37+
if (max_raw <= 0.0f) {
38+
return 0.0f;
39+
}
40+
41+
return read_raw() / max_raw;
42+
}
43+
44+
[[nodiscard]] std::size_t bucket_index(std::size_t bucket_count) const {
45+
if (bucket_count == 0U) {
46+
return 0U;
47+
}
48+
49+
const auto index = static_cast<std::size_t>(normalized_raw() * bucket_count);
50+
return std::min(index, bucket_count - 1U);
51+
}
52+
53+
[[nodiscard]] std::size_t scaled_index(std::size_t max_index) const {
54+
const auto index = static_cast<std::size_t>(normalized_raw() * max_index);
55+
return std::min(index, max_index);
56+
}
57+
58+
ADCInstance* adc = nullptr;
59+
ValueType* value = nullptr;
60+
};
61+
62+
} // namespace ST_LIB::Sensors
Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#pragma once
22
#include <cstddef>
3-
#include <cstdint>
43

54
#include "Control/Blocks/MovingAverage.hpp"
6-
#include "HALAL/Services/ADC/NewADC.hpp"
5+
#include "Sensors/Common/ADCSensor.hpp"
76

8-
template <size_t N> class PT100 {
7+
template <size_t N> class PT100 : protected ST_LIB::Sensors::ADCValueSensor<float> {
98
public:
109
static constexpr float k = 841.836735;
1110
static constexpr float offset = -492.204082;
11+
static constexpr float reference_voltage = ST_LIB::Sensors::kDefaultADCReferenceVoltage;
1212
MovingAverage<N>* filter = nullptr;
1313

1414
PT100(ST_LIB::ADCDomain::Instance& adc, float* value, MovingAverage<N>& filter);
@@ -20,34 +20,34 @@ template <size_t N> class PT100 {
2020
void read();
2121

2222
protected:
23-
ST_LIB::ADCDomain::Instance* adc = nullptr;
24-
float* value = nullptr;
23+
using Base = ST_LIB::Sensors::ADCValueSensor<float>;
2524
};
2625

2726
template <size_t N>
2827
PT100<N>::PT100(ST_LIB::ADCDomain::Instance& adc, float* value, MovingAverage<N>& filter)
29-
: adc(&adc), value(value), filter(&filter) {}
28+
: Base(adc, value), filter(&filter) {}
3029

3130
template <size_t N>
3231
PT100<N>::PT100(ST_LIB::ADCDomain::Instance& adc, float& value, MovingAverage<N>& filter)
33-
: adc(&adc), value(&value), filter(&filter) {}
32+
: Base(adc, &value), filter(&filter) {}
3433

3534
template <size_t N>
36-
PT100<N>::PT100(ST_LIB::ADCDomain::Instance& adc, float* value) : adc(&adc), value(value) {}
35+
PT100<N>::PT100(ST_LIB::ADCDomain::Instance& adc, float* value) : Base(adc, value) {}
3736

3837
template <size_t N>
39-
PT100<N>::PT100(ST_LIB::ADCDomain::Instance& adc, float& value) : adc(&adc), value(&value) {}
38+
PT100<N>::PT100(ST_LIB::ADCDomain::Instance& adc, float& value) : Base(adc, &value) {}
4039

4140
template <size_t N> void PT100<N>::read() {
42-
if (adc == nullptr || value == nullptr) {
41+
if (!this->is_configured()) {
4342
return;
4443
}
45-
const float raw = adc->get_raw();
46-
const float val = adc->get_value_from_raw(raw, 3.3f);
44+
45+
const float val = this->read_voltage(reference_voltage);
4746
if (filter != nullptr) {
4847
filter->input(k / val + offset);
4948
filter->execute();
50-
*value = filter->output_value;
51-
} else
52-
*value = k / val + offset;
49+
*this->value = filter->output_value;
50+
} else {
51+
*this->value = k / val + offset;
52+
}
5353
}

Inc/ST-LIB_LOW/Sensors/LinearSensor/FilteredLinearSensor.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ template <class Type, size_t N> class FilteredLinearSensor : public LinearSensor
2626
: LinearSensor<Type>(adc, slope, offset, value), filter(filter) {}
2727

2828
void read() {
29-
if (this->adc == nullptr || this->value == nullptr) {
29+
if (!this->is_configured()) {
3030
return;
3131
}
32-
const float raw = this->adc->get_raw();
33-
const float val = this->adc->get_value_from_raw(raw, this->vref);
34-
*this->value = filter.compute(this->slope * static_cast<Type>(val) + this->offset);
32+
33+
*this->value =
34+
filter.compute(this->compute_value_from_voltage(this->read_voltage(this->vref)));
3535
}
3636
};
3737

Inc/ST-LIB_LOW/Sensors/LinearSensor/LinearSensor.hpp

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@
66
*/
77

88
#pragma once
9-
#include <cstdint>
109
#include <type_traits>
1110

12-
#include "HALAL/Services/ADC/NewADC.hpp"
11+
#include "Sensors/Common/ADCSensor.hpp"
1312

1413
template <class Type>
1514
requires std::is_integral_v<Type> || std::is_floating_point_v<Type>
16-
class LinearSensor {
15+
class LinearSensor : protected ST_LIB::Sensors::ADCValueSensor<Type> {
1716
public:
1817
LinearSensor() = default;
1918
LinearSensor(
@@ -34,19 +33,21 @@ class LinearSensor {
3433
void read();
3534

3635
void set_offset(Type new_offset);
37-
Type get_offset();
36+
[[nodiscard]] Type get_offset() const;
3837

3938
void set_gain(Type new_gain);
40-
Type get_gain();
39+
[[nodiscard]] Type get_gain() const;
4140

42-
Type* get_value_pointer() const;
41+
[[nodiscard]] Type* get_value_pointer() const;
4342

4443
protected:
45-
ST_LIB::ADCDomain::Instance* adc = nullptr;
46-
Type slope;
47-
Type offset;
48-
Type* value = nullptr;
49-
float vref = 3.3f;
44+
using Base = ST_LIB::Sensors::ADCValueSensor<Type>;
45+
46+
[[nodiscard]] Type compute_value_from_voltage(float voltage) const;
47+
48+
Type slope{};
49+
Type offset{};
50+
float vref = ST_LIB::Sensors::kDefaultADCReferenceVoltage;
5051
};
5152

5253
template <class Type>
@@ -58,7 +59,7 @@ LinearSensor<Type>::LinearSensor(
5859
Type* value,
5960
float vref
6061
)
61-
: adc(&adc), slope(slope), offset(offset), value(value), vref(vref) {}
62+
: Base(adc, value), slope(slope), offset(offset), vref(vref) {}
6263

6364
template <class Type>
6465
requires std::is_integral_v<Type> || std::is_floating_point_v<Type>
@@ -69,29 +70,34 @@ LinearSensor<Type>::LinearSensor(
6970
Type& value,
7071
float vref
7172
)
72-
: LinearSensor::LinearSensor(adc, slope, offset, &value, vref) {}
73+
: LinearSensor(adc, slope, offset, &value, vref) {}
7374

7475
template <class Type>
7576
requires std::is_integral_v<Type> || std::is_floating_point_v<Type>
7677
void LinearSensor<Type>::read() {
77-
if (adc == nullptr || value == nullptr) {
78+
if (!this->is_configured()) {
7879
return;
7980
}
80-
const float raw = adc->get_raw();
81-
const float val = adc->get_value_from_raw(raw, vref);
8281

83-
*value = slope * (Type)val + offset;
82+
*this->value = compute_value_from_voltage(this->read_voltage(vref));
83+
}
84+
85+
template <class Type>
86+
requires std::is_integral_v<Type> || std::is_floating_point_v<Type>
87+
Type LinearSensor<Type>::compute_value_from_voltage(float voltage) const {
88+
const Type sensor_voltage = static_cast<Type>(voltage);
89+
return slope * sensor_voltage + offset;
8490
}
8591

8692
template <class Type>
8793
requires std::is_integral_v<Type> || std::is_floating_point_v<Type>
88-
Type LinearSensor<Type>::get_offset() {
94+
Type LinearSensor<Type>::get_offset() const {
8995
return offset;
9096
}
9197

9298
template <class Type>
9399
requires std::is_integral_v<Type> || std::is_floating_point_v<Type>
94-
Type LinearSensor<Type>::get_gain() {
100+
Type LinearSensor<Type>::get_gain() const {
95101
return slope;
96102
}
97103

@@ -110,5 +116,5 @@ void LinearSensor<Type>::set_gain(Type new_gain) {
110116
template <class Type>
111117
requires std::is_integral_v<Type> || std::is_floating_point_v<Type>
112118
Type* LinearSensor<Type>::get_value_pointer() const {
113-
return value;
119+
return this->value;
114120
}

Inc/ST-LIB_LOW/Sensors/LookupSensor/LookupSensor.hpp

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,47 @@
66
*/
77

88
#pragma once
9-
#include <cstdint>
10-
#include "HALAL/Services/ADC/NewADC.hpp"
11-
#include "ErrorHandler/ErrorHandler.hpp"
12-
#include "C++Utilities/CppUtils.hpp"
9+
#include <cstddef>
10+
#include <span>
1311

14-
#define REFERENCE_VOLTAGE 3.3
12+
#include "Sensors/Common/ADCSensor.hpp"
1513

16-
class LookupSensor {
14+
class LookupSensor : protected ST_LIB::Sensors::ADCValueSensor<double> {
1715
public:
1816
LookupSensor() = default;
19-
LookupSensor(ST_LIB::ADCDomain::Instance& adc, double* table, int table_size, double* value);
20-
LookupSensor(ST_LIB::ADCDomain::Instance& adc, double* table, int table_size, double& value);
21-
void read();
17+
LookupSensor(ST_LIB::ADCDomain::Instance& adc, std::span<const double> table, double* value)
18+
: Base(adc, value), table(table) {}
19+
LookupSensor(ST_LIB::ADCDomain::Instance& adc, std::span<const double> table, double& value)
20+
: LookupSensor(adc, table, &value) {}
21+
LookupSensor(
22+
ST_LIB::ADCDomain::Instance& adc,
23+
const double* table,
24+
std::size_t table_size,
25+
double* value
26+
)
27+
: LookupSensor(
28+
adc,
29+
(table == nullptr) ? std::span<const double>{}
30+
: std::span<const double>(table, table_size),
31+
value
32+
) {}
33+
LookupSensor(
34+
ST_LIB::ADCDomain::Instance& adc,
35+
const double* table,
36+
std::size_t table_size,
37+
double& value
38+
)
39+
: LookupSensor(adc, table, table_size, &value) {}
40+
void read() {
41+
if (!this->is_configured() || table.empty()) {
42+
return;
43+
}
44+
45+
*this->value = table[this->bucket_index(table.size())];
46+
}
2247

2348
protected:
24-
ST_LIB::ADCDomain::Instance* adc = nullptr;
25-
double* table = nullptr;
26-
int table_size = 0;
27-
double* value = nullptr;
49+
using Base = ST_LIB::Sensors::ADCValueSensor<double>;
50+
51+
std::span<const double> table{};
2852
};

Inc/ST-LIB_LOW/Sensors/NTC/NTC.hpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,22 @@
99
This NTC class is not generic. It is only for 10k Ohm, 1976Beta value NTCs.
1010
*/
1111
#pragma once
12-
#include <cstdint>
12+
#include <cstddef>
1313

14-
#include "HALAL/Services/ADC/NewADC.hpp"
14+
#include "Sensors/Common/ADCSensor.hpp"
1515

16-
class NTC {
16+
class NTC : protected ST_LIB::Sensors::ADCValueSensor<float> {
1717
public:
1818
NTC() = default;
19-
NTC(ST_LIB::ADCDomain::Instance& adc, float* src);
20-
NTC(ST_LIB::ADCDomain::Instance& adc, float& src);
21-
void read();
19+
NTC(ST_LIB::ADCDomain::Instance& adc, float* src) : Base(adc, src) {}
20+
NTC(ST_LIB::ADCDomain::Instance& adc, float& src) : Base(adc, &src) {}
21+
void read() {
22+
if (!this->is_configured()) {
23+
return;
24+
}
25+
26+
*this->value = static_cast<float>(NTC_table[this->scaled_index(table_max_index)]) * 0.1f;
27+
}
2228

2329
private:
2430
static constexpr int NTC_table[4096] = {
@@ -297,6 +303,7 @@ class NTC {
297303
-625, -632, -640, -648, -657, -666, -677, -688, -700, -714, -729, -748, -770, -797, -835,
298304
-873
299305
};
300-
float* value = nullptr;
301-
ST_LIB::ADCDomain::Instance* adc = nullptr;
306+
using Base = ST_LIB::Sensors::ADCValueSensor<float>;
307+
308+
static constexpr std::size_t table_max_index = 4095U;
302309
};

Src/ST-LIB_LOW/Sensors/LookupSensor/LookupSensor.cpp

Lines changed: 0 additions & 31 deletions
This file was deleted.

0 commit comments

Comments
 (0)