/
Htu21d.cs
114 lines (95 loc) · 4.22 KB
/
Htu21d.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
using Meadow.Hardware;
using Meadow.Units;
using System;
using System.Threading;
using System.Threading.Tasks;
using HU = Meadow.Units.RelativeHumidity.UnitType;
namespace Meadow.Foundation.Sensors.Atmospheric
{
/// <summary>
/// Provide access to the Htu21d(f)
/// temperature and humidity sensors
/// </summary>
public partial class Htu21d : Htux1dBase
{
/// <summary>
/// Firmware revision of the sensor.
/// </summary>
public byte FirmwareRevision { get; private set; }
/// <summary>
/// Create a new Htu21d temperature and humidity sensor
/// </summary>
/// <param name="address">Sensor address (default to 0x40)</param>
/// <param name="i2cBus">I2CBus (default to 100 KHz)</param>
public Htu21d(II2cBus i2cBus, byte address = (byte)Addresses.Default)
: base(i2cBus, address)
{
Initialize();
}
/// <summary>
/// Initialize HTU21D
/// </summary>
protected void Initialize()
{
BusComms?.Write((byte)Registers.SOFT_RESET);
Thread.Sleep(100);
SetResolution(SensorResolution.TEMP11_HUM11);
}
/// <summary>
/// Reads data from the sensor
/// </summary>
/// <returns>The latest sensor reading</returns>
protected override async Task<(Units.Temperature? Temperature, RelativeHumidity? Humidity)> ReadSensor()
{
(Units.Temperature? Temperature, RelativeHumidity? Humidity) conditions;
BusComms?.Write((byte)Registers.HUMDITY_MEASURE_NOHOLD);
await Task.Delay(20); // Maximum conversion time is 12ms (page 5 of the datasheet)
BusComms?.Read(ReadBuffer.Span[0..2]);// 2 data bytes plus a checksum (we ignore the checksum here)
var humidityReading = (ushort)((ReadBuffer.Span[0] << 8) + ReadBuffer.Span[1]);
var humidity = (125 * (float)humidityReading / 65536) - 6;
humidity = Math.Clamp(humidity, 0, 100);
conditions.Humidity = new RelativeHumidity(humidity, HU.Percent);
BusComms?.Write((byte)Registers.TEMPERATURE_MEASURE_NOHOLD);
await Task.Delay(20); // Maximum conversion time is 12ms (page 5 of the datasheet)
BusComms?.Read(ReadBuffer.Span[0..2]);// 2 data bytes plus a checksum (we ignore the checksum here)
var temperatureReading = (short)((ReadBuffer.Span[0] << 8) + ReadBuffer.Span[1]);
conditions.Temperature = new Units.Temperature((float)(((175.72 * temperatureReading) / 65536) - 46.85), Units.Temperature.UnitType.Celsius);
return conditions;
}
/// <summary>
/// Turn the heater on or off
/// </summary>
/// <param name="heaterOn">Heater status, true = turn heater on, false = turn heater off.</param>
public void Heater(bool heaterOn)
{
if (BusComms == null) return;
var register = BusComms.ReadRegister((byte)Registers.READ_HEATER_REGISTER);
register &= 0xfd;
if (heaterOn)
{
register |= 0x02;
}
BusComms.WriteRegister((byte)Registers.WRITE_HEATER_REGISTER, register);
}
//Set sensor resolution
/*******************************************************************************************/
//Sets the sensor resolution to one of four levels
//Page 12:
// 0/0 = 12bit RH, 14bit Temp
// 0/1 = 8bit RH, 12bit Temp
// 1/0 = 10bit RH, 13bit Temp
// 1/1 = 11bit RH, 11bit Temp
//Power on default is 0/0
void SetResolution(SensorResolution resolution)
{
if (BusComms == null) return;
var register = BusComms.ReadRegister((byte)Registers.READ_USER_REGISTER);
var res = (byte)resolution;
register &= 0x73; //Turn off the resolution bits
res &= 0x81; //Turn off all other bits but resolution bits
register |= res; //Mask in the requested resolution bits
//Request a write to user register
BusComms.WriteRegister((byte)Registers.WRITE_USER_REGISTER, register); //Write the new resolution bits
}
}
}