Remarks
AnalogTemperature | |
---|---|
Status | |
Source code | GitHub |
NuGet package |
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()
{
Resolver.Log.Info("Initializing...");
// configure our AnalogTemperature sensor
analogTemperature = new AnalogTemperature (
analogPin: Device.Pins.A03,
sensorType: AnalogTemperature.KnownSensorType.LM35
);
//==== IObservable Pattern with an optional notification filter.
var consumer = AnalogTemperature.CreateObserver(
handler: result => Resolver.Log.Info($"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) => {
Resolver.Log.Info($"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();
Resolver.Log.Info($"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:
Syntax
public class AnalogTemperature : SamplingSensorBase<Temperature>, IObservable<IChangeResult<Temperature>>, ITemperatureSensor, ISamplingSensor<Temperature>, ISensor<Temperature>
Constructors
AnalogTemperature(IAnalogInputPort, KnownSensorType, 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 |
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. |
Remarks
AnalogTemperature | |
---|---|
Status | |
Source code | GitHub |
NuGet package |
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()
{
Resolver.Log.Info("Initializing...");
// configure our AnalogTemperature sensor
analogTemperature = new AnalogTemperature (
analogPin: Device.Pins.A03,
sensorType: AnalogTemperature.KnownSensorType.LM35
);
//==== IObservable Pattern with an optional notification filter.
var consumer = AnalogTemperature.CreateObserver(
handler: result => Resolver.Log.Info($"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) => {
Resolver.Log.Info($"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();
Resolver.Log.Info($"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:
AnalogTemperature(IPin, KnownSensorType, Calibration?, int, TimeSpan?)
Creates a new instance of the AnalogTemperature class.
Declaration
public AnalogTemperature(IPin analogPin, AnalogTemperature.KnownSensorType sensorType, AnalogTemperature.Calibration? calibration = null, int sampleCount = 5, TimeSpan? sampleInterval = null)
Parameters
Type | Name | Description |
---|---|---|
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 - used if sensorType is set to Custom |
int | sampleCount | How many samples to take during a given reading. These are automatically averaged to reduce noise |
TimeSpan? | sampleInterval | The time between sample readings |
Remarks
AnalogTemperature | |
---|---|
Status | |
Source code | GitHub |
NuGet package |
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()
{
Resolver.Log.Info("Initializing...");
// configure our AnalogTemperature sensor
analogTemperature = new AnalogTemperature (
analogPin: Device.Pins.A03,
sensorType: AnalogTemperature.KnownSensorType.LM35
);
//==== IObservable Pattern with an optional notification filter.
var consumer = AnalogTemperature.CreateObserver(
handler: result => Resolver.Log.Info($"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) => {
Resolver.Log.Info($"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();
Resolver.Log.Info($"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:
Properties
AnalogInputPort
Provide the ability to read the temperature from the following sensors:
- TMP35 / 36 / 37
- LM35 / 45
Declaration
protected IAnalogInputPort AnalogInputPort { get; }
Property Value
Type | Description |
---|---|
IAnalogInputPort |
Remarks
AnalogTemperature | |
---|---|
Status | |
Source code | GitHub |
NuGet package |
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()
{
Resolver.Log.Info("Initializing...");
// configure our AnalogTemperature sensor
analogTemperature = new AnalogTemperature (
analogPin: Device.Pins.A03,
sensorType: AnalogTemperature.KnownSensorType.LM35
);
//==== IObservable Pattern with an optional notification filter.
var consumer = AnalogTemperature.CreateObserver(
handler: result => Resolver.Log.Info($"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) => {
Resolver.Log.Info($"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();
Resolver.Log.Info($"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:
SensorCalibration
Provide the ability to read the temperature from the following sensors:
- TMP35 / 36 / 37
- LM35 / 45
Declaration
public AnalogTemperature.Calibration SensorCalibration { get; set; }
Property Value
Type | Description |
---|---|
AnalogTemperature.Calibration |
Remarks
AnalogTemperature | |
---|---|
Status | |
Source code | GitHub |
NuGet package |
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()
{
Resolver.Log.Info("Initializing...");
// configure our AnalogTemperature sensor
analogTemperature = new AnalogTemperature (
analogPin: Device.Pins.A03,
sensorType: AnalogTemperature.KnownSensorType.LM35
);
//==== IObservable Pattern with an optional notification filter.
var consumer = AnalogTemperature.CreateObserver(
handler: result => Resolver.Log.Info($"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) => {
Resolver.Log.Info($"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();
Resolver.Log.Info($"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:
Temperature
Current Temperature
Declaration
public Temperature? Temperature { get; protected set; }
Property Value
Type | Description |
---|---|
Temperature? |
Remarks
AnalogTemperature | |
---|---|
Status | |
Source code | GitHub |
NuGet package |
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()
{
Resolver.Log.Info("Initializing...");
// configure our AnalogTemperature sensor
analogTemperature = new AnalogTemperature (
analogPin: Device.Pins.A03,
sensorType: AnalogTemperature.KnownSensorType.LM35
);
//==== IObservable Pattern with an optional notification filter.
var consumer = AnalogTemperature.CreateObserver(
handler: result => Resolver.Log.Info($"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) => {
Resolver.Log.Info($"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();
Resolver.Log.Info($"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:
Methods
RaiseEventsAndNotify(IChangeResult<Temperature>)
Method to notify subscribers to TemperatureUpdated event handler
Declaration
protected override void RaiseEventsAndNotify(IChangeResult<Temperature> changeResult)
Parameters
Type | Name | Description |
---|---|---|
IChangeResult<Temperature> | changeResult |
Overrides
Remarks
AnalogTemperature | |
---|---|
Status | |
Source code | GitHub |
NuGet package |
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()
{
Resolver.Log.Info("Initializing...");
// configure our AnalogTemperature sensor
analogTemperature = new AnalogTemperature (
analogPin: Device.Pins.A03,
sensorType: AnalogTemperature.KnownSensorType.LM35
);
//==== IObservable Pattern with an optional notification filter.
var consumer = AnalogTemperature.CreateObserver(
handler: result => Resolver.Log.Info($"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) => {
Resolver.Log.Info($"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();
Resolver.Log.Info($"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:
ReadSensor()
Convenience method to get the current temperature. For frequent reads, use StartSampling() and StopSampling() in conjunction with the SampleBuffer.
Declaration
protected override Task<Temperature> ReadSensor()
Returns
Type | Description |
---|---|
Task<Temperature> | The temperature averages of the given sample count |
Overrides
Remarks
AnalogTemperature | |
---|---|
Status | |
Source code | GitHub |
NuGet package |
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()
{
Resolver.Log.Info("Initializing...");
// configure our AnalogTemperature sensor
analogTemperature = new AnalogTemperature (
analogPin: Device.Pins.A03,
sensorType: AnalogTemperature.KnownSensorType.LM35
);
//==== IObservable Pattern with an optional notification filter.
var consumer = AnalogTemperature.CreateObserver(
handler: result => Resolver.Log.Info($"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) => {
Resolver.Log.Info($"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();
Resolver.Log.Info($"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:
StartUpdating(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 override void StartUpdating(TimeSpan? updateInterval)
Parameters
Type | Name | Description |
---|---|---|
TimeSpan? | updateInterval | A |
Overrides
Remarks
AnalogTemperature | |
---|---|
Status | |
Source code | GitHub |
NuGet package |
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()
{
Resolver.Log.Info("Initializing...");
// configure our AnalogTemperature sensor
analogTemperature = new AnalogTemperature (
analogPin: Device.Pins.A03,
sensorType: AnalogTemperature.KnownSensorType.LM35
);
//==== IObservable Pattern with an optional notification filter.
var consumer = AnalogTemperature.CreateObserver(
handler: result => Resolver.Log.Info($"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) => {
Resolver.Log.Info($"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();
Resolver.Log.Info($"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:
StopUpdating()
Stops sampling the temperature
Declaration
public override void StopUpdating()
Overrides
Remarks
AnalogTemperature | |
---|---|
Status | |
Source code | GitHub |
NuGet package |
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()
{
Resolver.Log.Info("Initializing...");
// configure our AnalogTemperature sensor
analogTemperature = new AnalogTemperature (
analogPin: Device.Pins.A03,
sensorType: AnalogTemperature.KnownSensorType.LM35
);
//==== IObservable Pattern with an optional notification filter.
var consumer = AnalogTemperature.CreateObserver(
handler: result => Resolver.Log.Info($"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) => {
Resolver.Log.Info($"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();
Resolver.Log.Info($"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:
VoltageToTemperature(Voltage)
Converts voltage to Temperature
Declaration
protected Temperature VoltageToTemperature(Voltage voltage)
Parameters
Type | Name | Description |
---|---|---|
Voltage | voltage |
Returns
Type | Description |
---|---|
Temperature | Temperature |
Remarks
AnalogTemperature | |
---|---|
Status | |
Source code | GitHub |
NuGet package |
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()
{
Resolver.Log.Info("Initializing...");
// configure our AnalogTemperature sensor
analogTemperature = new AnalogTemperature (
analogPin: Device.Pins.A03,
sensorType: AnalogTemperature.KnownSensorType.LM35
);
//==== IObservable Pattern with an optional notification filter.
var consumer = AnalogTemperature.CreateObserver(
handler: result => Resolver.Log.Info($"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) => {
Resolver.Log.Info($"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();
Resolver.Log.Info($"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:
Events
TemperatureUpdated
Raised when the value of the reading changes.
Declaration
public event EventHandler<IChangeResult<Temperature>> TemperatureUpdated
Event Type
Type | Description |
---|---|
EventHandler<IChangeResult<Temperature>> |
Remarks
AnalogTemperature | |
---|---|
Status | |
Source code | GitHub |
NuGet package |
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()
{
Resolver.Log.Info("Initializing...");
// configure our AnalogTemperature sensor
analogTemperature = new AnalogTemperature (
analogPin: Device.Pins.A03,
sensorType: AnalogTemperature.KnownSensorType.LM35
);
//==== IObservable Pattern with an optional notification filter.
var consumer = AnalogTemperature.CreateObserver(
handler: result => Resolver.Log.Info($"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) => {
Resolver.Log.Info($"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();
Resolver.Log.Info($"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: