未验证 提交 7bed5c10 编写于 作者: H Hakan Lindestaf 提交者: GitHub

Added support for MCP9808 (#1026)

* Added support for MCP9808

* Fixed formatting issues

* Fixed items from comments

* Fixes from comments

* Added documentation
上级 5d0120bb
// 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.Units;
namespace Iot.Device.Mcp9808
{
/// <summary>
/// Microchip's MCP9808 I2C Temp sensor
/// </summary>
public class Mcp9808 : IDisposable
{
private I2cDevice _i2cDevice;
/// <summary>
/// MCP9808 I2C Address
/// </summary>
public const byte DefaultI2cAddress = 0x18;
#region prop
/// <summary>
/// MCP9808 Temperature
/// </summary>
public Temperature Temperature { get => Temperature.FromCelsius(GetTemperature()); }
private bool _disable;
/// <summary>
/// Disable MCP9808
/// </summary>
public bool Disabled
{
get
{
return _disable;
}
set
{
SetShutdown(value);
}
}
#endregion
/// <summary>
/// Creates a new instance of the MCP9808
/// </summary>
/// <param name="i2cDevice">The I2C device used for communication.</param>
public Mcp9808(I2cDevice i2cDevice)
{
_i2cDevice = i2cDevice;
Disabled = false;
if (!Init())
{
throw new Exception("Unable to identify manufacturer/device id");
}
}
/// <summary>
/// Checks if the device is a MCP9808
/// </summary>
/// <returns>True if device has been correctly detected</returns>
private bool Init()
{
if (Read16(Register8.MCP_MANUF_ID) != 0x0054)
{
return false;
}
if (Read16(Register8.MCP_DEVICE_ID) != 0x0400)
{
return false;
}
return true;
}
/// <summary>
/// Return the internal resolution register
/// </summary>
/// <returns>Resolution setting</returns>
public byte GetResolution()
{
return Read8(Register8.MCP_RESOLUTION);
}
/// <summary>
/// Wakes-up the device
/// </summary>
public void Wake()
{
SetShutdown(false);
// Sleep 250 ms, which is the typical temperature conversion time for the highest resolution (page 3 in datasheet, tCONV)
Thread.Sleep(250);
}
/// <summary>
/// Shuts down the device
/// </summary>
public void Shutdown()
{
SetShutdown(true);
}
/// <summary>
/// Read MCP9808 Temperature (℃)
/// </summary>
/// <returns>Temperature</returns>
private double GetTemperature()
{
ushort value = Read16(Register8.MCP_AMBIENT_TEMP);
if (value == 0xFFFF)
{
// Return NaN if the MCP9808 doesn't have a measurement ready at the time of reading
return double.NaN;
}
double temp = value & 0x0FFF;
temp /= 16.0;
if ((value & 0x1000) != 0)
{
temp -= 256;
}
return Math.Round(temp, 5);
}
/// <summary>
/// Set MCP9808 Shutdown
/// </summary>
/// <param name="isShutdown">Shutdown when value is true.</param>
private void SetShutdown(bool isShutdown)
{
Register16 curVal = ReadRegister16(Register8.MCP_CONFIG);
if (isShutdown)
{
curVal |= Register16.MCP_CONFIG_SHUTDOWN;
}
else
{
curVal &= ~Register16.MCP_CONFIG_SHUTDOWN;
}
Write16(Register8.MCP_CONFIG, curVal);
_disable = isShutdown;
}
/// <summary>
/// Cleanup
/// </summary>
public void Dispose()
{
_i2cDevice?.Dispose();
_i2cDevice = null;
}
internal Register16 ReadRegister16(Register8 reg)
{
return (Register16)Read16(reg);
}
internal ushort Read16(Register8 reg)
{
_i2cDevice.WriteByte((byte)reg);
Span<byte> buf = stackalloc byte[2];
_i2cDevice.Read(buf);
return (ushort)(buf[0] << 8 | buf[1]);
}
internal void Write16(Register8 reg, Register16 value)
{
_i2cDevice.Write(new byte[]
{
(byte)reg,
(byte)((ushort)value >> 8),
(byte)((ushort)value & 0xFF)
});
}
internal byte Read8(Register8 reg)
{
_i2cDevice.WriteByte((byte)reg);
return _i2cDevice.ReadByte();
}
internal void Write8(Register8 reg, byte value)
{
_i2cDevice.Write(new byte[]
{
(byte)reg,
value
});
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<EnableDefaultItems>false</EnableDefaultItems>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="$(MainLibraryPath)System.Device.Gpio.csproj">
<AdditionalProperties>$(AdditionalProperties);RuntimeIdentifier=linux</AdditionalProperties>
</ProjectReference>
<ProjectReference Include="..\Units\Units.csproj" />
<Compile Include="Register.cs" />
<Compile Include="Mcp9808.cs" />
</ItemGroup>
<ItemGroup>
<None Remove="README.md" />
</ItemGroup>
</Project>
# MCP9808 - Digital Temperature Sensor
Microchip Technology Inc.’s MCP9808 digital temperature sensor converts temperatures between -20°C and +100°C to a digital word with ±0.25°C/±0.5°C (typical/maximum) accuracy
## Usage
```C#
I2cConnectionSettings settings = new I2cConnectionSettings(1, Mcp9808.DefaultI2cAddress);
I2cDevice device = I2cDevice.Create(settings);
using(Mcp9808 sensor = new Mcp9808(device))
{
double temperature = sensor.Temperature.Celsius;
}
```
## References
http://ww1.microchip.com/downloads/en/DeviceDoc/25095A.pdf
// 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.Mcp9808
{
/// <summary>
/// MCP9808 Register
/// </summary>
internal enum Register16 : ushort
{
MCP_CONFIG_SHUTDOWN = 0x0100, // shutdown config
MCP_CONFIG_CRITLOCKED = 0x0080, // critical trip lock
MCP_CONFIG_WINLOCKED = 0x0040, // alarm window lock
MCP_CONFIG_INTCLR = 0x0020, // interrupt clear
MCP_CONFIG_ALERTSTAT = 0x0010, // alert output status
MCP_CONFIG_ALERTCTRL = 0x0008, // alert output control
MCP_CONFIG_ALERTSEL = 0x0004, // alert output select
MCP_CONFIG_ALERTPOL = 0x0002, // alert output polarity
MCP_CONFIG_ALERTMODE = 0x0001, // alert output mode
}
internal enum Register8 : byte
{
MCP_CONFIG = 0x01, // config
MCP_UPPER_TEMP = 0x02, // upper alert boundary
MCP_LOWER_TEMP = 0x03, // lower alert boundery
MCP_CRIT_TEMP = 0x04, // critical temperature
MCP_AMBIENT_TEMP = 0x05, // ambient temperature
MCP_MANUF_ID = 0x06, // manufacture ID
MCP_DEVICE_ID = 0x07, // device ID
MCP_RESOLUTION = 0x08 // resolution
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Mcp9808.csproj" />
<ProjectReference Include="$(MainLibraryPath)System.Device.Gpio.csproj">
<AdditionalProperties>$(AdditionalProperties);RuntimeIdentifier=linux</AdditionalProperties>
</ProjectReference>
<ProjectReference Include="..\..\Units\Units.csproj" />
</ItemGroup>
<ItemGroup>
<None Remove="README.md" />
</ItemGroup>
</Project>
// 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;
namespace Iot.Device.Mcp9808.Samples
{
internal class Program
{
public static void Main(string[] args)
{
I2cConnectionSettings settings = new I2cConnectionSettings(1, Mcp9808.DefaultI2cAddress);
I2cDevice device = I2cDevice.Create(settings);
using (Mcp9808 sensor = new Mcp9808(device))
{
while (true)
{
// read temperature
Console.WriteLine($"Temperature: {sensor.Temperature.Celsius} ℃");
Console.WriteLine();
Thread.Sleep(1000);
}
}
}
}
}
# MCP9808 - Samples
## Hardware Required
* MCP9808
* Male/Female Jumper Wires
## Circuit
* SCL - SCL
* SDA - SDA
* VCC - 5V
* GND - GND
## Code
```C#
I2cConnectionSettings settings = new I2cConnectionSettings(1, Mcp9808.DefaultI2cAddress);
I2cDevice device = I2cDevice.Create(settings);
using(Mcp9808 sensor = new Mcp9808(device))
{
while (true)
{
Console.WriteLine($"Temperature: {sensor.Temperature.Celsius} ℃");
Console.WriteLine();
Thread.Sleep(1000);
}
}
```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册