C# RFID windows 服务 串口方式

C# RFID windows 服务 串口方式

 

话说RFID以前很火所以整理一下一年前自己处理的RFID程序,放源码.

一开始觉得他是个很神奇的东西。 包含串口通讯和网络通讯。 由于网络通讯设备太贵,所以国内的设备基本上都是在外置一个比较便宜的模块在里面。  

本案例应该适用于大多数的RFID模块。

首先我们先放上RFID API:如下 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Runtime.InteropServices;
 
namespace  Rfid
{
     public  class  EPCSDKHelper
     {
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  IntPtr OpenComm( int  portNo);
 
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  void  CloseComm(IntPtr hCom);
 
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  bool  ReadFirmwareVersion(IntPtr hCom, out  int  main, out  int  sub, byte  ReaderAddr);
 
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  bool  GetReaderParameters(IntPtr hCom, int  addr, int  paramNum, byte [] parms, byte  ReaderAddr);
         
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  bool  SetReaderParameters(IntPtr hCom, int  addr, int  paramNum, byte [] parms, byte  ReaderAddr);
 
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  bool  StopReading(IntPtr hCom, byte  ReaderAddr);
 
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  bool  ResumeReading(IntPtr hCom, byte  ReaderAddr);
 
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  bool  IdentifySingleTag(IntPtr hCom, byte [] tagId, byte [] antennaNo, byte  ReaderAddr);
 
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  bool  IdentifyUploadedSingleTag(IntPtr hCom, byte [] tagId, byte [] devNos, byte [] antennaNo);
 
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  bool  IdentifyUploadedMultiTags(IntPtr hCom, out  byte  tagNum, byte [] tagIds, byte [] devNos, byte [] antennaNos);
 
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  bool  ReadTag(IntPtr hCom, byte  memBank, byte  address, byte  length, byte [] data, byte  ReaderAddr);
 
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  bool  WriteTagSingleWord(IntPtr hCom, byte  memBank, byte  address, byte  data1, byte  data2, byte  ReaderAddr);
 
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  bool  FastWriteTagID(IntPtr hCom, int  bytesNum, byte [] bytes, byte  ReaderAddr);
 
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  bool  FastWriteTagID_Lock(IntPtr hCom, int  bytesNum, byte [] bytes, byte  ReaderAddr);
 
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  bool  InitializeTag(IntPtr hCom, byte  ReaderAddr);
 
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  bool  LockPassWordTag(IntPtr hCom, byte  passwd1, byte  passwd2, byte  passwd3, byte  passwd4, byte  lockType, byte  ReaderAddr);
 
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  bool  UnlockPassWordTag(IntPtr hCom, byte  passwd1, byte  passwd2, byte  passwd3, byte  passwd4, byte  lockType, byte  ReaderAddr);
 
         [DllImport( "EPCSDK.dll" )]
         public  static  extern  bool  KillTag(IntPtr hCom, byte  passwd1, byte  passwd2, byte  passwd3, byte  passwd4, byte  ReaderAddr);
     }
}

  我们看到OpenComm他还是一串口方式打开的。

  我们要记录每个设备的信息所以我们需要一个设备类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.Threading;
using  RfidService.Common;
 
namespace  Rfid
{
     public  class  RfidDevice
     {
         /// <summary>
         /// 开启监听现成
         /// </summary>
         private  Thread _mThread = null ;
 
         /// <summary>
         /// 暂停事件
         /// </summary>
         private  readonly  ManualResetEvent _mManualReset = null ;
 
         /// <summary>
         /// 串口号
         /// </summary>
         private  readonly  int  _comNo = 0;
 
         /// <summary>
         /// 时间间隔
         /// </summary>
         private  readonly  int  _timeTick = 0;
 
         /// <summary>
         /// 是否多卡读取
         /// </summary>
         private  bool  _multiFlag = false ;
 
         /// <summary>
         /// RFID数据
         /// </summary>
         private  readonly  List< byte []> _data = new  List< byte []>();
 
         /// <summary>
         /// 数据锁
         /// </summary>
         private  readonly  object  _dataLock = new  object ();
 
         /// <summary>
         /// 错误数量
         /// </summary>
         private  int  _errorCount = 0;
 
         /// <summary>
         /// 只读 串口号
         /// </summary>
         public  int  ComNo
         {
             get
             {
                 return  _comNo;
             }
         }
 
         /// <summary>
         /// 串口句柄
         /// </summary>
         public  IntPtr ComHadle { set ; get ; }
 
         /// <summary>
         /// 只读 时间间隔 毫秒级
         /// </summary>
         public  int  TimeTick
         {
             get
             {
                 return  _timeTick;
             }
         }
 
         /// <summary>
         /// 是否多卡标志
         /// </summary>
         public  bool  MultiFlag { set  { _multiFlag = value; } get  { return  _multiFlag; } }
 
         /// <summary>
         /// 暂停读取标志
         /// </summary>
         public  bool  StopReadFlag { set ; get ; }
 
         /// <summary>
         /// 出入串口
         /// </summary>
         public  PassCom PassCom { set ; get ; }
 
         /// <summary>
         /// 构造函数
         /// </summary>
         /// <param name="comNo"></param>
         /// <param name="sleepTime"></param>
         public  RfidDevice( int  comNo, int  sleepTime)
         {
             _comNo = comNo;
             _timeTick = sleepTime;
             _mManualReset = new  ManualResetEvent( true );
             ComHadle = EPCSDKHelper.OpenComm(_comNo);
             if  (ComHadle == new  IntPtr())
             {
                 //输出系统日志
                 //throw new Exception("打开串口失败!");
 
                 LogInfo.Error( "打开串口:"  + comNo + "失败!"  );
             }
         }
 
         /// <summary>
         /// 构造函数
         /// </summary>
         /// <param name="comNo"></param>
         /// <param name="sleepTime"></param>
         /// <param name="multiFlag"></param>
         public  RfidDevice( int  comNo, int  sleepTime, bool  multiFlag)
         {
             _comNo = comNo;
             _timeTick = sleepTime;
             MultiFlag = multiFlag;
             _mManualReset = new  ManualResetEvent( true );
             ComHadle = EPCSDKHelper.OpenComm(_comNo);
             if  (ComHadle == new  IntPtr())
             {
                 //输出系统日志
                 //throw new Exception("打开串口失败!");
                 LogInfo.Error( "打开串口:"  + comNo + "失败!" );
             }
         }
 
         /// <summary>
         /// 构造函数
         /// </summary>
         /// <param name="comNo"></param>
         /// <param name="sleepTime"></param>
         /// <param name="multiFlag"></param>
         /// <param name="passCom"></param>
         public  RfidDevice( int  comNo, int  sleepTime, bool  multiFlag,PassCom passCom)
         {
             _comNo = comNo;
             _timeTick = sleepTime;
             _multiFlag = multiFlag;
             MultiFlag = multiFlag;
             _mManualReset = new  ManualResetEvent( true );
             this .PassCom = passCom;
             ComHadle = EPCSDKHelper.OpenComm(_comNo);
#if DEBUG
             Console.WriteLine( "串口号:"  + this .ComNo.ToString() + " - "  + ComHadle.ToString());
#endif
             if  (ComHadle == new  IntPtr())
             {
                 //输出系统日志
                 //throw new Exception("打开串口失败!");
                 LogInfo.Error( "打开串口:"  + comNo + "失败!" );
             }
         }
 
         /// <summary>
         /// 关闭串口
         /// </summary>
         public  void  CloseComm()
         {
             EPCSDKHelper.CloseComm( this .ComHadle);
             LogInfo.Info( "关闭串口:"  + this .ComNo );
         }
         
         /// <summary>
         /// 开始读取
         /// </summary>
         public  void  Start()
         {
             if  (_mThread != null ) return ;
             _mThread = new  Thread(GetRfidTag) {IsBackground = true };
             _mThread.Start();
         }
 
         /// <summary>
         /// 暂停
         /// </summary>
         public  void  ReStart()
         {
             _mManualReset.Set();
         }
 
         /// <summary>
         /// 继续
         /// </summary>
         public  void  Stop()
         {
             _mManualReset.Reset();
         }
 
         /// <summary>
         /// 获取RFID标签现成
         /// </summary>
         private  void  GetRfidTag()
         {
             while ( true )
             {
                 GcCollect();
                 try
                 {
                     Monitor.Enter( this ._dataLock);
                     _mManualReset.WaitOne();
                     byte [] ids;
                     byte [] devNos;
                     byte [] antennaNos;
                     if  ( this ._multiFlag)
                     {
                         ids = new  byte [12 * 200];
                         devNos = new  byte [200];
                         antennaNos = new  byte [200];
                         //处理多卡读取模式
                         byte  idNum = 0;
                         if  (EPCSDKHelper.IdentifyUploadedMultiTags( this .ComHadle, out  idNum, ids, devNos, antennaNos))
                         {
                             _errorCount = 0;
                             var  tmpids = new  byte [idNum * 12];
                             Array.Copy(ids, 0, tmpids, 0, tmpids.Length);
                             this ._data.Add(tmpids);
#if DEBUG
                             Console.WriteLine( "串口号:" + this .ComNo.ToString() + " - "  + DateTime.Now.ToString( "yyyy-MM-dd HH:mm:ss.yyy" ) + " - 02 - "  + TextEncoder.ByteArrayToHexString(ids));
                             LogInfo.Info( "串口号:"  + this .ComNo.ToString() + " - "  + DateTime.Now.ToString( "yyyy-MM-dd HH:mm:ss.yyy" ) + " - 02 - "  + TextEncoder.ByteArrayToHexString(ids));
#endif
                         }
                     }
                     else
                     {
                         ids = new  byte [12];
                         devNos = new  byte [1];
                         antennaNos = new  byte [1];
                         //处理单卡读取模式
                         if  (EPCSDKHelper.IdentifyUploadedSingleTag( this .ComHadle, ids, devNos, antennaNos))
                         {
                             _errorCount = 0;
                             this ._data.Add(ids);
#if DEBUG
                             Console.WriteLine( "串口号:"  + this .ComNo.ToString() + " - "  + DateTime.Now.ToString( "yyyy-MM-dd HH:mm:ss.yyy" ) + " - 01 - "  + TextEncoder.ByteArrayToHexString(ids));
                             LogInfo.Info( "串口号:"  + this .ComNo.ToString() + " - "  + DateTime.Now.ToString( "yyyy-MM-dd HH:mm:ss.yyy" ) + " - 01 - "  + TextEncoder.ByteArrayToHexString(ids));
#endif
                         }
                     }
                 }
                 catch  (Exception er)
                 {
#if DEBUG
                     Console.WriteLine( "串口号:"  + this .ComNo.ToString() + " - "  + DateTime.Now.ToString( "yyyy-MM-dd HH:mm:ss.yyy" ) + " Error: "  + er.Message);
                     LogInfo.Error( "串口号:"  + this .ComNo.ToString() + " - "  + DateTime.Now.ToString( "yyyy-MM-dd HH:mm:ss.yyy" ) + " Error: "  + er.Message);
#endif
                     _errorCount++;
                     if  (_errorCount > 10)
                     {
                         //设备复位
                     }
                 }
                 finally
                 {
                     Monitor.Exit( this ._dataLock);
                 }
                 Thread.Sleep( this ._timeTick);
             }
         }
 
         /// <summary>
         /// 获取RFID数据标签
         /// </summary>
         /// <returns></returns>
         public  IList< byte []> GetData()
         {
             try
             {
                 Monitor.Enter( this ._dataLock);
                 GC.WaitForPendingFinalizers();
                 GC.Collect();
                 GC.WaitForPendingFinalizers();
                 var  tmpData = new  List< byte []>();
                 tmpData.AddRange(_data);
                 _data.Clear();
#if DEBUG
                 Console.WriteLine( "串口号:"  + this .ComNo.ToString() + " - "  + "_tmpData:"  + tmpData.Count + "  _data:"  + _data.Count);
                 LogInfo.Info( "串口号:"  + this .ComNo.ToString() + " - "  + "_tmpData:"  + tmpData.Count + "  _data:"  + _data.Count);
#endif
                 return  tmpData;
             }
             finally
             {
                 Monitor.Exit( this ._dataLock);
             }
         }
 
         /// <summary>
         /// 数据回收
         /// </summary>
         private  static  void  GcCollect()
         {
             GC.WaitForFullGCComplete();
             GC.Collect();
             GC.WaitForFullGCComplete();
         }
 
     }
}

  当然我们还需要一个设备管理类作为设备的监管。

  通过以上几个类我们可以对设备的记录读写了。 在设备处理方法中你可以自行处理自己的业务逻辑。

  其实从整体上看RFID的处理还是很简单的。 跟处理串口没什么却别。发送数据-> 读取接收的数据->解析->处理业务入库。 

  

  分享是种美德,要提倡!

 

 
 
 
标签:  RFID

你可能感兴趣的:(RFID)