Created
April 17, 2016 00:19
-
-
Save mariodivece/526b3395bc36638b1c75ee7309935fd5 to your computer and use it in GitHub Desktop.
A very simple wrapper to control the popular fingerprint reader model GT511C3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO.Ports; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace Unosquare.Devices | |
{ | |
public class GT511C3 : IDisposable | |
{ | |
private const int InitialBaudRate = 9600; | |
private const int TargetBaudRate = 115200; | |
private SerialPort m_SerialPort; | |
private bool IsDisposing = false; | |
public enum Command : ushort | |
{ | |
Open = 0x01, | |
Close = 0x02, | |
UsbInternalCheck = 0x03, | |
ChangeBaudRate = 0x04, | |
SetIAPMode = 0x05, | |
CmosLed = 0x12, | |
GetEnrollCount = 0x20, | |
CheckEnrolled = 0x21, | |
EnrollStart = 0x22, | |
Enroll1 = 0x23, | |
Enroll2 = 0x24, | |
Enroll3 = 0x25, | |
IsPressFinger = 0x26, | |
DeleteID = 0x40, | |
DeleteAll = 041, | |
Verify = 0x50, | |
Identify = 0x51, | |
VerifyTemplate = 0x52, | |
IdentifyTemplate = 0x53, | |
CaptureFinger = 0x60, | |
MakeTemplate = 0x61, | |
} | |
public GT511C3() | |
{ | |
} | |
public void Open(string portName) | |
{ | |
if (this.m_SerialPort != null) throw new InvalidOperationException("Device is already open. Call the Close method first."); | |
this.m_SerialPort = new SerialPort(portName, InitialBaudRate); | |
this.m_SerialPort.Open(); | |
this.Send(Command.Open, 1); | |
this.Send(Command.ChangeBaudRate, TargetBaudRate); | |
this.Close(); | |
this.m_SerialPort = new SerialPort(portName, TargetBaudRate); | |
this.m_SerialPort.Open(); | |
var result = this.Send(Command.Open, 1); | |
} | |
public ResponsePacket Send(Command command, int param) | |
{ | |
var packet = new CommandPacket() { Command = (ushort)command, Parameter = param }; | |
var packetBytes = packet.ToByteArray(); | |
this.m_SerialPort.Write(packetBytes, 0, packetBytes.Length); | |
this.m_SerialPort.BaseStream.Flush(); | |
if (this.m_SerialPort.IsOpen && this.m_SerialPort.BytesToRead == 0) | |
System.Threading.Thread.Sleep(100); | |
var response = new List<byte>(this.m_SerialPort.BytesToRead); | |
while (this.m_SerialPort.BytesToRead > 0) | |
{ | |
var count = this.m_SerialPort.BytesToRead; | |
var buffer = new byte[count]; | |
this.m_SerialPort.Read(buffer, 0, count); | |
response.AddRange(buffer); | |
} | |
return ResponsePacket.FromBytes(response.ToArray()); | |
} | |
public class ResponsePacket | |
{ | |
public static ResponsePacket FromBytes(byte[] payload) | |
{ | |
var response = new ResponsePacket(); | |
response.Payload = payload; | |
return response; | |
} | |
private byte[] Payload { get; set; } | |
public bool IsDataPacket { get { return Payload != null && Payload.Length >= 2 && Payload[1] == 0xA5; } } | |
public byte[] Data | |
{ | |
get | |
{ | |
if (IsDataPacket == false) | |
return new byte[] { }; | |
var data = new byte[Payload.Length - 6]; | |
Array.Copy(Payload, 4, data, 0, data.Length); | |
return data; | |
} | |
} | |
public int Parameter | |
{ | |
get | |
{ | |
var dataBytes = new byte[4]; | |
Array.Copy(Payload, 4, dataBytes, 0, dataBytes.Length); | |
if (BitConverter.IsLittleEndian == false) | |
Array.Reverse(dataBytes); | |
return BitConverter.ToInt32(dataBytes, 0); | |
} | |
} | |
public ushort Response | |
{ | |
get | |
{ | |
var dataBytes = new byte[2]; | |
Array.Copy(Payload, 8, dataBytes, 0, dataBytes.Length); | |
if (BitConverter.IsLittleEndian == false) | |
Array.Reverse(dataBytes); | |
return BitConverter.ToUInt16(dataBytes, 0); | |
} | |
} | |
public ushort Checksum | |
{ | |
get | |
{ | |
var dataBytes = new byte[2]; | |
Array.Copy(Payload, Payload.Length - 2, dataBytes, 0, dataBytes.Length); | |
if (BitConverter.IsLittleEndian == false) | |
Array.Reverse(dataBytes); | |
return BitConverter.ToUInt16(dataBytes, 0); | |
} | |
} | |
public bool IsError | |
{ | |
get | |
{ | |
if (IsDataPacket) return false; | |
return Response == 0x31; | |
} | |
} | |
} | |
private class CommandPacket | |
{ | |
private static readonly byte[] Header = { 0x55, 0xAA, 0x00, 0x01 }; | |
private static readonly ushort HeaderSum = Convert.ToUInt16(Header.Sum(b => Convert.ToInt32(b))); | |
public int Parameter { get; set; } | |
public ushort Command { get; set; } | |
public byte[] ToByteArray() | |
{ | |
var paramBytes = BitConverter.GetBytes(Parameter); | |
var commandBytes = BitConverter.GetBytes(Command); | |
var checksum = HeaderSum; | |
var payload = paramBytes.Concat(commandBytes).ToArray(); | |
foreach (var b in payload) | |
checksum += Convert.ToUInt16(b); | |
var checksumBytes = BitConverter.GetBytes(checksum); | |
if (BitConverter.IsLittleEndian == false) | |
{ | |
Array.Reverse(paramBytes); | |
Array.Reverse(commandBytes); | |
Array.Reverse(checksumBytes); | |
} | |
return Header.Concat(payload).Concat(checksumBytes).ToArray(); | |
} | |
} | |
private void Close() | |
{ | |
if (this.m_SerialPort == null) return; | |
try | |
{ | |
if (this.m_SerialPort.IsOpen) | |
this.m_SerialPort.Close(); | |
} | |
finally | |
{ | |
this.m_SerialPort.Dispose(); | |
this.m_SerialPort = null; | |
} | |
} | |
public void Dispose() | |
{ | |
if (this.IsDisposing) return; | |
this.IsDisposing = true; | |
this.Close(); | |
} | |
} | |
} |
Hi, can you make an example?
The method IdentifyTemplate, is equals to GetTemplate of GT511C3 c++ library?
Sorry for my bad english. ๐
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks!! ๐