目录
前言
停车场收费系统是通过计算机、网络设备、车道管理设备搭建的一套对停车场车辆出入、场内车流引导、停车费收取工作进行管理的网络系统,如图 14-1 所示。停车场收费系统采用非接触式智能卡,在停车场的出入口处设置一套出入口管理设备,使停车场形成一个相对封闭的场所,进出车只需将 IC 卡在读卡箱前轻晃一下,系统即能瞬时完成检验、记录、核算、收费等工作,挡车道闸自动启闭,方便快捷地进行着停车场的管理。进场车主和停车场的管理人员均持有一张属于自己的智能卡,作为个人的身份识别,只有通过系统检验认可的智能卡才能进行操作(管理卡)或进出(停车卡),充分保证了系统的安全性、保密性,有效地防止车辆失窃,免除车主后顾之忧。本章中用到的停车场收费系统示意图和高频卡如下图所示:
目标
基于NEWLab 平台模拟停车场收费系统
(1)功能需求
本停车场管理系统基于 NEWLab 平台高频读卡器模拟实现,适合于有长期固定停放车位的停车场。其系统功能如下:
1)NEWLab 平台高频读卡器模拟停车场进出刷卡器,高频 M1 卡模拟停车卡,
2)采用刷卡计费方式,车主通过打卡进出停车场,并能实现自动扣款缴费
3)能实时显示[入场]和[出场]的时间和卡内的余额、停车消费金额。
3)停车场管理系统可以记录车辆的[入场]、[出场]时间和停车费等历史数据
4)当出现以下异常情况时,系统自动提示错误:
(a) 没有[入场],就[出场],系统提示“未查到入场记录”
(b)[出场]时未检查到高频卡,提示“未查到入场记录”;(c)[入场]时未检查到高频卡,提示“未查到入场记录”
(d) 上次[入场]未[出场],再次入场,提示“前面有入场记录,没有出场记录!”(2) 系统流程图,如图 14-5 所示。
1) 进行初始化
2)入场,读卡信息,记录卡信息,记录入场时间,写入系统
2)出场,读卡信息,如果查询到入场记录、计算停留时间,扣费:如果无入场记录,则发出警报。
实验界面
设计一个停车收费系统,要求车辆进入时刷卡登记,出场刷卡后计算时间,并显示扣费金额。
学习目标:
1、了解停车场收费系统基本概念
2、了解停车场收费系统开发手段、步骤、调试方法
串口开关
private void btnOpen_Click(object sender, EventArgs e)
{
if (btnOpen.Text == "打开串口")
{
try
{
if (!com.IsOpen)
{
com.PortName = cmbPort.Text;
com.BaudRate = int.Parse(cmbBaudRate.Text);
com.DataBits = int.Parse(cmbDataBits.Text);
switch (cmbStopBits.SelectedIndex)
{
case 0:
com.StopBits = StopBits.One; break;
case 1:
com.StopBits = StopBits.Two; break;
case 2:
com.StopBits = StopBits.OnePointFive; break;
case 3:
com.StopBits = StopBits.None; break;
}
switch (cmbParity.SelectedIndex)
{
case 0: com.Parity = Parity.None; break;
case 1: com.Parity = Parity.Odd; break;
case 2: com.Parity = Parity.Even; break;
}
com.Open();//打开串口
}
btnOpen.Text = "关闭串口";
txtStatus.Text = "串口已打开!";
btnInformation.Enabled = true;
btnClear.Enabled = true;
button1.Enabled = true;
button2.Enabled = true;
button3.Enabled = true;
button4.Enabled = true;
button5.Enabled = true;
button6.Enabled = true;
button7.Enabled = true;
button8.Enabled = true;
button9.Enabled = true;
button10.Enabled = true;
button11.Enabled = true;
// 数据接收模式变化时,设置串口的数据接收侦听事件
try
{
com.DataReceived += new SerialDataReceivedEventHandler(com_DataReceived); //加载接收事件
}
catch (Exception err)
{
txtStatus.Text = err.ToString();
}
}
catch
{ txtStatus.Text = "串口打开错误或串口不存在!"; }
}
else //关闭串口
try
{
if (com.IsOpen)
com.Close(); //关闭串口
btnOpen.Text = "打开串口";
txtStatus.Text = "串口已关闭!";
btnInformation.Enabled = false;
btnClear.Enabled = false;
button1.Enabled = false;
button2.Enabled = false;
button3.Enabled = false;
button4.Enabled = false;
button5.Enabled = false;
button6.Enabled = false;
button7.Enabled = false;
button8.Enabled = false;
button9.Enabled = false;
button10.Enabled = false;
button11.Enabled = false;
}
catch
{
txtStatus.Text = "串口关闭错误或串口不存在!";
}
}
用定时器自动接收串口信息
public void theout(object source, System.Timers.ElapsedEventArgs e)
{
timer_num++;
this.BeginInvoke(new TextOption(function1));//invok 委托实现跨线程的调用
}
delegate void TextOption();//定义一个委托
void function1()
{
if ((timer_num > 10)&&(com_num>5))
{
com_num = 0;
try
{
int count = com.BytesToRead;
byte[] readBuffer = new byte[count];
com.Read(readBuffer, 0, count);
//strReceive = Encoding.Default.GetString(readBuffer); //字母、数字、汉字转换为字符串
String strReceive = getStringFromBytes(readBuffer); //转十六进制
this.Invoke(new showReceiveDelegate(doShowReceive), strReceive);
}
catch (Exception err)
{
txtStatus.Text = err.ToString();
}
}
}
激活高频卡
//发送命令,激活高频卡
private void button3_Click(object sender, EventArgs e)
{
txtSend.Text = "";
txtReceive.Text = "";
status_num = 4;
String str1 = "FF 55 00 00 02 00 00 C0 85";
byte[] data = getBytesFromString(str1);
com.Write(data, 0, data.Length);
txtSend.Text = str1;
}
//发送命令,激活高频卡
//----------1---------2---------3---------4---------
//01234567890123456789012345678901234567890123456789
//FF 55 00 00 82 00 04 E3 64 41 21 68 6B
//打开天线
if (status_num == 4)
{
status_num = 0;
int i;
for (i = 0; i < 5; i++)
{
if (str.Substring(i, 20).Equals("FF 55 00 00 82 00 04"))
{
txtStatus.Text = "激活高频卡成功!";
g2.FillEllipse(bush1, 0, 0, 60, 60);//红色
break;
}
}
if (i >= 5)
{
txtStatus.Text = "无法激活高频卡!";
}
}
验证M1卡扇区密码
M1卡有16个扇区(每个扇区有四个数据块,其中块0、块1、块2为数据块,块3密码和操作设置),各自有各自密码,互不相干,必须分别加以认证才能对该扇区进一步操作。
//发送命令,高频M1卡密码认证
//FF 55 00 00 05 02 08 00 FF FF FF FF FF FF 00 ED 9Astatus_num = 8;
private void button7_Click(object sender, EventArgs e)
{
txtSend.Text = "";
txtReceive.Text = "";
txtInformation.Text = "";
status_num = 8;
String str1 = "00 00 05 02 08 00 " + this.txtBoxSector.Text + " " + (Convert.ToInt32(this.cmbSector.Text) * 4).ToString("X").PadLeft(2, '0');
byte[] data = getBytesFromString(str1);
var crc = crc16(data, data.Length);
Array.Reverse(crc);
str1 = "FF 55 " + str1 + " " + getStringFromBytes(crc);
data = getBytesFromString(str1);
com.Write(data, 0, data.Length);
txtSend.Text = str1;
}
进入停车场
//01234567890123456789012345678901234567890123456789
//FF 55 00 00 81 03 08 E3 64 41 21 E3 64 41 00 C7 DD
//进入停车场
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 = "读卡失败,请再次读取!";
}
}
记录出停车场信息
//发送读取高频卡信息命令(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;
}
总结
通过学习高频卡停车收费系统,了解到了高频卡停车系统是一种现代化的无人值守停车管理系统,通过使用高频射频卡作为车辆进出门禁的身份识别方式,实现自动识别、计费、查询等多种功能,逐渐代替了传统停车收费员的人工管理方式,具有高效、便捷、安全等特点。
总结来说,高频卡停车系统的优点包括:
-
高效性:自动识别车辆进出,无需人工干预,大大提高车辆出入速度,避免拥堵。
-
准确性:采用高频射频卡进行身份识别,准确率高,杜绝了人工管理带来的误差和漏洞。
-
安全性:实现了对车辆进出的严格控制,避免无证车辆、盗抢车辆等不法行为,保障车辆停车安全。
-
易管理:可通过远程监控、实时查询等方式实现对停车场的实时管理,提高管理效率,减少管理成本。
-
用户友好性:方便快捷的预付费模式,加上高频卡的便捷性,提升了用户的停车体验。
总之,高频卡停车系统已经成为城市停车管理的发展趋势,是一个高效、准确、安全、易管理、用户友好的停车解决方案。