第三章 基于RFID的仓储管理系统实现关键技术

版权声明:本文出自www.54manong.com,转载请注明原地址,谢谢! https://blog.csdn.net/xiaohuanglv/article/details/89184324

3.1.Alien RFID 系统

3.1.1.Alien RFID 系统概述

本次研究所用到的RFID系统为Alien RFID系统,它便于管理、功能强大,是业界最为领先的RFID系统。

Alien RFID系统主要有三个部分组成:

1Alien ALR-9900 阅读器

 Alien ALR-9900 阅读器用于读取和处理任何EPC标签,然后将事件信息报告给主机系统。主机可以在本地通过RS-232连接到阅读器或者在远程通过网络连接。Alien ALR-9900阅读器具有高性能、操作简单、易于管理、抗干扰能力强等一系列优点。

2Alien RFID天线

 Alien RFID天线用来广播RFID阅读器内部产生的射频信号,同时可以接受一定范围内电子标签的应答信号。

3Alien RFID无源电子标签

 Alien RFID无源电子标签类似于条形码,都包含了标记信息。然而Alien RFID电子标签跟条形码相比包含了更多的信息,同时它可以在更远的距离,更复杂的环境下被阅读器识别。

3.1.2.Alien RFID 系统的工作原理

 Alien RFID系统最基本的功能就是读取RFID标签的信息,然后提供给用户

或应用程序一个接口将标签信息列表显示出来。因此,我们首先必须将Alien RFID阅读器与计算机主机连接起来。Alien RFID系统提供了两种连接方式,一种是在本地通过RS-232串行通信端口,一种是通过网络。

    为了方便网络管理,Alien RFID阅读器提供了heartbeats机制,即心跳机制,它允许应用程序在局域网内方便地发现阅读器。

    在局域网内操作Alien RFID阅读器,我们必须知道阅读器的IP地址才能够与阅读器进行连接。通过heatbeats机制,我们可以在局域网内监听heatbeats信息来得到阅读器的IP地址。

    当一个阅读器成功启动后,它会在局域网内通过UDP协议定时地广播heartbeats信息。这些heartbeats信息可以被局域网内的应用程序拦截,同时它提供了足够的信息在局域网内定位阅读器,与阅读器进行通信。

    Heatbeats机制有四个配置选项,可通过阅读器提供的命令来设置。

HeatBeatTime:这个命令用来指定阅读器广播heartbeats信息的时间间隔。

HeatBeatPort:这个命令用来指定一个端口信息,heatbeats信息将发送到HeatBeatAddress命令所指定IP地址的这个端口上。

HeatBeatAddress:这个命令用来指定一个特定的IP地址,heartbeats信息将发送到这个IP地址。

HeatBeatAddress:这个命令指定一个数值,代表heartbeats信息所发送的总数。

    同时,Alien RFID阅读器提供了两种读取标签信息的方式:Interactive ModeAutonomous Mode

1Interactive Mode

读取电子标签信息在Interactive Mode下非常简单,只需向阅读器发送一

taglist或者t命令。当taglistformat = text 的时候,读到的电子标签信息如下:

Tag:E200 3411 B801 0108, Disc:2007/06/29 08:30:49, Last:2007/06/29 10:38:12, Count:292, Ant:0, Proto:2

Tag:4461 7669 6445 2E4B, Disc:2007/06/29 10:38:13, Last:2007/06/29 10:38:13, Count:187, Ant:1, Proto:2

2Autonomous Mode

Autonomous Mode是一种需要配置和操作的模式,它可以自动检测和处理数

据。在这种工作模式下,首先需要配置一下信息,例如AutoMode命令必须置成On

一旦设置在这种模式下工作,阅读器可以自主的进行标签的读取等操作。主机上的应用程序可以设置监听事件来读取阅读器上的电子标签信息。

这种操作模式最主要的优势在于它可以让许多阅读器同时向一个主机发送信息。这样,一个应用程序可以监听并处理局域网内多个阅读器发来的taglist信息。

此外,为了更好地接受多个阅读器广播的taglist信息,我们需要对标签信息进行一些简单的配置。Taglist Commands主要有以下几种:

PesistTime:这个命令用来指定标签的数据信息在阅读器内部的活跃标签列表中存在的时间长度,缺省值为-1

