Skip to content

Commit

Permalink
Merge pull request #1090 from WildernessLabs/feature/thermistor
Browse files Browse the repository at this point in the history
added b-parameter calculation for a thermistor
  • Loading branch information
adrianstevens authored Nov 10, 2024
2 parents 126afe4 + 963cb05 commit 5b8ecd4
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 88 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using Meadow.Hardware;
using Meadow.Units;
using System;
using System.Threading.Tasks;

namespace Meadow.Foundation.Sensors.Temperature;

/// <summary>
/// Thermistor temperature sensor object using the B-Parameter or Beta equation to determine temperature
/// </summary>
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)

/// <inheritdoc/>
public override Resistance NominalResistance { get; }

/// <summary>
/// Gets the resistance of the fixed-value series resistor in your voltage divider circuit
/// </summary>
public Resistance SeriesResistance { get; }

/// <summary>
/// Creates an instance of a BParameterThermistor using a 10k resistor and a 10k thermistor
/// </summary>
/// <param name="analogInput">The analog input reading the thermistor voltage divider output</param>
public BParameterThermistor(IAnalogInputPort analogInput)
: this(analogInput, 10_000.Ohms(), 10_000.Ohms())
{
}

/// <summary>
/// Creates an instance of a BParameterThermistor
/// </summary>
/// <param name="analogInput">The analog input reading the thermistor voltage divider output</param>
/// <param name="nominalResistance">The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor)</param>
/// <param name="seriesResistance">The resistance of the fixed-value series resistor in your voltage divider circuit</param>
public BParameterThermistor(
IAnalogInputPort analogInput,
Resistance nominalResistance,
Resistance seriesResistance
)
: base(analogInput)
{
SeriesResistance = seriesResistance;
NominalResistance = nominalResistance;
}

/// <inheritdoc/>
protected override async Task<Units.Temperature> 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,107 +3,106 @@
using System;
using System.Threading.Tasks;

namespace Meadow.Foundation.Sensors.Temperature
namespace Meadow.Foundation.Sensors.Temperature;

