Remarks

AnalogTemperature
Status Status badge: working
Source code GitHub
NuGet package NuGet Gallery for Meadow.Foundation

The analog temperature sensor driver can be used with any sensor that has a linear voltage response. It has been tested with the following series of temperature sensors:

  • TMP35
  • TMP36
  • TMP37
  • LM35

These sensors exhibit a linear change in the analog voltage for each degree centigrade. This is often presented in the datasheet as follows:

This driver should work with any sensor of this type.

Code Example

AnalogTemperature analogTemperature;

public override Task Initialize()
{
    Console.WriteLine("Initializing...");

    // configure our AnalogTemperature sensor
    analogTemperature = new AnalogTemperature (
        device: Device,
        analogPin: Device.Pins.A03,
        sensorType: AnalogTemperature.KnownSensorType.LM35
    );

    //==== IObservable Pattern with an optional notification filter.
    var consumer = AnalogTemperature.CreateObserver(
        handler: result => Console.WriteLine($"Observer filter satisfied: {result.New.Celsius:N2}C, old: {result.Old?.Celsius:N2}C"),

        // only notify if the change is greater than 0.5°C
        filter: result => {
            if (result.Old is { } old) 
            {   //c# 8 pattern match syntax. checks for !null and assigns var.
                return (result.New - old).Abs().Celsius > 0.5; // returns true if > 0.5°C change.
            }
            return false;
        }
        // if you want to always get notified, pass null for the filter:
        //filter: null
    );
    analogTemperature.Subscribe(consumer);

    // classical .NET events can also be used:
    analogTemperature.TemperatureUpdated += (sender, result) => {
        Console.WriteLine($"Temp Changed, temp: {result.New.Celsius:N2}C, old: {result.Old?.Celsius:N2}C");
    };

    //==== One-off reading use case/pattern
    ReadTemp().Wait();

    // Spin up the sampling thread so that events are raised and IObservable notifications are sent.
    analogTemperature.StartUpdating(TimeSpan.FromMilliseconds(1000));

    return Task.CompletedTask;
}

protected async Task ReadTemp()
{
    var temperature = await analogTemperature.Read();
    Console.WriteLine($"Initial temp: {temperature.Celsius:N2}C");
}

Sample project(s) available on GitHub

Purchasing

TMP36 sensors can be purchased from a number of suppliers including:

The following application demonstrates how to use the TMP36 in interrupt mode. The sensor will be read every second and changes in values greater than +/- 0.1C will generate and interrupt:

public class MeadowApp : App<F7Micro, MeadowApp>
{
    AnalogTemperature analogTemperature;

    public MeadowApp()
    {
        Console.WriteLine("Initializing...");

        analogTemperature = new AnalogTemperature (
            device: Device,
            analogPin: Device.Pins.A00,
            sensorType: AnalogTemperature.KnownSensorType.LM35
        );

        var consumer = AnalogTemperature.CreateObserver(
            handler: result => {
                Console.WriteLine($"Observer filter satisfied: {result.New.Celsius:N2}C, old: {result.Old?.Celsius:N2}C");
            },
            filter: result => {
                if (result.Old is { } old) { //c# 8 pattern match syntax. checks for !null and assigns var.
                    return (result.New - old).Abs().Celsius > 0.5; // returns true if > 0.5°C change.
                } return false;
            }
        );
        analogTemperature.Subscribe(consumer);

        analogTemperature.TemperatureUpdated += (object sender, IChangeResult<Meadow.Units.Temperature> result) => {
            Console.WriteLine($"Temp Changed, temp: {result.New.Celsius:N2}C, old: {result.Old?.Celsius:N2}C");
        };

        ReadTemp().Wait();

        analogTemperature.StartUpdating();
    }

    async Task ReadTemp()
    {
        var temperature = await analogTemperature.Read();
        Console.WriteLine($"Initial temp: {temperature.New.Celsius:N2}C");
    }
}

Sample projects available on GitHub

Wiring Example

To wire a TMP36 to your Meadow board, connect the following:

TMP36 Meadow Pin
GND GND
IN A1
VCC 5V

It should look like the following diagram:

Characteristic Locus
Inheritance System.Object ObservableBase<Units.Temperature> SensorBase<Units.Temperature> > AnalogTemperature
Implements ITemperatureSensor
Inherited Members SensorBase<Units.Temperature>.Updated SensorBase<Units.Temperature>.samplingLock SensorBase<Units.Temperature>.SamplingTokenSource SensorBase<Units.Temperature>.Conditions SensorBase<Units.Temperature>.IsSampling SensorBase<Units.Temperature>.UpdateInterval SensorBase<Units.Temperature>.Read() ObservableBase<Units.Temperature>.observers ObservableBase<Units.Temperature>.NotifyObservers(IChangeResult<Units.Temperature>) ObservableBase<Units.Temperature>.Subscribe(IObserver<IChangeResult<Units.Temperature>>) ObservableBase<Units.Temperature>.CreateObserver(Action<IChangeResult<Units.Temperature>>, Nullable<Predicate<IChangeResult<Units.Temperature>>>)
Namespace Meadow.Foundation.Sensors.Temperature
Assembly Meadow.Foundation.dll

