Skip to content

Commit

Permalink
ntc: scale based on input voltage
Browse files Browse the repository at this point in the history
resolves #2500
resolves #2523

- fixing default config values, make sure we take inputs into
  an account and not assume we stay in the 0.0...1.0 range
- use shelly values from tasmota analog sensor impl
- handle edgecase when both resistances are zeroed
- clearer description of available connection schemes

in theory, there is also an option of having *both* up and down
resistors at the same time; right now we simply deduce NTC position by
making it an opposite of resistance. ldrsensor implementation currently
allows to explicitly set sensor position
  • Loading branch information
mcspr committed Jul 20, 2022
1 parent b366d77 commit 1b49326
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 18 deletions.
4 changes: 2 additions & 2 deletions code/espurna/config/hardware.h
Original file line number Diff line number Diff line change
Expand Up @@ -3792,9 +3792,9 @@
#define NTC_SUPPORT 1
#define SENSOR_SUPPORT 1
#define NTC_BETA 3350
#define NTC_R_UP 10000
#define NTC_R_UP 32000
#define NTC_R_DOWN 0
#define NTC_R0 8000
#define NTC_R0 10000

#elif defined(ALLTERCO_SHELLY25)
// Info
Expand Down
14 changes: 11 additions & 3 deletions code/espurna/config/sensors.h
Original file line number Diff line number Diff line change
Expand Up @@ -876,12 +876,20 @@
#define NTC_DELAY 0 // Delay between samples in micros
#endif

#ifndef NTC_R_UP
#define NTC_R_UP 0 // Resistor upstream, set to 0 if none
#ifndef NTC_INPUT_VOLTAGE
#define NTC_INPUT_VOLTAGE 3.3 // Actual voltage that is connected to the ADC
#endif

#ifndef NTC_R_DOWN
#define NTC_R_DOWN 10000 // Resistor downstream, set to 0 if none
#define NTC_R_DOWN 10000 // (Ohm) Resistor DOWN, NTC is connected to the voltage
// [V]─NTC─┬─R_DOWN─[GND]
// [ADC]
#endif

#ifndef NTC_R_UP
#define NTC_R_UP 0 // (Ohm) Resistor UP, NTC is connected to the ground
// [V]─R_UP─┬─NTC─[GND]
// [ADC]
#endif

#ifndef NTC_T0
Expand Down
1 change: 1 addition & 0 deletions code/espurna/sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2125,6 +2125,7 @@ void load() {
sensor->setDelay(NTC_DELAY);
sensor->setUpstreamResistor(NTC_R_UP);
sensor->setDownstreamResistor(NTC_R_DOWN);
sensor->setInputVoltage(NTC_INPUT_VOLTAGE);
sensor->setBeta(NTC_BETA);
sensor->setR0(NTC_R0);
sensor->setT0(NTC_T0);
Expand Down
49 changes: 36 additions & 13 deletions code/espurna/sensors/NTCSensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ class NTCSensor : public AnalogSensor {
}
}

void setInputVoltage(double voltage) {
if (voltage > 0) {
_input_voltage = voltage;
}
}

// ---------------------------------------------------------------------
// Sensor API
// ---------------------------------------------------------------------
Expand All @@ -57,6 +63,16 @@ class NTCSensor : public AnalogSensor {
return 1;
}

void begin() override {
_error = SENSOR_ERROR_OK;
if (!_resistance_down && !_resistance_up) {
_error = SENSOR_ERROR_CONFIG;
return;
}

AnalogSensor::begin();
}

// Descriptive name of the sensor
String description() const override {
return F("NTC @ TOUT");
Expand All @@ -80,21 +96,27 @@ class NTCSensor : public AnalogSensor {
return espurna::sensor::Unit::None;
}

// Previous version happened to use AnalogSensor readings with factor and offset applied
// In case it was useful, this should also support the scaling in calculations for T
void pre() override {
// Previous version happened to use AnalogSensor readings with factor and offset applied
// In case it was useful, this should also support the scaling in calculations for T
// Actual ADC voltage is 0.0...1.0, convert back from 12bit scale
// Depending on where NTC is connected, get current resistance
const double voltage = static_cast<double>(_rawRead()) / AnalogSensor::RawMax;

_error = SENSOR_ERROR_OK;
if (_input_voltage < voltage) {
_error = SENSOR_ERROR_OVERFLOW;
return;
}

// Ru = (AnalogMax/c - 1) * Rd
const auto reading = _rawRead();
const double alpha {
(reading != 0)
? ((AnalogSensor::RawMax / reading) - 1.0)
: 1.0 };

const double resistance = (_resistance_down > 0)
? (_resistance_down * alpha)
: ((_resistance_up > 0) && (alpha > 0.0))
? (_resistance_up / alpha)
: (_R0);
const bool resistance_down = (_resistance_down > 0.0);
const double resistance =
(resistance_down && (voltage > 0.0))
? ((_resistance_down * (_input_voltage - voltage)) / voltage)
: (resistance_down)
? std::numeric_limits<decltype(_rawRead())>::max()
: ((_resistance_up * voltage) / (_input_voltage - voltage));

// 1/T = 1/T0 + 1/B * ln(R/R0)
_value = 1.0 / ((1.0 / _T0) + (fs_log(resistance / _R0) / _beta));
Expand All @@ -117,5 +139,6 @@ class NTCSensor : public AnalogSensor {
unsigned long _resistance_down = NTC_R_DOWN;
unsigned long _R0 = NTC_R0;
double _T0 = NTC_T0;
double _input_voltage = NTC_INPUT_VOLTAGE;

};

0 comments on commit 1b49326

Please sign in to comment.