diff --git a/WaveshareUARTFingerprintSensor.Sample/App.config b/WaveshareUARTFingerprintSensor.Sample/App.config new file mode 100644 index 0000000..56efbc7 --- /dev/null +++ b/WaveshareUARTFingerprintSensor.Sample/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/WaveshareUARTFingerprintSensor.Sample/Program.cs b/WaveshareUARTFingerprintSensor.Sample/Program.cs new file mode 100644 index 0000000..bdd5f59 --- /dev/null +++ b/WaveshareUARTFingerprintSensor.Sample/Program.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.IO.Ports; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Unosquare.RaspberryIO; +using Unosquare.RaspberryIO.Abstractions; +using Unosquare.WiringPi; + +namespace WaveshareUARTFingerprintSensor.Sample +{ + class Program + { + static void Main(string[] args) + { + var sensor = new FingerprintSensor(FingerprintSensor.PrimarySerialPort); + + sensor.Start(); + + var count = sensor.GetUserCount(); + + Thread.Sleep(-1); + } + } +} diff --git a/WaveshareUARTFingerprintSensor.Sample/Properties/AssemblyInfo.cs b/WaveshareUARTFingerprintSensor.Sample/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f180a5e --- /dev/null +++ b/WaveshareUARTFingerprintSensor.Sample/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations +// associées à un assembly. +[assembly: AssemblyTitle("WaveshareUARTFingerprintSensor.Sample")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("WaveshareUARTFingerprintSensor.Sample")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly +// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de +// COM, affectez la valeur true à l'attribut ComVisible sur ce type. +[assembly: ComVisible(false)] + +// Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM +[assembly: Guid("0a9c9910-45e4-428f-9bc4-054808794c66")] + +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut +// en utilisant '*', comme indiqué ci-dessous : +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/WaveshareUARTFingerprintSensor.Sample/WaveshareUARTFingerprintSensor.Sample.csproj b/WaveshareUARTFingerprintSensor.Sample/WaveshareUARTFingerprintSensor.Sample.csproj new file mode 100644 index 0000000..24ae430 --- /dev/null +++ b/WaveshareUARTFingerprintSensor.Sample/WaveshareUARTFingerprintSensor.Sample.csproj @@ -0,0 +1,107 @@ + + + + + Debug + AnyCPU + {0A9C9910-45E4-428F-9BC4-054808794C66} + Exe + WaveshareUARTFingerprintSensor.Sample + WaveshareUARTFingerprintSensor.Sample + v4.7.2 + 512 + true + true + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Unosquare.Swan.3.0.0\lib\net461\Swan.dll + + + ..\packages\Unosquare.Swan.Lite.3.0.0\lib\net461\Swan.Lite.dll + + + + + + + ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll + + + + + + + + + ..\packages\Unosquare.Raspberry.Abstractions.0.4.1\lib\netstandard2.0\Unosquare.Raspberry.Abstractions.dll + + + ..\packages\Unosquare.Raspberry.IO.0.27.1\lib\netstandard2.0\Unosquare.RaspberryIO.dll + + + ..\packages\Unosquare.WiringPi.0.5.1\lib\netstandard2.0\Unosquare.WiringPi.dll + + + + + + + + + + + + + False + Microsoft .NET Framework 4.7.2 %28x86 et x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + + {dc535997-1161-4a7d-8573-259b13595778} + WaveshareUARTFingerprintSensor + + + + \ No newline at end of file diff --git a/WaveshareUARTFingerprintSensor.Sample/packages.config b/WaveshareUARTFingerprintSensor.Sample/packages.config new file mode 100644 index 0000000..e93a0bf --- /dev/null +++ b/WaveshareUARTFingerprintSensor.Sample/packages.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/WaveshareUARTFingerprintSensor.sln b/WaveshareUARTFingerprintSensor.sln new file mode 100644 index 0000000..37ebdd2 --- /dev/null +++ b/WaveshareUARTFingerprintSensor.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30711.63 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WaveshareUARTFingerprintSensor.Sample", "WaveshareUARTFingerprintSensor.Sample\WaveshareUARTFingerprintSensor.Sample.csproj", "{0A9C9910-45E4-428F-9BC4-054808794C66}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WaveshareUARTFingerprintSensor", "WaveshareUARTFingerprintSensor\WaveshareUARTFingerprintSensor.csproj", "{DC535997-1161-4A7D-8573-259B13595778}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0A9C9910-45E4-428F-9BC4-054808794C66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0A9C9910-45E4-428F-9BC4-054808794C66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0A9C9910-45E4-428F-9BC4-054808794C66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0A9C9910-45E4-428F-9BC4-054808794C66}.Release|Any CPU.Build.0 = Release|Any CPU + {DC535997-1161-4A7D-8573-259B13595778}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DC535997-1161-4A7D-8573-259B13595778}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DC535997-1161-4A7D-8573-259B13595778}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DC535997-1161-4A7D-8573-259B13595778}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4D22CA29-4B04-4D9E-A21D-E7DBF3013CBF} + EndGlobalSection +EndGlobal diff --git a/WaveshareUARTFingerprintSensor/CommandType.cs b/WaveshareUARTFingerprintSensor/CommandType.cs new file mode 100644 index 0000000..291d5cc --- /dev/null +++ b/WaveshareUARTFingerprintSensor/CommandType.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WaveshareUARTFingerprintSensor +{ + public enum CommandType : byte + { + ModifySerialNumber = 0x08, + QuerySerialNumber = 0x2A, + SleepMode = 0x2C, + ManageFingerprintAddingMode = 0x2D, + AddFingerprint1 = 0x01, + AddFingerprint2 = 0x02, + AddFingerprint3 = 0x03, + AddAndAcquireFingerprint = 0x06, + DeleteUser = 0x04, + DeleteAllUsers = 0x05, + QueryUserCount = 0x09, + Comparison11 = 0x0B, + Comparison1N = 0x0C, + QueryPermission = 0x0A, + ManageComparisonLevel = 0x28, + AcquireImage = 0x24, + AcquireEigenvalues = 0x23, + UploadEigenvaluesAndCompare = 0x44, + UploadEigenvaluesAndCompare11 = 0x42, + UploadEigenvaluesAndCompare1N = 0x43, + AcquireEigenvaluesDSP = 0x31, + CreateUserFromEigenvalues = 0x41, + QueryUsersInfo = 0x2B, + ManageCaptureTimeout = 0x2E + } +} diff --git a/WaveshareUARTFingerprintSensor/FingerprintSensor.cs b/WaveshareUARTFingerprintSensor/FingerprintSensor.cs new file mode 100644 index 0000000..9e3531b --- /dev/null +++ b/WaveshareUARTFingerprintSensor/FingerprintSensor.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.IO.Ports; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Unosquare.RaspberryIO; +using Unosquare.RaspberryIO.Abstractions; +using Unosquare.WiringPi; + +namespace WaveshareUARTFingerprintSensor +{ + public class FingerprintSensor : IDisposable + { + public const string PrimarySerialPort = "/dev/ttyAMA0"; + public const string SecondarySerialPort = "/dev/ttyS0"; + + public string PortName { get; } + + private const byte PacketSeparator = 0xF5; + + private SerialPort _serialPort; + private int _wakePinNumber; + private int _rstPinNumber; + private IGpioPin _wakePin; + private IGpioPin _rstPin; + private object _lock = new object(); + + public FingerprintSensor(string portName, int wakePin = 23, int rstPin = 24) + { + PortName = portName; + _wakePinNumber = wakePin; + _rstPinNumber = rstPin; + } + + public void Start() + { + // Initialize Gpio + Pi.Init(); + + _wakePin = Pi.Gpio[_wakePinNumber]; + _rstPin = Pi.Gpio[_rstPinNumber]; + + _wakePin.PinMode = GpioPinDriveMode.Input; + _rstPin.PinMode = GpioPinDriveMode.Output; + + _rstPin.Write(GpioPinValue.High); + _wakePin.RegisterInterruptCallback(EdgeDetection.FallingAndRisingEdge, OnWake); + + // Initialize SerialPort + _serialPort = new SerialPort(PortName, 19200); + + _serialPort.Open(); + } + + private byte ComputeChecksum(byte[] data) + { + byte checksum = 0; + + for (int i = 1; i < 6; i++) + { + checksum += data[i]; + } + + return checksum; + } + + private (byte first, byte second, ResponseType responseType) SendAndReceive(CommandType commandType, byte first, byte second, byte third) + { + // Command packet + byte[] buffer = { PacketSeparator, (byte)commandType, first, second, third, 0, 0, PacketSeparator }; + + lock (_lock) + { + + // Checksum + buffer[6] = ComputeChecksum(buffer); + + _serialPort.Write(buffer, 0, buffer.Length); + + // Response + _serialPort.Read(buffer, 0, buffer.Length); + + if (buffer[0] != PacketSeparator || buffer[7] != PacketSeparator || buffer[1] != (byte)commandType) + { + throw new InvalidDataException("Invalid response from the sensor"); + } + + if (buffer[6] != ComputeChecksum(buffer)) + { + throw new InvalidDataException("Invalid checksum"); + } + } + + return (buffer[2], buffer[3], (ResponseType)buffer[4]); + } + + /* + private void Send(CommandType commandType, byte first, byte second, byte third) + { + // Command packet + byte[] buffer = { PacketSeparator, (byte)commandType, first, second, third, 0, 0, PacketSeparator }; + + // Checksum + buffer[6] = ComputeChecksum(buffer); + + _serialPort.Write(buffer, 0, buffer.Length); + } + + private (byte first, byte second, byte third) Receive(CommandType commandType) + { + // Response buffer + var buffer = new byte[8]; + + // Response + _serialPort.Read(buffer, 0, buffer.Length); + + if (buffer[0] != PacketSeparator || buffer[7] != PacketSeparator || buffer[1] != (byte)commandType) + { + throw new InvalidDataException("Invalid response from the sensor"); + } + + if (buffer[6] != ComputeChecksum(buffer)) + { + throw new InvalidDataException("Invalid checksum"); + } + + return (buffer[2], buffer[3], buffer[4]); + } + */ + + public bool TryGetUserCount(out ushort count) + { + (byte countHigh, byte countLow, ResponseType response) = SendAndReceive(CommandType.QueryUserCount, 0, 0, 0); + + count = Utils.Merge(countHigh, countLow); + + return response == ResponseType.Success; + } + + public void Sleep() + { + _rstPin.Write(GpioPinValue.Low); + } + + private void OnWake() + { + if (_wakePin.Read()) + { + Console.WriteLine("Sensor WAKE signal received"); + } + } + + public void Dispose() + { + _serialPort.Close(); + } + } +} diff --git a/WaveshareUARTFingerprintSensor/Properties/AssemblyInfo.cs b/WaveshareUARTFingerprintSensor/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b1a50cc --- /dev/null +++ b/WaveshareUARTFingerprintSensor/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations +// associées à un assembly. +[assembly: AssemblyTitle("WaveshareUARTFingerprintSensor")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("WaveshareUARTFingerprintSensor")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly +// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de +// COM, affectez la valeur true à l'attribut ComVisible sur ce type. +[assembly: ComVisible(false)] + +// Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM +[assembly: Guid("dc535997-1161-4a7d-8573-259b13595778")] + +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut +// en utilisant '*', comme indiqué ci-dessous : +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/WaveshareUARTFingerprintSensor/ResponseType.cs b/WaveshareUARTFingerprintSensor/ResponseType.cs new file mode 100644 index 0000000..6862a80 --- /dev/null +++ b/WaveshareUARTFingerprintSensor/ResponseType.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WaveshareUARTFingerprintSensor +{ + public enum ResponseType : byte + { + Success = 0x00, + Fail = 0x01, + Full = 0x04, + NoUser = 0x05, + UserOccupied = 0x06, + FingerOccupied = 0x07, + Timeout = 0x08 + } +} diff --git a/WaveshareUARTFingerprintSensor/Utils.cs b/WaveshareUARTFingerprintSensor/Utils.cs new file mode 100644 index 0000000..4a15e8a --- /dev/null +++ b/WaveshareUARTFingerprintSensor/Utils.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WaveshareUARTFingerprintSensor +{ + public static class Utils + { + public static ushort Merge(byte high, byte low) => (ushort)(high << 8 | low); + + public static (byte high, byte low) Split(ushort value) => ((byte)(value >> 8), (byte)(value & 0xFF)); + } +} diff --git a/WaveshareUARTFingerprintSensor/WaveshareUARTFingerprintSensor.csproj b/WaveshareUARTFingerprintSensor/WaveshareUARTFingerprintSensor.csproj new file mode 100644 index 0000000..93b814a --- /dev/null +++ b/WaveshareUARTFingerprintSensor/WaveshareUARTFingerprintSensor.csproj @@ -0,0 +1,74 @@ + + + + + Debug + AnyCPU + {DC535997-1161-4A7D-8573-259B13595778} + Library + Properties + WaveshareUARTFingerprintSensor + WaveshareUARTFingerprintSensor + v4.7.2 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Unosquare.Swan.3.0.0\lib\net461\Swan.dll + + + ..\packages\Unosquare.Swan.Lite.3.0.0\lib\net461\Swan.Lite.dll + + + + + + + ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll + + + + + + + + + ..\packages\Unosquare.Raspberry.Abstractions.0.4.1\lib\netstandard2.0\Unosquare.Raspberry.Abstractions.dll + + + ..\packages\Unosquare.Raspberry.IO.0.27.1\lib\netstandard2.0\Unosquare.RaspberryIO.dll + + + ..\packages\Unosquare.WiringPi.0.5.1\lib\netstandard2.0\Unosquare.WiringPi.dll + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WaveshareUARTFingerprintSensor/packages.config b/WaveshareUARTFingerprintSensor/packages.config new file mode 100644 index 0000000..e93a0bf --- /dev/null +++ b/WaveshareUARTFingerprintSensor/packages.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file