diff --git a/src/devices/Shtc3/README.md b/src/devices/Shtc3/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..ec1df011d70eff6a52db871a2ed4375da392f3de
--- /dev/null
+++ b/src/devices/Shtc3/README.md
@@ -0,0 +1,28 @@
+# SHTC3 - Temperature & Humidity Sensor
+
+SHTC3 is a digital humidity and temperature sensor designed especially for battery-driven high-volume consumer electronics application.
+To reduce power cosumption this project use capability of sensor to allow measurement in low power mode and active sleep mode.
+
+## Usage
+
+```C#
+I2cConnectionSettings settings = new I2cConnectionSettings(1, Iot.Device.Shtc3.Shtc3.DefaultI2cAddress);
+I2cDevice device = I2cDevice.Create(settings);
+
+using (Shtc3 sensor = new Shtc3(device))
+{
+ if (sensor.TryGetTemperatureAndHumidity(out var temperature, out var relativeHumidity))
+ {
+ // temperature (℃)
+ Console.WriteLine($"Temperature: {temperature.DegreesCelsius:0.#}\u00B0C");
+ // humidity (%)
+ Console.WriteLine($"Humidity: {relativeHumidity.Percent:0.#}%");
+ }
+
+ // Make sensor in sleep mode
+ sensor.Sleep();
+}
+```
+
+## References
+https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/2_Humidity_Sensors/Datasheets/Sensirion_Humidity_Sensors_SHTC3_Datasheet.pdf
diff --git a/src/devices/Shtc3/Register.cs b/src/devices/Shtc3/Register.cs
new file mode 100644
index 0000000000000000000000000000000000000000..b02a9e95d44f0af28fe521bf85992181626e7552
--- /dev/null
+++ b/src/devices/Shtc3/Register.cs
@@ -0,0 +1,57 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace Iot.Device.Shtc3
+{
+ ///
+ /// Shtc3 Register
+ ///
+ internal enum Register : ushort
+ {
+ SHTC3_ID = 0xEFC8,
+ SHTC3_RESET = 0x805D,
+ SHTC3_SLEEP = 0xB098,
+ SHTC3_WAKEUP = 0x3517,
+
+ ///
+ /// Temperature and Humidity with Clock stretching disable in normal power mode
+ ///
+ SHTC3_MEAS_T_RH_POLLING_NPM = 0x7866,
+
+ ///
+ /// Temperature and Humidity with Clock Stretching enable and normal power mode
+ ///
+ SHTC3_MEAS_T_RH_CLOCKSTR_NPM = 0x7CA2,
+
+ ///
+ /// Temperature and Humidity with Clock stretching disable in low power mode
+ ///
+ SHTC3_MEAS_T_RH_POLLING_LPM = 0x609C,
+
+ ///
+ /// Temperature and Humidity with Clock stretching enable in low power mode
+ ///
+ SHTC3_MEAS_T_RH_CLOCKSTR_LPM = 0x6458,
+
+ ///
+ /// Humidity and Temperature with Clock stretching disable in normal power mode
+ ///
+ SHTC3_MEAS_RH_T_POLLING_NPM = 0x58E0,
+
+ ///
+ /// Humidity and Temperature with Clock stretching enable in normal power mode
+ ///
+ SHTC3_MEAS_RH_T_CLOCKSTR_NPM = 0x5C24,
+
+ ///
+ /// Humidity and Temperature with Clock stretching disable in low power mode
+ ///
+ SHTC3_MEAS_RH_T_POLLING_LPM = 0x401A,
+
+ ///
+ /// Humidity and Temperature with Clock stretching enable in low power mode
+ ///
+ SHTC3_MEAS_RH_T_CLOCKSTR_LPM = 0x44DE,
+ }
+}
diff --git a/src/devices/Shtc3/Shtc3.cs b/src/devices/Shtc3/Shtc3.cs
new file mode 100644
index 0000000000000000000000000000000000000000..de89c04730abc3878097fe56d1330bb10e5e79d5
--- /dev/null
+++ b/src/devices/Shtc3/Shtc3.cs
@@ -0,0 +1,285 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Buffers.Binary;
+using System.Device;
+using System.Device.I2c;
+using System.Threading;
+using UnitsNet;
+
+namespace Iot.Device.Shtc3
+{
+ ///
+ /// Temperature and humidity sensor Shtc3
+ ///
+ public class Shtc3 : IDisposable
+ {
+ // CRC const
+ private const byte CRC_POLYNOMIAL = 0x31;
+ private const byte CRC_INIT = 0xFF;
+
+ ///
+ /// Default I2C address
+ ///
+ public const int DefaultI2cAddress = 0x70;
+
+ private I2cDevice _i2cDevice;
+ private int? _id = null;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The I2C device used for communication.
+ public Shtc3(I2cDevice i2cDevice)
+ {
+ if (i2cDevice == null)
+ {
+ throw new ArgumentNullException(nameof(i2cDevice));
+ }
+
+ _i2cDevice = i2cDevice;
+
+ Wakeup();
+ _status = Status.Idle;
+
+ Reset();
+ }
+
+ private Status _status;
+
+ ///
+ /// Set Shtc3 state
+ ///
+ public Status Status
+ {
+ get
+ {
+ return _status;
+ }
+ }
+
+ ///
+ /// Try read Temperature and Humidity
+ ///
+ /// Temperature returned by sensor
+ /// Humidity return by sensor
+ /// "true" measured in low power mode, "false"(default) measured in normal power mode
+ /// "true" allow clock stretching, "false" (default) without clock stretching
+ /// True if operation was successful
+ public bool TryGetTemperatureAndHumidity(out Temperature temperature, out Ratio relativeHumidity, bool lowPower = false, bool clockStretching = false)
+ {
+ if (Status == Status.Sleep)
+ {
+ Wakeup();
+ }
+
+ Register cmd = GetMeasurementCmd(lowPower, clockStretching);
+
+ if (!TryReadSensorData(cmd, out var st, out var srh))
+ {
+ temperature = default(Temperature);
+ relativeHumidity = default(Ratio);
+ return false;
+ }
+
+ // Details in the Datasheet P9
+ temperature = Temperature.FromDegreesCelsius(Math.Round(st * 175 / 65536.0 - 45, 1));
+ relativeHumidity = Ratio.FromDecimalFractions(srh / 65536.0);
+ return true;
+ }
+
+ private bool TryReadSensorData(Register cmd, out double temperature, out double humidity)
+ {
+ Write(cmd);
+
+ Span readBuff = stackalloc byte[6];
+
+ _i2cDevice.Read(readBuff);
+
+ // Details in the Datasheet P7
+ int st = BinaryPrimitives.ReadInt16BigEndian(readBuff.Slice(0, 2)); // Temp
+ int srh = BinaryPrimitives.ReadUInt16BigEndian(readBuff.Slice(3, 2)); // Humi
+
+ // check 8-bit crc
+ bool tCrc = CheckCrc8(readBuff.Slice(0, 2), readBuff[2]);
+ bool rhCrc = CheckCrc8(readBuff.Slice(3, 2), readBuff[5]);
+ if (!tCrc || !rhCrc)
+ {
+ temperature = double.NaN;
+ humidity = double.NaN;
+ return false;
+ }
+
+ temperature = st;
+ humidity = srh;
+ return true;
+ }
+
+ private static Register GetMeasurementCmd(bool lowPower, bool clockStretching)
+ {
+ if (lowPower)
+ {
+ if (clockStretching)
+ {
+ return Register.SHTC3_MEAS_T_RH_CLOCKSTR_LPM;
+ }
+ else
+ {
+ return Register.SHTC3_MEAS_T_RH_POLLING_LPM;
+ }
+ }
+ else
+ {
+ if (clockStretching)
+ {
+ return Register.SHTC3_MEAS_T_RH_CLOCKSTR_NPM;
+ }
+ else
+ {
+ return Register.SHTC3_MEAS_T_RH_POLLING_NPM;
+ }
+ }
+ }
+
+ ///
+ /// SHTC3 Sleep
+ ///
+ public void Sleep()
+ {
+ if (Status == Status.Sleep)
+ {
+ return;
+ }
+
+ Write(Register.SHTC3_SLEEP);
+ }
+
+ ///
+ /// SHTC3 Wakeup
+ ///
+ private void Wakeup()
+ {
+ Write(Register.SHTC3_WAKEUP);
+ }
+
+ ///
+ /// SHTC3 Soft Reset
+ ///
+ public void Reset()
+ {
+ if (Status == Status.Sleep)
+ {
+ Wakeup();
+ }
+
+ Write(Register.SHTC3_RESET);
+ }
+
+ ///
+ /// Sensor Id
+ ///
+ public int? Id
+ {
+ get
+ {
+ return _id = _id ?? ReadId();
+ }
+ }
+
+ ///
+ /// Read Id
+ ///
+ private int? ReadId()
+ {
+ if (Status == Status.Sleep)
+ {
+ Wakeup();
+ }
+
+ Write(Register.SHTC3_ID);
+
+ Span readBuff = stackalloc byte[3];
+
+ _i2cDevice.Read(readBuff);
+
+ // check 8-bit crc
+ if (!CheckCrc8(readBuff.Slice(0, 2), readBuff[2]))
+ {
+ return null;
+ }
+
+ int id = BinaryPrimitives.ReadInt16BigEndian(readBuff.Slice(0, 2));
+
+ // check the result match to the SHTC3 product code
+ if (!ValidShtc3Id(id))
+ {
+ return null;
+ }
+
+ return id;
+ }
+
+ ///
+ /// Check the match to the SHTC3 product code
+ /// Table 15 while bits 11 and 5:0 contain the SHTC3 specific product code 0b_0000_1000_0000_0111
+ ///
+ /// Id to test
+ ///
+ private static bool ValidShtc3Id(int id)
+ {
+ return (id & 0b_0000_1000_0011_1111) == 0b_0000_1000_0000_0111;
+ }
+
+ ///
+ /// 8-bit CRC Checksum Calculation
+ ///
+ /// Raw Data
+ /// Raw CRC8
+ /// Checksum is true or false
+ private static bool CheckCrc8(ReadOnlySpan data, byte crc8)
+ {
+ // Details in the Datasheet table 16 P9
+ byte crc = CRC_INIT;
+ for (int i = 0; i < 2; i++)
+ {
+ crc ^= data[i];
+
+ for (int j = 8; j > 0; j--)
+ {
+ if ((crc & 0x80) != 0)
+ {
+ crc = (byte)((crc << 1) ^ CRC_POLYNOMIAL);
+ }
+ else
+ {
+ crc = (byte)(crc << 1);
+ }
+ }
+ }
+
+ return crc == crc8;
+ }
+
+ private void Write(Register register)
+ {
+ Span writeBuff = stackalloc byte[2];
+ BinaryPrimitives.WriteUInt16BigEndian(writeBuff, (ushort)register);
+
+ _i2cDevice.Write(writeBuff);
+
+ // wait SCL free
+ DelayHelper.DelayMilliseconds(20, false);
+ }
+
+ ///
+ /// Cleanup
+ ///
+ public void Dispose()
+ {
+ _i2cDevice?.Dispose();
+ _i2cDevice = null;
+ }
+ }
+}
diff --git a/src/devices/Shtc3/Shtc3.csproj b/src/devices/Shtc3/Shtc3.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..153981be0ef53fbe6c061bb758458223d9c4f841
--- /dev/null
+++ b/src/devices/Shtc3/Shtc3.csproj
@@ -0,0 +1,16 @@
+
+
+
+ netcoreapp3.1
+
+ false
+
+
+
+
+
+
+
+
+
+
diff --git a/src/devices/Shtc3/Shtc3.sln b/src/devices/Shtc3/Shtc3.sln
new file mode 100644
index 0000000000000000000000000000000000000000..d522280748b9e7a7308cee4c6061ded22da695ff
--- /dev/null
+++ b/src/devices/Shtc3/Shtc3.sln
@@ -0,0 +1,48 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30002.166
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shtc3", "Shtc3.csproj", "{20BAE1B8-EC5B-4E2E-9876-8DCC4C18532F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{71FB7D89-939F-42FF-914D-60EE6B826694}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shtc3.Samples", "samples\Shtc3.Samples.csproj", "{299AE1A7-B530-4DD3-9384-C7E0A3960041}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Device.Gpio", "..\..\System.Device.Gpio\System.Device.Gpio.csproj", "{A81F4110-9D79-426B-BFD5-77C1CFADD15A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommonHelpers", "..\Common\CommonHelpers.csproj", "{9089BDBB-35CE-4CD6-BD79-484177C5B153}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {20BAE1B8-EC5B-4E2E-9876-8DCC4C18532F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {20BAE1B8-EC5B-4E2E-9876-8DCC4C18532F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {20BAE1B8-EC5B-4E2E-9876-8DCC4C18532F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {20BAE1B8-EC5B-4E2E-9876-8DCC4C18532F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {299AE1A7-B530-4DD3-9384-C7E0A3960041}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {299AE1A7-B530-4DD3-9384-C7E0A3960041}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {299AE1A7-B530-4DD3-9384-C7E0A3960041}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {299AE1A7-B530-4DD3-9384-C7E0A3960041}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A81F4110-9D79-426B-BFD5-77C1CFADD15A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A81F4110-9D79-426B-BFD5-77C1CFADD15A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A81F4110-9D79-426B-BFD5-77C1CFADD15A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A81F4110-9D79-426B-BFD5-77C1CFADD15A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9089BDBB-35CE-4CD6-BD79-484177C5B153}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9089BDBB-35CE-4CD6-BD79-484177C5B153}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9089BDBB-35CE-4CD6-BD79-484177C5B153}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9089BDBB-35CE-4CD6-BD79-484177C5B153}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {299AE1A7-B530-4DD3-9384-C7E0A3960041} = {71FB7D89-939F-42FF-914D-60EE6B826694}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {A3AA64A6-B047-418A-89EE-F0B0DCEA4766}
+ EndGlobalSection
+EndGlobal
diff --git a/src/devices/Shtc3/Status.cs b/src/devices/Shtc3/Status.cs
new file mode 100644
index 0000000000000000000000000000000000000000..79415e8f696e5128c18ec4a09911581e17bcb25e
--- /dev/null
+++ b/src/devices/Shtc3/Status.cs
@@ -0,0 +1,22 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace Iot.Device.Shtc3
+{
+ ///
+ /// Shtc3 Status
+ ///
+ internal enum Status
+ {
+ ///
+ /// Sensor ready to use
+ ///
+ Idle,
+
+ ///
+ /// Sensor in sleep mode
+ ///
+ Sleep
+ }
+}
diff --git a/src/devices/Shtc3/category.txt b/src/devices/Shtc3/category.txt
new file mode 100644
index 0000000000000000000000000000000000000000..28100afeb99f6b4d96865a9034a64b19d2e6f984
--- /dev/null
+++ b/src/devices/Shtc3/category.txt
@@ -0,0 +1,2 @@
+thermometer
+hygrometer
diff --git a/src/devices/Shtc3/samples/Program.cs b/src/devices/Shtc3/samples/Program.cs
new file mode 100644
index 0000000000000000000000000000000000000000..8c54a609eeaec87faf14cc987d326b37502af449
--- /dev/null
+++ b/src/devices/Shtc3/samples/Program.cs
@@ -0,0 +1,58 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Device.I2c;
+using System.Threading;
+using Iot.Device.Common;
+using UnitsNet;
+
+namespace Iot.Device.Shtc3.Samples
+{
+ internal class Program
+ {
+ private static void Main(string[] args)
+ {
+ I2cConnectionSettings settings = new I2cConnectionSettings(1, Iot.Device.Shtc3.Shtc3.DefaultI2cAddress);
+ I2cDevice device = I2cDevice.Create(settings);
+
+ using (Shtc3 sensor = new Shtc3(device))
+ {
+ Console.WriteLine($"Sensor Id: {sensor.Id}");
+ while (true)
+ {
+ // Try sensor measurement in normal power mode
+ if (sensor.TryGetTemperatureAndHumidity(out var temperature, out var relativeHumidity))
+ {
+ Console.WriteLine($"====================In normal power mode===========================");
+ ConsoleWriteInfo(temperature, relativeHumidity);
+ }
+
+ // Try sensor measurement in low power mode
+ if (sensor.TryGetTemperatureAndHumidity(out temperature, out relativeHumidity, lowPower: true))
+ {
+ Console.WriteLine($"====================In low power mode===========================");
+ ConsoleWriteInfo(temperature, relativeHumidity);
+ }
+
+ // Set sensor in sleep mode
+ sensor.Sleep();
+
+ Console.WriteLine();
+ Thread.Sleep(1000);
+ }
+ }
+ }
+
+ private static void ConsoleWriteInfo(Temperature temperature, Ratio relativeHumidity)
+ {
+ Console.WriteLine($"Temperature: {temperature.DegreesCelsius:0.#}\u00B0C");
+ Console.WriteLine($"Humidity: {relativeHumidity.Percent:0.#}%");
+ // WeatherHelper supports more calculations, such as saturated vapor pressure, actual vapor pressure and absolute humidity.
+ Console.WriteLine($"Heat index: {WeatherHelper.CalculateHeatIndex(temperature, relativeHumidity).DegreesCelsius:0.#}\u00B0C");
+ Console.WriteLine($"Dew point: {WeatherHelper.CalculateDewPoint(temperature, relativeHumidity).DegreesCelsius:0.#}\u00B0C");
+ }
+
+ }
+}
diff --git a/src/devices/Shtc3/samples/README.md b/src/devices/Shtc3/samples/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..c49feee43e985eb8d6714e6a0b9f347b0049da48
--- /dev/null
+++ b/src/devices/Shtc3/samples/README.md
@@ -0,0 +1,44 @@
+# SHTC3 - Samples
+
+## Hardware Required
+* SHTC3
+* Male/Female Jumper Wires
+
+## Circuit
+* SCL - SCL
+* SDA - SDA
+* VCC - 3.3V
+* GND - GND
+
+
+## Code
+```C#
+I2cConnectionSettings settings = new I2cConnectionSettings(1, Shtc3.DefaultI2cAddress);
+I2cDevice device = I2cDevice.Create(settings);
+
+using (Shtc3 sensor = new Shtc3(device))
+{
+ Console.WriteLine($"Sensor Id: {sensor.Id}");
+
+ while (true)
+ {
+ if (sensor.TryGetTemperatureAndHumidity(out var temperature, out var relativeHumidity))
+ {
+ Console.WriteLine($"Temperature: {temperature.DegreesCelsius:0.#}\u00B0C");
+ Console.WriteLine($"Relative humidity: {relativeHumidity.Percent:0.#}%");
+ // WeatherHelper supports more calculations, such as saturated vapor pressure, actual vapor pressure and absolute humidity.
+ Console.WriteLine($"Heat index: {WeatherHelper.CalculateHeatIndex(temperature, relativeHumidity).DegreesCelsius:0.#}\u00B0C");
+ Console.WriteLine($"Dew point: {WeatherHelper.CalculateDewPoint(temperature, relativeHumidity).DegreesCelsius:0.#}\u00B0C");
+ Console.WriteLine();
+ }
+
+ sensor.Sleep();
+
+ Thread.Sleep(1000);
+ }
+
+}
+
+```
+## Result
+![](RunningResult.JPG)
diff --git a/src/devices/Shtc3/samples/RunningResult.JPG b/src/devices/Shtc3/samples/RunningResult.JPG
new file mode 100644
index 0000000000000000000000000000000000000000..baa4ecabe820208b8f22205c19e710eb344d6d3c
Binary files /dev/null and b/src/devices/Shtc3/samples/RunningResult.JPG differ
diff --git a/src/devices/Shtc3/samples/Shtc3.Samples.csproj b/src/devices/Shtc3/samples/Shtc3.Samples.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..297f665d6f225d1466265e2c8400708794e21b22
--- /dev/null
+++ b/src/devices/Shtc3/samples/Shtc3.Samples.csproj
@@ -0,0 +1,19 @@
+
+
+
+ Exe
+ netcoreapp3.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+