提交 b0a55d22 编写于 作者: M Marcus Fehde

Review remarks implemented

上级 e736c5ea
......@@ -22,7 +22,8 @@ namespace Iot.Device.Ahtxx
/// </summary>
public const int DeviceAddress = 0x38;
private enum StatusBit : byte // datasheet version 1.1, table 10
// datasheet version 1.1, table 10
private enum StatusBit : byte
{
Calibrated = 0x08,
Busy = 0x80
......@@ -35,7 +36,6 @@ namespace Iot.Device.Ahtxx
Measure = 0xac
}
private bool _disposed = false;
private I2cDevice _i2cDevice = null;
private double _temperature;
private double _humidity;
......@@ -48,7 +48,8 @@ namespace Iot.Device.Ahtxx
{
_i2cDevice = i2cDevice ?? throw new ArgumentNullException(nameof(i2cDevice));
SoftReset(); // even if not clearly stated in datasheet, start with a software reset to assure clear start conditions
// even if not clearly stated in datasheet, start with a software reset to assure clear start conditions
SoftReset();
// check whether the device indicates the need for a calibration cycle
// and perform calibration if indicated ==> c.f. datasheet, version 1.1, ch. 5.4
......@@ -87,8 +88,9 @@ namespace Iot.Device.Ahtxx
{
Span<byte> buffer = stackalloc byte[3]
{
// command parameters c.f. datasheet, version 1.1, ch. 5.4
(byte)Command.Measure,
0x33, // command parameters c.f. datasheet, version 1.1, ch. 5.4
0x33,
0x00
};
_i2cDevice.Write(buffer);
......@@ -121,7 +123,8 @@ namespace Iot.Device.Ahtxx
private void SoftReset()
{
_i2cDevice.WriteByte((byte)Command.SoftRest);
Thread.Sleep(20); // reset requires 20ms at most, c.f. datasheet version 1.1, ch. 5.5
// reset requires 20ms at most, c.f. datasheet version 1.1, ch. 5.5
Thread.Sleep(20);
}
/// <summary>
......@@ -136,13 +139,15 @@ namespace Iot.Device.Ahtxx
0x00
};
_i2cDevice.Write(buffer);
Thread.Sleep(10); // wait 10ms c.f. datasheet, version 1.1, ch. 5.4
// wait 10ms c.f. datasheet, version 1.1, ch. 5.4
Thread.Sleep(10);
}
private byte GetStatusByte()
{
_i2cDevice.WriteByte(0x71);
Thread.Sleep(10); // whithout this delay the reading the status fails often.
// whithout this delay the reading the status fails often.
Thread.Sleep(10);
byte status = _i2cDevice.ReadByte();
return status;
}
......@@ -163,21 +168,13 @@ namespace Iot.Device.Ahtxx
/// <inheritdoc cref="IDisposable" />
protected virtual void Dispose(bool disposing)
{
if (_disposed)
if (_i2cDevice == null)
{
return;
}
if (disposing)
{
if (_i2cDevice != null)
{
_i2cDevice?.Dispose();
_i2cDevice = null;
}
}
_disposed = true;
_i2cDevice?.Dispose();
_i2cDevice = null;
}
}
}
hygrometers
thermometers
\ No newline at end of file
......@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
......
......@@ -38,7 +38,6 @@ namespace Iot.Device.Mhz19b
private const int MessageSize = 9;
private bool _disposed = false;
private SerialPort _serialPort = null;
/// <summary>
......@@ -47,9 +46,9 @@ namespace Iot.Device.Mhz19b
/// <param name="uartDevice">Path to the UART device / serial port, e.g. /dev/serial0</param>
public Mhz19b(string uartDevice)
{
if (uartDevice == null)
if (string.IsNullOrEmpty(uartDevice))
{
throw new ArgumentNullException(nameof(uartDevice));
throw new ArgumentException(nameof(uartDevice));
}
// create serial port using the setting acc. to datasheet, pg. 7, sec. general settings
......@@ -66,7 +65,7 @@ namespace Iot.Device.Mhz19b
/// If the validity is false the ratio is set to 0.
/// </summary>
/// <returns>CO2 concentration in ppm and validity</returns>
public (Ratio concentration, bool validity) GetCo2Reading()
public (VolumeConcentration concentration, bool validity) GetCo2Reading()
{
try
{
......@@ -86,23 +85,23 @@ namespace Iot.Device.Mhz19b
if (timeout == 0)
{
return (Ratio.FromPartsPerMillion(0), false);
return (VolumeConcentration.Zero, false);
}
// read and process response
byte[] response = new byte[MessageSize];
if ((_serialPort.Read(response, 0, response.Length) == response.Length) && (response[(int)MessageFormat.Checksum] == Checksum(response)))
{
return (Ratio.FromPartsPerMillion((int)response[(int)MessageFormat.DataHighResponse] * 256 + (int)response[(int)MessageFormat.DataLowResponse]), true);
return (VolumeConcentration.FromPartsPerMillion((int)response[(int)MessageFormat.DataHighResponse] * 256 + (int)response[(int)MessageFormat.DataLowResponse]), true);
}
else
{
return (Ratio.FromPartsPerMillion(0), false);
return (VolumeConcentration.Zero, false);
}
}
catch
{ // no need for details here
return (Ratio.FromPartsPerMillion(0), false);
return (VolumeConcentration.Zero, false);
}
finally
{
......@@ -115,20 +114,26 @@ namespace Iot.Device.Mhz19b
/// The sensor doesn't respond anything, so this is fire and forget.
/// </summary>
/// <returns>true, if the command could be send</returns>
public bool ZeroPointCalibration() => SendRequest(CreateRequest(Command.CalibrateZeroPoint));
public bool PerformZeroPointCalibration() => SendRequest(CreateRequest(Command.CalibrateZeroPoint));
/// <summary>
/// Initiate a span point calibration.
/// The sensor doesn't respond anything, so this is fire and forget.
/// </summary>
/// <param name="span">span value, e.g. 2000[ppm]</param>
/// <param name="span">span value, between 1000[ppm] and 5000[ppm]. The typical value is 2000[ppm].</param>
/// <returns>true, if the command could be send</returns>///
public bool SpanPointCalibration(int span)
/// <exception cref="System.Exception">Thrown when span value is out of range</exception>
public bool PerformSpanPointCalibration(VolumeConcentration span)
{
if ((span.PartsPerMillion < 1000) || (span.PartsPerMillion > 5000))
{
throw new ArgumentException("Span value out of range (1000-5000[ppm])", nameof(span));
}
var request = CreateRequest(Command.CalibrateSpanPoint);
// set span in request, c. f. datasheet rev. 1.0, pg. 8 for details
request[(int)MessageFormat.DataHighRequest] = (byte)(span / 256);
request[(int)MessageFormat.DataLowRequest] = (byte)(span % 256);
request[(int)MessageFormat.DataHighRequest] = (byte)(span.PartsPerMillion / 256);
request[(int)MessageFormat.DataLowRequest] = (byte)(span.PartsPerMillion % 256);
return SendRequest(request);
}
......@@ -139,7 +144,7 @@ namespace Iot.Device.Mhz19b
/// </summary>
/// <param name="state">State of automatic correction</param>
/// <returns>true, if the command could be send</returns>
public bool AutomaticBaselineCorrection(AbmState state)
public bool SetAutomaticBaselineCorrection(AbmState state)
{
var request = CreateRequest(Command.AutoCalibrationSwitch);
// set on/off state in request, c. f. datasheet rev. 1.0, pg. 8 for details
......@@ -154,7 +159,7 @@ namespace Iot.Device.Mhz19b
/// </summary>
/// <param name="detectionRange">Detection range of the sensor</param>
/// <returns>true, if the command could be send</returns>
public bool SensorDetectionRange(DetectionRange detectionRange)
public bool SetSensorDetectionRange(DetectionRange detectionRange)
{
var request = CreateRequest(Command.DetectionRangeSetting);
// set detection range in request, c. f. datasheet rev. 1.0, pg. 8 for details
......@@ -171,11 +176,13 @@ namespace Iot.Device.Mhz19b
try
{
_serialPort.Open();
_serialPort.Write(request, 0, request.Length);
return true;
// _serialPort.Write(request, 0, request.Length);
return false;
// return true;
}
catch
{ // no need fo details here
{
// no need fo details here
return false;
}
finally
......@@ -214,17 +221,13 @@ namespace Iot.Device.Mhz19b
/// <inheritdoc cref="IDisposable" />
public void Dispose()
{
if (_disposed)
if (_serialPort == null)
{
return;
}
if (_serialPort != null)
{
_serialPort.Dispose();
_serialPort = null;
_disposed = true;
}
_serialPort.Dispose();
_serialPort = null;
}
}
}
\ No newline at end of file
......@@ -9,7 +9,7 @@
<ItemGroup>
<Compile Include="*.cs" />
<None Include="README.md" />
<PackageReference Include="System.IO.Ports" Version="5.0.0-rc.1.20451.14" />
<PackageReference Include="System.IO.Ports" Version="4.7.0" />
<ProjectReference Include="$(MainLibraryPath)System.Device.Gpio.csproj" />
</ItemGroup>
......
......@@ -19,16 +19,35 @@ namespace Iot.Device.Mhz19b.Samples
public static void Main(string[] args)
{
Mhz19b sensor = new Mhz19b("/dev/serial0");
// Switch ABM on (default).
// sensor.SetAutomaticBaselineCorrection(AbmState.On);
// Set sensor detection range to 2000ppm (default).
// sensor.SetSensorDetectionRange(DetectionRange.Range2000);
// Perform calibration
// Step #1: perform zero point calibration
// Step #2: perform span point calibration at 2000ppm
// CAUTION: enable the following lines only if you know exactly what you do.
// Consider also that zero point and span point calibration are performed
// at different concentrations. The sensor requires up to 20 min to be
// saturated at the target level.
// sensor.PerformZeroPointCalibration();
// ---- Now change to target concentration for span point.
// sensor.PerformSpanPointCalibration(VolumeConcentration.FromPartsPerMillion(200));
// Continously read current concentration
while (true)
{
(Ratio concentration, bool validity) reading = sensor.GetCo2Reading();
(VolumeConcentration concentration, bool validity) reading = sensor.GetCo2Reading();
if (reading.validity)
{
Console.WriteLine($"{reading.concentration}");
}
else
{
Console.WriteLine("Concentration counldn't be read");
Console.WriteLine("Concentration couldn't be read");
}
Thread.Sleep(1000);
......
gas sensors
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册