From 0f2f35bfaec5de1f664482801f2da1db56995e0d Mon Sep 17 00:00:00 2001 From: Eveldee Date: Wed, 27 Jan 2021 21:59:49 +0100 Subject: [PATCH] Add xml doc --- WaveshareUARTFingerprintSensor/CommandType.cs | 3 + .../FingerprintSensor.cs | 172 +++++++++++++++++- .../ResponseType.cs | 6 + .../UserPermission.cs | 3 + WaveshareUARTFingerprintSensor/Utils.cs | 29 +++ 5 files changed, 207 insertions(+), 6 deletions(-) diff --git a/WaveshareUARTFingerprintSensor/CommandType.cs b/WaveshareUARTFingerprintSensor/CommandType.cs index 291d5cc..5d00b25 100644 --- a/WaveshareUARTFingerprintSensor/CommandType.cs +++ b/WaveshareUARTFingerprintSensor/CommandType.cs @@ -6,6 +6,9 @@ using System.Threading.Tasks; namespace WaveshareUARTFingerprintSensor { + /// + /// Command flags recognized by the sensor + /// public enum CommandType : byte { ModifySerialNumber = 0x08, diff --git a/WaveshareUARTFingerprintSensor/FingerprintSensor.cs b/WaveshareUARTFingerprintSensor/FingerprintSensor.cs index 6aae482..48400dd 100644 --- a/WaveshareUARTFingerprintSensor/FingerprintSensor.cs +++ b/WaveshareUARTFingerprintSensor/FingerprintSensor.cs @@ -16,17 +16,45 @@ namespace WaveshareUARTFingerprintSensor { public class FingerprintSensor : IDisposable { - public const string PrimarySerialPort = "/dev/ttyAMA0"; + /// + /// Primary serial port on the RPI. Source + /// + public const string PrimarySerialPort = "/dev/ttyAMA0"; + /// + /// Secondary serial port on the RPI. Source + /// public const string SecondarySerialPort = "/dev/ttyS0"; + /// + /// Timeout used for the I/O operations + /// public const int DefaultTimeout = 10_000; + /// + /// Maximum number of user that the sensor can store before throwing . It is also the ID of the last user + /// public const int MaxUserID = 0xFFF; + /// + /// Internal buffer size + /// public const int DataBufferSize = 4095; + /// + /// Thrown when "WAKE" pin is high, works like a press button. Can be used while the sensor is asleep + /// public event WakedEventHandler Waked; + /// + /// Delegate for the event + /// + /// public delegate void WakedEventHandler(FingerprintSensor sender); + /// + /// name/path used + /// public string PortName { get; } + /// + /// Mark the end of a command packet, usually the 8th byte + /// private const byte PacketSeparator = 0xF5; private SerialPort _serialPort; @@ -37,6 +65,12 @@ namespace WaveshareUARTFingerprintSensor private bool _sleeping = false; private readonly object _lock = new object(); + /// + /// Create a new instance of , don't forget to call before using any command + /// + /// A valid name/path to a serial port, see and for the RPI + /// WAKE number, default is according to the sensor documentation wiring + /// RST number, default is according to the sensor documentation wiring public FingerprintSensor(string portName, int wakePin = 23, int rstPin = 24) { PortName = portName; @@ -44,6 +78,9 @@ namespace WaveshareUARTFingerprintSensor _rstPinNumber = rstPin; } + /// + /// Start the sensor, initializing , the Gpio pins and the + /// public void Start() { // Initialize Gpio @@ -64,6 +101,11 @@ namespace WaveshareUARTFingerprintSensor _serialPort.Open(); } + /// + /// Compute the checksum for a command packet: XOR of 1 to 5 (counting from 0) + /// + /// A command packet, usually 8 bytes + /// The computed checksum, usually stored in the 6th private byte ComputeChecksum(byte[] data) { byte checksum = 0; @@ -76,6 +118,12 @@ namespace WaveshareUARTFingerprintSensor return checksum; } + /// + /// Compute the checksum for a data packet: XOR of 1 to (last - 2) (counting from 0) + /// + /// A data, not to be confused with a command packet + /// Length of the data packet, should be 2 bytes less than data.Length + /// The computed checksum, usually stored in the (last - 2)th byte private byte ComputeChecksumData(byte[] data, int length) { byte checksum = 0; @@ -88,6 +136,15 @@ namespace WaveshareUARTFingerprintSensor return checksum; } + /// + /// Send an 8 command and read the response, can throw an + /// + /// Command flag, see + /// First data , the 2th (counting from 0) + /// Second data , the 3th (counting from 0) + /// Third data , the 4th (counting from 0) + /// Timeout used for the , default to + /// The 3 data from the response (2, 3 and 4), the third one is parsed as a private (byte first, byte second, ResponseType responseType) SendAndReceive(CommandType commandType, byte first, byte second, byte third, int timeout = DefaultTimeout) { if (_sleeping) @@ -132,6 +189,15 @@ namespace WaveshareUARTFingerprintSensor return (buffer[2], buffer[3], (ResponseType)buffer[4]); } + /// + /// Send an 8 command and read the response, can throw an + /// + /// Command flag, see + /// First data , the 2th (counting from 0) + /// Second data , the 3th (counting from 0) + /// Third data , the 4th (counting from 0) + /// Timeout used for the , default to + /// The 3 data from the response (2, 3 and 4) private (byte first, byte second, byte third) SendAndReceiveRaw(CommandType commandType, byte first, byte second, byte third, int timeout = DefaultTimeout) { (byte f, byte s, ResponseType response) = SendAndReceive(commandType, first, second, third, timeout); @@ -139,6 +205,16 @@ namespace WaveshareUARTFingerprintSensor return (f, s, (byte)response); } + /// + /// Send an 8 command and read the response without throwing an + /// + /// Command flag, see + /// First data , the 2th (counting from 0) + /// Second data , the 3th (counting from 0) + /// Third data , the 4th (counting from 0) + /// The response as returned by + /// Timeout used for the , default to + /// true if successful, false otherwise private bool TrySendAndReceive(CommandType commandType, byte first, byte second, byte third, out (byte first, byte second, ResponseType responseType) response, int timeout = DefaultTimeout) { try @@ -153,8 +229,18 @@ namespace WaveshareUARTFingerprintSensor } return true; - } - + } + + /// + /// Send an 8 command and read the response without throwing an + /// + /// Command flag, see + /// First data , the 2th (counting from 0) + /// Second data , the 3th (counting from 0) + /// Third data , the 4th (counting from 0) + /// The response as returned by + /// Timeout used for the , default to + /// true if successful, false otherwise private bool TrySendAndReceiveRaw(CommandType commandType, byte first, byte second, byte third, out (byte first, byte second, byte third) response, int timeout = DefaultTimeout) { try @@ -171,6 +257,12 @@ namespace WaveshareUARTFingerprintSensor return true; } + /// + /// Read a data packet + /// + /// The length of the data packet + /// An invalid checksum will throw an , use this to ignore the checksum + /// private byte[] ReadData(int length, bool skipChecksum = false) { byte first = (byte)_serialPort.ReadByte(); @@ -200,6 +292,10 @@ namespace WaveshareUARTFingerprintSensor return data; } + /// + /// Query the sensor serial number + /// + /// public uint QuerySerialNumber() { (byte first, byte second, byte third) = SendAndReceiveRaw(CommandType.QuerySerialNumber, 0, 0, 0); @@ -207,6 +303,11 @@ namespace WaveshareUARTFingerprintSensor return Utils.Merge(first, second, third); } + /// + /// Get the number of registered users (fingerprints) + /// + /// User count if the command is successful + /// public bool TryGetUserCount(out ushort count) { if (TrySendAndReceive(CommandType.QueryUserCount, 0, 0, 0, out var response, 1000)) @@ -223,6 +324,12 @@ namespace WaveshareUARTFingerprintSensor return false; } + /// + /// Add a fingerprint by sending three commands, with a delay between each to ensure the fingerprint is perfectly read + /// + /// The id where to store the user (fingerprint) + /// The to store + /// public ResponseType AddFingerprint(ushort userID, UserPermission userPermission) { if (userID > MaxUserID) @@ -312,6 +419,11 @@ namespace WaveshareUARTFingerprintSensor } } + /// + /// Delete a user (fingerprint) from the sensor + /// + /// A valid user (fingerprint) id + /// true if successful, false otherwise public bool DeleteUser(ushort userID) { (byte high, byte low) = Utils.Split(userID); @@ -324,6 +436,10 @@ namespace WaveshareUARTFingerprintSensor return false; } + /// + /// Delete all users (fingerprints) from the sensor + /// + /// true if successful, false otherwise public bool DeleteAllUsers() { if (TrySendAndReceive(CommandType.DeleteAllUsers, 0, 0, 0, out var response, 1000)) @@ -334,6 +450,11 @@ namespace WaveshareUARTFingerprintSensor return false; } + /// + /// Delete all users that match a specified + /// + /// + /// true if successful, false otherwise public bool DeleteAllUsersWithPermission(UserPermission userPermission) { if (TrySendAndReceive(CommandType.DeleteAllUsers, 0, 0, (byte)userPermission, out var response, 1000)) @@ -348,7 +469,7 @@ namespace WaveshareUARTFingerprintSensor /// Read a fingerprint and check if it matches with the specified user /// /// A registered user ID - /// + /// true if the fingerprint match public bool Comparison11(ushort userID) { (byte high, byte low) = Utils.Split(userID); @@ -365,7 +486,7 @@ namespace WaveshareUARTFingerprintSensor /// Read a fingerprint and check if it match with any registered user /// /// The matched user info - /// + /// true if the fingerprint match public bool TryComparison1N(out (ushort userID, UserPermission permission) userInfo) { if (TrySendAndReceive(CommandType.Comparison1N, 0, 0, 0, out var response)) @@ -383,6 +504,12 @@ namespace WaveshareUARTFingerprintSensor return false; } + /// + /// Get the stored for a user + /// + /// A registered user + /// + /// true if the user exist, false otherwise public bool TryQueryPermission(ushort userID, out UserPermission userPermission) { (byte high, byte low) = Utils.Split(userID); @@ -402,6 +529,11 @@ namespace WaveshareUARTFingerprintSensor return false; } + /// + /// Retrieve the comparison level used internally by the sensor to compare fingerprints + /// + /// + /// public bool TryGetComparisonLevel(out byte comparisonLevel) { if (TrySendAndReceive(CommandType.ManageComparisonLevel, 0, 0, 1, out var response, 1000)) @@ -420,7 +552,7 @@ namespace WaveshareUARTFingerprintSensor } /// - /// Set comparison level used to compare fingerprints + /// Set the comparison level used internally by the sensor to compare fingerprints /// /// A value in 0..9 range, 9 is the strictest, default is 5 /// @@ -439,6 +571,11 @@ namespace WaveshareUARTFingerprintSensor return false; } + /// + /// Read a fingerprint and retrieve it's raw image + /// + /// + /// true if a valid fingerprint has been read public bool TryAcquireImage(out byte[] image) { if (TrySendAndReceive(CommandType.AcquireImage, 0, 0, 0, out var response)) @@ -458,6 +595,11 @@ namespace WaveshareUARTFingerprintSensor return false; } + /// + /// Read a fingerprint and retrieve the sensor computed eigenvalues + /// + /// + /// true if a valid fingerprint has been read public bool TryAcquireEigenvalues(out Span eigenvalues) { if (TrySendAndReceive(CommandType.AcquireEigenvalues, 0, 0, 0, out var response)) @@ -477,6 +619,13 @@ namespace WaveshareUARTFingerprintSensor return false; } + /// + /// Retrieve the sensor computed eigenvalues from a registered user + /// + /// + /// + /// + /// public bool TryAcquireUserEigenvalues(ushort userID, out Span eigenvalues, out UserPermission userPermission) { (byte high, byte low) = Utils.Split(userID); @@ -501,12 +650,20 @@ namespace WaveshareUARTFingerprintSensor return false; } + /// + /// Make the sensor sleep, in this mode the sensor use less power (<16 µA) but won't answer commands until it is waked using . + /// + /// You can know when to wake the sensor using the event that is still triggered while asleep + /// public void Sleep() { _sleeping = true; _rstPin.Write(GpioPinValue.Low); } + /// + /// Wake the sensor, do nothing if it was not sleeping + /// public void Wake() { _sleeping = false; @@ -525,6 +682,9 @@ namespace WaveshareUARTFingerprintSensor } } + /// + /// Dispose by disposing the used + /// public void Dispose() { _serialPort.Close(); diff --git a/WaveshareUARTFingerprintSensor/ResponseType.cs b/WaveshareUARTFingerprintSensor/ResponseType.cs index 6862a80..d23e3ae 100644 --- a/WaveshareUARTFingerprintSensor/ResponseType.cs +++ b/WaveshareUARTFingerprintSensor/ResponseType.cs @@ -6,10 +6,16 @@ using System.Threading.Tasks; namespace WaveshareUARTFingerprintSensor { + /// + /// If available, it is the third byte from a response packet + /// public enum ResponseType : byte { Success = 0x00, Fail = 0x01, + /// + /// Sensor has exceeded maximum number of users (0xFFF) + /// Full = 0x04, NoUser = 0x05, UserOccupied = 0x06, diff --git a/WaveshareUARTFingerprintSensor/UserPermission.cs b/WaveshareUARTFingerprintSensor/UserPermission.cs index 9b80fba..3b30fc2 100644 --- a/WaveshareUARTFingerprintSensor/UserPermission.cs +++ b/WaveshareUARTFingerprintSensor/UserPermission.cs @@ -1,5 +1,8 @@ namespace WaveshareUARTFingerprintSensor { + /// + /// Permission level stored on the sensor for each user, it does not have any direct signification + /// public enum UserPermission : byte { Level1 = 1, diff --git a/WaveshareUARTFingerprintSensor/Utils.cs b/WaveshareUARTFingerprintSensor/Utils.cs index 356a5d2..cd23834 100644 --- a/WaveshareUARTFingerprintSensor/Utils.cs +++ b/WaveshareUARTFingerprintSensor/Utils.cs @@ -8,12 +8,41 @@ namespace WaveshareUARTFingerprintSensor { public static class Utils { + /// + /// Parse two to an according to the sensor documentation + /// + /// Usually the first data from a response + /// Usually the second data from a response + /// public static ushort Merge(byte high, byte low) => (ushort)(high << 8 | low); + /// + /// Parse threee to an according to the sensor documentation + /// + /// Usually the first data from a response + /// Usually the second data from a response + /// Usually the third data from a response + /// public static uint Merge(byte first, byte second, byte third) => (uint)(first << 16 | second << 8 | third); + /// + /// Split an to two bytes according to the sensor documentation + /// + /// + /// The first (high) and the second (low) public static (byte high, byte low) Split(ushort value) => ((byte)(value >> 8), (byte)(value & 0xFF)); + /// + /// Split an to three bytes according to the sensor documentation + /// + /// + /// public static (byte first, byte second, byte third) Split(uint value) => ((byte)(value >> 16 & 0xFF), (byte)(value >> 8 & 0xFF), (byte)(value & 0xFF)); + /// + /// Display an array in a standard format + /// + /// + /// + /// A in the form: [ element1, element2, element3, ... ] public static string ArrayDisplay(T[] arr) => $"[ {string.Join(", ", arr)} ]"; } }