-
-
Notifications
You must be signed in to change notification settings - Fork 109
/
Copy pathLps22Hb.cs
173 lines (142 loc) · 5.05 KB
/
Lps22Hb.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Buffers.Binary;
using System.Device.I2c;
using System.Device.Model;
using UnitsNet;
namespace Iot.Device.Lps22Hb
{
/// <summary>
/// Class for the LIS2MDL magnetometer.
/// </summary>
[Interface("Lps22Hb - MEMS nano pressure sensor: 260-1260 hPa absolute digital output barometer")]
public class Lps22Hb : IDisposable
{
private const float PressureScale = 4096.0f;
private const float TemperatureScale = 100.0f;
/// <summary>
/// Configuration: ODR = 25 Hz(continuous mode), LPF active with ODR/9, BDU activ.
/// </summary>
private const int ConfigFifoBypass = 0x3A;
/// <summary>
/// Device ID when reading the WHO_AM_I register.
/// </summary>
public const byte DeviceId = 0xB1;
// storage for raw data
private readonly byte[] _dataRaw;
// backing field for the I2C device
private I2cDevice _i2c;
/// <summary>
/// Device I2C Address.
/// </summary>
public const byte DefaultI2cAddress = 0x2E;
/// <summary>
/// Initializes a new instance of the <see cref="Lps22Hb" /> class.
/// </summary>
/// <param name="i2cDevice">I2C device.</param>
/// <param name="mode">FIFO mode selection.</param>
/// <exception cref="ArgumentNullException" >If the provided I2C device is <see langword="null"/>.</exception>
/// <exception cref="Exception">If the device is not found.</exception>
public Lps22Hb(
I2cDevice i2cDevice,
FifoMode mode)
{
_i2c = i2cDevice ?? throw new ArgumentNullException(nameof(i2cDevice));
// check if the device is present
var id = Read(Register.WhoAmI);
if (id != DeviceId)
{
throw new Exception("Device not found");
}
InitializeRegisters(mode);
// instantiate the raw data array
_dataRaw = new byte[3];
}
/// <summary>
/// Temperature reading.
/// </summary>
[Telemetry]
public Temperature Temperature => Temperature.FromDegreesCelsius(GetTemperature());
/// <summary>
/// Pressure reading.
/// </summary>
[Telemetry]
public Pressure Pressure => Pressure.FromHectopascals(GePressure());
private void WriteByte(Register register, byte data)
{
SpanByte buff = new byte[2]
{
(byte)register,
data
};
_i2c.Write(buff);
}
private short ReadInt16(Register register)
{
SpanByte val = new byte[2];
Read(register, val);
return BinaryPrimitives.ReadInt16LittleEndian(val);
}
private void Read(Register register, SpanByte buffer)
{
_i2c.WriteByte((byte)register);
_i2c.Read(buffer);
}
private byte Read(Register register)
{
_i2c.WriteByte((byte)register);
return _i2c.ReadByte();
}
private float GetTemperature()
{
// read the 2 raw data registers into data array
var tempRaw = ReadInt16(Register.TemperatureOutL);
// Convert tempRaw from two's complement to signed integer
short raw = tempRaw;
return raw / TemperatureScale;
}
private float GePressure()
{
Read(Register.PressureOutXl, _dataRaw);
int raw = ((_dataRaw[2] << 16) | (_dataRaw[1] << 8)) | _dataRaw[0];
if ((raw & 0x800000) == 0x800000)
{
raw = -(0x1000000 - raw);
}
return raw / PressureScale;
}
/// <inheritdoc/>
public void Dispose()
{
if (_i2c != null)
{
// Clear register to default value (Power off)
WriteByte(Register.ControlRegister1, 0x00);
_i2c?.Dispose();
_i2c = null;
}
}
private void InitializeRegisters(FifoMode mode)
{
switch (mode)
{
case FifoMode.Bypass:
// ODR = 25 Hz(continuous mode), LPF active with ODR/9, BDU activ
WriteByte(Register.ControlRegister1, ConfigFifoBypass);
// FIFO OFF and Multiple reading ON
WriteByte(Register.ControlRegister2, 0x10);
break;
case FifoMode.Fifo:
case FifoMode.Stream:
case FifoMode.StreamToFifo:
case FifoMode.BypassToStream:
case FifoMode.BypassToFifo:
case FifoMode.DynamicStream:
default:
// not implemented
throw new NotImplementedException();
}
}
}
}