吴元君
(安徽财贸职业学院,安徽 合肥 230601)
学生上课的出勤率是学校教务部门需要考查的一项重要数据,也是班级和学生评优评奖的重要指标。在高等院校,特别是多个班级合班的大课,教师在上课前点名会耗费大量时间。而且对于班主任而言,除了到班级检查外,无法及时获得旷课的学生信息。为了帮助授课教师提高点名的效率,协助班主任及时了解班级出勤率,为学生考试、评优提供依据,同时将这些数据共享发布,项目组研究开发了一个基于Android和Ardunio的移动便携点名系统。
系统采用目前主流的射频卡RFID(工作频率为125KMHz,如饭卡、上机卡等)技术标识学生身份,采用相应的读卡模块,利用Arduino Nano读取并处理射频卡数据,并将该数据以目前广泛普及的蓝牙技术发送给移动智能设备客户端,如采用Android操作系统的智能手机等,完成点名的操作,并最终利用智能设备的WIFI或3G功能将点名信息上传至学校教务部门公网服务器,达到数据共享的目的[1]。该系统方案成本较低,不增加学生负担,对教师而言,只需要配备一款基于Android操作系统的手机即可使用,具有一定的推广价值。
Android名词源于法国作家的科幻小说《未来夏娃》中的小机器人,2005年Google收购了刚成立22个月的Android公司,开始开发名为Android的开放源代码的移动系统,Android软件系列包括了操作系统、中间件和一些关键应用。Android代码开源的特性,利于开发人员明确细节,开发出差异化的应用程序。Android的源代码遵循 Apache V2软件许可,而不是 GPL v2许可证,非常利于商业开发。目前Android基于 QEMU开发的模拟器调试手段有限,仅支持通话、SMS等,且运行效率较低[2]。但是,Android丰富的开发工具,包括模拟机、调试工具、内存运行检测,以及为 Eclipse所写的 ADT插件,深受广大开发人员欢迎。
Arduino是一个基于开放原始码的软硬体平台,是一款便捷灵活、方便上手的开源电子原型平台,包含硬件(各种型号的arduino板)和软件(arduino IDE)。Arduino构建于开放原始码simple I/O介面版,并且具有使用类似Java,C语言的Processing/Wiring开发环境。
Arduino能通过各种各样的传感器来感知环境,通过控制灯光、马达和其他的装置来反馈、影响环境。板子上的微控制器可以通过Arduino的编程语言来编写程序,编译成二进制文件,烧录进微控制器。对Arduino的编程是利用 Arduino编程语言 (基于 Wiring)和Arduino开发环境(based on Processing)来实现的。基于Arduino的项目,可以只包含Arduino,也可以包含Arduino和其他一些在PC上运行的软件,他们之间进行通信(比如 Flash,Processing,MaxMSP)来实现[3]。
RDM630系列非接触式射频ID卡专用模块,釆用先进的射频接收线路及嵌入式微控制器设计,结合高效译码算法,完成对EM4100兼容式ID卡的数据接收。具有接收灵敏度高、工作电流小、稳定性高等特点,适用于门禁、考勤、收费、防盗、巡更等各种射频识别应用领域。
该模块可以读取125K EM4100系列RFID卡,且使用方便,供电后串口连接Arduino主板即可。当有RFID卡进入读卡范围时,模块会通过串口直接把卡号发送给Arduino。如果再用继电器模块连接Arduino的话,就可以实现简单的门禁控制。
数据输出格式如下:
(1)9600bps,N,8,1
(2)CHECKSUM:card 10byte DATA entire do XOR operation
?
卡号:62E3086CED
输出:36H、32H、45H、33H、30H、38H、36H、43H、45H、44H
CHECKSUM:(62H)XOR (E3H)XOR (08H)XOR (6CH)XOR (EDH)=08H
核心模块使用HC-06从模块,引出接口包括VCC、GND、TXD、RXD,预留LED状态输出脚。led指示蓝牙连接状态,闪烁表示没有蓝牙连接,常亮表示蓝牙已连接并打开了端口。底板设置LDO,输入电压3.6-6V,未配对时电流约30mA,配对后约10mA。接口电平3.3V,可以直接连接各种单片机(51,AVR,PIC,ARM,MSP430等)。配对以后当全双工串口使用,仅支持8位数据位、1位停止位、无奇偶校验的通信格式。配对后只需要当成固定波特率的串口一样使用即可,因此只要是以“固定波特率,8位数据位,无奇偶校验”通信格式的串口设备都可以直接取代原来的有线串口而不需要修改程序。如数据采集、智能车、串口打印机、户外点阵条屏控制等[4]。适合手机跟设备间通过蓝牙串口通信。
Arduino Nano是Arduino USB接口的微型版本,最大的不同是没有电源插座以及USB接口是Mini-B型插座。Arduino Nano是尺寸非常小的而且可以直接插在面包板上使用。其处理器核心是ATmega328(或ATmega168),同时具有14路数字输入/输出口(其中6路可作为PWM输出),8路模拟输入,一个16MHz晶体振荡器,一个mini-B USB口,一个ICSP header和一个复位按钮。
该板提供一个硬件串口(TX pin、RX Pin),可以连接其它TTL电平设备,作为数据通讯[5]。作为扩展,可以通过SoftSerial类创建软串口,连接其它串口设备。实现后的蓝牙RFID读卡器原理图如图1。
图1 蓝牙RFID读卡器原理图
本系统硬件设备部分,使用开源的eclipse集成开发环境,并安装了Arduino插件以提供支持。应用系统部分,使用微软Visual Studio 2010,配合微软SQLServer 2008 R2 Express完成数据的存储,并提供Web服务。
该部分主要是利用面向对象的方法,将硬件设备抽象为类,如类Rfid表示RFID读卡器,类Led表示指示灯,类Buzzer表示蜂鸣器等。这样做可以极大提供代码的利用率,提高程序的可读性[6]。关键代码如下:
bool Rfid::nextCard(unsigned char*card) {
hasCard=false;
//把现有的数据放入数组
while (Serial.available() > 0) {
//加入判断,位置0时,数据应为2,位置13时,数据应为3
unsigned char c;
c=Serial.read();
if(currentByte==0&&c!=2) {
continue;
}
if(currentByte==13&&c!=3) {
currentByte=0;
continue;
}
newData[currentByte++]=c;
//放入14个以后,退出
if(currentByte >=14) {
//比较前后两次读取的是否一致,如果不一致,则表示是新卡
for(currentByte=0;currentByte<14;currentByte++){
if (preData[currentByte]!=newData[currentByte]){
preData[currentByte]=newData[currentByte];
hasCard=true;
}
}
if(hasCard==true) {
for(currentByte=0;currentByte< 14;currentByte++){
card[currentByte]=newData[currentByte];
}
}
Nano上首先实例化RFID读卡器,不停的查询是否有磁卡接近,当有磁卡接近,读取卡号并将卡号发送给蓝牙模块。关键代码如下:
#include “SendCardByBT3.h”
#include “Rfid.h”
#include “SoftwareSerial.h”
//因为Nano版只有一个硬串口,所以使用软串口连接蓝牙
SoftwareSerial mySerial(7,8);//使用Pin7作为软串口的RX,使用Pin8作为软串口的TX
//RFID模块
Rfid*rfid;
//存储卡号的临时数组
unsigned char card[14];
//存储卡号的临时字符串对象
String s;
//蜂鸣器//Buzzer*buzzer;
void setup() {
rfid=new Rfid();//实例化 RFID 读卡器模块
//buzzer=new Buzzer(4);//实例化蜂鸣器,用 Pin4 进行控制
//
mySerial.begin(9600);//软串口开始工作,准备向蓝牙模块发送卡片信息
}
void loop() {
//当读到有卡片时,从蓝牙将卡号发出
if(rfid->nextCard(card) ==true) {
s= “”;
for(int i=1;i< 11;i++){
s.concat((char)card[i]);
}
mySerial.println(s+ “ ”);//把卡号发送到蓝牙模块,并附带换行符,以便 Java
//能顺利读取数据
//buzzer->beep();//读取一个磁卡,蜂鸣器发出一次声音
}
}
手机端蓝牙与蓝牙模块配对后,会一直读取蓝牙模块输入流的数据,以判断是否有新卡信息到达[7]。当有新卡信息到达时,会自动更新对应学生的出勤状态;否则,继续等待。如果这个操作在Activity主线程中运行的话,必然导致界面无法响应用户操作。因此,在获取蓝牙输入流后,需要单独开启一个线程运行读卡信息的操作。当蓝牙模块关闭或Activity主线程结束时,该读卡信息的线程会自动结束。该过程可参照流程图见图2,关键代码如下。
图2 流程图
//启用手机蓝牙设备
@Override
protected void onStart(){//在Activity启动时,判断手机蓝牙是否启用
super.onStart();
if(!bluetoothAdapter.isEnabled()) {
//请求蓝牙权限
Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent,REQUEST_BLUETOOTH_ENABLED);
}
}
//连接蓝牙读卡器后需要进行读卡操作,因此使用单独的线程运行
private void connectDevice(final String address) {
new Thread(new Runnable(){
public void run() {
try{
//获取要连接的蓝牙设备
BluetoothDevice device=bluetoothAdapter
.getRemoteDevice(address);
/
/创建Socket连接
bluetoothSocket=device
.createRfcommSocketToServiceRecord(MY_UUID);
//进行连接
bluetoothSocket.connect();
Log.d(“Message”, “启动读卡线程“);//输入操作日志
//开始读卡
readCards();
}catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
//读卡操作的线程
private void readCards() {
BufferedReader reader=null;
String nextCard=null;
String preCard=null;
try{
reader=new BufferedReader(new InputStreamReader(
bluetoothSocket.getInputStream()));
while ((nextCard=reader.readLine()) !=null) {
if(!nextCard.equals(preCard)) {
//读到新卡信息,更新对应学生出勤状态
}
}
}catch (Exception e) {
}finally{//…
}
}
该系统基于RFID技术标示学生身份,采用开源的硬件平台Arduino作为主控设备,与采用单片机作为主控设备相比,该方案可扩展性更强,操作更为方便;同时,利用蓝牙技术,在智能设备与Arduino之间建立起连接,借助智能设备的WIFI或3G功能共享数据[8]。使用智能Android设备配合射频卡完成上课点名的操作是本系统的亮点,此外,系统还设计了完整的应用程序,方便用户操作。系统结构图如图3所示。
图3 系统结构图
系统有较强的实用性,RFID蓝牙读卡器价格普遍在500元以上,而该方案的成本可以控制在200元以内,利用该系统不仅可以极大提高点名效率,而且教学相关人员可以及时了解和监控学生上课情况。该系统支持多种Android终端设备,如手机、电脑等,RFID技术的普及、智能设备的广泛使用也都为该系统在校园的普及奠定了基础。
[1] 杨丰盛.Android应用开发揭秘[M].北京:机械工业出版社,2010.
[2] 杨明极,毕晶.基于 Android 视频客户端的设计[J].电视技术,2012,(3):43-47.
[3] H.Hagras,Victor Callaghan,Martin Colley,Graham Clarke,Anthony Pounds-Cornish,and Hakan Duman.Creating an ambient-telligence environment using embedded agents[J].IEEE Intelligent Systems,2004,(4):12-20.
[4] 周时伟,谢维波.基于Android的智能家居终端设计与实现[J].微型机与应用,2012,(14):10-13
[5] 王朝华,陈德艳,黄国宏,等.基于Android的智能家居系统的研究与实现[J].计算机技术与发展,2012,(6):225-228.
[6] 詹成国,朱伟,徐敏.基于Android的测控装置人机界面的设计与开发[J].电力自动化设备,2012,(1):119-122
[7] 唐赛武,满君丰,谢成剑.便于省时排队的无线监测系统的研制[J].福建电脑,2012,(11):35-37.
[8] 宫磊,周聪.基于Android的移动终端应用程序开发与研究[J].计算机与现代化,2008,(8):85-89