TagListFormat:这个命令用来指定taglist信息的显示格式,主要有四种:Text格式,Terse格式,XML格式和Custom格式。

TagListAntennaCombine:这个命令用来打开或者关闭天线组合模式。当该命令为On时,阅读器会将多个相同的标签ID值用一个单一的标签信息来标识,即使这是ID值被不同的天线读到。反之,当TagListAntennaCombine命令为OFF时,阅读器会保存每个天线发现的标签ID信息的多个副本。

TagStreamMode:这个命令用来打开或者关闭阅读器的TagStream功能。当TagStreamMode命令为On的时候,每个被读到的标签信息都会直接发送给TagStreamAddress命令所指定的IP地址,没有数据缓冲。

TagStreamAddress:这个命令用来指定TagStream事件中数据信息应该发送到的地址。

TagStreamFormat:这个命令用来指定TagStream事件中数据的显示格式,区别于TagListFormat

3.2.C#多线程技术

使用C#编写任何程序时,都有一个入口:Main()方法。程序从Main()方法的第一条语句开始执行,直到这个方法返回为止。这样的程序结构非常适合有一个可识别的任务序列的程序,但程序常常需要同时完成多个任务。例如在使用文字处理软件的时候,用户在输入文字的同时,软件能同步进行拼写检查而不需要用户的等待;再如在本文基于RFID的仓储管理系统中,后台需要有一个线程不断的接受阅读器广播的taglist数据信息并对这些数据进行压缩,然后存储到本地数据库中,与此同时用户还可以进行物品的出库、入库,库存盘点等相关操作。这时我们就需要能让程序具有同时处理多个任务的能力,这就是C#的多线程技术。

C# WinForm程序中创建一个新的线程是非常容易的,可以通过一下语句来完成:

Thread t = new Thread(new ThreadStart(ThreadFuc))

tstart();

第一条语句创建一个新的Thread对象,并指明一个该线程的方法ThreadFuc()。当新的线程开始执行时,该方法也就被调用执行了。该线程对象通过一个System.Threading.ThreadStart类的一个实例以类型安全的方法来调用它要调用的线程方法。

第二条语句正式开始执行该新线程,一旦方法Start()被调用,该线程就保持在一个alive的状态下。不过,线程对象的Start()方法只是启动了该线程,而并不保证其线程方法ThreadFuc()能立即执行。它只是保证该线程对象能被分配到CPU时间,而实际的执行还要有操作系统根据处理器时间来决定。

同时C#的公共语言运行时(Common Language RuntimeCLR)能区分两种不同类型的线程:前台线程和后台线程。这两者的区别是:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时会自动结束。因此,我们可以将基于RFID的仓储管理系统中实时接受阅读器广播的数据信息的线程设置为后天线程,这样用户就可以同时进行一些其他的库存操作。

假设有这样一种情况,两个线程同时维护一个队列,如果一个线程向队列中添加元素,而另外一个线程从队列中取出元素,那么我们称添加元素的为生产者,称取用元素的为消费者。生产者和消费者问题看起来简单,但却是多线程应用中一个必须要解决的问题,它涉及到线程之间的同步和通讯问题。每个线程都有自己的资源,但是代码区是共享的,即每个线程都可以执行相同的函数。但是在多线程环境下,可能带来的问题就是几个线程同时执行一个函数,导致数据混乱,产生不可预料的后果,因此我们必须避免这种情况发生。C#提供了一个关键字lock,它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻只允许一个线程进入执行,而其他线程必须等待。例如:

定义一个队列:

Private Queue TagStreamQueue = new Queue();

一个线程Tread_A要执行入队列操作的代码如下:

Lock(TagStreamQueue.SyncRoot)

{

   TagStreamQueue.Enqueue(msg);

}

同理,当另外一个线程Tread_B要执行出队列操作时,代码如下:

Lock(TagStreamQueue.SyncRoot)

{

   TagStreamQueue.Dequeue(msg);

}


来源:我是码农,转载请保留出处和链接!

本文链接:http://www.54manong.com/?id=1249

'); (window.slotbydup = window.slotbydup || []).push({ id: "u3646208", container: s }); })();
'); (window.slotbydup = window.slotbydup || []).push({ id: "u3646147", container: s }); })();

猜你喜欢

转载自blog.csdn.net/xiaohuanglv/article/details/89184324
今日推荐