Hình 3.36 Giao diện phần mềm trên PC
3.8.4 Thiết kế chi tiết
Sau đây là thiết kế chi tiết của một số module quan trọng:
3.8.4.2 Module Khởi động
a. Chức năng
Chức năng của module này là khai báo các thư viện, khai báo biến và khởi tạo giá trị của các biến.
b. Lưu đồ chi tiết
Hình 3.37 Lưu đồ chi tiết module khởi động
c. Đoạn code chính yếu
using System; using System.Drawing; using System.IO; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Drawing.Imaging; using DirectShowLib; using System.Xml; using System.Threading; using System.Data; using System.Data.SqlClient;
privatebool db_check = false;
privateCapture[] cam = newCapture[4] { null, null, null, null }; string char_test_module = "w";
privateint[] device = newint[4] { -1, -1, -1, -1 };
privatebool[] device_bussy = new bool[4] { false, false, false, false
}; //false: free, true: bussy
privatebool[] working_device = newbool[2]{false,false};
privatestring[] device_working = new string[2] { "dv001", "dv002"
};
privatestring[,] arr_user_id = newstring[2,3] { {"","",""}, {"","",""
}};
privatebyte[] btn_function = newbyte[4]{8,7,8,7}; //chua ma so chuc nang nut an
privatebyte[] btn_function_previous = newbyte[4] { 3, 0, 3, 0 };
//chua ma so chuc nang nut an cu~
privatebool[] wait_msg_card_not_leave = newbool[2]{false,false}; privatebool[] wait_msg_card_not_enter = newbool[2] { false, false
};
privatebool[] wait_msg_card_not_exist = newbool[2] { false, false
};
privatebool[] wait_msg_card_has_error = newbool[2] { false, false
};
privatebool[] wait_msg_logout = new bool[2] { false, false }; privatebool wait_check_module_connect = false;
privatebool[] device_need_reset = newbool[2] { true, true }; privatestring[] btn_function_string = new string[20] {
/*0*/"Đổi chiều làn xe", /*1*/"",
/*1 the nay chua gui xe*/"Đồng ý", /*3 khong chuc nang (disabled)*/"", /*4*/"Đóng thông báo",
/*6 the nay xay ra loi trong qua khu...*/"Không hiện nữa", /*7*/"Chọn nhân viên",
/*8*/"Đăng nhập", /*9*/"",
/*10 dang xuat phien lam viec*/"Tôi muốn đăng xuất", /*11*/"", /*12*/"", /*13*/"", /*14*/"", /*15*/"", /*16*/"", /*17*/"", /*18*/"", /*19*/"", };
privatestring img_dir; privatestring pc_id = ""; constint VIDEODEVICE = 0; constint VIDEOWIDTH = 640; constint VIDEOHEIGHT = 480;
constint VIDEOBITSPERPIXEL = 5;
3.8.4.3 Module kiểm tra kết nối
a. Chức năng
Module kiểm tra kết nối có vai trò rất quan trọng. Trong module này có hai chức năng chức là kiểm tra kết nối giữa phần mềm với cơ sở dữ liệu SQL và kiểm tra kết nối giữa phần mềm với module.
Do phần mềm hoạt động đều cần phải có hai kết nối này luôn sẵn sàng, nên ngoài việc gọi module này sau bước khởi động thì trong lúc hoạt động cũng nên luôn phải kiểm tra kết nối bằng cách thường xuyên gọi module này.
b. Lưu đồ chi tiết
c. Đoạn code chính yếu
privatevoid check_sql_conecttion() { string new_server;
try { new_server = get_xml_node("server", "connect_db"); } catch { new_server = "null"; }
sqlcon = new SqlConnection("Data Source=" + new_server +
";Initial Catalog=db_htgx;User ID=htgx;Password=123"); bool sqlcon_check = false;
while (db_check == false) { try
{ lbx_notice.Items.Insert(0, "[!] Đang kiểm tra kết nối với cơ
sở dữ liệu.");
sqlcon = newSqlConnection("Data Source=" + new_server + ";Initial Catalog=db_htgx;User ID=htgx;Password=123");
//if (open_sql_con() == false) check_module_connection();
sqlcon.Open(); //sqlcon.Close();
lbx_notice.Items.Insert(0, "[!] Kết nối thành công với cơ sở
dữ liệu.");
save_xml_node("server", "connect_db", new_server); db_check = true; }
catch
{ lbx_notice.Items.Insert(0, "[x] Kết nối thất bại với cơ sở dữ
liệu.");
new_server =
Microsoft.VisualBasic.Interaction.InputBox("Kết nối cơ sở dữ liệu thất
bại từ máy chủ: " + new_server + "\nNhập tên hoặc IP máy chủ mới:",
if (new_server.Length==0)new_server = "null"; } } }
privatevoid reset_com(string com) { serialPort1.Close();
serialPort1.PortName = com; try
{ serialPort1.Open();
lbx_notice.Items.Insert(0, "[!] Kết nối thành công cổng: " + com);
wait_check_module_connect = true;
serialPort1.Write(get_xml_node("char","serialport")); } catch
{ lbx_notice.Items.Insert(0, "[x] Kết nối thất bại cổng: " + com); byte tmp = (byte)(byte.Parse(com.Substring(com.Length - 1))+1);
if (tmp > 5) tmp = 1;
lbx_notice.Items.Insert(0, "[!] Đang tự kiểm tra kết nối qua
cổng COM" + tmp.ToString());
now_com = "COM" + tmp.ToString(); timer_test_com.Enabled = true; } }
privatebool check_module_connection() { try
{ serialPort1.Open();
serialPort1.Write(char_test_module); }
catch { lbx_notice.Items.Insert(0, "[x] Không kết nối được với
cổng COM"); }
returntrue; }
if (time_wait_module_response > 3) { time_wait_module_response = 0; wait_check_module_connect = false;
lbx_notice.Items.Insert(0, "[x] Module không phản hồi, vui
lòng kiểm tra lại dây kết nối!"); byte tmp =
(byte)(byte.Parse(now_com.Substring(now_com.Length - 1)) + 1); if (tmp > 5) tmp = 1;
lbx_notice.Items.Insert(0, "[!] Đang tự kiểm tra kết nối qua
cổng COM" + tmp.ToString());
now_com = "COM" + tmp.ToString(); timer_test_com.Enabled = true; } }
3.8.4.4 Module Đăng nhập hệ thống
a. Chức năng
Sau khi kiểm tra các kết nối thành công, công đoạn tiếp theo bắt người dùng đăng nhập hệ thống. Nhưng trước khi đăng nhập cần cần lấy danh sách các nhân viên trong hệ thống. Việc lấy sẵn danh sách nhằm dễ dàng kiểm tra đăng nhập và để đưa danh sách tên nhân viên vào danh sách chọn đăng nhập.
Dữ liệu vào: mã số thẻ được quét, tên nhân viên được chọn. Dữ liệu ra: đăng nhập thành công hay thất bại.
Từ dữ liệu ra mà chương trình cho phép sử dụng phần mềm hoặc vẫn bắt người dùng đăng nhập.
b. Lưu đồ chi tiết
Hình 3.39 Lưu đồ chi tiết module đăng nhập
c. Đoạn code chính yếu
privatevoid get_user_list() { string sql_cmd; SqlCommand cmd;
SqlDataReader sqlReader;
sql_cmd = "SELECT * FROM tbuser ORDER BY id"; cmd = newSqlCommand(sql_cmd, sqlcon);
//if (open_sql_con() == false) check_module_connection();
close_sql_con(); open_sql_con();
sqlReader = cmd.ExecuteReader(); byte i = 0;
while (sqlReader.Read())
{ user_list[i, 0] = sqlReader["full_name"].ToString(); user_list[i, 1] = sqlReader["user_id"].ToString(); user_list[i, 2] = sqlReader["card_id"].ToString(); user_list[i, 3] = sqlReader["user_type"].ToString(); i++; }
//if (close_sql_con() == false) check_module_connection();
cbx_user_list_1.Items.Clear(); cbx_user_list_2.Items.Clear(); for (byte j = 0; j < i; j++)
{ cbx_user_list_1.Items.Add(newKeyValueData(user_list[j, 0], user_list[j, 1], user_list[j, 2],user_list[j,3]));
cbx_user_list_2.Items.Add(newKeyValueData(user_list[j, 0], user_list[j, 1], user_list[j, 2], user_list[j, 3])); }
cbx_user_list_1.SelectedIndex = 0; cbx_user_list_2.SelectedIndex = 0; } if (device_id == 0) { KeyValueData k; k = (KeyValueData)cbx_user_list_1.SelectedItem; if (txt_user_card_id_1.Text == k.CardId ) { txt_user_card_id_1.Text = ""; pn_login_1.Visible = false;
btn_function[0] = 3; btn_function[1] = 0; arr_user_id[0,0] = k.CardId; arr_user_id[0, 1] = k.UserType; arr_user_id[0, 2] = k.Text; lbl_full_name_1.Text = cbx_user_list_1.Text; if (k.UserType == "0") admin_tool(true); } reset_camera(0); btn_pop(0); } if (device_id == 1) { KeyValueData k; k = (KeyValueData)cbx_user_list_2.SelectedItem; if (txt_user_card_id_2.Text == k.CardId) { txt_user_card_id_2.Text = ""; pn_login_2.Visible = false; btn_function[2] = 3; btn_function[3] = 0; arr_user_id[1,0] = k.CardId; arr_user_id[1, 1] = k.UserType; arr_user_id[1, 2] = k.Text; lbl_full_name_2.Text = cbx_user_list_2.Text; if (k.UserType == "0") admin_tool(true); }
3.8.4.5 Module Đăng ký thẻ
a. Chức năng
Chức năng của module này là đăng ký thẻ giữ xe với hệ thống. Mục đích của việc đăng ký thẻ là nhằm kiểm soát thẻ giữ xe. Chỉ những thẻ giữ xe đã được đăng ký với hệ thống thì mới có thể sử dụng được. Còn những thẻ khác nếu không đăng ký thì
Module này chỉ được gọi khi phần mềm đang ở công đoạn thêm thẻ mới, khi đó mã số thẻ đọc được từ đầu đọc sẽ được gửi tới để đăng ký thẻ. Những thẻ đã được sử dụng thì không được đăng ký lại. Những thẻ đã dùng làm thẻ nhân viên thì cũng không thể đăng ký được.
b. Lưu đồ chi tiết
c. Đoạn code chính yếu
if (checkBox1.Checked)
{ for (byte i = 0; i < 10; i++) {
if ((my_data_receive.site_code.ToString() + my_data_receive.card_id.ToString()) == user_list[i, 2]) { card_not_free = true;
break; } }
if (check_exist_card(my_data_receive.site_code, my_data_receive.card_id) == true) card_not_free = true; if (card_not_free == false)
{ add_card(my_data_receive.site_code, my_data_receive.card_id, now());
load_list_card();
lbx_notice.Items.Insert(0, "[!] Thêm thành công thẻ:
"+my_data_receive.site_code.ToString()+my_data_receive.card_id.ToStr
ing()); }
else {
MessageBox.Show("Không thể dùng thẻ này, vì nó đã
3.8.4.6 Module Thực thi lệnh nút ấn
a. Chức năng
Module này có chức năng là thực hiện những lệnh tương ứng với các nút ấn. Do mỗi thời điểm khác nhau thì nhiệm vụ của các nút ấn trên board điều khiển là khác nên việc xác định nhiệm vụ của từng nút là rất quan trọng.
Mặc khác ở board điều khiển có đến hai cặp nút ấn, nên cần phải kết hợp thêm xác định nút ấn ấy thuộc làn xe nào để thực thi lệnh phần mềm cho làn xe tương ứng ấy.
Tín hiệu vào: làn xe cần thực thi lệnh, nút ấn cần thực thi lệnh, mã lệnh của nút ấn ấy.
c. Đoạn code chính yếu
privatevoid btn_control(byte btn_id) { byte device_id = 0; switch (btn_id) { case 0: device_id = 0; break; case 1: device_id = 0; break; case 2: device_id = 1; break; case 3: device_id = 1; break; } switch (btn_function[btn_id]) { case 0: switch_direction(device_id); break; case 1: undo_function(device_id); break; case 2: break; case 3: accept_card_not_enter(device_id);
break; case 4: close_msg(device_id); break; case 5: accept_card_not_leave(device_id); break; case 6: break; case 7: if (device_id == 0) { if (cbx_user_list_1.SelectedIndex == cbx_user_list_1.Items.Count - 1) { cbx_user_list_1.SelectedIndex = 0; } else { cbx_user_list_1.SelectedIndex = cbx_user_list_1.SelectedIndex + 1; } } if (device_id == 1) { if (cbx_user_list_2.SelectedIndex == cbx_user_list_2.Items.Count - 1) { cbx_user_list_2.SelectedIndex = 0; } else { cbx_user_list_2.SelectedIndex = cbx_user_list_2.SelectedIndex + 1; } } break;
case 8: //dang nhap
log_in();
reset_camera(1); btn_pop(1); } refresh_text();
case 9: break; case 10:
accept_logout(device_id); break; }}
3.8.4.7 Module Gửi xe
a. Chức năng
Đây là module thực hiện các lệnh liên quan đến thủ tục gửi một chiếc xe vào bãi giữ xe. Các thủ tục gửi xe bao gồm:
Lấy mã số thẻ
Kiểm tra mã số thẻ
Kiểm tra xem thẻ đã trả xe chưa
Lấy thông tin của phiên làm việc đó gồm: tên máy tính, tên thiết bị (làn xe), thời gian hiện tại, nhân viên trực…
Chụp hình biển kiểm soát và chủ phương tiện
Lưu hình ảnh vào ổ cứng ở máy chủ
Lưu thông tin chi tiết về mã thẻ và thông số hình ảnh… vào cơ sở dữ liệu
Dữ liệu vào: Mã số thẻ, mã máy tính, mã thiết bị (làn xe), thời gian gửi xe, tên nhân viên đang trực ca.
b. Lưu đồ chi tiết
c. Đoạn code chính yếu
publicvoid enter_func(string pcid, byte device_id, int site_code, int
card_id, string enter_time, string user_id) { int idx;
string sql_cmd; SqlCommand cmd;
idx = id_card_null_leave_time(site_code, card_id);
int card_error_id = get_error_card_id(site_code, card_id);
if (idx != -1 && wait_msg_card_not_leave[device_id] == false ) { btn_push(device_id); wait_msg_card_not_leave[device_id] = true; card_tmp[device_id, 0] = idx.ToString(); card_tmp[device_id, 1] = site_code.ToString(); card_tmp[device_id, 2] = card_id.ToString(); card_tmp[device_id, 3] = now();
show_msg(device_id, "Thẻ này chưa lấy xe. Xoá dữ liệu cũ của
thẻ này \nvà tiếp tục gửi xe?", 5, 4); refresh_text();
return; }
//if (open_sql_con() == false) check_module_connection();
sql_cmd = "INSERT INTO tbmaster
(pcid,dvid,site_code,card_id,enter_time,leave_time,user_id) VALUES ('"
+ pcid + "','" + device_working[device_id] + "'," + site_code + "," + card_id + ",'" + enter_time + "','0','"+user_id+"')";
cmd = newSqlCommand(sql_cmd, sqlcon); close_sql_con();
open_sql_con();
//if (close_sql_con() == false) check_module_connection();
set_label_info(device_id,site_code, card_id, pcid, device_working[device_id], enter_time, "0", user_id); if (device_id == 0)
{ CamSnap(0, 1, id_card_null_leave_time(site_code, card_id)); } else CamSnap(2, 3, id_card_null_leave_time(site_code, card_id)); }}
3.8.4.8 Module Trả xe
a. Chức năng
Đây là module thực hiện các lệnh liên quan đến thủ tục trả xe. Các thủ tục gửi xe bao gồm:
Lấy mã số thẻ từ chủ phương tiện
Kiểm tra mã số thẻ
Kiểm tra xem thẻ đã trả xe chưa
Kiểm tra xem thẻ có gửi xe không
Lấy thông tin từ cơ sở dữ liệu gồm: tên máy tính, tên thiết bị (làn xe), thời gian hiện tại, nhân viên trực…
Chụp hình biển kiểm soát và chủ phương tiện lúc trả xe
Lưu hình ảnh vào ổ cứng ở máy chủ nhằm mục đích kiểm tra sau này
Lấy hình ảnh đã lưu lúc gửi xe và so sánh với hình ảnh đang hiển thị trên camera.
Thị thực và cho xe ra nếu hợp lệ.
Cập nhật thời gian trả xe của thẻ đó vào cơ sở dữ liệu Dữ liệu vào: Mã số thẻ.
Dữ liệu ra: thông tin cơ bản của phiên làm việc lúc gửi xe lấy từ cơ sở dữ liệu, hình ảnh lấy từ ổ cứng.
b. Lưu đồ chi tiết
c. Đoạn code chính yếu
privatevoid leave_func(int site_code, int card_id,string leave_time,byte
device_id) { int idx;
string sql_cmd; SqlCommand cmd; bool leave_time_0 = true;
idx = id_card_null_leave_time(site_code, card_id);
sql_cmd = "UPDATE tbmaster SET leave_time='" + leave_time + "', user_id2 ='"+arr_user_id[device_id,2]+"' WHERE id=" + idx; if (idx == -1) { leave_time_0 = false; btn_push(device_id); wait_msg_card_not_enter[device_id] = true; card_tmp[device_id, 0] = idx.ToString(); card_tmp[device_id, 1] = site_code.ToString(); card_tmp[device_id, 2] = card_id.ToString(); card_tmp[device_id, 3] = now();
show_msg(device_id, "Thẻ này đã lấy xe. Vui lòng kiểm tra
lại", 4, 3);
idx = id_card_last_leave(site_code, card_id);
lbx_notice.Items.Insert(0,"[!] "+ idx.ToString() +" - Thẻ đã lấy
xe");
refresh_text(); }
cmd = newSqlCommand(sql_cmd, sqlcon); close_sql_con();
open_sql_con();
set_label_info(idx,device_id); if (device_id == 0)
{ try { picPic11.Image = Image.FromFile(img_dir + idx.ToString() + "1.jpeg"); }
catch { lbox_client.Items.Insert(0, "[x] Không tìm thấy file ảnh 1: " + idx.ToString()); }
try { picPic12.Image = Image.FromFile(img_dir + idx.ToString() + "2.jpeg"); }
catch { lbox_client.Items.Insert(0, "[x] Không tìm thấy file ảnh 2: " + idx.ToString()); }
if (leave_time_0 == true) { if (device_id == 0) { CamSnap2(0, 1, id_card_last_leave(site_code, card_id)); } else {
CamSnap2(2, 3, id_card_last_leave(site_code, card_id)); } } } else {try{
picPic21.Image = Image.FromFile(img_dir + idx.ToString() + "1.jpeg"); }
catch
{ lbox_client.Items.Insert(0, "[x] Không tìm thấy file ảnh 3: " + idx.ToString()); }
try { picPic22.Image = Image.FromFile(img_dir + idx.ToString() + "2.jpeg"); }
catch { lbox_client.Items.Insert(0, "[x] Không tìm thấy file ảnh
4: " + idx.ToString()); } } }
3.8.4.9 Nhận xét
Cơ sở dữ liệu được tạo lập đáp ứng tốt với các yêu cầu lưu trữ dữ liệu của phần mềm. Việc chọn hệ cơ sở dữ liệu SQL cũng phù hợp với ngôn ngữ lập trình và với phần mềm lập trình Visual Studio.
Ưu điểm: truy cập nhanh, dễ quản lý, ngôn ngữ C# kết nối dễ dàng và đơn giản với cơ sở dữ liệu.
Nhược điểm: tính toán và thiết kế dữ liệu còn lãng phí bộ nhớ, một số trường có kiểu dữ liệu lớn hơn nhiều những dữ liệu mà nó có thể có, không tạo ràng buộc cứng giữa các bảng dữ liệu với nhau.
b. Lập trình phần mềm
Nhìn chung phần mềm đã hoạt động theo ý tưởng ban đầu, đáp ứng thể hiện được những thông tin cần thiết cho người sử dụng.
Ưu điểm: Thiết kế đơn giản, dễ thao tác, giao diện trực quan, đáp ứng đủ các thông tin hiển thị cần thiết cho người sử dụng. Cài đặt dễ dàng và tương thích với nhiều hệ điều hành Windows.
Nhược điểm: do đây là phiên bản đầu nên đôi khi chưa trãi qua hết các tình huống có trong thực tế. Điều này dẫn đến khả năng phần mềm hoạt động không như ý muốn.
CHƯƠNG 4: KẾT QUẢ THỰC HIỆN 4.1 KẾT QUẢ ĐẠT ĐƯỢC
4.1.1 Mô hình
Hoàn thiện được toàn bộ mô hình của hệ thống gồm:
Một máy tính (PC) Một làn xe
Board điều khiển 2 camera
Mô hình xe
4.1.2 Phần cứng
Thiết kế hoàn thiện mạch điều khiển, kết nối được giữa các module với nhau.
Hình 4.17 Bên trong board điều khiển
4.1.3 Phần mềm trên PC
Thiết kế, lập trình hoàn thiện phần mềm quản lý trên máy tính và nó có khả năng:
Bảo mật được tài dữ liệu lưu trên máy tính trong qua trình hoạt động.
Quản lý và đăng ký cho thẻ RFID dễ dàng đơn giản.
4.2 KẾT LUẬN VÀ KIẾN NGHỊ
4.2.1 Kết luận
a. Ưu điểm
Qua Kết quả thực tế ta thấy “hệ thống giữ xe sử dụng thẻ chip” , cách sử dụng đơn giản, chính xác với yêu cầu thiết kế ban đầu như :
Giao diện đơn giản, giúp người quản lý dễ dàng sử dụng.
Tính linh hoạt và tính bảo mật của hệ thống rất cao.
Sửa lổi dể dạng khi có sự cố xảy ra như chương trình bị lổi….
Dể dàng theo dỏi hoạt động của hệ thống.
b. Khuyết điểm
Do đây là một đề tài còn mới nên khi thực hiện đề tài này nguồn tài liệu bị hạn chế. Mặt khác thời gian và kiến thức còn bị hạn chế nhiều vì vậy còn nhiều vấn đề chưa được giải quyết triệt để như:
Phần lập trình cho vi điều khiển và giao diện máy tính chưa được tốt, tuy thời gian đầu hoạt động đáp ứng được nhu cầu đặc ra nhưng về sau có thể bị một số lỗi.
Kiến thức về thiết kế sản phẩm còn kém vì vậy sản phẩm tạo ra chưa được đẹp.
4.2.2 Kiến nghị.
Để hệ thống hoạt động tốt hơn thì ta nên dùng các loại camera chuyên dụng cho việc quan sát hình ảnh vì như vậy ta sẽ thu được chất lượng ảnh tốt hơn.
Thiết kế cơ khí phải bảo đảm được các sự cố như chống va đập, thắm nước… Phần mềm cần phải cải tiến hơn để có thể quản lý nguôn dữ liệu một cách logic, nơi lưu lại hình ảnh thì cần cải tiến lại nên lưu hình ảnh trực tiếp lên board điều khiển, ta sẽ không phụ thuộc vào CPU máy tính nhiều.
4.3 HƯỚNG DẪN SỬ DỤNG
4.3.1 Cách thiết lập hệ thống
Hình 4.18 Cách kết nối hệ thống
Camera 1, 2, 3, 4: kết nối với máy tính bằng cổng USB hay kết nối bằng card ghi hình nếu sử dụng camera chuyên dụng.
Board điều khiển: Kết nối với máy tính bằng cổng USB qua dây chuyển đổi RS232 sang USB. Boar d đi ều khiể n Camera 3 Camera 4 Camera 2 Camera 1
4.3.2 Cách sử dụng trên board phần cứng
Hình 4.19 Mô hình thực tế
a. Kiểm tra hệ thống.
Trước tiên ta cấp nguồn cho hệ thống và kiểm tra như sau: