话说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
65
|
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();
}
}
} |
当然我们还需要一个设备管理类作为设备的监管。
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
|
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
RfidService;
using
System.Diagnostics;
using
System.Threading;
using
RfidService.Common;
namespace
Rfid
{ public
class RfidDevices : IDisposable
{
/// <summary>
/// RFID设备集合
/// </summary>
private
IList<RfidDevice> _lstRfidDevice = new
List<RfidDevice>();
private
readonly RfidDataContext _oRfidDataContext = new
RfidDataContext();
/// <summary>
/// 添加RFID设备
/// </summary>
/// <param name="rfidDevice"></param>
public
void Add(RfidDevice rfidDevice)
{
this ._lstRfidDevice.Add(rfidDevice);
}
/// <summary>
/// 移除RFID设备
/// </summary>
/// <param name="rfidDevice"></param>
public
void Remove(RfidDevice rfidDevice)
{
foreach
( var
o in
_lstRfidDevice.Where(o => o.ComHadle == rfidDevice.ComHadle &&
o.ComNo == rfidDevice.ComNo))
{
_lstRfidDevice.Remove(o);
break ;
}
}
public
void DeviceClose()
{
foreach
( var
o in
_lstRfidDevice)
{
try
{
o.CloseComm();
}
catch (Exception er)
{
LogInfo.Error( "设备监听关闭失败:"
+ o.ComNo);
LogInfo.Error( "设备监听关闭失败:"
+ er.Message);
}
}
}
public
IList<RfidDevice> GetDevices()
{
return
_lstRfidDevice;
}
readonly
object _oLock = new
object ();
/// <summary>
/// 获取所有设备数据
/// </summary>
/// <returns></returns>
public
void GetData()
{
try
{
Monitor.Enter(_oLock);
var
sw = new
Stopwatch();
sw.Start();
var
lstByteArray = new
List< byte []>();
var
serviceDateTime = DateTime.Now;
foreach
( var
o in
_lstRfidDevice)
{
try
{
var
lstByt = o.GetData();
foreach
( var
byt in
lstByt)
{
for
( var
i = 0; i < byt.Length; i = i + 12)
{
var
buffer = new
byte [4];
GcCollect();
Array.Copy(byt, i + 8, buffer, 0, 4);
var
id = ((buffer[0]) + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 32)).ToString();
//处理自己的业务把
}
}
}
catch
(Exception er)
{
Console.WriteLine(er.Message + "\t\n"
+ er.StackTrace.ToString());
LogInfo.Info(er.Message);
LogInfo.Info(er.StackTrace.ToString());
}
}
sw.Stop();
Console.WriteLine( "操作数据库执行时间:"
+ sw.ElapsedMilliseconds.ToString());
LogInfo.Info( "操作数据库执行时间:"
+ sw.ElapsedMilliseconds.ToString());
}
finally
{
Monitor.Exit(_oLock);
}
}
public
void Dispose()
{
_lstRfidDevice.Clear();
_lstRfidDevice = null ;
GcCollect();
}
public
void GcCollect()
{
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
} |
通过以上几个类我们可以对设备的记录读写了。 在设备处理方法中你可以自行处理自己的业务逻辑。
其实从整体上看RFID的处理还是很简单的。 跟处理串口没什么却别。发送数据-> 读取接收的数据->解析->处理业务入库。
分享是种美德,要提倡!