二维码

RFID的仓储管理系统实现关键技术 - 数据结构 - 机器学习

1668 人阅读 | 时间:2021年01月15日 01:23


RFID的仓储管理系统实现关键技术

1638 人参与  2019年04月10日 12:33  分类 : 物联网/云计算  评论

3.1.Alien RFID系统

3.1.1. Alien RFID系统组成

    1)Alien ALR-9900 阅读器

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

    2)Alien RFID天线

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

    3)Alien RFID无源电子标签

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

3.1.2.Alien RFID 系统的工作原理

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

或应用程序一个接口,并将标签信息列表显示出来。因此,我们首先必须将Alien RFID阅读器与计算机主机连接起来,这样主机与RFID阅读器可以通过接口进行通信.主机与阅读器的通信有两种方式:串行接口(RS-232)和远程登陆协议(Tcp/Ip)。

 串口通信:

这种方法有助于安装一个新的RFID的阅读器。不需要重复配置,并且可以很容易地应用于大部分的计算机。该方法能够通过串行通信(COM)端口实时操作阅读器。串行通信是与阅读器交互和实现阅读器协议的最简单方法。阅读器通过使用DHCP协议来获得它的网络设置,由于这种网络配置的方法结构简单、方便,问题是为了和阅读器通信,我们必须知道它的IP地址,串行通信接口可以用来确定网络中阅读器的IP地址。

 远程登陆协议(Tcp/Ip):

主机与RFID阅读器在一个局域网内,通过Tcp/Ip协议进行通信。在局域网内操作Alien RFID阅读器,我们必须知道阅读器的IP地址才能够与阅读器进行连接。通过“heatbeats”机制,我们可以在局域网内监听heatbeats信息来得到阅读器的IP地址,心跳模式使应用程序在局域网内能方便地发现阅读器。

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

3.1.3.Heatbeats机制

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

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

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

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

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

同时,Alien RFID阅读器提供了两种读取标签信息的方式:Interactive Mode和Autonomous 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

taglistformat = XML 的时候,读到的电子标签信息如下:

<?xml version="1.0" encoding="UTF-8"?>

<Alien-RFID-Tag-List>

<Alien-RFID-Tag>

<TagID> E200 3411 B801 0108</TagID>

<DiscoveryTime>2007/06/29 08:30:49</DiscoveryTime>

<LastSeenTime>2007/06/29 10:38:12</LastSeenTime>

<ReadCount>292</ReadCount>

<Antenna>0</Antenna>

<Protocol>2</Protocol>

</Alien-RFID-Tag>

<Alien-RFID-Tag>

<TagID>1155 4461 7669 6445 2E4B</TagID>

<DiscoveryTime>2007/06/29 10:38:13</DiscoveryTime>

<LastSeenTime>2007/06/29 10:38:13</LastSeenTime>

<ReadCount>187</ReadCount>

<Antenna>1</Antenna>

<Protocol>2</Protocol>

</Alien-RFID-Tag>

</Alien-RFID-Tag-List>

Autonomous Mode

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

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

一旦设置在这种模式下工作,阅读器可以自主的进行标签的读取等操作,用户不用再去管它。主机上的应用程序可以设置监听事件来读取阅读器上的电子标签信息。这种操作模式最主要的优势在于它可以让许多阅读器同时向一个主机发送信息。这样,一个应用程序可以监听并处理局域网内多个阅读器发来的taglist信息。

3.2.C#多线程技术

工作线程与UI交互:

在本文基于RFID的仓储管理系统中,当阅读器工作在Autonomous Mode模式时,多个阅读器会实时的以“流”的方式向仓储管理系统发送TagList信息,仓储管理系统一边将这些数据处理并存入数据库,一边在UI界面上显示这些数据。在C#中,从Main()方法开始一个默认的线程,一般称之为主线程,如果在这个线程上进行一些非常耗CPU的计算,那么UI界面就会被挂起而处于假死状态,也就是说无法和用户进行交互了。如果多开一些线程来完成一些耗时的计算,那么工作线程也是无法如此更新UI界面中的元素的,比如直接显示一个提示信息:label1.Text=outstring,原因很简单UI属于默认的主线程,而线程间是不能这样直接访问彼此的成员的,也就是说如果从另外一个线程操作windows窗体上的控件,就会和主线程产生竞争,造成不可预料的结果,甚至死锁。因此windows GUI编程有一个规则,就是只能通过创建控件的线程来操作控件的数据,否则就可能产生不可预料的结果。对于本系统内的工作线程与UI交互问题我们是通过调用BeginInvoke方法和委托事件处理机制来解决的。

举个简单的例子来说明本系统这类问题的解决方案吧:

class main:form
{
private void main_load(object sender, eventargs e)
thread t=new thread(new threadstart(run));//创建一个新线程,并指出入口函数;
t.isbackground = true;//设为后台线程;
t.start();//启动线程;
}
private void run()
{
for(int i = 0; i < 5; i++)
{
outtext( i.tostring() );
thread.sleep(1000);
}
}

public delegate void outdelegate(string text);
public void outtext(string text)
{
if( txt.invokerequired ) //txt是textbox控件的名称;
{
outdelegate outdelegate = new outdelegate( outtext );
this.begininvoke(outdelegate, new object[]{text});
return;
}
txt.appendtext(text);
txt.appendtext( "\t\n" ); 

}
}

其中InvokeRequired 属性在当前线程不是创建控件的线程时为true,否则为false。比如可以自己开个Thread,或使用Timer的事件来访问窗体上的控件的时候,在线程中窗体的这个属性就是True的。简单的说,如果有两个线程,Thread A和Thread B,并且有一个Control c,是在Thread A里面new的。那么在Thread A里面运行的任何方法调用c.InvokeRequired都会返回false。相反,如果在Thread B里面运行的任何方法调用c.InvokeRequired都会返回true。

如果当前线程不是创建控件的线程则调用BeginInvoke方法,通过一个委托把调用封送到控件所属的线程上执行。BeginInvoke方法需要一个委托对象作为参数,委托类似于回调函数的地址,因此调用者通过这个方法就可以把需要调用的函数地址封送给界面线程,这些需要调用的函数里面如果包含了更改控件状态的代码,那么由于最终执行这些函数的是界面线程,从而避免了竞争条件,避免了不可预料的问题。如果当前线程是创建控件的线程,则直接执行更改控件状态的语句。本系统就是这样解决工作线程与UI交互问题的。



©著作权归作者所有:来自ZhiKuGroup博客作者没文化的原创作品,如需转载,请注明出处,否则将追究法律责任 来源:ZhiKuGroup博客,欢迎分享。

评论专区
  • 昵 称必填
  • 邮 箱选填
  • 网 址选填
◎已有 0 人评论
搜索
作者介绍
30天热门
×
×
本站会员尊享VIP特权,现在就加入我们吧!登录注册×
»
会员登录
新用户注册
×
会员注册
已有账号登录
×