From 963cb05798f36d299455e8e955a0dd33bc99f448 Mon Sep 17 00:00:00 2001 From: Chris Tacke Date: Sat, 9 Nov 2024 16:22:27 -0600 Subject: [PATCH] added b-parameter calculation for a thermistor --- .../Driver/BParameterThermistor.cs | 64 +++++++ .../SteinhartHartCalculatedThermistor.cs | 175 +++++++++--------- 2 files changed, 151 insertions(+), 88 deletions(-) create mode 100644 Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Thermistor/Driver/BParameterThermistor.cs diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Thermistor/Driver/BParameterThermistor.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Thermistor/Driver/BParameterThermistor.cs new file mode 100644 index 0000000000..4c58a51bc0 --- /dev/null +++ b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Thermistor/Driver/BParameterThermistor.cs @@ -0,0 +1,64 @@ +using Meadow.Hardware; +using Meadow.Units; +using System; +using System.Threading.Tasks; + +namespace Meadow.Foundation.Sensors.Temperature; + +/// +/// Thermistor temperature sensor object using the B-Parameter or Beta equation to determine temperature +/// +public class BParameterThermistor : Thermistor +{ + // Constants for the thermistor + private const double B = 3950; // B-parameter (in Kelvin) + private const double T0 = 298.15; // Reference temperature T0 (in Kelvin, which is 25°C) + + /// + public override Resistance NominalResistance { get; } + + /// + /// Gets the resistance of the fixed-value series resistor in your voltage divider circuit + /// + public Resistance SeriesResistance { get; } + + /// + /// Creates an instance of a BParameterThermistor using a 10k resistor and a 10k thermistor + /// + /// The analog input reading the thermistor voltage divider output + public BParameterThermistor(IAnalogInputPort analogInput) + : this(analogInput, 10_000.Ohms(), 10_000.Ohms()) + { + } + + /// + /// Creates an instance of a BParameterThermistor + /// + /// The analog input reading the thermistor voltage divider output + /// The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor) + /// The resistance of the fixed-value series resistor in your voltage divider circuit + public BParameterThermistor( + IAnalogInputPort analogInput, + Resistance nominalResistance, + Resistance seriesResistance + ) + : base(analogInput) + { + SeriesResistance = seriesResistance; + NominalResistance = nominalResistance; + } + + /// + protected override async Task ReadSensor() + { + var voltageReading = await AnalogInputPort.Read(); + + // ohms + var measuredResistance = (SeriesResistance.Ohms * voltageReading.Volts) / (AnalogInputPort.ReferenceVoltage.Volts - voltageReading.Volts); + + // Calculate temperature in Kelvin using the B-parameter equation + double temperatureK = 1 / ((1 / T0) + (1 / B) * Math.Log(measuredResistance / NominalResistance.Ohms)); + + return new Units.Temperature(temperatureK, Units.Temperature.UnitType.Kelvin); + } +} diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Thermistor/Driver/SteinhartHartCalculatedThermistor.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Thermistor/Driver/SteinhartHartCalculatedThermistor.cs index 1dc77d57d5..e3fa277862 100644 --- a/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Thermistor/Driver/SteinhartHartCalculatedThermistor.cs +++ b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Thermistor/Driver/SteinhartHartCalculatedThermistor.cs @@ -3,107 +3,106 @@ using System; using System.Threading.Tasks; -namespace Meadow.Foundation.Sensors.Temperature +namespace Meadow.Foundation.Sensors.Temperature; + +/// +/// Thermistor temperature sensor object using the Steinhart-Hart equation to determine temperature +/// +public class SteinhartHartCalculatedThermistor : Thermistor { /// - /// Thermistor temperature sensor object using the Steinhart-Hart equation to determine temperature + /// The common default beta coefficient (3950) for many thermistors /// - public class SteinhartHartCalculatedThermistor : Thermistor - { - /// - /// The common default beta coefficient (3950) for many thermistors - /// - public const double DefaultBetaCoefficient = 3950d; + public const double DefaultBetaCoefficient = 3950d; - /// - /// Gets the beta coefficient of the thermistor used in the Steinhart-Hart equation - /// - public double BetaCoefficient { get; } = DefaultBetaCoefficient; + /// + /// Gets the beta coefficient of the thermistor used in the Steinhart-Hart equation + /// + public double BetaCoefficient { get; } = DefaultBetaCoefficient; - /// - /// Gets the resistance of the fixed-value series resistor in your voltage divider circuit - /// - public Resistance SeriesResistance { get; } + /// + /// Gets the resistance of the fixed-value series resistor in your voltage divider circuit + /// + public Resistance SeriesResistance { get; } - /// - /// Gets the nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor) - /// - public override Resistance NominalResistance { get; } + /// + /// Gets the nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor) + /// + public override Resistance NominalResistance { get; } - /// - /// Creates a new SteinhartHartCalculatedThermistor object using the provided analog input and the thermistor's nominal resistance (i.e. 10kOhm) - /// - /// The analog input reading the thermistor voltage divider output - /// The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor) - /// The fixed resistor value will be assumed to match the thermistor's nominal resistance - public SteinhartHartCalculatedThermistor(IAnalogInputPort analogInput, Resistance nominalResistance) - : base(analogInput) - { - NominalResistance = nominalResistance; - SeriesResistance = nominalResistance; - } + /// + /// Creates a new SteinhartHartCalculatedThermistor object using the provided analog input and the thermistor's nominal resistance (i.e. 10kOhm) + /// + /// The analog input reading the thermistor voltage divider output + /// The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor) + /// The fixed resistor value will be assumed to match the thermistor's nominal resistance + public SteinhartHartCalculatedThermistor(IAnalogInputPort analogInput, Resistance nominalResistance) + : base(analogInput) + { + NominalResistance = nominalResistance; + SeriesResistance = nominalResistance; + } - /// - /// Creates a new SteinhartHartCalculatedThermistor object using the provided analog input and the thermistor's nominal resistance (i.e. 10kOhm) and the fixed resistor value of the voltage divider circuit. - /// - /// The analog input reading the thermistor voltage divider output - /// The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor) - /// The resistance of the fixed-value series resistor in your voltage divider circuit - public SteinhartHartCalculatedThermistor(IAnalogInputPort analogInput, Resistance nominalResistance, Resistance seriesResistance) - : base(analogInput) - { - NominalResistance = nominalResistance; - SeriesResistance = seriesResistance; - } + /// + /// Creates a new SteinhartHartCalculatedThermistor object using the provided analog input and the thermistor's nominal resistance (i.e. 10kOhm) and the fixed resistor value of the voltage divider circuit. + /// + /// The analog input reading the thermistor voltage divider output + /// The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor) + /// The resistance of the fixed-value series resistor in your voltage divider circuit + public SteinhartHartCalculatedThermistor(IAnalogInputPort analogInput, Resistance nominalResistance, Resistance seriesResistance) + : base(analogInput) + { + NominalResistance = nominalResistance; + SeriesResistance = seriesResistance; + } - /// - /// Creates a new SteinhartHartCalculatedThermistor object using the provided analog input and the thermistor's nominal resistance (i.e. 10kOhm) and the fixed resistor value of the voltage divider circuit. - /// - /// The analog input reading the thermistor voltage divider output - /// The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor) - /// The resistance of the fixed-value series resistor in your voltage divider circuit - /// The beta coefficient of the thermistor used in the Steinhart-Hart equation - public SteinhartHartCalculatedThermistor(IAnalogInputPort analogInput, Resistance nominalResistance, Resistance seriesResistance, double betaCoefficient) - : base(analogInput) - { - NominalResistance = nominalResistance; - SeriesResistance = seriesResistance; - BetaCoefficient = betaCoefficient; - } + /// + /// Creates a new SteinhartHartCalculatedThermistor object using the provided analog input and the thermistor's nominal resistance (i.e. 10kOhm) and the fixed resistor value of the voltage divider circuit. + /// + /// The analog input reading the thermistor voltage divider output + /// The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor) + /// The resistance of the fixed-value series resistor in your voltage divider circuit + /// The beta coefficient of the thermistor used in the Steinhart-Hart equation + public SteinhartHartCalculatedThermistor(IAnalogInputPort analogInput, Resistance nominalResistance, Resistance seriesResistance, double betaCoefficient) + : base(analogInput) + { + NominalResistance = nominalResistance; + SeriesResistance = seriesResistance; + BetaCoefficient = betaCoefficient; + } - /// - /// Creates a new SteinhartHartCalculatedThermistor object using the provided analog input and the thermistor's nominal resistance (i.e. 10kOhm) and the fixed resistor value of the voltage divider circuit. - /// - /// The analog input reading the thermistor voltage divider output - /// The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor) - /// The beta coefficient of the thermistor used in the Steinhart-Hart equation - /// The fixed resistor value will be assumed to match the thermistor's nominal resistance - public SteinhartHartCalculatedThermistor(IAnalogInputPort analogInput, Resistance nominalResistance, double betaCoefficient) - : base(analogInput) - { - NominalResistance = nominalResistance; - SeriesResistance = nominalResistance; - BetaCoefficient = betaCoefficient; - } + /// + /// Creates a new SteinhartHartCalculatedThermistor object using the provided analog input and the thermistor's nominal resistance (i.e. 10kOhm) and the fixed resistor value of the voltage divider circuit. + /// + /// The analog input reading the thermistor voltage divider output + /// The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor) + /// The beta coefficient of the thermistor used in the Steinhart-Hart equation + /// The fixed resistor value will be assumed to match the thermistor's nominal resistance + public SteinhartHartCalculatedThermistor(IAnalogInputPort analogInput, Resistance nominalResistance, double betaCoefficient) + : base(analogInput) + { + NominalResistance = nominalResistance; + SeriesResistance = nominalResistance; + BetaCoefficient = betaCoefficient; + } - /// - /// Update the Temperature property - /// - protected override async Task ReadSensor() - { - var voltageReading = await AnalogInputPort.Read(); + /// + /// Update the Temperature property + /// + protected override async Task ReadSensor() + { + var voltageReading = await AnalogInputPort.Read(); - // ohms - var measuredResistance = (SeriesResistance.Ohms * voltageReading.Volts) / (AnalogInputPort.ReferenceVoltage.Volts - voltageReading.Volts); + // ohms + var measuredResistance = (SeriesResistance.Ohms * voltageReading.Volts) / (AnalogInputPort.ReferenceVoltage.Volts - voltageReading.Volts); - double steinhart; - steinhart = measuredResistance / NominalResistance.Ohms; - steinhart = Math.Log(steinhart); - steinhart /= BetaCoefficient; - steinhart += 1.0 / NominalTemperature.Kelvin; - steinhart = 1.0 / steinhart; + double steinhart; + steinhart = measuredResistance / NominalResistance.Ohms; + steinhart = Math.Log(steinhart); + steinhart /= BetaCoefficient; + steinhart += 1.0 / NominalTemperature.Kelvin; + steinhart = 1.0 / steinhart; - return new Units.Temperature(steinhart, Units.Temperature.UnitType.Kelvin); - } + return new Units.Temperature(steinhart, Units.Temperature.UnitType.Kelvin); } }