Skip to content

Commit 2e5e110

Browse files
authored
Adding Max31856 (#43)
1 parent e9320b9 commit 2e5e110

16 files changed

+615
-0
lines changed

devices/Max31856/Max31856.cs

+188
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Buffers.Binary;
6+
using System.Device.Spi;
7+
using System.IO;
8+
using UnitsNet;
9+
10+
namespace Iot.Device.Max31856
11+
{
12+
/// <summary>
13+
/// Max31856 - cold-junction compensated thermocouple to digital converter
14+
/// </summary>
15+
public class Max31856 : IDisposable
16+
{
17+
private readonly byte _thermocoupleType;
18+
private SpiDevice _spiDevice;
19+
20+
#region SpiSettings
21+
22+
/// <summary>
23+
/// Spi Clock Frequency
24+
/// </summary>
25+
public const int SpiClockFrequency = 5_000_000;
26+
27+
/// <summary>
28+
/// SPI data flow
29+
/// </summary>
30+
public const DataFlow SpiDataFlow = DataFlow.MsbFirst;
31+
32+
/// <summary>
33+
/// SPI Mode
34+
/// </summary>
35+
public const SpiMode SpiModeSetup = SpiMode.Mode1;
36+
37+
#endregion
38+
39+
/// <summary>
40+
/// Command to Get Temperature from the device
41+
/// </summary>
42+
public Temperature GetTemperature()
43+
{
44+
return ReadTemperature(out byte[] spiOutputData);
45+
}
46+
47+
/// <summary>
48+
/// Reads the temperature from the Cold-Junction sensor
49+
/// </summary>
50+
/// <returns>
51+
/// Temperature, precision +- 0.7 Celsius range from -20 Celsius to +85 Celsius
52+
/// </returns>
53+
public Temperature GetColdJunctionTemperature() => Temperature.FromDegreesCelsius(ReadCJTemperature());
54+
55+
/// <summary>
56+
/// Creates a new instance of the Max31856.
57+
/// </summary>
58+
/// <param name="spiDevice">The communications channel to a device on a SPI bus</param>
59+
/// <param name="thermocoupleType">Thermocouple type. It Defaults to T.</param>
60+
public Max31856(SpiDevice spiDevice, ThermocoupleType thermocoupleType = ThermocoupleType.T)
61+
{
62+
_spiDevice = spiDevice ?? throw new ArgumentNullException(nameof(spiDevice));
63+
_thermocoupleType = (byte)thermocoupleType;
64+
Initialize();
65+
}
66+
67+
#region private and internal
68+
69+
/// <summary>
70+
/// Standard initialization routine.
71+
/// </summary>
72+
/// /// <remarks>
73+
/// You can add new write lines if you want to alter the settings of the device. Settings can be found in the Technical Manual
74+
/// </remarks>
75+
private void Initialize()
76+
{
77+
SpanByte configurationSetting0 = new byte[]
78+
{
79+
(byte)Register.WRITE_CR0,
80+
(byte)Register.ONESHOT_FAULT_SETTING
81+
};
82+
SpanByte configurationSetting1 = new byte[]
83+
{
84+
(byte)Register.WRITE_CR1,
85+
_thermocoupleType
86+
};
87+
88+
Write(configurationSetting0);
89+
Write(configurationSetting1);
90+
91+
}
92+
93+
/// <summary>
94+
/// Command to Get Temperature from the Device
95+
/// </summary>
96+
/// <remarks>
97+
/// Initializes the device and then reads the data for the cold junction temperature also checks for errors to throw
98+
/// </remarks>
99+
private double ReadCJTemperature()
100+
{
101+
var spiOutputData = WriteRead(Register.READ_CR0, 16);
102+
var coldJunctionTemperature = ConvertspiOutputDataTempColdJunction(spiOutputData);
103+
return coldJunctionTemperature;
104+
}
105+
106+
/// <summary>
107+
/// Converts the Thermocouple Temperature Reading
108+
/// </summary>
109+
/// <remarks>
110+
/// Takes the spi data as an input and outputs the Thermocouple Temperature Reading
111+
/// </remarks>
112+
private Temperature ReadTemperature(out byte[] spiOutputData)
113+
{
114+
spiOutputData = WriteRead(Register.READ_CR0, 16);
115+
double tempRaw = (((spiOutputData[13] & 0x7F) << 16) + (spiOutputData[14] << 8) + (spiOutputData[15]));
116+
double temperature = tempRaw / 4096; // temperature in degrees C
117+
if ((spiOutputData[13] & 0x80) == 0x80) // checks if the temp is negative
118+
{
119+
temperature = -temperature;
120+
}
121+
122+
var temperatureOut = Temperature.FromDegreesCelsius(temperature); // Converts temperature to type Temperature struct and establishes it as Degrees C for its initial units
123+
124+
return temperatureOut;
125+
}
126+
127+
/// <summary>
128+
/// Converts Cold Junction Temperature Reading
129+
/// </summary>
130+
/// <remarks>
131+
/// Takes the spi data as an input and outputs the Cold Junction Temperature Reading
132+
/// </remarks>
133+
/// <param name="spiOutputData">Spidata read from the device as 16 bytes</param>
134+
private double ConvertspiOutputDataTempColdJunction(byte[] spiOutputData)
135+
{
136+
SpanByte reading = new SpanByte(spiOutputData, 11, 2);
137+
reading[0] = (byte)(spiOutputData[11] & 0x7F);
138+
short tempRaw = BinaryPrimitives.ReadInt16BigEndian(reading);
139+
if ((spiOutputData[11] & 0x80) == 0x80) // checks if the temp is negative
140+
{
141+
return -tempRaw / 256.0;
142+
}
143+
144+
return tempRaw / 256.0;
145+
}
146+
147+
#endregion
148+
149+
#region read and write operations
150+
151+
/// <summary>
152+
/// Writes the Data to the Spi Device
153+
/// </summary>
154+
/// <remarks>
155+
/// Takes the data input byte and writes it to the spi device
156+
/// </remarks>
157+
/// <param name="data">Data to write to the device</param>
158+
private void Write(SpanByte data) => _spiDevice.Write(data);
159+
160+
/// <summary>
161+
/// Full Duplex Read of the Data on the Device
162+
/// </summary>
163+
/// <remarks>
164+
/// Writes the read address of the register and outputs a byte list of the length provided
165+
/// </remarks>
166+
/// /// <param name="register">Register location to write to which starts the device reading</param>
167+
/// /// <param name="readbytesize">Number of bytes being read</param>
168+
private byte[] WriteRead(Register register, int readbytesize)
169+
{
170+
SpanByte readBuf = new byte[readbytesize + 1];
171+
SpanByte regAddrBuf = new byte[1 + readbytesize];
172+
173+
regAddrBuf[0] = (byte)(register);
174+
_spiDevice.TransferFullDuplex(regAddrBuf, readBuf);
175+
var rawData = readBuf.ToArray();
176+
return rawData;
177+
}
178+
179+
#endregion
180+
181+
/// <inheritdoc/>
182+
public void Dispose()
183+
{
184+
_spiDevice?.Dispose();
185+
_spiDevice = null!;
186+
}
187+
}
188+
}

devices/Max31856/Max31856.nfproj

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="Current" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup Label="Globals">
4+
<NanoFrameworkProjectSystemPath>$(MSBuildToolsPath)..\..\..\nanoFramework\v1.0\</NanoFrameworkProjectSystemPath>
5+
</PropertyGroup>
6+
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.Default.props" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.Default.props')" />
7+
<PropertyGroup>
8+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
9+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
10+
<ProjectTypeGuids>{11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
11+
<ProjectGuid>{8902BF4F-94F3-4032-8C09-CC44A42E79DA}</ProjectGuid>
12+
<OutputType>Library</OutputType>
13+
<AppDesignerFolder>Properties</AppDesignerFolder>
14+
<FileAlignment>512</FileAlignment>
15+
<RootNamespace>Iot.Device.Max31856</RootNamespace>
16+
<AssemblyName>Iot.Device.Max31856</AssemblyName>
17+
<TargetFrameworkVersion>v1.0</TargetFrameworkVersion>
18+
<DocumentationFile>bin\$(Configuration)\Iot.Device.Max31856.xml</DocumentationFile>
19+
<LangVersion>9.0</LangVersion>
20+
</PropertyGroup>
21+
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.props" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.props')" />
22+
<ItemGroup>
23+
<Reference Include="mscorlib">
24+
<HintPath>packages\nanoFramework.CoreLibrary.1.10.4-preview.11\lib\mscorlib.dll</HintPath>
25+
<Private>True</Private>
26+
</Reference>
27+
<Reference Include="System.Device.Spi">
28+
<HintPath>packages\nanoFramework.System.Device.Spi.1.0.0-preview.38\lib\System.Device.Spi.dll</HintPath>
29+
<Private>True</Private>
30+
</Reference>
31+
<Reference Include="UnitsNet.Frequency, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
32+
<HintPath>packages\UnitsNet.nanoFramework.Frequency.4.92.1\lib\UnitsNet.Frequency.dll</HintPath>
33+
<Private>True</Private>
34+
<SpecificVersion>True</SpecificVersion>
35+
</Reference>
36+
<Reference Include="UnitsNet.Temperature, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
37+
<HintPath>packages\UnitsNet.nanoFramework.Temperature.4.92.1\lib\UnitsNet.Temperature.dll</HintPath>
38+
<Private>True</Private>
39+
<SpecificVersion>True</SpecificVersion>
40+
</Reference>
41+
</ItemGroup>
42+
<ItemGroup>
43+
<None Include="packages.config" />
44+
<Compile Include="*.cs" />
45+
<None Include="README.md" />
46+
</ItemGroup>
47+
<ItemGroup>
48+
<Compile Include="Properties\AssemblyInfo.cs" />
49+
<Compile Include="*.cs" />
50+
<None Include="*.md" />
51+
</ItemGroup>
52+
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets')" />
53+
<Import Project="..\..\src\BinaryPrimitives\BinaryPrimitives.projitems" Label="Shared" />
54+
<ProjectExtensions>
55+
<ProjectCapabilities>
56+
<ProjectConfigurationsDeclaredAsItems />
57+
</ProjectCapabilities>
58+
</ProjectExtensions>
59+
<Import Project="packages\Nerdbank.GitVersioning.3.4.194\build\Nerdbank.GitVersioning.targets" Condition="Exists('packages\Nerdbank.GitVersioning.3.4.194\build\Nerdbank.GitVersioning.targets')" />
60+
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
61+
<PropertyGroup>
62+
<ErrorText> This project references NuGet package(s) that are missing on this computer.Enable NuGet Package Restore to download them.For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.</ErrorText>
63+
</PropertyGroup>
64+
<Error Condition="!Exists('packages\Nerdbank.GitVersioning.3.4.194\build\Nerdbank.GitVersioning.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Nerdbank.GitVersioning.3.4.194\build\Nerdbank.GitVersioning.targets'))" />
65+
</Target>
66+
</Project>

devices/Max31856/Max31856.nuspec

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
3+
<metadata>
4+
<id>nanoFramework.Iot.Device.Max31856</id>
5+
<version>$version$</version>
6+
<title>nanoFramework.Iot.Device.Max31856</title>
7+
<authors>nanoFramework project contributors</authors>
8+
<owners>nanoFramework project contributors,dotnetfoundation</owners>
9+
<requireLicenseAcceptance>false</requireLicenseAcceptance>
10+
<license type="file">LICENSE.md</license>
11+
<releaseNotes>
12+
</releaseNotes>
13+
<developmentDependency>false</developmentDependency>
14+
<projectUrl>https://github.com/nanoframework/nanoFramework.IoT.Device</projectUrl>
15+
<iconUrl>https://secure.gravatar.com/avatar/97d0e092247f0716db6d4b47b7d1d1ad</iconUrl>
16+
<icon>images\nf-logo.png</icon>
17+
<repository type="git" url="https://github.com/nanoframework/nanoFramework.IoT.Device" commit="$commit$" />
18+
<copyright>Copyright (c) .NET Foundation and Contributors</copyright>
19+
<description>This package includes the .NET IoT Core binding Iot.Device.Max31856 for .NET nanoFramework C# projects.</description>
20+
<summary>Iot.Device.Max31856 assembly for .NET nanoFramework C# projects</summary>
21+
<tags>nanoFramework C# csharp netmf netnf Iot.Device.Max31856</tags>
22+
<dependencies>
23+
<dependency id="nanoFramework.CoreLibrary" version="1.10.4-preview.11" />
24+
<dependency id="nanoFramework.System.Device.Spi" version="1.0.0-preview.38" />
25+
<dependency id="UnitsNet.nanoFramework.Frequency" version="4.92.1" />
26+
<dependency id="UnitsNet.nanoFramework.Temperature" version="4.92.1" />
27+
</dependencies>
28+
</metadata>
29+
<files>
30+
<file src="bin\Release\Iot.Device.Max31856.dll" target="lib\Iot.Device.Max31856.dll" />
31+
<file src="bin\Release\Iot.Device.Max31856.pdb" target="lib\Iot.Device.Max31856.pdb" />
32+
<file src="bin\Release\Iot.Device.Max31856.pdbx" target="lib\Iot.Device.Max31856.pdbx" />
33+
<file src="bin\Release\Iot.Device.Max31856.pe" target="lib\Iot.Device.Max31856.pe" />
34+
<file src="bin\Release\Iot.Device.Max31856.xml" target="lib\Iot.Device.Max31856.xml" />
35+
<file src="readme.md" target="" />
36+
<file src="..\..\assets\nf-logo.png" target="images" />
37+
<file src="..\..\LICENSE.md" target="" />
38+
</files>
39+
</package>

devices/Max31856/Max31856.sln

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
Microsoft Visual Studio Solution File, Format Version 12.00
2+
# Visual Studio Version 16
3+
VisualStudioVersion = 16.0.30413.136
4+
MinimumVisualStudioVersion = 10.0.40219.1
5+
Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "Max31856", "Max31856.nfproj", "{8902BF4F-94F3-4032-8C09-CC44A42E79DA}"
6+
EndProject
7+
Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "Max31856.Samples", "samples\Max31856.Samples.nfproj", "{990B8289-9127-4EB1-9AB7-959C2027E2E0}"
8+
EndProject
9+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared Projects", "Shared Projects", "{D4A396D5-734F-4F36-8323-37288B08FB5E}"
10+
EndProject
11+
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "BinaryPrimitives", "..\..\src\BinaryPrimitives\BinaryPrimitives.shproj", "{3F28B003-6318-4E21-A9B6-6C0DBD0BDBFD}"
12+
EndProject
13+
Global
14+
GlobalSection(SharedMSBuildProjectFiles) = preSolution
15+
..\..\src\BinaryPrimitives\BinaryPrimitives.projitems*{3f28b003-6318-4e21-a9b6-6c0dbd0bdbfd}*SharedItemsImports = 13
16+
EndGlobalSection
17+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
18+
Debug|Any CPU = Debug|Any CPU
19+
Release|Any CPU = Release|Any CPU
20+
EndGlobalSection
21+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
22+
{8902BF4F-94F3-4032-8C09-CC44A42E79DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23+
{8902BF4F-94F3-4032-8C09-CC44A42E79DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
24+
{8902BF4F-94F3-4032-8C09-CC44A42E79DA}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
25+
{8902BF4F-94F3-4032-8C09-CC44A42E79DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
26+
{8902BF4F-94F3-4032-8C09-CC44A42E79DA}.Release|Any CPU.Build.0 = Release|Any CPU
27+
{8902BF4F-94F3-4032-8C09-CC44A42E79DA}.Release|Any CPU.Deploy.0 = Release|Any CPU
28+
{990B8289-9127-4EB1-9AB7-959C2027E2E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29+
{990B8289-9127-4EB1-9AB7-959C2027E2E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
30+
{990B8289-9127-4EB1-9AB7-959C2027E2E0}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
31+
{990B8289-9127-4EB1-9AB7-959C2027E2E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
32+
{990B8289-9127-4EB1-9AB7-959C2027E2E0}.Release|Any CPU.Build.0 = Release|Any CPU
33+
{990B8289-9127-4EB1-9AB7-959C2027E2E0}.Release|Any CPU.Deploy.0 = Release|Any CPU
34+
EndGlobalSection
35+
GlobalSection(SolutionProperties) = preSolution
36+
HideSolutionNode = FALSE
37+
EndGlobalSection
38+
GlobalSection(NestedProjects) = preSolution
39+
{3F28B003-6318-4E21-A9B6-6C0DBD0BDBFD} = {D4A396D5-734F-4F36-8323-37288B08FB5E}
40+
EndGlobalSection
41+
GlobalSection(ExtensibilityGlobals) = postSolution
42+
SolutionGuid = {1A4B7D9D-8B82-4688-B89E-F07B3B28373C}
43+
EndGlobalSection
44+
EndGlobal
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
[assembly: AssemblyTitle("Iot.Device.Max31856")]
6+
[assembly: AssemblyCompany("nanoFramework Contributors")]
7+
[assembly: AssemblyCopyright("Copyright(c).NET Foundation and Contributors")]
8+
9+
[assembly: ComVisible(false)]
10+

devices/Max31856/README.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Max31856 - cold-junction compensated thermocouple to digital converter
2+
3+
## Summary
4+
The Max31856 device is a SPI interface cold-junction compensated thermocouple to digital converter.
5+
6+
## Sensor Image
7+
![Illustration of wiring from a Raspberry Pi device](device.jpg)
8+
9+
**Note:** _ThermocoupleType.K is configured for a K type thermocouple if you want to use a B,E,J,K,N,R,S, or T simply change the K to the thermocouple type of your choosing._
10+
11+
## References
12+
13+
**Max31856** [datasheet](https://datasheets.maximintegrated.com/en/ds/Max31856.pdf)

0 commit comments

Comments
 (0)