/// <summary>
/// Thermistor temperature sensor object using the Steinhart-Hart equation to determine temperature
/// </summary>
public class SteinhartHartCalculatedThermistor : Thermistor
{
/// <summary>
/// Thermistor temperature sensor object using the Steinhart-Hart equation to determine temperature
/// The common default beta coefficient (3950) for many thermistors
/// </summary>
public class SteinhartHartCalculatedThermistor : Thermistor
{
/// <summary>
/// The common default beta coefficient (3950) for many thermistors
/// </summary>
public const double DefaultBetaCoefficient = 3950d;
public const double DefaultBetaCoefficient = 3950d;

/// <summary>
/// Gets the beta coefficient of the thermistor used in the Steinhart-Hart equation
/// </summary>
public double BetaCoefficient { get; } = DefaultBetaCoefficient;
/// <summary>
/// Gets the beta coefficient of the thermistor used in the Steinhart-Hart equation
/// </summary>
public double BetaCoefficient { get; } = DefaultBetaCoefficient;

/// <summary>
/// Gets the resistance of the fixed-value series resistor in your voltage divider circuit
/// </summary>
public Resistance SeriesResistance { get; }
/// <summary>
/// Gets the resistance of the fixed-value series resistor in your voltage divider circuit
/// </summary>
public Resistance SeriesResistance { get; }

/// <summary>
/// Gets the nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor)
/// </summary>
public override Resistance NominalResistance { get; }
/// <summary>
/// Gets the nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor)
/// </summary>
public override Resistance NominalResistance { get; }

/// <summary>
/// Creates a new SteinhartHartCalculatedThermistor object using the provided analog input and the thermistor's nominal resistance (i.e. 10kOhm)
/// </summary>
/// <param name="analogInput">The analog input reading the thermistor voltage divider output</param>
/// <param name="nominalResistance">The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor)</param>
/// <remarks>The fixed resistor value will be assumed to match the thermistor's nominal resistance</remarks>
public SteinhartHartCalculatedThermistor(IAnalogInputPort analogInput, Resistance nominalResistance)
: base(analogInput)
{
NominalResistance = nominalResistance;
SeriesResistance = nominalResistance;
}
/// <summary>
/// Creates a new SteinhartHartCalculatedThermistor object using the provided analog input and the thermistor's nominal resistance (i.e. 10kOhm)
/// </summary>
/// <param name="analogInput">The analog input reading the thermistor voltage divider output</param>
/// <param name="nominalResistance">The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor)</param>
/// <remarks>The fixed resistor value will be assumed to match the thermistor's nominal resistance</remarks>
public SteinhartHartCalculatedThermistor(IAnalogInputPort analogInput, Resistance nominalResistance)
: base(analogInput)
{
NominalResistance = nominalResistance;
SeriesResistance = nominalResistance;
}

/// <summary>
/// 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.
/// </summary>
/// <param name="analogInput">The analog input reading the thermistor voltage divider output</param>
/// <param name="nominalResistance">The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor)</param>
/// <param name="seriesResistance">The resistance of the fixed-value series resistor in your voltage divider circuit</param>
public SteinhartHartCalculatedThermistor(IAnalogInputPort analogInput, Resistance nominalResistance, Resistance seriesResistance)
: base(analogInput)
{
NominalResistance = nominalResistance;
SeriesResistance = seriesResistance;
}
/// <summary>
/// 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.
/// </summary>
/// <param name="analogInput">The analog input reading the thermistor voltage divider output</param>
/// <param name="nominalResistance">The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor)</param>
/// <param name="seriesResistance">The resistance of the fixed-value series resistor in your voltage divider circuit</param>
public SteinhartHartCalculatedThermistor(IAnalogInputPort analogInput, Resistance nominalResistance, Resistance seriesResistance)
: base(analogInput)
{
NominalResistance = nominalResistance;
SeriesResistance = seriesResistance;
}

/// <summary>
/// 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.
/// </summary>
/// <param name="analogInput">The analog input reading the thermistor voltage divider output</param>
/// <param name="nominalResistance">The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor)</param>
/// <param name="seriesResistance">The resistance of the fixed-value series resistor in your voltage divider circuit</param>
/// <param name="betaCoefficient">The beta coefficient of the thermistor used in the Steinhart-Hart equation</param>
public SteinhartHartCalculatedThermistor(IAnalogInputPort analogInput, Resistance nominalResistance, Resistance seriesResistance, double betaCoefficient)
: base(analogInput)
{
NominalResistance = nominalResistance;
SeriesResistance = seriesResistance;
BetaCoefficient = betaCoefficient;
}
/// <summary>
/// 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.
/// </summary>
/// <param name="analogInput">The analog input reading the thermistor voltage divider output</param>
/// <param name="nominalResistance">The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor)</param>
/// <param name="seriesResistance">The resistance of the fixed-value series resistor in your voltage divider circuit</param>
/// <param name="betaCoefficient">The beta coefficient of the thermistor used in the Steinhart-Hart equation</param>
public SteinhartHartCalculatedThermistor(IAnalogInputPort analogInput, Resistance nominalResistance, Resistance seriesResistance, double betaCoefficient)
: base(analogInput)
{
NominalResistance = nominalResistance;
SeriesResistance = seriesResistance;
BetaCoefficient = betaCoefficient;
}

/// <summary>
/// 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.
/// </summary>
/// <param name="analogInput">The analog input reading the thermistor voltage divider output</param>
/// <param name="nominalResistance">The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor)</param>
/// <param name="betaCoefficient">The beta coefficient of the thermistor used in the Steinhart-Hart equation</param>
/// <remarks>The fixed resistor value will be assumed to match the thermistor's nominal resistance</remarks>
public SteinhartHartCalculatedThermistor(IAnalogInputPort analogInput, Resistance nominalResistance, double betaCoefficient)
: base(analogInput)
{
NominalResistance = nominalResistance;
SeriesResistance = nominalResistance;
BetaCoefficient = betaCoefficient;
}
/// <summary>
/// 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.
/// </summary>
/// <param name="analogInput">The analog input reading the thermistor voltage divider output</param>
/// <param name="nominalResistance">The nominal resistance of the thermistor (e.g. 10kOhm for a 10k thermistor)</param>
/// <param name="betaCoefficient">The beta coefficient of the thermistor used in the Steinhart-Hart equation</param>
/// <remarks>The fixed resistor value will be assumed to match the thermistor's nominal resistance</remarks>
public SteinhartHartCalculatedThermistor(IAnalogInputPort analogInput, Resistance nominalResistance, double betaCoefficient)
: base(analogInput)
{
NominalResistance = nominalResistance;
SeriesResistance = nominalResistance;
BetaCoefficient = betaCoefficient;
}

/// <summary>
/// Update the Temperature property
/// </summary>
protected override async Task<Units.Temperature> ReadSensor()
{
var voltageReading = await AnalogInputPort.Read();
/// <summary>
/// Update the Temperature property
/// </summary>
protected override async Task<Units.Temperature> 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);
}
}

0 comments on commit 5b8ecd4

Please sign in to comment.