diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Datasheet/MCP960X-L0X-RL0X-Data-Sheet-20005426F.pdf b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Datasheet/MCP960X-L0X-RL0X-Data-Sheet-20005426F.pdf
new file mode 100644
index 0000000000..00d3c07d2b
Binary files /dev/null and b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Datasheet/MCP960X-L0X-RL0X-Data-Sheet-20005426F.pdf differ
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Drivers/Mcp9600.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Drivers/Mcp9600.cs
new file mode 100644
index 0000000000..c118755f7d
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Drivers/Mcp9600.cs
@@ -0,0 +1,19 @@
+using Meadow.Hardware;
+
+namespace Meadow.Foundation.Sensors.Temperature
+{
+ ///
+ /// Represents a Mcp9600 Thermocouple sensor object
+ ///
+ public partial class Mcp9600 : Mcp960x
+ {
+ ///
+ /// Create a new Mcp9600 object using the default configuration for the sensor
+ ///
+ /// The I2C bus
+ /// I2C address of the sensor
+ public Mcp9600(II2cBus i2cBus, byte address = (byte)Addresses.Default) : base(i2cBus, address)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Drivers/Mcp9601.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Drivers/Mcp9601.cs
new file mode 100644
index 0000000000..bdf771d233
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Drivers/Mcp9601.cs
@@ -0,0 +1,19 @@
+using Meadow.Hardware;
+
+namespace Meadow.Foundation.Sensors.Temperature
+{
+ ///
+ /// Represents a Mcp9601 Thermocouple sensor object
+ ///
+ public partial class Mcp9601 : Mcp960x
+ {
+ ///
+ /// Create a new Mcp9601 object using the default configuration for the sensor
+ ///
+ /// The I2C bus
+ /// I2C address of the sensor
+ public Mcp9601(II2cBus i2cBus, byte address = (byte)Addresses.Default) : base(i2cBus, address)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Mcp960x.Enums.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Mcp960x.Enums.cs
new file mode 100644
index 0000000000..87e6d5b455
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Mcp960x.Enums.cs
@@ -0,0 +1,172 @@
+namespace Meadow.Foundation.Sensors.Temperature
+{
+ public partial class Mcp960x
+ {
+ ///
+ /// Valid addresses for the sensor
+ ///
+ public enum Addresses : byte
+ {
+ ///
+ /// Bus address 0x60
+ ///
+ Address_0x60 = 0x60,
+ ///
+ /// Bus address 0x61
+ ///
+ Address_0x61 = 0x61,
+ ///
+ /// Bus address 0x62
+ ///
+ Address_0x62 = 0x62,
+ ///
+ /// Bus address 0x63
+ ///
+ Address_0x63 = 0x63,
+ ///
+ /// Bus address 0x64
+ ///
+ Address_0x64 = 0x64,
+ ///
+ /// Bus address 0x65
+ ///
+ Address_0x65 = 0x65,
+ ///
+ /// Bus address 0x60
+ ///
+ Address_0x66 = 0x66,
+ ///
+ /// Bus address 0x66
+ ///
+ Address_0x67 = 0x67,
+ ///
+ /// Default bus address 0x67
+ ///
+ Default = Address_0x67
+ }
+
+ ///
+ /// Represents the supported thermocouple types for the MCP960x
+ ///
+ public enum ThermocoupleType
+ {
+ ///
+ /// K-type thermocouple (chromel–alumel), widely used due to its broad temperature range and durability
+ ///
+ K = 0x00,
+ ///
+ /// J-type thermocouple (iron–constantan), commonly used in general-purpose applications
+ ///
+ J = 0x01,
+ ///
+ /// T-type thermocouple (copper–constantan), suitable for low-temperature measurements
+ ///
+ T = 0x02,
+ ///
+ /// N-type thermocouple (nicrosil–nisil), known for its stability and resistance to high temperatures
+ ///
+ N = 0x03,
+ ///
+ /// S-type thermocouple (platinum–rhodium), suitable for high-temperature measurements
+ ///
+ S = 0x04,
+ ///
+ /// E-type thermocouple (chromel–constantan), featuring a high output signal and excellent stability
+ ///
+ E = 0x05,
+ ///
+ /// B-type thermocouple (platinum–rhodium), used for very high-temperature measurements
+ ///
+ B = 0x06,
+ ///
+ /// R-type thermocouple (platinum–rhodium), suitable for high-temperature measurements
+ ///
+ R = 0x07
+ }
+
+ ///
+ /// Represents the available ADC resolutions for the MCP960x
+ ///
+ public enum AdcResolution
+ {
+ ///
+ /// 18-bit ADC resolution, providing the fastest conversion time
+ ///
+ _18Bit = 0x00,
+ ///
+ /// 16-bit ADC resolution, providing a balance between conversion time and resolution
+ ///
+ _16Bit = 0x01,
+ ///
+ /// 14-bit ADC resolution, providing a slower conversion time but higher resolution
+ ///
+ _14Bit = 0x02,
+ ///
+ /// 12-bit ADC resolution, providing the slowest conversion time but highest resolution
+ ///
+ _12Bit = 0x03
+ }
+
+ ///
+ /// Represents the available filter coefficients for the MCP960x
+ ///
+ public enum FilterCoefficient
+ {
+ ///
+ /// Filter coefficient value 0
+ ///
+ _0 = 0x00,
+ ///
+ /// Filter coefficient value 1
+ ///
+ _1 = 0x01,
+ ///
+ /// Filter coefficient value 2
+ ///
+ _2 = 0x02,
+ ///
+ /// Filter coefficient value 3
+ ///
+ _3 = 0x03,
+ ///
+ /// Filter coefficient value 4
+ ///
+ _4 = 0x04,
+ ///
+ /// Filter coefficient value 5
+ ///
+ _5 = 0x05,
+ ///
+ /// Filter coefficient value 4
+ ///
+ _6 = 0x06,
+ ///
+ /// Filter coefficient value 5
+ ///
+ _7 = 0x07
+ }
+
+ ///
+ /// Represents the alert number for the MCP9600
+ ///
+ public enum AlertNumber
+ {
+ ///
+ /// Alert number 1
+ ///
+ Alert1 = 1,
+ ///
+ /// Alert number 2
+ ///
+ Alert2 = 2,
+ ///
+ /// Alert number 3
+ ///
+ Alert3 = 3,
+ ///
+ /// Alert number 4
+ ///
+ Alert4 = 4
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Mcp960x.Registers.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Mcp960x.Registers.cs
new file mode 100644
index 0000000000..2528d1b8e2
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Mcp960x.Registers.cs
@@ -0,0 +1,25 @@
+namespace Meadow.Foundation.Sensors.Temperature
+{
+ public partial class Mcp960x
+ {
+ const byte HOTJUNCTION = 0x00; // Hot junction temperature T_H
+ const byte JUNCTIONDELTA = 0x01; // Hot/Cold junction delta
+ const byte COLDJUNCTION = 0x02; // Cold junction temperature T_C
+ const byte RAWDATAADC = 0x03; // The raw uV reading
+ const byte STATUS = 0x04; // Current device status
+ const byte SENSORCONFIG = 0x05; // Configuration for thermocouple type
+ const byte DEVICECONFIG = 0x06; // Device config like sleep mode
+ const byte DEVICEID = 0x20; // Device ID/Revision
+ const byte ALERTCONFIG_1 = 0x08; // The first alert's config
+ const byte ALERTHYST_1 = 0x0C; // The first alert's hystersis
+ const byte ALERTLIMIT_1 = 0x10; // the first alert's limitval
+
+ const byte STATUS_ALERT1 = 0x01; // Bit flag for alert 1 status
+ const byte STATUS_ALERT2 = 0x02; // Bit flag for alert 2 status
+ const byte STATUS_ALERT3 = 0x04; // Bit flag for alert 3 status
+ const byte STATUS_ALERT4 = 0x08; // Bit flag for alert 4 status
+ const byte STATUS_INPUTRANGE = 0x10; // Bit flag for input range
+ const byte STATUS_THUPDATE = 0x40; // Bit flag for TH update
+ const byte STATUS_BURST = 0x80; // Bit flag for burst complete
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Mcp960x.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Mcp960x.cs
new file mode 100644
index 0000000000..8cd86ca51e
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Mcp960x.cs
@@ -0,0 +1,292 @@
+using Meadow.Hardware;
+using Meadow.Peripherals.Sensors;
+using System;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Sensors.Temperature
+{
+ ///
+ /// Represents a Mcp960x Thermocouple sensor object
+ ///
+ public abstract partial class Mcp960x : ByteCommsSensorBase<(Units.Temperature? TemperatureHot, Units.Temperature? TemperatureCold)>, ITemperatureSensor
+ {
+ ///
+ /// Raised when the Hot temperature value changes
+ ///
+ public event EventHandler> TemperatureUpdated = delegate { };
+
+ ///
+ /// Raised when the Hot temperature value changes
+ ///
+ public event EventHandler> TemperatureHotUpdated = delegate { };
+
+ ///
+ /// Raised when the Cold / ambient temperature value changes
+ ///
+ public event EventHandler> TemperatureColdUpdated = delegate { };
+
+ ///
+ /// The Hot Temperature value from the last reading
+ ///
+ public Units.Temperature? Temperature => TemperatureHot;
+
+ ///
+ /// The Hot Temperature value from the last reading
+ ///
+ public Units.Temperature? TemperatureHot { get; protected set; }
+
+ ///
+ /// The Cold Temperature value from the last reading
+ ///
+ public Units.Temperature? TemperatureCold { get; protected set; }
+
+ ///
+ /// Create a new Mcp960x object using the default configuration for the sensor
+ ///
+ /// The I2C bus
+ /// I2C address of the sensor
+ public Mcp960x(II2cBus i2cBus, byte address)
+ : base(i2cBus, address)
+ {
+ Peripheral.WriteRegister(DEVICECONFIG, 0x80);
+ }
+
+ ///
+ /// Update the Temperature property
+ ///
+ protected override Task<(Units.Temperature? TemperatureHot, Units.Temperature? TemperatureCold)> ReadSensor()
+ {
+ return Task.Run(() =>
+ {
+ (Units.Temperature? TemperatureHot, Units.Temperature? TemperatureCold) conditions;
+
+ conditions.TemperatureHot = new Units.Temperature(ReadTemperatureHot(), Units.Temperature.UnitType.Celsius);
+ conditions.TemperatureCold = new Units.Temperature(ReadTemperatureCold(), Units.Temperature.UnitType.Celsius);
+
+ return conditions;
+ });
+ }
+
+ ///
+ /// Reads the hot junction temperature from the MCP960x
+ ///
+ /// The hot junction temperature in degrees Celsius
+ double ReadTemperatureHot()
+ {
+ byte[] readBuffer = new byte[2];
+
+ Peripheral?.ReadRegister(HOTJUNCTION, readBuffer);
+
+ int rawTemp = (readBuffer[0] << 8) | readBuffer[1];
+ double temperature = rawTemp * 0.0625;
+
+ return temperature;
+ }
+
+ ///
+ /// Reads the cold/ambient temperature from the MCP960x
+ ///
+ /// The cold/ambient temperature in degrees Celsius
+ double ReadTemperatureCold()
+ {
+ byte[] readBuffer = new byte[2];
+
+ Peripheral?.ReadRegister(COLDJUNCTION, readBuffer);
+
+ int rawTemp = (readBuffer[0] << 8) | readBuffer[1];
+ double temperature = rawTemp * 0.0625;
+
+ return temperature;
+ }
+
+ ///
+ /// Sets the thermocouple type for the MCP960x
+ ///
+ /// The thermocouple type to set
+ public void SetThermocoupleType(ThermocoupleType type)
+ {
+ byte config = Peripheral.ReadRegister(SENSORCONFIG);
+
+ config = (byte)((config & 0xF8) | (byte)type);
+
+ Peripheral.WriteRegister(SENSORCONFIG, config);
+ }
+
+ ///
+ /// Gets the thermocouple type currently configured for the MCP960x
+ ///
+ /// The currently configured thermocouple type
+ public ThermocoupleType GetThermocoupleType()
+ {
+ byte config = Peripheral.ReadRegister(SENSORCONFIG);
+
+ return (ThermocoupleType)(config & 0x07);
+ }
+
+ ///
+ /// Sets the ADC resolution for the MCP960x
+ ///
+ /// The ADC resolution to set
+ public void SetAdcResolution(AdcResolution resolution)
+ {
+ byte config = Peripheral.ReadRegister(SENSORCONFIG);
+
+ config = (byte)((config & 0x9F) | ((byte)resolution << 5));
+
+ Peripheral.WriteRegister(SENSORCONFIG, config);
+ }
+
+ ///
+ /// Gets the ADC resolution currently configured for the MCP960x
+ ///
+ /// The currently configured ADC resolution
+ public AdcResolution GetAdcResolution()
+ {
+ byte config = Peripheral.ReadRegister(SENSORCONFIG);
+
+ return (AdcResolution)((config & 0x60) >> 5);
+ }
+
+ ///
+ /// Sets the filter coefficient for the MCP960x
+ ///
+ /// The filter coefficient to set
+ public void SetFilterCoefficient(FilterCoefficient coefficient)
+ {
+ byte config = Peripheral.ReadRegister(SENSORCONFIG);
+
+ config = (byte)((config & 0xF8) | ((byte)coefficient & 0x07));
+
+ Peripheral.WriteRegister(SENSORCONFIG, config);
+ }
+
+ ///
+ /// Gets the filter coefficient for the MCP960x
+ ///
+ /// The currently configured filter coefficient
+ public FilterCoefficient GetFilterCoefficient()
+ {
+ byte config = Peripheral.ReadRegister(SENSORCONFIG);
+
+ return (FilterCoefficient)(config & 0x07);
+ }
+
+ ///
+ /// Sets the alert temperature for the specified alert number of the MCP960x
+ ///
+ /// The alert number (1-4) to set the temperature for
+ /// The temperature value
+ public void SetAlertTemperature(AlertNumber alertNumber, Units.Temperature temperature)
+ {
+ if (alertNumber < AlertNumber.Alert1 || alertNumber > AlertNumber.Alert4)
+ {
+ throw new ArgumentOutOfRangeException("Alert number must be between Alert1 and Alert4.");
+ }
+
+ short tempData = (short)(temperature.Celsius / 0.0625);
+
+ Peripheral.WriteRegister((byte)(ALERTLIMIT_1 + ((int)alertNumber - 1) * 2), new byte[] { (byte)(tempData >> 8), (byte)(tempData & 0xFF) });
+ }
+
+ ///
+ /// Gets the alert temperature for the specified alert number of the MCP960x
+ ///
+ /// The alert number (1-4) to get the temperature for
+ /// The alert temperature value
+ public Units.Temperature GetAlertTemperature(AlertNumber alertNumber)
+ {
+ if (alertNumber < AlertNumber.Alert1 || alertNumber > AlertNumber.Alert4)
+ {
+ throw new ArgumentOutOfRangeException("Alert number must be between Alert1 and Alert4.");
+ }
+
+ byte[] readBuffer = new byte[2];
+
+ Peripheral.ReadRegister((byte)(ALERTLIMIT_1 + ((int)alertNumber - 1) * 2), readBuffer);
+
+ ushort tempData = (ushort)((readBuffer[0] << 8) | readBuffer[1]);
+ double temperature = tempData / 16.0;
+
+ return new Units.Temperature(temperature, Units.Temperature.UnitType.Celsius);
+ }
+
+ ///
+ /// Configures the alert settings for the MCP960x
+ ///
+ /// The alert number (Alert1-Alert4) to configure
+ /// Whether the alert is enabled
+ /// Whether the alert triggers on a rising temperature. Set to false for falling temperature
+ /// Whether the alert triggers on cold junction temperature. Set to false for thermocouple temperature
+ /// Whether the alert pin is active high. Set to false for active low
+ /// Whether the alert pin is in interrupt mode. Set to false for comparator mode
+ public void ConfigureAlert(AlertNumber alertNumber, bool enabled, bool rising, bool alertColdJunction, bool activeHigh, bool interruptMode)
+ {
+ if (alertNumber < AlertNumber.Alert1 || alertNumber > AlertNumber.Alert4)
+ {
+ throw new ArgumentOutOfRangeException("Alert number must be between Alert1 and Alert4.");
+ }
+
+ byte configValue = 0;
+
+ if (enabled) configValue |= 0x01;
+ if (interruptMode) configValue |= 0x02;
+ if (activeHigh) configValue |= 0x04;
+ if (rising) configValue |= 0x08;
+ if (alertColdJunction) configValue |= 0x10;
+
+ Peripheral.WriteRegister((byte)(ALERTCONFIG_1 + ((int)alertNumber - 1)), configValue);
+ }
+
+ ///
+ /// Enables or disables the MCP960x sensor
+ ///
+ /// True to enable the sensor, false to enter sleep mode
+ public void Enable(bool enable)
+ {
+ byte config = Peripheral.ReadRegister(DEVICECONFIG);
+
+ config &= 0b1111_1100; // Clear bits 0 and 1
+
+ if (!enable) // Sleep mode
+ {
+ config |= 0x01;
+ }
+
+ Peripheral.WriteRegister(DEVICECONFIG, config);
+ }
+
+ ///
+ /// Checks whether the MCP960x sensor is enabled and working or in sleep mode
+ ///
+ /// True if in awake mode, false if in sleep mode
+ public bool IsEnabled()
+ {
+ byte config = Peripheral.ReadRegister(DEVICECONFIG);
+ int statusBits = (config & 0b11);
+
+ return statusBits == 0;
+ }
+
+ ///
+ /// Raise events for subcribers and notify of value changes
+ ///
+ /// The updated sensor data
+ protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? TemperatureHot, Units.Temperature? TemperatureCold)> changeResult)
+ {
+ if (changeResult.New.TemperatureHot is { } hot)
+ {
+ TemperatureUpdated?.Invoke(this, new ChangeResult(hot, changeResult.Old?.TemperatureHot));
+ TemperatureHotUpdated?.Invoke(this, new ChangeResult(hot, changeResult.Old?.TemperatureHot));
+ }
+ if (changeResult.New.TemperatureCold is { } cold)
+ {
+ TemperatureHotUpdated?.Invoke(this, new ChangeResult(cold, changeResult.Old?.TemperatureCold));
+ }
+
+ base.RaiseEventsAndNotify(changeResult);
+ }
+
+ async Task ISensor.Read()
+ => (await Read()).TemperatureHot ?? throw new Exception("Temperature not available");
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Sensors.Temperature.Mcp960x.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Sensors.Temperature.Mcp960x.csproj
new file mode 100644
index 0000000000..1a75acf479
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Driver/Sensors.Temperature.Mcp960x.csproj
@@ -0,0 +1,27 @@
+
+
+ true
+ icon.png
+ Wilderness Labs, Inc
+ netstandard2.1
+ Library
+ Mcp960x
+ Wilderness Labs, Inc
+ http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/
+ Meadow.Foundation.Sensors.Temperature.Mcp960x
+ https://github.com/WildernessLabs/Meadow.Foundation
+ Meadow.Foundation,Temperature,Thermocouple,Mcp9600,Mcp9601,Mcp960x
+ 0.1.0
+ true
+ Mcp960x I2C thermocouple temperature sensor
+ enable
+ Meadow.Foundation.Sensors.Temperature
+
+
+ 10.0
+
+
+
+
+
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9600_Sample/Mcp9600_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9600_Sample/Mcp9600_Sample.csproj
new file mode 100644
index 0000000000..d867cb748b
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9600_Sample/Mcp9600_Sample.csproj
@@ -0,0 +1,20 @@
+
+
+ https://github.com/WildernessLabs/Meadow.Foundation
+ Wilderness Labs, Inc
+ Wilderness Labs, Inc
+ true
+ netstandard2.1
+ Library
+ App
+
+
+
+
+
+
+
+ Always
+
+
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9600_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9600_Sample/MeadowApp.cs
new file mode 100644
index 0000000000..1b7b67b244
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9600_Sample/MeadowApp.cs
@@ -0,0 +1,45 @@
+using Meadow;
+using Meadow.Devices;
+using Meadow.Foundation.Sensors.Temperature;
+using System.Threading.Tasks;
+
+namespace Sensors.Temperature.MCP9600_Sample
+{
+ public class MeadowApp : App
+ {
+ //
+
+ Mcp9600 sensor;
+
+ public override Task Initialize()
+ {
+ Resolver.Log.Info("Initialize...");
+
+ sensor = new Mcp9600(Device.CreateI2cBus());
+
+ var consumer = Mcp9600.CreateObserver(
+ handler: result =>
+ {
+ Resolver.Log.Info($"Temperature New Value {result.New.TemperatureHot.Value.Celsius}C");
+ },
+ filter: null
+ );
+ sensor.Subscribe(consumer);
+
+ sensor.Updated += Sensor_Updated;
+ return Task.CompletedTask;
+ }
+
+ private void Sensor_Updated(object sender, IChangeResult<(Meadow.Units.Temperature? TemperatureHot, Meadow.Units.Temperature? TemperatureCold)> e)
+ {
+ Resolver.Log.Info($"Temperature hot: {e.New.TemperatureHot.Value.Celsius:n2}C, Temperature cold: {e.New.TemperatureCold.Value.Celsius:n2}C");
+ }
+
+ public override async Task Run()
+ {
+ sensor.StartUpdating();
+ }
+
+ //
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9600_Sample/meadow.config.yaml b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9600_Sample/meadow.config.yaml
new file mode 100644
index 0000000000..32363cb69c
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9600_Sample/meadow.config.yaml
@@ -0,0 +1,2 @@
+MonoControl:
+ Options: --jit
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9601_Sample/Mcp9601_Sample.csproj b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9601_Sample/Mcp9601_Sample.csproj
new file mode 100644
index 0000000000..090550a98d
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9601_Sample/Mcp9601_Sample.csproj
@@ -0,0 +1,20 @@
+
+
+ https://github.com/WildernessLabs/Meadow.Foundation
+ Wilderness Labs, Inc
+ Wilderness Labs, Inc
+ true
+ netstandard2.1
+ Library
+ App
+
+
+
+
+
+
+
+ Always
+
+
+
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9601_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9601_Sample/MeadowApp.cs
new file mode 100644
index 0000000000..a7af3d2982
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9601_Sample/MeadowApp.cs
@@ -0,0 +1,45 @@
+using Meadow;
+using Meadow.Devices;
+using Meadow.Foundation.Sensors.Temperature;
+using System.Threading.Tasks;
+
+namespace Sensors.Temperature.MCP9601_Sample
+{
+ public class MeadowApp : App
+ {
+ //
+
+ Mcp9601 sensor;
+
+ public override Task Initialize()
+ {
+ Resolver.Log.Info("Initialize...");
+
+ sensor = new Mcp9601(Device.CreateI2cBus());
+
+ var consumer = Mcp9601.CreateObserver(
+ handler: result =>
+ {
+ Resolver.Log.Info($"Temperature New Value {result.New.TemperatureHot.Value.Celsius}C");
+ },
+ filter: null
+ );
+ sensor.Subscribe(consumer);
+
+ sensor.Updated += Sensor_Updated;
+ return Task.CompletedTask;
+ }
+
+ private void Sensor_Updated(object sender, IChangeResult<(Meadow.Units.Temperature? TemperatureHot, Meadow.Units.Temperature? TemperatureCold)> e)
+ {
+ Resolver.Log.Info($"Temperature hot: {e.New.TemperatureHot.Value.Celsius:n2}C, Temperature cold: {e.New.TemperatureCold.Value.Celsius:n2}C");
+ }
+
+ public override async Task Run()
+ {
+ sensor.StartUpdating();
+ }
+
+ //
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9601_Sample/meadow.config.yaml b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9601_Sample/meadow.config.yaml
new file mode 100644
index 0000000000..32363cb69c
--- /dev/null
+++ b/Source/Meadow.Foundation.Peripherals/Sensors.Temperature.Mcp960x/Samples/Mcp9601_Sample/meadow.config.yaml
@@ -0,0 +1,2 @@
+MonoControl:
+ Options: --jit
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.sln b/Source/Meadow.Foundation.sln
index 3f33f376a4..564639055e 100644
--- a/Source/Meadow.Foundation.sln
+++ b/Source/Meadow.Foundation.sln
@@ -1217,6 +1217,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sensors.Motion.Lis2Mdl", "M
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lis2Mdl_Sample", "Meadow.Foundation.Peripherals\Sensors.Motion.Lis2Mdl\Samples\Lis2Mdl_Sample\Lis2Mdl_Sample.csproj", "{6923DB1E-CDDC-4A84-AAEF-6F6F7D9DC406}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mcp960x", "Mcp960x", "{CBF95E20-6021-4E5B-807A-E099DBC98764}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{573A2A08-CB36-480E-9C5D-56F851847045}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sensors.Temperature.Mcp960x", "Meadow.Foundation.Peripherals\Sensors.Temperature.Mcp960x\Driver\Sensors.Temperature.Mcp960x.csproj", "{754AFC87-A98F-4BD6-A934-61DB69C0B643}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mcp9600_Sample", "Meadow.Foundation.Peripherals\Sensors.Temperature.Mcp960x\Samples\Mcp9600_Sample\Mcp9600_Sample.csproj", "{3AC34973-19FC-453A-A90E-4406EB355F72}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mcp9601_Sample", "Meadow.Foundation.Peripherals\Sensors.Temperature.Mcp960x\Samples\Mcp9601_Sample\Mcp9601_Sample.csproj", "{41A4E1A7-0BC4-474F-910F-F140EEA1A4BE}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -2889,6 +2899,24 @@ Global
{6923DB1E-CDDC-4A84-AAEF-6F6F7D9DC406}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6923DB1E-CDDC-4A84-AAEF-6F6F7D9DC406}.Release|Any CPU.Build.0 = Release|Any CPU
{6923DB1E-CDDC-4A84-AAEF-6F6F7D9DC406}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {754AFC87-A98F-4BD6-A934-61DB69C0B643}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {754AFC87-A98F-4BD6-A934-61DB69C0B643}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {754AFC87-A98F-4BD6-A934-61DB69C0B643}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {754AFC87-A98F-4BD6-A934-61DB69C0B643}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {754AFC87-A98F-4BD6-A934-61DB69C0B643}.Release|Any CPU.Build.0 = Release|Any CPU
+ {754AFC87-A98F-4BD6-A934-61DB69C0B643}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {3AC34973-19FC-453A-A90E-4406EB355F72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3AC34973-19FC-453A-A90E-4406EB355F72}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3AC34973-19FC-453A-A90E-4406EB355F72}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {3AC34973-19FC-453A-A90E-4406EB355F72}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3AC34973-19FC-453A-A90E-4406EB355F72}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3AC34973-19FC-453A-A90E-4406EB355F72}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {41A4E1A7-0BC4-474F-910F-F140EEA1A4BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {41A4E1A7-0BC4-474F-910F-F140EEA1A4BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {41A4E1A7-0BC4-474F-910F-F140EEA1A4BE}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {41A4E1A7-0BC4-474F-910F-F140EEA1A4BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {41A4E1A7-0BC4-474F-910F-F140EEA1A4BE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {41A4E1A7-0BC4-474F-910F-F140EEA1A4BE}.Release|Any CPU.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -3496,6 +3524,11 @@ Global
{385CB50B-4D17-4FFF-BCCE-C8BF9D280A52} = {698A96DD-692F-4ABE-9B4D-9BDA300C8B84}
{09E368FA-1ACA-4F96-9153-B4959A7EE390} = {698A96DD-692F-4ABE-9B4D-9BDA300C8B84}
{6923DB1E-CDDC-4A84-AAEF-6F6F7D9DC406} = {385CB50B-4D17-4FFF-BCCE-C8BF9D280A52}
+ {CBF95E20-6021-4E5B-807A-E099DBC98764} = {DBC6C89D-A932-4F99-9382-7405A0045988}
+ {573A2A08-CB36-480E-9C5D-56F851847045} = {CBF95E20-6021-4E5B-807A-E099DBC98764}
+ {754AFC87-A98F-4BD6-A934-61DB69C0B643} = {CBF95E20-6021-4E5B-807A-E099DBC98764}
+ {3AC34973-19FC-453A-A90E-4406EB355F72} = {573A2A08-CB36-480E-9C5D-56F851847045}
+ {41A4E1A7-0BC4-474F-910F-F140EEA1A4BE} = {573A2A08-CB36-480E-9C5D-56F851847045}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AF7CA16F-8C38-4546-87A2-5DAAF58A1520}