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