Luận văn Nghiên cứu hệ thống biểu quyết điện tử số

Bản luận văn đi sâu nghiên cứu hệ thống biểu quyết điện tử số DCN với nguyên lý hoạt động, định tuyến âm thanh, thông số truyền thông, giao thức truyền giữa bộ điều khiển trung tâm CCU với các thiết bị điều khiển từ xa. Luận văn nêu tổng quan hệ thống biểu quyết số và nêu bật được các đặc tính truy cập hệ thống, các loại biểu quyết điện tử, các bước thực hiện điều khiển microphone, biểu quyết điện tử số và chuẩn ghép nối RS 232C, đi sâu tìm hiểu trình điểu khiển MS Com trong ngôn ngữ Visual Basic 6.

pdf67 trang | Chia sẻ: lylyngoc | Lượt xem: 2376 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Luận văn Nghiên cứu hệ thống biểu quyết điện tử số, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
DCE->DTE Remote Loopback: Tạo ra bởi DCE khi tín hiệu nhận 14 - STxD DTE->DCE Secondary Transmitted Data 16 - SRxD DCE->DTE Secondary Received Data 19 - SRTS DTE->DCE Secondary Request To Send 13 - SCTS DCE->DTE Secondary Clear To Send 12 - SDSRD DCE->DTE Secondary Received Line Signal Detector 25 - TM Test Mode 9 - Dành riêng cho chế độ test 10 - Dành riêng cho chế độ test 11 Không dùng Bảng 1.2: Chức năng các chân của cổng nối tiếp. 25 2.3.1 Truyền thông giữa hai nút Các sơ đồ khi kết nối dùng cổng nối tiếp: Hình 2.5: Kết nối đơn giản trong truyền thông nối tiếp Khi thực hiện kết nối như trên là kết nối không móc nối, quá trình truyền phải bảo đảm tốc độ ở đầu phát và thu giống nhau. Khi có dữ liệu đến DTE, dữ liệu này sẽ được đưa vào bộ đệm và tạo ngắt. Ngoài ra, khi thực hiện kết nối giữa hai DTE theo cách móc nối cứng, ta dùng sơ đồ sau: Hình 2.6: Kết nối trong truyền thông nối tiếp dùng tín hiệu bắt tay Khi DTE1 cần truyền dữ liệu thì cho DTR tích cực tác động lên DSR của DTE2 cho biết sẵn sàng nhận dữ liệu và cho biết đã nhận được sóng mang của MODEM (ảo). Sau đó, DTE1 tích cực chân RTS để tác động đến chân CTS của DTE2 cho biết DTE1 có thể nhận dữ liệu. Khi thực hiện kết nối giữa DTE và DCE, do tốc độ truyền khác nhau nên phải thực hiện điều khiển lưu lượng. Quá trinh điều khiển này có thể thực hiện bằng phần mềm hay phần cứng. Quá trình điều khiển bằng phần mềm thực hiện bằng hai ký tự Xon có giá trị 11h và Xoff có giá tri 13h. Ký tự Xon được DCE gửi đi khi rỗi (có thể nhận dữ liệu). Nếu DCE bận thì sẽ gửi ký tự Xoff. Quá trình điều khiển bằng phần cứng dùng hai chân RTS và CTS. Nếu DTE muốn truyền dữ liệu thì sẽ nâng đường tín hiệu 26 RTS lên mức cao để yêu cầu truyền rồi kiểm tra trạng thái dây CTS cho đến khi CTS ở mức cao, khi CTS ở mức thấp có nghĩa bên thu vẫn bận chưa nhận được dữ liệu.Khi bên thu nhận xong dữ liệu từ bộ đệm của nó thì RTS nối với CTS của bên phát sẽ nhảy lên mức cao. Quá trình nhận dữ liệu cũng giống như quá trình truyền. Khi DCE muốn phát tới DTE , DSR bên thu sẽ trở nên tích cực. Nếu bên thu không thể nhận dữ liệu thì DSR ở trạng thái không tích cực. 2.3.2 Truy xuất trực tiếp thông qua cổng COM Các cổng nối tiếp trong máy tính được đánh số là COM1, COM2, COM3, COM4 với các địa chỉ như sau: Tên Địa chỉ Ngắt Vị trí chứa địa chỉ COM1 3F8h 4 0000h:0400h COM2 2F8h 3 0000h:0402h COM3 3E8h 4 0000h:0404h COM4 2E8h 3 0000h:0406h Bảng 1.3: Các ngắt cổng COM 27 CHƯƠNG 3 GIAO DIỆN ĐIỂU KHIỂN TỪ XA ĐẾN HỆ THỐNG DCN 3.1 Mô hình hệ thống điều khiển từ xa Sơ đồ ghép nối điều khiển từ xa hệ thống biểu quyết điện tử được trình bày trên hình 3.1 dưới đây. Hình 3.1: Sơ đồ ghép nối với bộ điều khiển từ xa. Bộ điều khiển từ xa hệ thống DCN được kết nối qua đường RS 232 đến bộ điều khiển trung tâm CCU. Để bộ điều khiển từ xa điều khiển được CCU phải thông qua các giao thức truyền dẫn (protocol) simple hoặc (protocol) Full của bộ điều khiển trung tâm CCU. 3.2 Các thông số điều khiển từ xa Thiết bị (PC, bộ điều khiển, …) kết nối với cổng nối tiếp là bộ điều khiển hệ thống thứ hai đến bộ điểu khiển trung tâm CCU. Các thiết bị này được gọi là bộ điều khiển từ xa. Trên hình vẽ máy tính điều khiển DCN kết nối qua kênh ACN hoặc qua cổng COM. Bộ điều khiển từ xa điều khiển các ứng dụng từ xa sử dụng đường nối tiếp của bộ điều khiển trung tâm. Chẳng hạn như: điều khiển từ xa, điều khiển biểu quyết, hiển thị kết quả biểu quyết… Các phần mềm điều khiển từ xa này sử dụng giao thức ghép nối từ xa với bộ điều khiển trung tâm CCU. 3.2.1 Kiểu thông báo định dạng: Truyền thông giữa bộ điều khiển từ xa và bộ điều khiển trung tâm CCU dựa trên bản tin thông báo( Message format). 28 3.2.2 Kiểu định dạng thông báo cơ bản: Type Length Data Khai báo cấu trúc được định nghĩa như sau: typedef struct { BYTEbyType; // Loại thông báo WORDwLength; // Độ dài thông báo BYTEbyData []; // Dữ liệu thông báo. } T_MESSAGE; where: byType Loại thông báo. Các kiểu thông báo truyền thông với bộ điều khiển trung tâm CCU:  MDSC_REMOTEPROCEDURE_REQ  MDSC_REMOTEPROCEDURE_RSP  MDSC_NOTIFY wLength Độ dài thực sự của dữ liệu trong dãy dữ liệu được truyền phát có giới hạn = 5000. byData [] Dãy dữ liệu truyền đi phụ thuộc vào loại thông báo. 3.2.3 Định dạng yêu cầu điều khiển từ xa Định dạng yêu cầu điều khiển từ xa này là một thông báo luôn được truyền tới bộ điều khiển trung tâm. Thông báo MDSC_REMOTEPROCEDURE_REQ này có cấu trúc như sau: typedef struct { WORD wFnId; // khai báo chức năng. REQSTRUC tStructure; // Tham số chức năng } RSMT_REMOTEPROCEDURE_REQ; wFnId khai báo chức năng. tStructure Tham số chức năng. Sau khi yêu cầu chức năng điều khiển từ xa gửi tới bộ điều khiển trung tâm, bộ điều khiển trung tâm luôn luôn gửi lại một đáp ứng dựa trên việc nhận chức năng điều khiển từ xa. Bộ điều khiển từ xa sẽ đợi chắc chắn đáp ứng được trả lời trước khi gửi các chức năng điều khiển từ xa khác đến bộ điều khiển 29 trung tâm CCU. 3.2.4 Định dạng đáp ứng điều khiển từ xa Dựa trên việc nhận chức năng điều khiển từ xa bộ điều khiển trung tâm CCU sẽ xử lý các chức năng yêu cầu và tạo ra một đáp ứng tương ứng với chức năng điều khiển từ xa đó. Cấu trúc đáp ứng trả lời chức năng điều khiển từ xa như sau: typedef struct { Word wFnId; // định nghĩa chức năng. Word wError; // trả mã lỗi Tstructure; } RSMT_REMOTEPROCEDURE_RSP; trong đó: wFnId Khai báo chức năng. wError Trả về mã lỗi của hàm chức năng. Nểu giá trị là khác không thì nội dung của tham số ‘tStructure’ là không hợp lệ. tStructure Cấu trúc chứa thông tin đáp ứng sau khi xử lý chức năng điều khiển từ xa. 3.2.5 Định dạng thông báo cập nhật MDSC_NOTIFY: - Dựa vào trạng thái cập nhật thông tin bộ điều khiển trung tâm CCU sẽ gửi một thông điệp cập nhật đến bộ điểu khiển từ xa. Bộ điều khiển trung tâm chờ trả lời lại của bộ điều khiển từ xa trên cơ sở các thông điệp đó. - Việc cập nhật thông điệp luôn luôn được cập nhật từ bộ điểu khiển từ xa CCU và chỉ gửi đến bộ điều khiển từ xa nếu có đăng ký cho ứng dụng. typedef struct { WORD wFnId; NTFSTRUC tStructure; } RSMT_NOTIFY; wFnId Khai báo thông báo The notification identifier. tStructure Cấu trúc chứa thông tin cập nhật. 30 3.2.6 Định dạng thông số truyền thông DSC_COMMUNICATION_PARAMS Trong thủ tục (protocol) Full có rất nhiều tham số để điều khiển các chức năng của thủ tục. Một số chức năng này có thể thay đổi chức năng điều khiển từ xa với thời gian tốt hơn dựa vào hệ thống sử dụng bộ điều khiển từ xa. - Khi truyền thông tin có thể chuyển từ bộ điều khiển từ xa 1 đến bộ điều khiển từ xa 2 khi này bộ điều khiển thứ 1 từ chối công việc mà không mất mát thông tin liên lạc. Thời gian heart – beat time lớn hơn thời gian chuyển mạch. Để thay đối thông số truyền thông thì sử dụng tham số truyền thông như sau: typedef struct {WORDwFnId; WORDwHeartbeatTime; WORDwNrRetries; WORDwRetryTime; } RSMT_COMMUNICATION_PARAMS; wFnId Đặt thông số truyền thông. Thông số này phải đặt giá trị RSMC_SET_COMMUNICATION_PARAMS cho việc thiết lập thông số truyền thông. wHeartbeatTime Thời gian heartbeat time là số giây được sử dụng có giá trị thay đổi từ 0-1000. Giá trị 0 để gán cho chức năng tắt kiểm tra thời gian heartbeat. wNrRetries Số lượng lần thực hiện lại trước khi gói dữ liệu bị loại bỏ, giá trị thay đổi từ 0-10. Số đếm này là số lần truyền lại dựa vào gói NAK. wRetryTime Thời gian thực hiện lại khi không nhận các đáp ứng trả lời.Giá trị thay đổi từ 1 - 100. 3.3. Thủ tục truyền thông của bộ điều khiển trung tâm: Tất cả các thông báo nêu trên phải được truyền giữa bộ điều khiển trung tâm CCU và bộ điều khiển từ xa. Kỹ thuật truyền dẫn sử dụng các thủ tục phát hiện lỗi đường truyền. Truyền thông nối tiếp trong CCU có 3 loại giao thức truyền: - Giao thức truyền đầu cuối dữ liệu (Terminal protocol ): Giao thức này ít được sử dụng để truyền dữ liệu.Thiết lập này được sử dụng cho đầu cuối dữ liệu ASCII. - Giao thức truyền Camera (camera protocol): Giao thức này được sử dụng truyền thông giữa hệ thống chuyển mạch video đến bộ điều khiển trung tâm CCU. 31 - Giao thức đầy đủ (Full protocol): bao gồm phát hiện lỗi và truyền lại thông tin. kỹ thuật kiểm tra được sử dụng truyền thông là heart beat. - Giao thức đơn giản (Single protocol): Chỉ kiểm tra lỗi đường truyền. - Kiểu gói dữ liệu: Truyền thông cơ bản giữa bộ điều khiển trung tâm với bộ điều khiển từ xa được dựa trên gói cơ bản như sau: Tiêu đề (header) Thông tin (message) Bít kiểm tra chksum 3.3.1 Đặc tính của giao thức truyền thông Full Trong hệ thống biểu quyết điện tử số DCN sử dụng giao thức truyền thông Full cung cấp đầy đủ chức năng giao thức bao gồm truyển lại và kiểm tra truyền thông. Trong hệ thống Multi - CCU thì đòi hỏi số lượng lớn bộ nhớ khi sử dụng giao thức này. Đặc tính của giao thức truyền Full: - Ưu tiên sử dụng phát hiện header bằng việc sử dụng escape handling. - Thủ tục cung cấp thông tin ACK và NACK - Thông tin được gửi bằng một khối. Bộ điều khiển trung tâm kiểm tra nếu mỗi byte nhận được trong 50 ms của byte trước. Nếu không thì gói NACK được gửi đi. - Dựa vào việc nhận gói NACK sau đó thông tin được gửi lại. - Mỗi thông tin bao gồm một số tuần tự. Việc nhận sử dụng dãy tuần tự này để nhận thông tin. - Khi không có gói ACK được nhận trong 2 giây sau khi kết thúc việc truyền dữ liệu thì sẽ truyền lại.Tổng số truyền lại thông tin là 2 lần trước khi truyền gói dữ liệu bị huỷ bỏ. - Kiểm tra kết nối sử dụng heartbeat. Mỗi gói nhận được có giá trị heart beat chính xác. Khi vượt qua thời gian heartbeat thì truyền thông sẽ dừng lại. Tất cả gói dữ liệu bị tạm dừng sẽ bị huỷ bỏ. Trên các ứng dụng sẽ thông báo đến bộ điều khiển từ xa là truyền thông lỗi, thất bại. - Trong trường hợp đặc biệt thay đổi thông số truyền thông được thiết lập thông qua MDSC_COMMUNICATION_PARAMS: sau khi truyền thông tin này hệ thống đợi trả lời. Điều này giảm thông số truyền qua. 1. Định dạng thông tin header: Header có kiểu như sau: Escape Header type Sequence 32 typedef struct { BYTEbyEscape; // có giá trị 0xC8 BYTEbyHeaderType; BYTEbySequence; } RSMT_HEADER; byEscape Escape byte dùng cho nhận dạng phần header. Dạng escape byte kết hợp cùng với loại tiêu đề để định nghĩa ra mục đích của gói dữ liệu. byHeaderType Thông tin loại gói dữ liệu bySequence Thông tin tuần tự khi gói dữ liệu được kích hoạt 2.Định nghĩa kiểu gói dữ liệu: Đặc tính giao thức Full sử dụng nhiều loại header để nhận biết thông tin truyền đi. Sau đây là các loại headertypes: ‘$’ Gói chứa thông tin dữ liệu. ‘@’ Gói thông tin xác nhận ACK. Gói dữ liệu này chỉ chứa header và checksum. ‘#’ Gói không xác nhận trả lời NAK. Gói dữ liệu này chỉ chứa header và checksum không có thông tin trong gói này. Gói này yêu cầu truyền lại dữ liệu xác định với số tuần tự trong header. ‘?’ Gói dữ liệu heartbeat . Khi số tuần tự được truyền qua thì số tiếp theo của gói tiếp được truyền. Gói này được sử dụng để kiểm tra truyền thông. 3.Tính toán kiểm tra lỗi Checksum: Gói dữ liệu kết thúc bằng vùng checksum. Kiểm tra tất cả thông tin bên trong header và dữ liệu. Gói checksum có cấu tạo: correction checksum typedef struct { BYTEbyCorrection; BYTEbyChecksum; 33 } RSMT_CHECKSUM; byCorrection Giá trị chính xác này tính toán bằng giá trị 0xC8. Cũng có thể giá trị này gồm: 0x00 hoặc 0x13. byCheck Tính toán checksum thông qua header, thông tin dữ liệu và giá trị xác định. The Checksum được tính toán theo thứ tự như sau: 1. Đặt byte chính xác bằng giá trị 0x00. 2. Tính tổng tất cả các bytes với tiêu đề, thông tin và kiểm lỗi. 3. Đảo bít của checksum để đưa về module 256. 4. Kiểm tra lại checksum có bằng giá trị (0xC8). Khi bằng: a. Gán giá trị kiểm lỗi bằng 0x13. b. Trừ giá trị cũ bằng giá trị (0x00) và cộng giá trị mới (0x13) rồi tính tổng như bước 2. c. Đưa module 256 vào tính toán checksum và thực hiện đảo ngược bit của checksum. Kết quả không bao giờ bằng giá trị escape. Việc tính toán checksum này gửi đi phụ thuộc vào gói dữ liệu. Việc nhận được thực hiện chỉ ở bước 2 và 3 . 3.3.2 Tham số nhận biết thông tin Để nhận ra thông tin tiêu đề header trong luồng dữ liệu bytes là rất khó, bởi vì dữ liệu có thể là các số tuần tự giống nhau trong header. Vì lý do đó escape byte để phân biệt the header. Escape byte có giá trị 0xC8.Bởi vì dữ liệu được tryền cũng chứa giá trị escape. Điều này thể hiện dữ liệu phải quét chuyển giá trị escape thành các chuỗi escape. Giao thức ‘full’ sử dụng giá trị 0xC8 như là chuỗi escape. Chuỗi escape luôn theo sau các ký tự khác, nó thông tin chính xác các byte. 0xC8 Chuỗi bytes 0xC8 này sử dụng trong dữ liệu nếu dữ liệu chứa 0xC8 trong quá trình chuẩn bị thông tin ‘$’ Định nghĩa header của gói dữ liệu mới. Sau header sẽ là thông tin và checksum. ‘@’ Định nghĩa gói xác nhận thông tin ACK. ‘#’ Gói thông tin xác nhận không trả lời ‘?’ Gói dữ liệu heartbeat. others.... Các giá trị khác báo lỗi và phớt lờ sau khi truyền thông tin NAK. 34 3.3.3 Giao thức truyền thông Giao thức bắt tay kết nối giữa bộ điểu khiển trung tâm CCU và bộ điều khiển từ xa sử dụng giao diện RS - 232. Dữ liệu được kiểm tra lỗi bằng việc nhận checksum và thông tin xác nhận ACK. Giao thức truyền thông “Full” được thể hiện qua sơ đồ trạng thái truyền dẫn như hình vẽ : Hình 3.2: Sơ đồ trạng thái truyền trong thủ tục truyền “ FULL” Giao thức truyền thông full được thực hiện như sau: - Trước khi chấp nhận bất kỳ dữ liệu thông tin nào thì gói dữ liệu heartbeat được nhận trước. Bởi vì heartbeat bao gồm số tiếp theo của gói dữ liệu tiếp theo. Việc nhận chỉ kiểm tra nếu gói dữ liệu nhận được là chuỗi sau khi nhận heartbeat. - Số phân cách được tìm thấy cùng dữ liệu. - Mỗi gói dữ liệu được gửi cùng với checksum, sau mỗi thông tin được gửi, bộ phát đợi thông tin xác nhận ACK hoặc thông tin không xác nhận NACK từ bộ nhận. - Dựa vào việc nhận dữ liệu, checksum được kiểm tra và phản hồi gói dữ liệu ACK hoặc gói NAK gửi lại theo kết quả. - Sau khi gửi dữ liệu thông báo bộ phát sẽ đợi đúng giá trị ACK hoặc NAK. Không có bất kỳ dữ liệu được nhận chính xác trước khi thông báo ACK bị bỏ qua. - Bên gửi truyền lại dữ liệu dựa trên việc nhận NAK hoặc sau thời gian time - out. 35 - Tối đa 2 lần thực hiện lại. - Độ dài tối đa được hạn chế 5000 bytes. - Kiểm tra kết nối cơ khí khi thời gian trễ tối đa giữa 2 bytes là 50ms. 3.3.3.1 Gói dữ liệu không trả lời : Khi checksum lỗi, không chính xác thì NAK sẽ phát yêu cầu truyền lại gói dữ liệu. Để giúp bên gửi dữ liệu, bên nhận gửi gói chuỗi dữ liệu tuần tự. Chuỗi dữ liệu có các giá trị sau: - Số tuần tự nhận biết: Bên nhận đợi gói dữ liệu hoặc thông báo heartbeat. Trong trường hợp này, Bên nhận không có thông báo tạm hoãn, tạm treo ( trên hình vẽ không có thông báo được đánh dấu), vì vậy không có trả lời ACK đã chờ đợi. - Bên gửi dữ liệu: Đáp ứng gói NAK bằng việc yêu cầu phát lại dữ liệu. Khi không có gói dữ liệu bị treo heartbeat phải được truyền lại. 36 3.3.3.2 Giá trị thời gian của kết nối đường truyền Thông số kết nối đường truyền Giá trị Độ trễ tối đa giữa hai consecutive bytes of a message 50 ms Số lượng thông báo độc lập cho các thông báo, Thời gian đợi truyền gói ACK. 1 Số lượng thực hiện lại trước khi huỷ thông báo. Số này bao gồm số truyền lại sau khi nhận gói NAK. 2 Thời gian bắt đầu phát lại thông tin. Thời gian được tính sau byte cuối cùng được phát. 2 sec. Thời gian truyền giữa 2 consecutive heartbeat 5 sec. Thời gian heartbeat time-out. Sau thời gian không nhận bất kỳ gói dữ liệu nào 10 sec. Độ dài gói dữ liệu tối đa 5000 bytes Thời gian thực hiện chức năng điều khiển từ xa < 0,5 sec. Bảng 1.4: Thông số kết nối đường truyền 37 CHƯƠNG 4 XÂY DỰNG PHẦN MỀM BIỂU QUYẾT 4.1 Chức năng đăng ký đại biểu Để truy cập được hệ thống biểu quyết điện tử số DCN, đại biểu được gắn các quyền đăng nhập hệ thống như sau: - Đăng ký tham dự. - Kiểm tra quyền truy cập hệ thống. - Nhận biết đại biểu. Các chức năng này dùng để phân quyền truy cập cho đại biểu: - Dự thính. - Có quyền phát biểu với tư cách khách mời, không có quyền biểu quyết. - Đầy đủ các chức năng biểu quyết, phát biểu, truy cập hệ thống. 4.1.1 Đăng ký tham dự Đăng ký tham dự là một ứng dụng cho phép điều khiển từ xa để giữ lại những dấu hiệu sự hiện diện của các đại biểu trong hệ thống như thời gian bắt đầu truy cập hệ thống (có mặt) và thời gian thoát khỏi hệ thống (vắng mặt). - Để đăng nhập vào hệ thống biểu quyết điện tử, đại biểu phải tự đăng ký bằng cách sử dụng một trong những lựa chọn sau: - Nhấn nút điểm danh ở vị trí của mình. - Nhập mã nhận dạng PIN ở vị trí của mình. - Cài ID-card vào thiết bị đọc thẻ. - Để thoát khỏi hệ thống, đại biểu rút IC-card khỏi bộ đọc thẻ. 4.1.2 Điều khiển truy cập hệ thống Để truy cập hệ thống biểu quyết điện tử số, Đại biểu phải thực hiện các bước truy cập như sau: - Vào mã PIN tại vị trí đại biểu. - Cắm thẻ đại biểu ID – card vào hộp đại biểu. 4.1.3 Nhận biết đại biểu Chức năng này cung cấp thông tin vị trí ngồi của đại biểu cho hệ thống biểu quyết nhận biết đại biểu thông qua kết qủa của việc nhập ID card vào hoặc rút chúng ra khỏi vị trí đại biểu. 38 Nhận biết đại biểu có 2 khả năng: - Đại biểu ngồi đúng vị trí: Đại biểu phải ngồi đúng vị trí mới có quyền truy cập hệ thống: đăng ký phát biểu, phát biểu, biểu quyết. - Đại biểu ngồi không đúng vị trí: đại biểu không ngồi đúng vị trí không có quyền truy cập hệ thống ngoại trừ hệ thống biểu quyết thiết lập chế độ ngồi tự do. 4.1.4 Kết hợp giữa đăng ký tham dự với truy cập hệ thống Dựa vào có sự kết hợp này mà có thể kiểm soát được chặt chẽ hệ thống biểu quyết: Khi “Mã hiện diện” được lựa chọn để đánh dấu sự có mặt, việc điều khiển đường vào không thể hoạt động. - Khi đại biểu ngồi sai vị trí việc đăng ký tham dự sử dụng Mã hiện diện là không thể. 4.1.5 Thông số chức năng Thông số Ý nghĩa SeatAttend Xác định vị trí nơi đăng ký: vị trí míc, vị trí chỗ ngồi. SeatAccess Cho phép truy cập hay không được truy cập đến thiết bị. ControlType Xác định đại biểu đăng nhập vào hệ thống bằng cách: Ấn phím điểm danh, vào mã PIN, cài thẻ đại biểu ID Card hoặc cài thẻ đại biểu ID và mã PIN. 4.2 Điều khiển microphone trong hệ thống biểu quyết điện tử số 4.2.1 Các bước đăng ký phát biểu Khi đại biểu tham gia vào hội nghị, đại biểu có quyền đăng ký phát biểu, phát biểu thì đại biểu thực hiện các thao tác sau: - Ấn phím đăng ký phát biểu “Mic” tại hộp đại biểu để vào danh sách đăng ký phát biểu. - Hủy bỏ đăng ký phát biểu đại biểu ấn lại phím “Mic” tại hộp đại biểu. - Người quản trị hệ thống sẽ căn cứ vào chủ tọa điều hành mà điều khiển việc bật/ tắt microphone của đại biểu. - Kết thúc phát biểu thì đại biểu ấn nút “Mic”. 39 Lưu đồ điều khiển microphone như sau: 4.2.2 Chương trình kiểm soát danh sách đại biểu Khi phát biểu thảo luận hội nghị, phần quan trọng để điều hành hội nghị phải kiểm soát được danh sách đại biểu đăng ký phát biểu và biết đại biểu nào đang phát biểu. Do đó, ta xây dựng phần mềm hiển thị danh sách đăng ký phát biểu và danh sách phát biểu như sau: Thiết lập trạng thái Bắt đầu Kiểm tra yêu cầu và trạng thái micro Bật / tắt Kiểm tra điều khiển bật/tắt Kết thúc Dừng chương trình Không Có Có 40 Xây dựng giao diện chương trình chính bằng ngôn ngữ Visual Basic 6.0 như trên hình 4.1. Hình 4.1: Giao diện chính phần mềm biểu quyết. + Thiết kế form quản lý danh sách đăng ký và phát biểu như hình 4.2 Hình 4.2: Giao diện Danh sách đăng ký phát biểu. 41 4.3 Biểu quyết điện tử 4.3.1 Các kiểu loại biểu quyết điện tử số -Biểu quyết điện tử số tuỳ vào thực tế sử dụng mà người ta chia làm nhiều kiểu loại khác nhau như sau: -Biểu quyết nghị viện: Đại biểu tham dự biểu quyết với 3 trạng thái biểu quyết: tán thành, không tán thành, bỏ phiếu trống hoặc đại biểu không tham gia biểu quyết. -Biểu quyết For/Againt: Đại biểu chỉ bỏ phiếu với 2 trạng thái: đồng ý hoặc phản đối. -Biểu quyết đáp ứng một số vấn đề: có 5 loại câu hỏi để đại biểu trả lời: rất phản đối, phản đối, bỏ phiếu trống, đồng ý, rất đồng ý. Đại biểu lựa chọn các ý kiến. Hệ thống biểu quyết sẽ tính tỷ lệ để chỉ thị sự đồng ý với các trạng thái. Tại các kỳ họp Quốc hội nước ta sử dụng kiểu biểu quyết nghị viện với 3 trạng thái biểu quyết: Tán thành, không tán thành, không biểu quyết. 4.3.2 Các bước thực hiện biểu quyết điện tử số - Đặt các thông số biểu quyết: thời gian biểu quyết. - Chọn loại biểu quyết: nghị viện công khai. - Khởi tạo biểu quyết. - Hiển thị kết quả biểu quyết ra màn hình. - Kết thúc biểu quyết. 42 Quá trình biểu quyết điện tử số được thực hiện theo lưu đồ sau: Bắt đầu biểu quyết Kiểm tra biểu quyết Kiểm tra thời gian Thuật toán thống kê đưa ra màn hình Kết thúc Hết thời gian Còn thời gian 43 4.3.3 Xây dựng chương trình hiển thị kết quả biểu quyết + Xây dựng form màn hình hiển thị biểu quyết như sau: Hình 4.3: Giao diện hiển thị kết quả biểu quyết 4.4 Điều khiển MSComm trong Visual Basic Visual Basic 6 là ngôn ngữ lập trình hướng đối tượng có nhiều tính năng trong đó có điều khiển ActiveX MSComm dùng truyền thông nối tiếp. Các tính chất của điều khiển này được dùng để thiết lập giao tiếp với các thiết bị ngoại vi qua cổng RS232. Các tính chất của MSComm được sắp xếp theo chức năng: Thiết lập tham số cho cổng: + CommID: trả lại handles đồng nhất tới thiết bị truyền thông, có kiểu Long. Tính chất này không có lúc thiết kế mà chỉ có khi thi hành, thuộc tính này là ReadOnly. + CommPort: dạng object.CommPort = value. Value là chỉ số của cổng Com có giá trị từ 1 ‐> 16 và mặc định có giá trị =1. Thiết lập thông số này trước khi mở cổng. Sẽ có lỗi error 68 (Device unavailable) nếu như không mở được cổng này. + InBuferSize: thiết lập hoặc trả lại kích thước của bộ đệm nhận, tính = byte. Mặc định là 1024 byte. + InputLen: object.InputLen [= value] thiết lập hoặc trả lại số byte mỗi lần thuộc tính Input đọc trong bộ đệm nhận. Mặc định giá trị Value = 0 tức là thuộc tính Input sẽ đọc hết nội dung của bộ đệm nhận khi thuộc tính này được 44 gọi. Nếu số kí tự trong bộ đệm nhận không = InputLen thì thuộc tính Input sẽ trả lại kí tự rỗng. Vì thế, chọn cách kiểm tra InBufferCount để chắc chắn số kí tự yêu cầu đã có đủ trước khi dùng lệnh Input. Tính chất này có ích khi đọc dữ liệu một máy mà dữ liệu ra được định dạng bằng các khối có kích thước cố định. + InputMode: object.InputMode [ = value ]. Value = 0 hay = comInputModeText dữ liệu nhận được dạng văn bản kiểu kí tự theo chuẩn ANSI. Dữ liệu nhận được sẽ là một sâu. Value =1 hay = comInputModeBinary dùng nhận mọi kiểu dữ liệu như kí tự điều khiển nhúng, kí tự NULL,.. Giá trị nhận được từ Input sẽ là một mảng kiểu Byte. + NullDiscard: object.NullDiscard [ = value ] tính chất này quyết định kí tự trống có được truyền từ cổng đến bộ đệm nhận hay không. Nếu value= True kí tự này không được truyền. value = false kí tự trống sẽ được truyền. Kí tự trống được định nghĩa theo chuẩn ASCII là kí tự 0 – chr$(0). + OutBuferSize: giống như InBuferSize, mặc định là 512. + ParityReplace: thiết lập và trả lại kí tự thay thế kí tự không đúng trong lỗi giống nhau. + PortOpen: thiết lập và trả lại tính trạng của cổng (đóng hoặc mở). object.PortOpen [ = value ]. value = true cổng mở. value =false cổng đóng và xóa toàn bộ dữ liệu trong bộ đệm nhận và truyền. Cần phải thiết lập thuộc tính CommPort đúng với tên của cổng trước khi mở cổng giao tiếp. Thêm vào đó, cổng giao tiếp của thiết bị phải hỗ trợ giá trị trong thuộc tính Setting thì thiết bị mới hoạt động đúng, còn không thì chạy không tốt. Đường DTR và RTS luôn giữ lại trạng thái của cổng. + RthresHold: object.Rthreshold [ = value ] value kiểu số nguyên. Thiết lập số kí tự nhận được trước khi gây lên sự kiện comEvReceive. Mặc định = 0 tức là không có sự kiện OnComm khi nhận được dữ liệu. Thiết lập = 1 tức là sự kiện OnComm xảy ra khi bất kì kí tự nào được chuyển đến bộ đệm nhận. + Settings: object.Settings [ = value ] thiết lập hoặc trả lại các thông số truyền: baudrate, bít dữ liệu, bít chẵn lẻ, bít stop. Nếu Value không có giá trị khi mở sẽ gây ra lỗi 380 (Invalidproperty value). + SThreshold: thiết lập và và trả lại số kí tự nhỏ nhất được cho phép trong bộ đệm gửi để xảy ra sự kiện OnComm = comEvSend . Theo mặc định giá trị này = 0 tức là khi truyền sẽ không gây ra sự kiện OnComm. Nếu thiết lập thông số này =1 thì sự kiện OnComm xảy ra khi bộ đệm truyền rỗng. Sự kiện OnComm = comEvSend chỉ xảy ra khi mà số kí tự trong bộ đệm truyền nhỏ hơn hoặc = Sthreshold. Nếu số kí tự trong bộ đệm này luôn lớn hơn Sthreshold thì sự kiện này không thể xảy ra. Truyền nhận dữ liệu: + CommEvent: trả lại phần lớn sự kiện giao tiếp hoặc có lỗi. CommEvent xảy ra khi có lỗi hoặc khi xảy ra sự kiện nào đó. 45 Sau đây là một số hằng số lỗi: Sự kiện Giá trị Miêu tả sự kiện comEventBreak 1001 khi nhận được một tín hiệu Break. comEventFrame 1004 Lỗi hệ thống. Phần cứng phát hiện ra một lỗi hệ thống comEventOverrun 1006 Xảy ra khi cổng tự tràn( Overrun). Kí tự không được đọc từ phần cứng trước khi kí tự tiếp theo tới và do đó kí tự này bị mất. comEventRxOver 1008 Xảy ra khi bộ đệm nhận bị tràn. Không có đủ chỗ cho dữ liệu trong bộ đệm nhận. comEventRxParity 1009 Lỗi Parity. Phần cứng phát hiện ra một lỗi Parity. comEventTxFull 1010 Xảy ra khi bộ đệm truyền bị đầy. Bộ đệm truyền bị đầy trong khi ghi dữ liệu lớn vào bộ đệm comEventDCB 1011 Một lỗi không mong muốn khi đang khôi phục lại khối điều khiển thiết bị( DCB – Device Control Block) cho cổng Bảng 1.5: Sự kiện comevent Một số sự kiện : Sự kiện Giá trị Miêu tả sự kiện comEvSend 1 Xảy ra khi số kí tự trong bộ đệm truyền nhỏ hơn giá trị SthresHold. comEvReceive 2 Xảy ra khi bộ đệm nhận được số kí tự bằng giá trị RthresHold. Sự kiện này được tạo ra liên tục cho tới khi dùng thuộc tính Input để lấy hết dữ liệu từ trong bộ đệm nhận. RcomEvCTS 3 Xảy ra khi có thay đổi trong đường CTS( Clear To Send) comEvDSR 4 Xảy ra khi thay đổi trong đường DSR( Data Set Ready). Sự kiện này chỉ xảy ra khi đường DSR thay đổi từ 1 ‐> 0. 46 comEvCD 5 Xảy ra khi có thay đổi trong đường CD( Carrier Detect) comEvRing 6 Phát hiện chuông (Ring).Một số UART không hỗ trợ sự kiện này. comEvEOF 7 Xảy ra khi nhận được kí tự kết thúc file ( kí tự 26 trong bảng mã ASCII) Bảng 1.6: Bảng các sự kiện EOFEnable : object.EOFEnable [ = value ] quyết định các hành động nếu MSComm tìm thấy kí tự kết thúc file. Nếu value=true khi tìm thấy kí tự kết thúc file thì sẽ gây lên sự kiện comEvEOF trong OnCommEvent. Nếu value= false thì sẽ không gây lên sự kiện này. + InBufferCout: trả lại số kí tự đang có trong bộ đệm nhận, có thể xoá bộ đệm nhận bằng cách đặt thuộc tính này =0. Không nhầm với thuộc tính InBufferSize là tổng kích thước của bộ đệm nhận. + Input: nhận và xoá dữ liệu trong bộ đệm nhận. Nếu InputMode là comInputModeText thì giá trị trả về sẽ là một xâu tức có kiểu String, dữ liệu dạng text trong một biến kiểu Variant. Nếu InputMode = comInputModeBinary thì thuộc tính này sẽ trả lại dữ liệu dạng nhị phân dưới dạng một mảng kiểu byte trong một biến Variant. + OutBufferCount: trả lại số kí tự trong bộ đệm truyền. + Output: ghi dữ liệu vào bộ đệm truyền. có thể truyền kiểu text hoặc kiểu nhị phân. Nếu truyền bằng kiểu text thì cho một biến Variant = kiểu String, nếu truyền kiểu nhị phân thì cho Output= variant = một mảng kiểu Byte. Bắt tay( handshaking): + Break : thiết lập hoặc xoá tín hiệu. object.Break [ = value] value = true hoặc false. Khi set value= true thì thông số Break này sẽ gửi một tín hiệu break. Tín hiệu break trì hoãn việc truyền dữ liệu và đưa đường truyền vào trạng thái break tới khi mà value = false. + CDHolding: quyết định xem sự truyền này đến đâu bằng cách truy vấn đường CD( Carrier Detect). Carrier Detect là tín hiệu gửi từ modem tới máy tính kết nối với nó thông báo rằng nó đang online. Nếu giá trị = true thì nó đường CD đang ở mức cao, nếu = false thì đường dây này đang ở mức thấp. Tính chất này không có trong lúc thiết kế chỉ có trong khi chạy chương trình.Carrier Detect được biết như là Receive Line Signal Detect (RLSD). + CTSHolding: quết định khi nào gửi dữ liệu bằng cách truy vấn trạng thái đường Clear To Send (CTS). Thông thường tín hiệu CTS được gửi từ modem tới máy tính kết nối với nó để báo rằng đang quá trình truyền dữ liệu. Thuộc tính Readonly chỉ xuất hiện khi chạy chương trình. Đường Clear To Send dùng trong RTS/CTS (Request To Send/Clear To Send) bắt tay phần cứng. CTSHolding để tự tay dò đường Clear To Send để biết trạng thái của nó. 47 + DSRHolding: biết trạng thái của đường Data Set Ready (DSR). Tín hiệu Data Set Ready truyền từ modem tới máy tính nối với nó để thông báo rằng modem đã sẵn sàng hoạt động. Tính chất này dùng khi viết Data Set Ready/Data Terminal Ready handshaking routine cho máy Data Terminal Equipment (DTE)‐ máy trang bị đầu cuối dữ liệu. + DTREnable: tính chất này quyết định khi nào cho phép đường Data Terminal Ready (DTR) trong truyền thông. Tín hiệu DTR gửi từ máy tính tới modem để báo rằng máy tính sẵn sàng là nơi nhận dữ liệu. Khi DTREnable = true thì đường Data Terminal Ready set lên cao khi cổng mở, và thấp khi cổng đóng. Nếu DTREnable = false thì đường đó luôn mức thấp. Trong phần lớn trường hợp set đường Data Terminal Ready thành thấp để hang up telephone. + Handshaking: thiết lập và trả lại giao thức bắt tay phần cứng. object.Handshaking [ =value ]. Các giá trị của value: comNone 0 (Mặc định) Không bắt tay comXOnXOff 1 Bắt tay XON/XOFF comRTS 2 Bắt tay RTS/CTS (Request To Send/Clear To Send) comRTSXOnXOff 3 Dùng cả bắt tay Request To Send and XON/XOFF Bảng 1.7: Bảng thiết lập giao thức bắt tay Handshaking chỉ là giao thức truyền thông nội tại quyết định bởi dữ liệu nào được truyền từ cổng phần cứng tới bộ đệm nhận. Khi kí tự của dữ liệu tới cổng nối tiếp, thiết bị truyền thông sẽ chuyển nó vào trong bộ đệm nhận. Nếu không có bộ đệm dữ liệu hoặc cần đọc kí tự trực tiếp từ phần cứng, có thể mất dữ liệu bởi vì kí tự từ phần cứng đến rất nhanh. Giao thức Handshaking đảm bảo dữ liệu không bị mất, khi dữ liệu đến cổng quá nhanh thì thiết bị truyền thông sẽ chuyển dữ liệu vào trong bộ đệm nhận. + RTSEnable: quyết định khi nào cho phép đường Request To Send (RTS), Tín hiệu RTS từ máy tính tới modem để yêu cầu được tryền dữ liệu. Khi RTSEnable = true thì đường RTS mức cao khi cổng mở, tích mức thấp khi cổng đóng. Và hiển nhiên khi RTSEnable thì đường RTS luôn mức thấp.RTS dùng trong RTS/CTS hardware handshaking. RTSEnable cho phép dò đường RTS khi cần biết tình trạng của đường này. 48 + Đoạn chương trình sử dụng MSCom để bắt dữ liệu biểu quyết điện tử số từ cổng( port 1) của CCU: Private Sub MSComm1_OnComm() Dim dem As String Dim ii As Integer Dim CoMat As Integer Dim TanThanh As Integer Dim KhongTanThanh As Integer Dim KhongThamGia As String Dim KhongBieuQuyet As Integer If MSComm1.CommEvent = comEvReceive Then dem = MSComm1.Input ii = Asc(dem) 'Neu doc vao ma ket thuc=27 hoac xuong dong=32 thi bo qua 'Doc ky tu tiep theo If (ii = 27) Then ChuoiThu = "" dem = MSComm1.Input ii = Asc(dem) End If If (ii = 32) Then dem = MSComm1.Input ii = Asc(dem) End If 'Chuoi thu duoc ChuoiThu = ChuoiThu & Chr(ii) End If 'Reset bien If Check = 1 Then Me.LblThoiGian.Caption = "00:00" Me.lblCoMat.Caption = "0" Me.lblTanThanh.Caption = "0" Me.lblKhongTanThanh.Caption = "0" Me.lblKhongBieuQuyet.Caption = "0" Me.lblCoMat_PT.Caption = "0%" Me.lblTanThanh_PT.Caption = "0%" Me.lblKhongTanThanh_PT.Caption = "0%" Me.lblKhongBieuQuyet_PT.Caption = "0%" End If 'Xu ly thoi gian 49 Me.LblThoiGian.Caption = Mid(ChuoiThu, 4, 4) Phut = Mid(Me.LblThoiGian.Caption, 1, 2) Giay = Mid(Me.LblThoiGian.Caption, 3, 2) Me.LblThoiGian.Caption = Phut & ":" & Giay 'Xu ly chuoi thu duoc If Len(ChuoiThu) = 28 Then CoMat = CInt(Trim(Mid(ChuoiThu, 8, 4))) Me.lblCoMat.Caption = CoMat TanThanh = CInt(Trim(Mid(ChuoiThu, 12, 4))) Me.lblTanThanh.Caption = TanThanh KhongTanThanh = CInt(Trim(Mid(ChuoiThu, 16, 4))) Me.lblKhongTanThanh.Caption = KhongTanThanh KhongBieuQuyet = CInt(Trim(Mid(ChuoiThu, 20, 4))) + Trim(Mid(ChuoiThu, 24, 4)) Me.lblKhongBieuQuyet.Caption = KhongBieuQuyet 'Tinh phan tram bieu quyet Me.lblCoMat_PT.Caption = Round(CoMat * 100 / 493, 2) & "%" Me.lblTanThanh_PT.Caption = Round(TanThanh * 100 / 493, 2) & "%" Me.lblKhongTanThanh_PT.Caption = Round(KhongTanThanh * 100 / 493, 2) & "%" Me.lblKhongBieuQuyet_PT.Caption = Round(KhongBieuQuyet * 100 / 493, 2) & "%" End If 50 Sử dụng Access 97 để thiết kế cơ sở dữ liệu như sau: - Cơ sở dữ liệu đại biểu Table/Delegate: Hình 4.4: Cơ sở dữ liệu đại biểu - Cơ sở dữ liệu các tỉnh, thành phố.Table\ GroupID: Hình 4.5: Cơ sở dữ liệu các tỉnh, thành phố 51 4.4 Kết quả ghép nối giữa máy tính với bộ điều khiển trung tâm: Toàn cảnh phiên họp Quốc hội: Hình 4.6: Toàn cảnh phiên họp Quốc hội Toàn cảnh hệ thống biểu quyết điện tử số: 52 Hình 4.7: Hệ thống biểu quyết tại Hội trường Bộ Quốc phòng Màn hình điều khiển hệ thống biểu quyết điện tử số: Hình 4.8: Giao diện điều khiển microphone và biểu quyết 53 Phần mềm biểu quyết điện tử được xây dựng bằng ngôn ngữ Visual Basic 6, cơ sở dữ liệu đại biểu được xây dựng bằng Access 97 với các tính năng chính sau: 1. Tra cứu thông tin Đại biểu Quốc hội: Hình 4.9: Tra cứu thông tin đại biểu 2.Hiển thị Danh sách đăng ký phát biểu: Hình 4.10: Hiển thị danh sách đăng ký phát biểu 54 3. Hiển thị kết quả biểu quyết: Hiển thị kết quả biểu quyết khởi tạo biểu quyết: Hình 4.11: Kết quả bắt đầu biểu quyết Hiển thị kết quả biểu quyết sau khi hết thời gian biểu quyết: Hình 4.12:Kết quả biểu quyết khi hết thời gian biểu quyết 55 KẾT LUẬN Bản luận văn đi sâu nghiên cứu hệ thống biểu quyết điện tử số DCN với nguyên lý hoạt động, định tuyến âm thanh, thông số truyền thông, giao thức truyền giữa bộ điều khiển trung tâm CCU với các thiết bị điều khiển từ xa. Luận văn nêu tổng quan hệ thống biểu quyết số và nêu bật được các đặc tính truy cập hệ thống, các loại biểu quyết điện tử, các bước thực hiện điều khiển microphone, biểu quyết điện tử số và chuẩn ghép nối RS 232C, đi sâu tìm hiểu trình điểu khiển MS Com trong ngôn ngữ Visual Basic 6. Đặc biệt, việc xây dựng phần mềm biểu quyết trong luận văn đã hiển thị được kết quả biểu quyết điện tử của hệ thống biểu quyết điện tử số DCN tại phiên họp của Quốc hội, Danh sách đăng ký đại biểu Quốc hội, truy cập thông tin đại biểu Quốc hội. Việc thực hiện ghép nối giữa máy tính với hệ thống biểu quyết số qua cổng port 1 của bộ điều khiển trung tâm trong hệ thống biểu quyết số tại hội trường Bộ Quốc phòng sử dụng trình điều khiển MS Com của Visual Basic 6. Trong luận văn này xây dựng phần mềm biểu quyết căn bản đã hiển thị được kết quả biểu quyết, danh sách đăng ký phát biểu. Vì vậy, cần hoàn thiện phần mềm biểu quyết thêm các tính năng về cơ sở dữ liệu đại biểu có kèm theo hình ảnh, lưu trữ chi tiết kết quả biểu quyết, tìm kiếm đại biểu theo tỉnh, thành phố, tên đại biểu v.v… làm cho phần mềm hoàn thiện hơn. Trên cơ sở nghiên cứu nguyên lý cơ bản của hệ thống biểu quyết điện tử số, hướng nghiên cứu tiếp của đề tài luận văn là thiết kế mạch biểu quyết ứng dụng thực tế. 56 TÀI LIỆU THAM KHẢO Tiếng Việt 1. Phạm Văn Ất (2008), Hướng dẫn sử dụng Access 2003 - 2007, NXB Giao thông vận tải, Hà Nội. 2. Phạm Thị Ngọc Mai (2005), Microsoft Visual Basic 6.0 & lập trình cơ sở dữ liệu, NXB Lao động - Xã hội, Hà Nội. 3. Trần Quang Vinh (2008), Cấu trúc máy vi tính, NXB Đại học Quốc gia Hà Nội, Hà Nội. Tiếng Anh 4. Bosch Security System (2003), General Remote Interface Description. 5. Bosch Security System (2003), AT Remote Interface Description. 6. Bosch Security System (2003), VT Remote Interface Description. 7. Bosch Security System (2003), MM Remote Interface Description. 8. Philips Comunication, Security & Image (2002), Digital Congress Network DCN Instalation & Operating Manual. 9. Bosch Security System (2003), SC &SI Remote Interface Description. 10. MSDN Library (2001), Visual Tools and Languages/ Visual Studio 6.0 Documentation / Visual Basic Documentation / Reference/ Control Reference / ActiveX Control/ MSComm Control. 57 PHỤ LỤC Khai báo các biến giá trị theo hệ thống biểu quyết số: Sub InitCommandTable() CmdTable(cmdMicroOn) = "$1" CmdTable(cmdMicroOff) = "$2" CmdTable(cmdAllMicroOff) = "$3" CmdTable(cmdPrioMicroOn) = "$4" CmdTable(cmdPrioMicroOff) = "$5" CmdTable(cmdRemainSpeech) = "$6" CmdTable(cmdRequestOn) = "&1" CmdTable(cmdRequestOff) = "&2" CmdTable(cmdAllRequestOff) = "&3" CmdTable(cmdVoteIndYes) = "#1" CmdTable(cmdVoteIndNo) = "#2" CmdTable(cmdVoteIndAbstain) = "#3" CmdTable(cmdVoteIndNoVoted) = "#4" CmdTable(cmdVoteTotal) = "%1" CmdTable(cmdVoteTotalResYes) = "%2" CmdTable(cmdVoteTotalResNo) = "%3" CmdTable(cmdVoteTotalResAbstain) = "%4" CmdTable(cmdVoteTotalResNoVoted) = "%5" CmdTable(cmdCardIn) = "!1" CmdTable(cmdCardOut) = "!2" End Sub Sub GetCommand() Dim CRLF As String Dim tmp As TCmd Dim i As Integer Dim j As Integer Dim s As String Dim n As Integer Dim cmd As String Dim Idx As Integer CRLF = Chr(13) j = InStr(InputBuffer, CRLF) While j > 0 s = Left(InputBuffer, j) InputBuffer = Right(InputBuffer, Len(InputBuffer) - j) n = Len(s) 58 For i = 1 To n - 2 cmd = Mid(s, i, 2) Select Case cmd Case CmdTable(cmdMicroOn) tmp.CmdID = cmdMicroOn tmp.Seat = Val(Mid(s, i + 2, 4)) tmp.Index = ConvertToInt(Mid(s, i + 6, 4)) SendCmdToAllUser tmp Exit For Case CmdTable(cmdMicroOff) tmp.CmdID = cmdMicroOff tmp.Seat = Val(Mid(s, i + 2, 4)) tmp.Index = ConvertToInt(Mid(s, i + 6, 4)) SendCmdToAllUser tmp Exit For Case CmdTable(cmdVoteIndYes) Idx = ConvertToInt(Mid(s, i + 2, 4)) If Idx < MaxDelegate - 1 Then VoteIndTable(Idx) = cmdVoteIndYes End If Exit For Case CmdTable(cmdVoteIndNo) Idx = ConvertToInt(Mid(s, i + 2, 4)) If Idx < MaxDelegate - 1 Then VoteIndTable(Idx) = cmdVoteIndNo End If Exit For Case CmdTable(cmdVoteIndAbstain) Idx = ConvertToInt(Mid(s, i + 2, 4)) If Idx < MaxDelegate - 1 Then VoteIndTable(Idx) = cmdVoteIndNoVoted End If Exit For Case CmdTable(cmdVoteIndNoVoted) Idx = ConvertToInt(Mid(s, i + 2, 4)) If Idx < MaxDelegate - 1 Then VoteIndTable(Idx) = cmdVoteIndNoVoted End If Exit For Case CmdTable(cmdVoteTotal) tmp.CmdID = cmdVoteTotal tmp.Total = Val(Mid(s, i + 2, 4)) SendCmdToAllUser tmp Exit For Case CmdTable(cmdVoteTotalResYes) tmp.CmdID = cmdVoteTotalResYes 59 tmp.Total = Val(Mid(s, i + 2, 4)) SendCmdToAllUser tmp Exit For Case CmdTable(cmdVoteTotalResNo) tmp.CmdID = cmdVoteTotalResNo tmp.Total = Val(Mid(s, i + 2, 4)) SendCmdToAllUser tmp Exit For Case CmdTable(cmdVoteTotalResAbstain) tmp.CmdID = cmdVoteTotalResAbstain tmp.Total = Val(Mid(s, i + 2, 4)) SendCmdToAllUser tmp Exit For Case CmdTable(cmdCardIn) tmp.CmdID = cmdCardIn tmp.Card = Val(Mid(s, i + 2, 4)) tmp.Seat = Val(Mid(s, i + 6, 4)) tmp.Index = ConvertToInt(Mid(s, i + 10, 4)) SendCmdToAllUser tmp Exit For Case CmdTable(cmdCardOut) tmp.CmdID = cmdCardOut tmp.Card = Val(Mid(s, i + 2, 4)) tmp.Seat = Val(Mid(s, i + 6, 4)) tmp.Index = ConvertToInt(Mid(s, i + 10, 4)) SendCmdToAllUser tmp Exit For End Select Next i j = InStr(InputBuffer, CRLF) Wend End Sub Sub SendCmdToAllUser(cmd As TCmd) Dim i As Integer For i = 0 To cUser - 1 SendCmdToUser i, cmd Next i End Sub Sub SendCmdToUser(uid As Integer, cmd As TCmd) Dim n As Integer n = UserCmds(uid).Pointer + UserCmds(uid).Counter If n >= BufferLen Then UserCmds(uid).Buffer(n - BufferLen) = cmd Else UserCmds(uid).Buffer(n) = cmd End If 60 UserCmds(uid).Counter = UserCmds(uid).Counter + 1 If UserCmds(uid).Counter = BufferLen Then UserCmds(uid).Counter = UserCmds(uid).Counter - 1 UserCmds(uid).Pointer = UserCmds(uid).Pointer + 1 If UserCmds(uid).Pointer = BufferLen Then UserCmds(uid).Pointer = 0 End If End If End Sub Sub SendMsgToUser(uid As Integer, Sender As String, Msg As String) Dim n As Integer n = UserMsgs(uid).Pointer + UserMsgs(uid).Counter If n >= MaxMsgNote Then UserMsgs(uid).Sender(n - MaxMsgNote) = Sender UserMsgs(uid).MsgNote(n - MaxMsgNote) = Msg Else UserMsgs(uid).Sender(n) = Sender UserMsgs(uid).MsgNote(n) = Msg End If UserMsgs(uid).Counter = UserMsgs(uid).Counter + 1 If UserMsgs(uid).Counter = MaxMsgNote Then UserMsgs(uid).Counter = UserMsgs(uid).Counter - 1 UserMsgs(uid).Pointer = UserMsgs(uid).Pointer + 1 If UserMsgs(uid).Pointer = MaxMsgNote Then UserMsgs(uid).Pointer = 0 End If End If End Sub Function ConvertToInt(s As String) As Integer Dim ch As String Dim tmp As Integer Dim rate(5) As Integer Dim n As Integer Dim i As Integer Dim x As Integer rate(4) = 1 rate(3) = 16 rate(2) = 16 * 16 rate(1) = 16 * 16 * 16 tmp = 0 s = Trim(s) If s = "????" Then ConvertToInt = 0 Exit Function End If 61 n = Len(s) For i = n To 1 Step -1 x = Asc(Mid(s, i, 1)) - Asc("0") If x >= 0 And x <= 15 Then tmp = tmp + x * rate(i) Else tmp = 0 Exit For End If Next i If tmp > 255 And tmp < 384 Then tmp = tmp - 128 End If If tmp > 511 And tmp < 640 Then tmp = tmp - 256 End If If tmp > 767 Then tmp = tmp - 384 End If ConvertToInt = tmp End Function Function SendCmdToFile(uid As Integer, cmd As TCmd) As Boolean Dim hf As Integer Dim fn As String On Error Resume Next fn = UserCmdFileName(uid) If Trim(fn) = "" Then SendCmdToFile = False Exit Function End If If Dir(fn) = "" Then hf = FreeFile Open fn For Binary As hf 'Len = LenB(cmd) Put hf, , cmd Close hf SendCmdToFile = True Else SendCmdToFile = False End If End Function Function SendMsgToFile(uid As Integer, Sender As String, Msg As String) As Boolean Dim hf As Integer Dim fn As String Dim s As String * 60 62 Dim s1 As String * 255 On Error Resume Next s = Trim(Sender) s1 = Trim(Msg) fn = UserMsgFileName(uid) If Trim(fn) = "" Then SendMsgToFile = False Exit Function End If If Dir(fn) = "" Then hf = FreeFile Open fn For Binary As hf Put hf, , s Put hf, , s1 Close hf SendMsgToFile = True Else SendMsgToFile = False End If End Function Sub InitComm(ComObj As Control, ComPort As Integer, Setting As String) On Error Resume Next ComObj.CommPort = ComPort ComObj.Settings = UCase(Setting) ComObj.InputLen = 0 ComObj.PortOpen = True InputBuffer = "" End Sub Sub ComEvent(ComObj As MSComm) Dim s As String s = ComObj.Input InputBuffer = InputBuffer & s GetCommand 'InputBuffer End Sub Đoạn chương trình hiển thị Danh sách đăng ký phát biểu: Private Sub cmdRegister_Click() Dim tmp As TCmd Dim i As Integer Dim c As Integer If tCardNumber.Text = "" Then Exit Sub If IndexToSeat(Val(tCardNumber.Text)) = 0 Then Exit Sub 63 c = lbRequestOn.ListCount For i = 0 To c - 1 If Val(tCardNumber.Text) = LRequestIndex(i).Index And _ Val(tOrder.Text) > c Then tOrder.Text = c + 1 tCardNumber.Text = "" tCardNumber.SetFocus Exit Sub End If Next i ' Request On tmp.CmdID = cmdRequestOn tmp.cmdIndex = Val(tOrder.Text) - 1 tmp.Index = Val(tCardNumber.Text) tmp.Seat = IndexToSeat(Val(tCardNumber.Text)) SendCmdToAllUser tmp 'lblInfo.Caption = "" tCardNumber.Text = "" tCardNumber.SetFocus End Sub Private Sub Form_Activate() Dim c As Integer c = lbRequestOn.ListCount ' tCardNumber.SetFocus tOrder.Text = Trim(Str(c + 1)) End Sub Private Sub lbMicroOn_GotFocus() If Me.Visible Then lbMicroOn.ListIndex = -1 tCardNumber.SetFocus End If End Sub Private Sub lbrequeston_GotFocus() If Me.Visible Then tCardNumber.SetFocus End If End Sub Private Sub SSFrame2_Click() 64 End Sub Private Sub tCardNumber_Change() Dim dInfo As TDelegate Dim s As String Dim i As Integer If Len(Trim(tCardNumber.Text)) > 3 Or _ Val(tCardNumber.Text) > MaxDelegate Or _ Val(tCardNumber.Text) < 0 Then tCardNumber.Text = "" ' lblInfo.Caption = "" Exit Sub End If For i = 1 To Len(tCardNumber.Text) If Asc(Mid(tCardNumber.Text, i, 1)) < Asc("0") Or _ Asc(Mid(tCardNumber.Text, i, 1)) > Asc("9") Then tCardNumber.Text = "" ' lblInfo.Caption = "" Exit Sub End If Next i If IndexToSeat(Val(tCardNumber.Text)) > 0 Then i = DelegateSearch(Val(tCardNumber.Text)) If i = -1 Then ResetDelegateInfo dInfo Else dInfo = DelegateTable(i) End If s = Padr(Trim(dInfo.DelegateName), 25, " ") + _ Padr(Trim(dInfo.GroupName), 25, " ") + _ "Sè ghÕ : " + Padr(Trim(Str(IndexToSeat(dInfo.CardNumber))), 4, " ") + _ " Micro : " + Trim(Str(STML(IndexToSeat(dInfo.CardNumber)))) 'lblInfo.Caption = s Else ' lblInfo.Caption = "" End If End Sub Private Sub tCardNumber_KeyDown(KeyCode As Integer, Shift As Integer) Dim tmp As TCmd Dim Idx As Integer Dim i As Integer Dim Shiftdown As Integer Dim c As Integer ' Arrow Up was pressed If KeyCode = vbKeyUp And lbRequestOn.ListCount > 0 Then If lbRequestOn.ListIndex = -1 Then lbRequestOn.ListIndex = 0 65 ElseIf lbRequestOn.ListIndex > 0 Then lbRequestOn.ListIndex = lbRequestOn.ListIndex - 1 End If End If ' Arrow Down was pressed If KeyCode = vbKeyDown And lbRequestOn.ListCount > 0 Then If lbRequestOn.ListIndex = -1 Then lbRequestOn.ListIndex = 0 ElseIf lbRequestOn.ListIndex < lbRequestOn.ListCount - 1 Then lbRequestOn.ListIndex = lbRequestOn.ListIndex + 1 End If End If ' Home key was pressed If KeyCode = vbKeyHome And lbRequestOn.ListCount > 0 Then lbRequestOn.ListIndex = 0 End If ' End key was pressed If KeyCode = vbKeyEnd And lbRequestOn.ListCount > 0 Then lbRequestOn.ListIndex = lbRequestOn.ListCount - 1 End If If Trim(tCardNumber.Text) = "" Or _ Val(tCardNumber.Text) > 999 Then tCardNumber.Text = "" Exit Sub End If Shiftdown = (Shift And vbShiftMask) > 0 Idx = Val(tCardNumber.Text) c = frmTMicro.lbRequestOn.ListCount ' Delete key was pressed ' Xoa mot dong trong Danh sach dai bieu DANG KY PHAT BIEU If Not Shiftdown And KeyCode = vbKeyDelete Then If c > 0 Then For i = 0 To lbRequestOn.ListCount - 1 If Idx = LRequestIndex(i).Index Then 'off current request tmp.CmdID = cmdRequestOff tmp.cmdIndex = Idx tmp.Index = Val(tCardNumber.Text) tmp.Seat = IndexToSeat(tmp.Index) SendCmdToAllUser tmp ' lblInfo.Caption = "" tCardNumber.Text = "" 66 tCardNumber.SetFocus End If Next i End If End If ' Shift + Delete key pressed ' Xoa mot dong trong Danh sach dai bieu PHAT BIEU If Shiftdown And KeyCode = vbKeyDelete And _ lbMicroOn.ListCount 0 Then For i = 0 To lbMicroOn.ListCount - 1 If Idx = LMicroIndex(i, 0) Then 'off current micro tmp.CmdID = cmdMicroOff tmp.Index = LMicroIndex(i, 0) tmp.Seat = LMicroIndex(i, 1) SendCmdToAllUser tmp tCardNumber.Text = "" tCardNumber.SetFocus Exit For End If Next i End If ' shift + Insert ket was pressed If Shiftdown And KeyCode = vbKeyInsert Then For i = 0 To lbMicroOn.ListCount - 1 If Idx = LMicroIndex(i, 0) Then tCardNumber.Text = "" Exit Sub End If Next i ' On new micro tmp.CmdID = cmdMicroOn tmp.Seat = IndexToSeat(Idx) tmp.Index = Val(tCardNumber.Text) SendCmdToAllUser tmp tCardNumber.Text = "" tCardNumber.SetFocus End If End Sub Private Sub tOrder_Change() Dim c As Integer Dim i As Integer 67 c = frmTMicro.lbRequestOn.ListCount If Len(tOrder.Text) > 2 Or _ Val(tOrder.Text) > 99 Or _ Val(tOrder.Text) <= 0 Or _ Val(tOrder.Text) > c + 1 Then tOrder.Text = Trim(Str(c + 1)) tOrder.SelStart = 0 tOrder.SelLength = 3 Exit Sub End If For i = 1 To Len(tOrder.Text) If Asc(Mid(Trim(tOrder.Text), i, 1)) < Asc("0") Or _ Asc(Mid(Trim(tOrder.Text), i, 1)) > Asc("9") Then tOrder.Text = Trim(Str(c + 1)) tOrder.SelStart = 0 tOrder.SelLength = 3 Exit Sub End If Next i End Sub Private Sub tOrder_GotFocus() tOrder.SelStart = 0 tOrder.SelLength = 3 End Sub Đoạn chương trình hiển thị thông tin đại biểu: Private Sub Form_Load() Dim s As String For i = 0 To TotalDelegate - 1 s = Padr(DelegateTable(i).DelegateName, 25, " ") + _ Padr(DelegateTable(i).GroupName, 25, " ") + _ Padr(Str(DelegateTable(i).CardNumber), 4, " ") lDelegate.AddItem s Next i End Sub

Các file đính kèm theo tài liệu này:

  • pdfLUẬN VĂN-NGHIÊN CỨU HỆ THỐNG BIỂU QUYẾT ĐIỆN TỬ SỐ.pdf
Luận văn liên quan