目录
任务目标:
设计一个停车场收费系统,要求车辆进入时刷卡登记,出场刷卡后计算时间,并显示扣费金额。
一、认识RFID
要实现任务目标所提到的刷卡功能,就需要了解到我们的RFID技术,
RFID(Radio Frequency Identification),即射频识别,又称无线射频识别,是一种通信技术,可通过无线电讯号识别特定目标并读写相关数据,而无需识别系统与特定目标之间建立机械或光学接触。
物联网分为应用层、网络层和感知层,RFID处于感知层。其在物联网中的应用十分广泛。
二、 停车场收费功能原理
停车场收费系统是现代化停车场车辆收费及设备自动化管理的统称,是将停车场完全置于计算机统一管理下的高科技机电一体化产品。现代社会,科技越来越发达,人们的日常生活不断的智能化、科技化,停车场也是如此,停车场收费系统就是停车场与现代社会交融的一个技术;该技术使用更加方便快捷,不仅提高了现代人类的工作效率,也大大的节约了人力物力,提高了管理能力,降低了停车场的运营成本。
三、页面设计
当高频卡放在感知设备上时,点击入场按钮则可以自动识别当前高频卡的卡号,并在后台的文档中将卡号以及时间余额记录下来,记录卡号防止一张卡入两次厂,记录时间用来计算和余额以便于后续的停车时间和出场消费统计。
四、部分代码展示
1.按键代码
按键代码通过清空相关的文本框显示的数据后再进行新的数据插入,通过自定义的一个变量在自定义的方法中进行数值判断,再根据不同的数值去判断应该实现什么功能,我给入场的代码设定的数字为11,所以存储的数字也为11;后续是一些硬件的初始化,使其接收到高频卡传输过来的信息。
//发送读取高频卡信息命令(FF 55 00 00 01 03 00 30 75)
//发送命令,获取高频卡信息,记录入停车场信息
private void button10_Click(object sender, EventArgs e)
{
txtSend.Text = "";
txtReceive.Text = "";
txtInformation.Text = "";
status_num = 11;
String str1 = "FF 55 00 00 01 03 00 30 75";
byte[] data = getBytesFromString(str1);
com.Write(data, 0, data.Length);
txtSend.Text = str1;
}
//发送读取高频卡信息命令(FF 55 00 00 01 03 00 30 75)
//发送命令,获取高频卡信息,记录出停车场信息
private void button11_Click(object sender, EventArgs e)
{
txtSend.Text = "";
txtReceive.Text = "";
txtInformation.Text = "";
textBox6.Text = "";
status_num = 12;
String str1 = "FF 55 00 00 01 03 00 30 75";
byte[] data = getBytesFromString(str1);
com.Write(data, 0, data.Length);
txtSend.Text = str1;
}
2.入场
当接收到的变量值为11时,则先将定义的变量清零,防止数值残留影响后续的判断。
因为接收到信息需要等待一些时间,所以需要定义一个变量i进行for循环;判断是否接收到的是高频卡对应的初始化数据,是则程序继续执行,若接收到的初始化数据不正确或超过所定时间则直接跳出循环,并在前台控制界面显示“读卡失败,请再次读取!”。
程序继续进行以后,便截取当前高频卡的卡号,前台控制界面便会显示“读卡成功,进入停车场,开始记录时间。”后便将当前时间记录下来放入时间变量1中,并显示当前高频卡余额。
后续加入的判断是判断当前高频卡是否已经入场过,若是已经入场了则无法再次入场,以防多次记录在出厂时读取数据出现错误。
//进入停车场
if (status_num == 11)
{
status_num = 0;
int i;
for (i = 0; i < 5; i++)
{
if (str.Substring(i, 20).Equals("FF 55 00 00 81 03 08"))
{
txtInformation.Text = str.Substring(i + 21, 11);//截取4个字节
txtStatus.Text = "读卡成功,进入停车场,开始记录时间!";
now1 = DateTime.Now;
textBox3.Text = now1.ToString("yyyy-MM-dd HH:mm:ss");//入场时间
//金额计算,显示余额
textBox4.Text = money.ToString();//显示余额
//--------------------------------------------------------------------------------------
//将信息写入文件
var path = AppDomain.CurrentDomain.BaseDirectory + @"data.txt";
if (!File.Exists(path))
{
File.Create(path);
}
string str2 = File.ReadAllText(path); //读文件,存储到字符串str2
int j;
for (j = 0; j < str2.Length - 25; j++) //查找是否已经入场
{
if (str2.Substring(j, 11).Equals(txtInformation.Text))
{
txtStatus.Text += "\r\n前面有入场记录,没有出场记录!";
}
}
str2 += txtInformation.Text; //添加内容到字符串str2
str2 += textBox3.Text; //记录时间
str2 += textBox4.Text; //记录金额
str2 += "\r\n";
File.WriteAllText(path, str2);//将字符串str2内容写入str1路径指向的文件
//--------------------------------------------------------------------------------------
break;
}
}
if (i >= 5)
{
txtStatus.Text = "读卡失败,请再次读取!";
}
}
3.出场
当接收到的变量值为12时,则先将定义的变量清零,防止数值残留影响后续的判断。
因为接收到信息需要等待一些时间,所以需要定义一个变量i进行for循环;判断是否接收到的是高频卡对应的初始化数据,是则程序继续执行,若接收到的初始化数据不正确或超过所定时间则直接跳出循环,并在前台控制界面显示“读卡失败,请再次读取!”。
进入程序之后,便开始读取文件,当读到高频卡信息后,便记录出场时间,记录为时间变量2,并执行(时间变量2-时间变量1)*所设定的收费标准计算余额,并显示“离开停车场!”“离场时间”“余额”。
离开停车场信息
if (status_num == 12)
{
status_num = 0;
int i;
for (i = 0; i < 5; i++)
{
if (str.Substring(i, 20).Equals("FF 55 00 00 81 03 08"))
{
txtInformation.Text = str.Substring(i + 21, 11);//截取4个字节
txtStatus.Text = "离开停车场!\r\n查找入场记录---";
now2 = DateTime.Now;
textBox5.Text = now2.ToString();//出场时间
//-------------------------------------------------------------------------------------
//读出文件,查找卡信息、时间信息
//0---------1---------2---------3---------4---------
//01234567890123456789012345678901234567890123456789
//E3 64 41 212016/1/26 18:31:5210000
//E3 64 41 212016/1/26 18:31:5610000
var path = AppDomain.CurrentDomain.BaseDirectory + @"data.txt";
if (!File.Exists(path))
{
File.Create(path);
}
string str2 = File.ReadAllText(path); //读文件,存储到字符串str2
int j;
for (j = 0; j < str2.Length - 30; j++) //查找是否已经入场
{
if (str2.Substring(j, 11).Equals(txtInformation.Text))
{
break;
}
}
if (j < str2.Length - 30)//有卡信息,先提取时间,然后删除卡信息
{
txtStatus.Text += "查找入场记录!\r\n计费中---";
var timeStr = str2.Substring(j + 11, 19);
//提取时间
now3 = DateTime.ParseExact(timeStr, "yyyy-MM-dd HH:mm:ss", null);
//停留时间
textBox8.Text = (now2 - now3).ToString();//显示停留时间
//计算秒,做为消费金额
TimeSpan ts = now2.Subtract(now3).Duration();
money1 = int.Parse(ts.Hours.ToString()) * 3600 + int.Parse(ts.Minutes.ToString()) * 60 + int.Parse(ts.Seconds.ToString());
money = money - money1;
textBox6.Text = money1.ToString();//显示消费金额
textBox4.Text = money.ToString(); //显示余额
txtStatus.Text += "计费完毕!\r\n欢迎下次光临!";
}
else
{
txtStatus.Text += "未查到入场记录!";
}
//--------------------------------------------------------------
//删除卡信息
for (j = 0; j < str2.Length - 30; j++) //查找是否已经入场
{
if (str2.Substring(j, 11).Equals(txtInformation.Text))
{
str2 = str2.Remove(j, 35);
}
}
File.WriteAllText(path, str2);//重新写入文件
//--------------------------------------------------------------
break;
}
}
if (i >= 5)
{
txtStatus.Text = "读卡失败,请再次读取!";
}
}
五、总结
本次任务目标以我们所学RFID知识以及C#编程知识同我们的生活相融合,给我们如何运用所学知识解决生活问题提供了鲜明的例子。并且在解决任务的过程中进行学习,使我们所学知识更丰富。本次学习中我们也接触到了平时接触不到的学习设备,如RFID的平台以及CC2530单片机以及各种本次课程中用到的硬件,收获颇丰。