Syntax

public class AnalogTemperature : SensorBase<Units.Temperature>, ITemperatureSensor

Constructors

AnalogTemperature(IAnalogInputController, IPin, AnalogTemperature.KnownSensorType, AnalogTemperature.Calibration, Int32, Nullable<TimeSpan>)

Creates a new instance of the AnalogTemperature class.

Declaration
public AnalogTemperature(IAnalogInputController device, IPin analogPin, AnalogTemperature.KnownSensorType sensorType, AnalogTemperature.Calibration calibration = null, int sampleCount = 5, TimeSpan? sampleInterval = null)

Parameters

Type Name Description
IAnalogInputController device

The IAnalogInputController to create the port on.

IPin analogPin

Analog pin the temperature sensor is connected to.

AnalogTemperature.KnownSensorType sensorType

Type of sensor attached to the analog port.

AnalogTemperature.Calibration calibration

Calibration for the analog temperature sensor. Only used if sensorType is set to Custom.

System.Int32 sampleCount

How many samples to take during a given reading. These are automatically averaged to reduce noise.

System.Nullable<TimeSpan> sampleInterval

The time, to wait in between samples during a reading.

AnalogTemperature(IAnalogInputPort, AnalogTemperature.KnownSensorType, AnalogTemperature.Calibration)

Creates a new instance of the AnalogTemperature class.

Declaration
public AnalogTemperature(IAnalogInputPort analogInputPort, AnalogTemperature.KnownSensorType sensorType, AnalogTemperature.Calibration calibration = null)

Parameters

Type Name Description
IAnalogInputPort analogInputPort

The IAnalogInputPort connected to the sensor.

AnalogTemperature.KnownSensorType sensorType

Type of sensor attached to the analog port.

AnalogTemperature.Calibration calibration

Calibration for the analog temperature sensor. Only used if sensorType is set to Custom.

Properties

AnalogInputPort

Declaration
protected IAnalogInputPort AnalogInputPort { get; }

Property Value

Type Description
IAnalogInputPort

SensorCalibration

Declaration
public AnalogTemperature.Calibration SensorCalibration { get; set; }

Property Value

Type Description
AnalogTemperature.Calibration

Temperature

Temperature in degrees centigrade.

Declaration
public Units.Temperature? Temperature { get; protected set; }

Property Value

Type Description
System.Nullable<Units.Temperature>

Remarks

The temperature is given by the following calculation: temperature = (reading in millivolts - yIntercept) / millivolts per degree centigrade

Methods

RaiseEventsAndNotify(IChangeResult<Units.Temperature>)

Method to notify subscribers to TemperatureUpdated event handler

Declaration
protected override void RaiseEventsAndNotify(IChangeResult<Units.Temperature> changeResult)

Parameters

Type Name Description
IChangeResult<Units.Temperature> changeResult

Overrides

Meadow.Foundation.SensorBase<Units.Temperature>.RaiseEventsAndNotify(IChangeResult<Units.Temperature>)

ReadSensor()

Convenience method to get the current temperature. For frequent reads, use StartSampling() and StopSampling() in conjunction with the SampleBuffer.

Declaration
protected override Task<Units.Temperature> ReadSensor()

Returns

Type Description
Task<Units.Temperature>

A float value that's ann average value of all the samples taken.

Overrides

Meadow.Foundation.SensorBase<Units.Temperature>.ReadSensor()

StartUpdating(Nullable<TimeSpan>)

Starts continuously sampling the sensor.

This method also starts raising Changed events and IObservable subscribers getting notified. Use the readIntervalDuration parameter to specify how often events and notifications are raised/sent.

Declaration
public void StartUpdating(TimeSpan? updateInterval)

Parameters

Type Name Description
System.Nullable<TimeSpan> updateInterval

A TimeSpan that specifies how long to wait between readings. This value influences how often *Updated events are raised and IObservable consumers are notified. The default is 5 seconds.

StopUpdating()

Stops sampling the temperature.

Declaration
public void StopUpdating()

VoltageToTemperature(Voltage)

Converts voltage to temperature in Celcius

Declaration
protected Units.Temperature VoltageToTemperature(Voltage voltage)

Parameters

Type Name Description
Voltage voltage

Returns

Type Description
Units.Temperature

temperature in celcius

Events

TemperatureUpdated

Raised when the value of the reading changes.

Declaration
public event EventHandler<IChangeResult<Units.Temperature>> TemperatureUpdated

Event Type

Type Description
EventHandler<IChangeResult<Units.Temperature>>