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

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的处理还是很简单的。 跟处理串口没什么却别。发送数据->
读取接收的数据->解析->处理业务入库。

  

  分享是种美德,要提倡!

时间: 2024-10-31 18:01:29

C# RFID windows 服务 串口方式的相关文章

以windows服务方式快速部署免安装版Postgres数据库

目录 以windows服务方式快速部署免安装版Postgres数据库 1.下载Postgresql数据库免安装包 2.安装环境准备及验证 解压文件 测试环境依赖 3.创建并初始化数据目录 创建数据目录 初始化数据目录 5.配置postgres数据库 打开并修改postgresql.conf 打开并修改pg_hba.conf 4.安装服务 6.创建用户.数据库 连接数据库 创建用户.数据库 以windows服务方式快速部署免安装版Postgres数据库 1.下载Postgresql数据库免安装包

Zookeeper以Windows服务安装运行

1.下载的Zookeeper是.cmd的批处理命令运行的,默认没有提供以windows服务的方式运行的方案 下载地址:http://zookeeper.apache.org/ 2.下载prunsrv 下载地址:http://archive.apache.org/dist/commons/daemon/binaries/windows/ 3.解压后复制文件 64位机器用amd64/prunsrv.exe  a. 复制 commons-daemon-1.0.15-bin-windows/amd64/

JavaService以Windows服务部署jar包

在生产环境,可执行jar包如果仅以 java -jar的方式运行,多个后台服务进程名称区分不清,且重启等无法自动控制: 所以使用java service,将jar包以windows服务的方式部署在服务器中. JavaService.exe -install aaaService "%JAVA_HOME%\jre\bin\server\jvm.dll" -Djava.class.path="G:\lrh\code\goodsMonitor\export\GoodsMonitor

Java魔法堂:以Windows服务的形式运行Java程序

一.前言 由于防止维护人员误操作关闭Java控制台程序,因此决定将其改造为以Windows服务的形式运行.弄了一个上午总算搞定了,下面记录下来,以供日后查阅. 二.Java Service Wrapper 官网地址:http://wrapper.tanukisoftware.com/doc/english/download.jsp JavaServiceWrapper以守护进程或windows服务的方式运行java程序.JSW提供四种方案改造原有项目,以实现守护进程或windows服务的方式运行

关于windows服务注册的问题

开发工具:VS2012 语言:C# 今天的工作内容是把wcf服务以windows服务的方式运行,由于之前没有做过windows服务,所有在网上找了些文章来看下,发现创建windows 服务是一件很简单的事情,很快创建完一个windows 服务程序,接着就是安装注册,网上给出的方法大概有两种: 1. InstallUtil.exe ×××.exe 2.copy C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe  Instal

(转)创建Windows服务(Windows Services)N种方式总结

转自:http://www.cnblogs.com/aierong/archive/2012/05/28/2521409.html 最近由于工作需要,写了一些windows服务程序,有一些经验,我现在总结写出来.目前我知道的创建创建Windows服务有3种方式:a.利用.net框架类ServiceBaseb.利用组件Topshelfc.利用小工具instsrv和srvany 下面我利用这3种方式,分别做一个windows服务程序,程序功能就是每隔5秒往程序目录下记录日志: a.利用.net框架类

批处理安装Windows服务,提示&quot;InstallUtil.exe&quot;不是内部命令也不是外部命令解决方式

今天在测试一个C#写的windows服务的时候,在用bat进行调用cmd安装的时候, cd C:\Windows\Microsoft.NET\Framework\v2.0.50727 InstallUtil.exe C:/Windows/DXTB/DianXiaoSync.exe 提示: "InstallUtil.exe"不是内部命令也不是外部命令解决方式 但事实上, C:\Windows\Microsoft.NET\Framework\v2.0.50727目录下是存在这个 安装工具的

创建Windows服务(Windows Services)N种方式总结

最近由于工作需要,写了一些windows服务程序,有一些经验,我现在总结写出来.目前我知道的创建创建Windows服务有3种方式:a.利用.net框架类ServiceBaseb.利用组件Topshelfc.利用小工具instsrv和srvany 下面我利用这3种方式,分别做一个windows服务程序,程序功能就是每隔5秒往程序目录下记录日志: a.利用.net框架类ServiceBase 本方式特点:简单,兼容性好 通过继承.net框架类ServiceBase实现 第1步: 新建一个Window

windows + myeclipse 调试 linux + tomcat 的java web服务 配置方式

一.linux tomcat配置和启动 1.catalina.sh第一行添加 declare -x CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000" 2.启动JPDA(这是tomcat下的启动方式,别的服务器可能会不一样,但道理是一样的) ./catalina.sh jpda start 3.启动web服务 ./start.sh 二.在windows端的myecli