Download as pdf or txt
Download as pdf or txt
You are on page 1of 61

Chương 6 Một số bài toán ứng dụng với Visual Studio

CHƯƠNG 6

MỘT SỐ BÀI TOÁN ỨNG DỤNG VỚI VISUAL STUDIO


6.1. Xây dựng giao diện trong Visual Studio:
I. Sử dụ ng Microsoft Visual Studio

1. Khởi động
 Bước 1: Khởi động Visual Studio 2008
Start | All Programs | Microsoft Visual Studio 2008 | Microsoft Visual Studio 2008
 Bước 2: Vào menu File | New | Project
 Bước 3: Khai báo

Trang 69
Chương 6 Một số bài toán ứng dụng với Visual Studio

 Mở hộp ToolBox: Menu View | ToolBox  chứa các control


 Mở cửa sổ Properties: Menu View | Properties  chứa thuộc tính
 Mở cửa sổ Solution Explorer: Menu View | Solution Explorer  cửa sổ Project
xuất hiện.
 Bước 4: Thiết kế Form – Viết code
 Thiết kế form: Nhắp vào View Designer (trong cửa số Solution Explorer)
 Viết code: Nhắp vào View Code (trong cửa số Solution Explorer)
 Bước 5: Để chạy chương trình, nhấn F5 hoặc nhắp vào nút
Để dừng chương trình, nhấn Shift + F5 hoặc nhắp vào nút
* Các thao tác với Project / Solution
a. Tạo Project
C1. Vào menu File | New | Project
C2. Ctrl + Shift + N
C3. Chọn công cụ New Project trên thanh Standart
b. Mở Project / Solution:
C1. Vào menu File | Open | Project / Solution
C2. Ctrl + Shift + O
c. Lưu Project / Solution
C1. Vào menu File | Save All
C2. Chọn công cụ Save All trên thanh Standart
d. Đóng Solution: Vào menu File | Close Solution

2. Màn hình giao diện của Windows Forms


a. Cửa sổ thiết kế Form (Designer):

b. Cửa sổ thiết viết code:

Trang 70
Chương 6 Một số bài toán ứng dụng với Visual Studio

* Các thao tác với Form


a. Thêm một Form mới vào Project:
b1.C1. Vào menu Project | Add New Item …
C2. Chọn công cụ Add New Item trên thanh Standart
b2. Khai báo
+ Categories: chọn Windows Forms
+ Templates: chọn Windows Form
+ Name: đặt tên Form
b3. Nhắp Add
b. Thêm một Form có sẵn vào Project:
b1. Vào menu Project | Add Existing Item …
b2. Chọn Form
b3. Nhắp Add
c. Xóa bỏ một Form đang có trong Project:
b1. Chọn Form cần gỡ bỏ (ở cửa sổ Solution Explorer)
b2. Vào menu Edit | Delete
d. Lưu Form
- Vào menu File | Save Form.cs
- Ctrl + S
* Ghi chú
-
Thuộc tính Mô tả
Anchor Có 4 hướng được định nghĩa là: top, bottom, left, right để cố định (neo).
Khi control chứa nó thay đổi kích thước thì nó sẽ bị thay đổi kích thước
nếu nếu các hướng left / right / top / bottom bị cố định (neo).

BackColor Màu nền của control.


Bottom Là khoảng cách theo chiều dọc từ cạnh đáy của control đến cạnh trên
của control chứa nó.

Dock Giống như Anchor nhưng việc cố định (neo) này theo một cạnh nào đó
của control (hoặc cả 4 cạnh) với control chứa nó.

Enabled Control được phép tương tác (True) hay không được phép tương tác
(False)) với người dùng.

Ta đem “bỏ vào” form các đối tượng như: Label, TextBox, Button, …
+ Label, TextBox, Button, … được gọi là control hay còn gọi là component.
+ Form được gọi là control “chứa”.
- Khi thay đổi nội dung của Label, TextBox, Button, … ta thay đổi vào Text. Text được
gọi là Property của control.

3. Control là gì?
- Control là lớp (class) các thành phần được thêm vào Windows Forms để tương tác giữa
người sử dụng với Windows.
- Có rất nhiều loại control trong Windows Forms như: Label, TextBox, ListBox,
ComboBox, Button, …
- Các control sử dụng trên Windows Forms dùng namespace System.Windows.Forms.

4. Properties (thuộc tính) của control

Trang 71
Chương 6 Một số bài toán ứng dụng với Visual Studio

- Properties là những thông tin mà ta có thể thay đổi nội dung, cách trình bày … của
người thiết kế để ứng dụng vào control.
- Mỗi lớp (class) có nhiều property khác nhau. Tuy nhiên, vẫn có một số property giống
Bảng trình bày các thuộc tính (Properties) giống nhau

ForeColor Màu chữ của control.


Height Là chiều cao của control tính từ cạnh trên của control đến cạnh dưới của
control.
Left Là khoảng cách theo chiều ngang từ cạnh trái của control đến cạnh trái
của control chứa nó.
Name Tên của control.
Parent Chỉ đến control chứa control hiện hành.
Right Là khoảng cách theo chiều ngang từ cạnh phải của control đến cạnh trái
của control chứa nó.
TabIndex Thứ tự focus khi nhấn phím Tab (trên bàn phím) của control so với các
control khác cùng nằm trong control chứa nó.
TabStop Chỉ định control có được phép “bắt” (True) / không được phép “bắt”
(False) phím Tab. Nếu không được phép thì TabIndex cũng không dùng
được.

Tag Là nhãn phân biệt giữa các control giống nhau trong cùng form.
Text Nội dung hiện trong control.
Top Là khoàng cách theo chiều dọc từ cạnh trên của control đến cạnh trên
của control chứa nó.
Visible Cho phép control hiện (True) / không hiện (False) khi chạy ứng dụng.
Width Là chiều rộng của control tính từ cạnh trái của control đến cạnh phải của
control.

Trang 72
Chương 6 Một số bài toán ứng dụng với Visual Studio

Bảng trình bày các phương thức (Method) xử lý trên chuỗi

Thuộc tính Mô tả
AutoSize Điều chỉnh kích thước đối tượng cho vừa với chiều dài chuỗi ký tự
Font
Name Quy định font chữ cho văn bản
Bold True: đậm / False: bỏ đậm
Italic True: nghiêng / False: bỏ nghiêng
Size Quy định cỡ chữ cho văn bản
Underline True: gạch dưới / False: bỏ gạch dưới
TextAlign Canh lề (Left / Center / Right)
Thuộc tính Mô tả
AutoSize Điều chỉnh kích thước đối tượng cho vừa với chiều dài chuỗi ký tự
Font
Name Quy định font chữ cho văn bản
Bold True: đậm / False: bỏ đậm
Italic True: nghiêng / False: bỏ nghiêng
Size Quy định cỡ chữ cho văn bản
Underline True: gạch dưới / False: bỏ gạch dưới
TextAlign Canh lề (Left / Center / Right)

II. Các control cơ bản

1. Label
a. Công dụng:
- Hiển thị chuỗi ký tự không thay đổi trên form (nhãn).

Phương thức Mô tả
Clear() Xóa nội dung
ResetText() Xóa nội dung Text
Trim() Cắt bỏ khoảng trắng thừa hai bên chuỗi
b. Tạo Label:
- Chọn công cụ

- Rê chuột và vẽ Label trên form.

c.Thuộc tính

2. TextBox

Trang 73
Chương 6 Một số bài toán ứng dụng với Visual Studio

a. Công dụng:-
Dùng trình bày văn bản và cho phép người dùng được thay đổi nội dung văn bản.
- Công dụng chính là cho người dùng nhập văn bản.
b. Tạo TextBox:
- Chọn công cụ

- Rê chuột và vẽ TextBox trên form.

c. Thuộc tính:

PasswordChar Quy định ký tự hiển thị cho ô mật khẩu.


Multiline True: hiện thanh cuộn / False: không hiện thanh cuộn
ScrollBars Thanh cuộn (None / Horizontal / Vertical / Both)

3. Button

a. Công dụng:
- Dùng để thực thi lệnh.

- Khi nhắp chuột lên button, chương trình nhận được tín hiệu Click và lệnh được thi hành.

b. Tạo Button:
- Chọn công cụ
- Rê chuột và vẽ Button trên form.

c. Thuộc tính:

Text Nhập nội dung vào Button

4. CheckBox

a. Công dụng:
- Cho phép người dùng chọn hoặc không chọn.
b. Tạo CheckBox:
- Chọn công cụ

- Rê chuột và vẽ CheckBox trên form.


c. Thuộc tính:

Checked Không có dấu check (False) / Có dấu check (True)

Trang 74
Chương 6 Một số bài toán ứng dụng với Visual Studio

Vi Du 3.1 * Khởi tạo một ứng dụng Windows Forms Application, lưu với tên là
như sau:

* Yêu cầu:
- Nhập:
+ Username vào TextBox Tên đăng nhập (Name: txtUser)
+ Password vào TextBox Mật khẩu (Name: txtPass)
Chọn hoặc không chọn ô CheckBox Ghi nhớ (Name: chkNho)
- Nhắp button Đăng nhập thì hiện ra hộp thông báo chứa Tên đăng nhập, Mật khẩu; Và
“Bạn có ghi nhớ” (nếu chkNho có đánh dấu chọn).
- Nhắp button Xóa thì xóa trống TextBox Tên đăng nhập và TextBox Mật khẩu, đồng
thời di chuyển con trỏ vào txtUser.
- Nhắp button Dừng thì dừng chương trình.
* Hướng dẫn:
- Thiết kế Form như yêu cầu, trong đó form có các thuộc tính sau:
+ AutoSize: True
+ Font: Times New Roman
+ Size: 12
+ Text: Form Đăng Nhập
+ Icon: logo.ico
- Nhắp đúp vào button Đăng nhập, thêm đoạn code sau:
string thongbao;
thongbao = "Tên đăng nhập là: " ;
thongbao += this.txtUser.Text ;
thongbao += "\n\rMật khẩu là: " ;
thongbao += this.txtPass.Text;
if (this.chkNho.Checked==true) {
thongbao += "\n\rBạn có ghi nhớ.";
}
MessageBox.Show(thongbao,"Thông báo");
- Nhắp đúp vào button Xóa, thêm đoạn code sau:
this.txtUser.Clear();
this.txtPass.Clear();
this.txtUser.Focus();
- Nhắp đúp vào button Dừng, thêm đoạn code sau:
Application.Exit();
+ Có thể thay button Xóa bằng button Reset với đoạn code như sau:
this.txtUser.ResetText();

Trang 75
Chương 6 Một số bài toán ứng dụng với Visual Studio

this.txtPass.ResetText();
this.txtUser.Focus();
* Phần Bổ sung:
1. MessageBox.Show: hiện hộp thông báo
MessageBox.Show("Thông báo" , "Tiêu đề");
MessageBox.Show("Thông báo", "Tiêu đề", Buttons, Icon);
+ Buttons (nút lệnh):
MessageBoxButtons.OK
MessageBoxButtons.OKCancel
MessageBoxButtons.YesNo
MessageBoxButtons.YesNoCancel
+ Icon (biểu tượng):
MessageBoxIcon.Information
MessageBoxIcon.Question
MessageBoxIcon.Warning
+ DialogResult (kết quả trả về):
DialogResult.Ok
DialogResult.Yes
2. Dừng chương trình:
this.Close();
Application.Exit();
3. Event (sự kiện) là gì?
- Sự kiện là những phản ứng của đối tượng. Nói cách khác, sự kiện là những tín hiệu phát
ra khi người dùng thao tác trên đối tượng.
- Nhờ có event, người lập trình sẽ nhận được những tín hiệu và xử lý những tín hiệu đó để
phản hồi lại cho người dùng, tạo nên sự nhịp nhàng cho chương trình.

Trang 76
Chương 6 Một số bài toán ứng dụng với Visual Studio

Sự kiện Mô tả
Click Gọi đến khi control bị Click. Trong một vài control, event này cũng xảy
ra khi người dùng nhấn phím Enter.
DoubleClick Gọi đến khi control bị Double-Click. Trong một vài control, event này
không báo giờ được gọi. Ví dụ: control Button.
DragDrop Gọi đến khi việc “Drag and Drop” được hoàn tất.
DragEnter Gọi đến khi đối tượng vừa được “Drag” đến biên của control.
DragLeave Gọi đến khi đối tượng vừa được “Drag” ra ngoài biên của control.
DragOver Gọi đến khi đối tượng được “Drag” bên trong control.
KeyDown Gọi đến khi vừa bấm một phím bất kỳ từ 1 control đang focus.
Sự kiện này luôn được gọi trước sự kiện KeyUp.
KeyPress Gọi đến khi vừa bấm một phím bất kỳ từ 1 control được focus.
Sự kiện này được gọi sau sự kiện KeyUp.
KeyUp Gọi đến khi vừa bấm một phím bất kỳ rồi thả ra từ 1 control đang focus.
Sự kiện này luôn được gọi sau sự kiện KeyDown.
GotFocus Gọi đến khi control được focus.
LostFocus Gọi đến khi control bị mất focus.
MouseDown Gọi đến khi con trỏ chuột nằm trên 1 control và nút chuột được nhắp
nhưng chưa thả ra.
MouseMove Gọi đến khi con trỏ chuột đi qua 1 control.
MouseUp Gọi đến khi con trỏ chuột nằm trên 1 control và nút chuột vừa được thả.
Paint Gọi đến khi control được vẽ.
Validated Gọi đến khi control focus, property CaucesValidation được đặt là true
và sau khi gọi việc kiểm tra bằng Validating.
Validating Gọi đến khi control mất focus, property CaucesValidation được đặt là
true.

Ví dụ 3.2:

Cải tiến Vi Du 3.1 cho button Dừng như sau:


- Khi nhắp vào button Dừng thì xuất hiện hộp thoại hỏi đáp có 2 button Ok, Cancel.
- Chương trình chỉ dừng khi nhắp tiếp vào nút Ok.
* Hướng dẫn: Sửa lại button Dừng như sau
DialogResult traloi;
traloi = MessageBox.Show("Chắc không?", "Trả lời",
MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
if ( traloi == DialogResult.OK) Application.Exit();

Trang 77
Chương 6 Một số bài toán ứng dụng với Visual Studio

5. ListBox
a. Công dụng:
- Dùng để hiển thị một danh sách các lựa chọn.
b. Tạo ListBox:
- Chọn công cụ

- Rê chuột và vẽ ListBox trên form.

c. Thuộc tính:

Thuộc tính Mô tả
Items Các mục giá trị trong ListBox
SelectedItemItem được chọn
Phương thứcMô tả
Add("chuỗi")Thêm một mục giá trị là "chuỗi"
ToString() Trả về chuỗi ký tự được chọn
Nhập giá trị vào ListBox: <Ten_ListBox>.Items.Add ("Chuỗi") ;
Lấy giá trị trong ListBox: <Ten_ListBox>.SelectedItem.ToString() ;
Ví dụ 4.1:
* Khởi tạo một ứng dụng Windows Forms Application, lưu với tên là Vi Du 4.1 như sau:

Yêu cầu:
- ListBox lstWeb (Liên kết website) chứa các giá trị:
+ Tuổi trẻ
+ Thanh niên
+ VNExpress
+ Dân trí
+ Công an
- TextBox txtKQ (chứa kết quả) để trống.

Trang 78
Chương 6 Một số bài toán ứng dụng với Visual Studio

- Nhắp button btnOk (Ok) sẽ hiện trong txtKQ tên website được chọn ở lstWeb.
- Nhắp button btnReset (Reset) sẽ xóa trống txtKQ.
* Hướng dẫn:
- Thiết kế Form như yêu cầu, trong đó form có các thuộc tính sau:
+ AutoSize: True
+ Font: Times New Roman
+ Size: 12
+ Text: FormWebLinks
- Nhắp đúp vào button Ok rồi thêm đoạn code sau:
this.txtKQ.Text = "Bạn đã chọn website ";
this.txtKQ.Text += this.lstWeb.SelectedItem.ToString();
- Nhắp đúp vào button Reset rồi thêm đoạn code sau:
this.txtKQ.ResetText();
* Cải tiến: Ta có thể đưa các giá trị của lstWeb trong Form1_Load.
+ Thiết kế lại form như sau

+ Nhắp đúp chuột vào nền form, rồi gõ đoạn code


this.lstWeb.Items.Add("Tuổi trẻ");
this.lstWeb.Items.Add("Thanh niên");
this.lstWeb.Items.Add("VNExpress");
this.lstWeb.Items.Add("Dân trí");
this.lstWeb.Items.Add("Công an");
this.lstWeb.SelectedItem = "Tuổi trẻ";
6. ComboBox
a. Công dụng:
- Dùng để hiển thị một danh sách các lựa chọn / hoặc nhập vào một giá trị.
b. Tạo ComboBox:
- Chọn công cụ

Trang 79
Chương 6 Một số bài toán ứng dụng với Visual Studio

- Rê chuột và vẽ ComboBox trên form.


c. Thuộc tính:

DisplayMember Gán nội dung thể hiện trên ComboBox


Items Liệt kê các mục giá trị trong ComboBox
SelectedItem Lấy Item được chọn
SelectedText Lấy nội dung thể hiện trên ComboBox từ DisplayMember
SelectedValue Lấy giá trị từ ValueMember
ValueMember Gán giá trị cho ComboBox

Ví dụ 4.2:
Khởi tạo một ứng dụng Windows Forms Application, lưu với tên là Vi Du 4.2 như sau:
* Yêu cầu: Thực hiện giống như Ví dụ 4.1, nhưng thay ListBox bằng ComboBoxcbWeb.

7. RadioButton
a. Công dụng:
- Dùng để chọn một trong các lựa chọn trong danh sách.
b. Tạo RadioButton:
- Chọn công cụ

- Rê chuột và vẽ RadioButton trên form.

c. Thuộc tính:

Checked Không có dấu chọn (False) / Có dấu chọn (True)

Trang 80
Chương 6 Một số bài toán ứng dụng với Visual Studio

8.GroupBox

a. Công dụng:
- Tạo ra một nhóm.
b. GroupBox:
- Chọn công cụ

- Rê chuột và vẽ GroupBox trên form.

c. Thuộc tính:

BackgroundImage Hình nền


BackgroundImageLayout None / Tile / Center / Stretch / Zoom

Ví dụ 4.3:
Khởi tạo một ứng dụng Windows Forms Application, lưu với tên là Vi Du 4.3 như sau:

* Yêu cầu:
- Nhập họ và tên vào TextBox txtHoTen
- Chọn kiểu chữ
+ Radio Button (rad1): chữ thường
+ Radio Button (rad2): chữ HOA
-
Nhắp vào Button Kết quả (btnKQ) sẽ in họ và tên bằng kiểu chữ được chọn trong
TextBox txtKQ.
-
Nhắp vào Button Xóa (btnXoa) sẽ xóa trống txtHoTen, txtKQ, rad1 được chọn và đưa

Trang 81
Chương 6 Một số bài toán ứng dụng với Visual Studio

con trỏ vào ô TextBox txtHoTen.


* Hướng dẫn:
- Thiết kế Form như yêu cầu, trong đó form có các thuộc tính sau:
+ AutoSize: True
+ Font: Times New Roman
Size: 12
+ Text: Đổi kiểu chữ
- Nhắp đúp vào nút Kết quả rồi thêm đoạn code sau:
string hoten=this.txtHoTen.Text.Trim();
if (this.rad1.Checked == true)
txtKQ.Text = hoten.ToLower();
if (this.rad2.Checked == true)
txtKQ.Text = hoten.ToUpper();
- Nhắp đúp vào nút Xóa rồi thêm đoạn code sau:
this.txtHoTen.Clear();
this.txtKQ.Clear();
this.rad1.Checked = true;
this.txtHoTen.Focus();
* Bổ sung:
- Nhắp vào Button Dừng (btnDung) sẽ dừng chương trình: thiết kế và viết code sau
Application.Exit();

9. Timer
a. Công dụng:
- Quy định khoảng thời gian định kỳ để thực hiện một công việc.
b. Tạo Timer:
- Chọn công cụ

- Rê chuột và vẽ Timer  là control dạng unvisible (ẩn).


c. Thuộc tính:

Enabled Bật / tắt chế độ hẹn thời gian


Interval Khoảng thời gian định kỳ

Ví dụ 4.4:
Khởi tạo một ứng dụng Windows Forms Application, lưu với tên là Vi Du 4.4 như sau:

Trang 82
Chương 6 Một số bài toán ứng dụng với Visual Studio

Yêu cầu:
- Tạo Timer1 có Enabled = false; Interval = 1000
- Khởi tạo biến đếm i = 20
- Button Bắt đầu (btnBatDau): dùng để bật chế độ hẹn thời gian.
- Button Dừng (btnDung): dùng để dừng chương trình.
- Timer1: Đếm ngược từ 20 đến 1 và xuất ra dòng chữ “Hết giờ”.
+ Xuất giá trị biến đếm i ra Label lblDongHo.
+ Giảm biến i xuống 1 đơn vị.
+ Khi biến đếm i < 0 thì tắt chế độ hẹn giờ và xuất “Hết giờ!” ra Label lblDongHo.
* Hướng dẫn:
- Thiết kế Form như yêu cầu, trong đó form có các thuộc tính sau:
+ AutoSize: True
+ Font: Times New Roman
+ Size: 12
+ Text: Đồng hồ đếm ngược
- Khai báo biến đếm i: qua code, thêm đoạn code để được kết quả như sau:
public Form1()
{
InitializeComponent();
}
int i = 10;
- Nhắp đúp vào nút Bắt đầu rồi thêm đoạn code sau:
this.timer1.Enabled = true;
- Nhắp đúp vào nút Dừng rồi thêm đoạn code sau:
Application.Exit();
- Nhắp đúp vào nút Timer1 (Timer1_Tick) rồi thêm đoạn code sau:
this.lblDongHo.Text = i.ToString();
i--;
if (i < 0)
this.timer1.Enabled = false;
10. RichTextBox
a. Công dụng:
- Dùng để nhập văn bản với định dạng văn bản đa dạng.
b. Tạo RichTextBox:
- Chọn công cụ

- Rê chuột và vẽ RichTextBox trên form.

Trang 83
Chương 6 Một số bài toán ứng dụng với Visual Studio

6.2. Các bài toán:

Bài toán 1: Điều khiển thiết bị điện gồm 2 đèn và 1 quạt giao tiếp máy tính theo giao diện
sau:

Các bước thực hiện:

Mở Visual Studio lên, và tạo một project C# mới:

Trang 84
Chương 6 Một số bài toán ứng dụng với Visual Studio

Chọn Windows Forms Application và đặt tên cho Project.

Trang 85
Chương 6 Một số bài toán ứng dụng với Visual Studio

Sau khi nhấn nút OK, màn hình sẽ xuất hiện giao diện của lập trình Form.

Trang 86
Chương 6 Một số bài toán ứng dụng với Visual Studio

Tiếp đến chúng ta sẽ dùng các Control trong Toolbox (vùng 1) để xây dựng
giao diện

Và đây là kết quả:

Trang 87
Chương 6 Một số bài toán ứng dụng với Visual Studio

Bước kế tiếp chúng ta sẽ điều chỉnh Text hiển thị và các thuộc tính cho các
Control, sử dụng Properties (vùng 5)

+Form:
Click chuột vào khung Form, bảng Properties cho Form sẽ hiện ra:

Trang 88
Chương 6 Một số bài toán ứng dụng với Visual Studio

Trang 89
Chương 6 Một số bài toán ứng dụng với Visual Studio

Trên Properties sẽ xuất hiện những thuộc tính mặc định, ta có thể thay đổi
chúng phù hợp với mong muốn của bản thân.
Để thay đổi các Control khác ta cũng làm tương tự, Click chuột và điều
chỉnh.

Có rất nhiều thuộc tính có thể điều chỉnh như: icon, hình nền, màu chữ, kích
thước, tên hiển thị,…………….Tuy nhiên, đối với 1số Control được sử dụng lại
nhiều lần thì ta nên đổi phần (Name) sao cho vừa nhìn vào là ta biết ngay đó là
Control gì, hoặc với các Control dùng để hiển thị thì ta phải thay đổi một số thuộc
tính nhất định các Control đó mới có thể thay đổi màu sắc như chúng ta mong
muốn.

Ví dụ:

Trang 90
Chương 6 Một số bài toán ứng dụng với Visual Studio

Với overShape, để có thể thay đổi BackColor để phục vụ cho việc hiển thị
thì ta phải đổi thuộc tính BackStyle lại thành Opaque

Phần (Name) của các Control sử dụng trong bài này:


+nút Kết nối/Ngắt: btKetNoi
+comboBox COM: cbCom
+comboBox BaudRate: cbRate
+nút bật đèn 1: btMoDen1
+nút tắt đèn 1: btTatDen1
+overShape h.thị trạng thái đèn 1: txMoDen1
+nút bật đèn 2: btMoDen2
+nút tắt đèn 2: btTatDen2
+overShape h.thị trạng thái đèn 2: txMoDen2
+nút bật quạt: btMoQuat
+nút tắt quạt: btTatQuat
+overShape h.thị trạng thái quạt: txMoQuat
Lưu ý: có phân biệt chữ hoa và chữ thường!!!!!

Trang 91
Chương 6 Một số bài toán ứng dụng với Visual Studio

Cuối cùng ta được một giao diện hoàn chỉnh:

Lập trình code cho giao diện C# vừa tạo:


Để lập trình cho một Control ta click chuột 2 lần vào Control đó, màn hình
sẽ tự động chuyển qua giao diện code và con trỏ chuột sẽ nhấp nháp ngay tại khu
vực lậptrình dành riêng cho Control đã chọn

Giải thích:

Trang 92
Chương 6 Một số bài toán ứng dụng với Visual Studio

+Khi có “sự kiện” btMoDen1 được nhấn (btMoDen1_Click) thì


chương trình con này sẽ được gọi ra sử dụng, và nó sẽ thực hiện lần lượt từng dòng
lệnh nằm trong khu vực của chương trình con đó (giới hạn bởi cặp dấu ”{}” )
+Mỗi chương trình con tương ứng chỉ được gọi khi một “sự kiện”
tương ứng xuất hiện.

Để tránh rối loạn thứ tự của các Control ta nên doubleclick 1 lượt từ trên
xuống dưới theo thứ tự sao cho dễ nhớ, rồi sau đó sẽ viết code sau

Các control như label,groupBox,overShape,statusStrip trong bài này ko


cần gọi chương trình con nên cũng không cần doubleclick tạo sự kiện

Để dùng SerialPort, ta chuyển qua giao diện code, thêm vào dòng khai báo
dùng IO.Port vào phần khai báo thư viện
using System.IO.Ports;// dòng này là khai báo thư viện, để sử dụng SeriaPort

Cài đặt các thông số SerialPort và BaudRate


public partial class Form1 : Form
{
SerialPort P = new SerialPort();// Khai báo 1 Object SerialPort mới
public Form1()
{
InitializeComponent();
// Cài đặt các thông số
// Mảng string port để chứa tất cả các cổng COM đang có trên máy
string[] ports = SerialPort.GetPortNames();// Thêm toàn bộ các COM đã tìm
được vào combox cbCom
cbCom.Items.AddRange(ports);
P.ReadTimeout = 1000;
string[] BaudRate = { "1200", "2400", "4800", "9600", "19200", "38400",
"57600", "115200" };
cbRate.Items.AddRange(BaudRate);
}

Trang 93
Chương 6 Một số bài toán ứng dụng với Visual Studio

Viết code lần lượt cho từng chương trình con

Chương trình con Form_Load này sẽ tự động chạy khi có “sự kiện” Form1
được bắt đầu, nghĩa là khi chạy giao diện thì đoạn code cũng sẽ đồng thời được gọi
ra sử dụng
private void Form1_Load(object sender, EventArgs e)
{
cbCom.SelectedIndex = 0;//giá trị chọn sẵn ban đầu cho combobox cbCom
cbRate.SelectedIndex = 3;//.............................combobox cbRate
btTatDen1.Enabled = false; //
btMoDen1.Enabled = false; //
btTatDen2.Enabled = false; //
btMoDen2.Enabled = false; //các button sẽ bị khóa khi
btTatDen2.Enabled = false; //cổng COM chưa kết nối
btMoQuat.Enabled = false; //
btTatQuat.Enabled = false; //
status.Text = "Chưa kết nối";//...trạng thái lúc đầu của cổng COM
}

Khi comboBox của cổng COM và BaudRate (cbCom và cbRate) thay đổi thì
đoạn code sẽ chạy và gán giá trị mới cho PortName và BaudRate

private void cbCom_SelectedIndexChanged(object sender, EventArgs e)


{
P.PortName = cbCom.SelectedItem.ToString;
}

private void cbRate_SelectedIndexChanged(object sender, EventArgs e)


{
P.BaudRate = Convert.ToInt32(cbRate.Text);
}

Chương trình con của nút “Kết nối/Ngắt”:


Phần này kết hợp 2 nút nhấn trong 1 nút nhấn nên ta sử dụng cấu trúc if…else

private void btKetNoi_Click(object sender, EventArgs e)


{
if (btKetNoi.Text == "Kết nối") //nếu phần Text của nút đang là chữ “Kết nối”
{
try //thử thực hiện các công việc bên dưới

{
P.Open();//mở cổng COM đã chọn
cbCom.Enabled = false; // ẩn 2 combox đi
cbRate.Enabled = false;
btTatDen1.Enabled = true; //hiện các button mở tắt đèn quạt
btMoDen1.Enabled = true;
btTatDen2.Enabled = true;
btMoDen2.Enabled = true;
btTatDen2.Enabled = true;
btMoQuat.Enabled = true;
btTatQuat.Enabled = true;

Trang 94
Chương 6 Một số bài toán ứng dụng với Visual Studio
btKetNoi.Text = "Ngắt"; //đổi phần Text của btKetNoi thành “Ngắt”
status.Text = "Đã kết nối với " + cbCom.SelectedItem.ToString();
//thay đổi phần Text của dòng statusStrip
}
catch (Exception) //nếu có xảy ra lỗi thì thực hiện
//ở đây do phần “thử thực hiện” (try) dòng P.Open(); được viết đầu tiên nên nếu ko mở đc
cổng Com chương tirnh2 sẽ nhảy ngay xuống chỗ này mà ko thực hiện các công việc bên dưới
dòng P.Open();
{
MessageBox.Show("Không kết nối được.", "Thử lại",
MessageBoxButtons.OK, MessageBoxIcon.Error); //xuất hiện bảng thông báo lỗi
}
}
Else //ngược lại, nếu Text của btKetNoi đang là chữ “Ngắt” thì
{
btKetNoi.Text = "Kết nối"; //đổi Text lại thành “Kết nối”
P.Close(); //đóng cổng COM
btMoDen1.Enabled = false; //ẩn các button Bật và Tắt của các thiết bị
btTatDen1.Enabled = false;
btTatDen2.Enabled = false;
btMoDen2.Enabled = false;
btTatDen2.Enabled = false;
btMoQuat.Enabled = false;
btTatQuat.Enabled = false;
cbCom.Enabled = true; //hiện và cho phép thay đổi thông số của 2 comboBox
cbRate.Enabled = true;
status.Text = "Đã ngắt kết nối"; //thay đổi Text của dòng statusStrip
}
}

Giao tiếp thông qua nút nhấn: (ở bài này chỉ truyền dữ liệu 1 chiều từ máy
tính xuống PIC thông qua cổng COM)

private void btMoDen1_Click(object sender, EventArgs e) //khi btMoDen1 được click


{
P.Write("a");//truyền “a” qua cổng COM
txMoDen1.BackColor = System.Drawing.Color.Red; //đổi BackColor của overShape
txMoDen1 thành Red
}

private void btTatDen1_Click(object sender, EventArgs e)//khi btTatDen1 được


click
{
P.Write("d");");//truyền “d” qua cổng COM
txMoDen1.BackColor = System.Drawing.Color.White; //đổi BackColor của
overShape txMoDen1 thành White
}
Các nút còn lại ta làm tương tự, và bên dưới là toàn bộ code của bài này

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;

Trang 95
Chương 6 Một số bài toán ứng dụng với Visual Studio
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace dk2den1quat
{
public partial class Form1 : Form
{
SerialPort P = new SerialPort();

public Form1()
{
InitializeComponent();
string[] ports = SerialPort.GetPortNames();
cbCom.Items.AddRange(ports);
P.ReadTimeout = 1000;
string[] BaudRate = { "1200", "2400", "4800", "9600", "19200", "38400",
"57600", "115200" };
cbRate.Items.AddRange(BaudRate);
}

private void Form1_Load(object sender, EventArgs e)


{
cbCom.SelectedIndex = 0;
cbRate.SelectedIndex = 3;
btTatDen1.Enabled = false;
btMoDen1.Enabled = false;
btTatDen2.Enabled = false;
btMoDen2.Enabled = false;
btTatDen2.Enabled = false;
btMoQuat.Enabled = false;
btTatQuat.Enabled = false;
status.Text = "Chưa kết nối";
}

private void cbCom_SelectedIndexChanged(object sender, EventArgs e)


{
P.PortName = cbCom.SelectedItem.ToString();
}

private void cbRate_SelectedIndexChanged(object sender, EventArgs e)


{
P.BaudRate = Convert.ToInt32(cbRate.Text);
}

private void btKetNoi_Click(object sender, EventArgs e)


{
if (btKetNoi.Text == "Kết nối")
{
try
{
P.Open();
cbCom.Enabled = false;
cbRate.Enabled = false;
btTatDen1.Enabled = true;
btMoDen1.Enabled = true;
btTatDen2.Enabled = true;

Trang 96
Chương 6 Một số bài toán ứng dụng với Visual Studio
btMoDen2.Enabled = true;
btTatDen2.Enabled = true;
btMoQuat.Enabled = true;
btTatQuat.Enabled = true;
btKetNoi.Text = "Ngắt";
status.Text = "Đã kết nối với " + cbCom.SelectedItem.ToString();
}
catch (Exception)
{
MessageBox.Show("Không kết nối được.", "Thử lại",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
btKetNoi.Text = "Kết nối";
P.Close();
btMoDen1.Enabled = false;
btTatDen1.Enabled = false;
btTatDen2.Enabled = false;
btMoDen2.Enabled = false;
btTatDen2.Enabled = false;
btMoQuat.Enabled = false;
btTatQuat.Enabled = false;
cbCom.Enabled = true;
cbRate.Enabled = true;
status.Text = "Đã ngắt kết nối";
}
}

private void btMoDen1_Click(object sender, EventArgs e)


{
P.Write("a");
txMoDen1.BackColor = System.Drawing.Color.Red;
}

private void btTatDen1_Click(object sender, EventArgs e)


{
P.Write("d");
txMoDen1.BackColor = System.Drawing.Color.White;
}

private void btMoDen2_Click(object sender, EventArgs e)


{
P.Write("b");
txMoDen2.BackColor = System.Drawing.Color.Red;
}

private void btTatDen2_Click(object sender, EventArgs e)


{
P.Write("e");
txMoDen2.BackColor = System.Drawing.Color.White;
}

private void btMoQuat_Click(object sender, EventArgs e)


{
P.Write("c");
txMoQuat.BackColor = System.Drawing.Color.Red;

Trang 97
Chương 6 Một số bài toán ứng dụng với Visual Studio
}

private void btTatQuat_Click(object sender, EventArgs e)


{
P.Write("f");
txMoQuat.BackColor = System.Drawing.Color.White;
}
}
}

Bài toán 2: Đo nhiệt độ giao tiếp máy tính.

Bài hướng dẫn này mình sẽ chỉ đề cập vào phần giao tiếp với PIC qua giao
diện C#, nên phần chương trình C mình sẽ không giải thích gì thêm. Và “tạo giao
diện giao tiếp máy tính” chỉ là một phần nhỏ của ngôn ngữ C#, các bạn có thể tìm
hiểu sâu hơn về C# vì nó là một ngôn ngữ mới phát triển nên rất dễ hiểu và sử
dụng.
Sử dụng Visual Studio 2010 trong bài hướng dẫn này, nếu các bạn có các
phiên bản khác như 2008,2012, 2013,…vẫn sử dụng được

Trang 98
Chương 6 Một số bài toán ứng dụng với Visual Studio

Trước hết chúng ta hãy xem sơ lược giao diện và nguyên lý cũng như hoạt
động tổng thể của chương trình giao tiếp sẽ được tạo ra sau bài hướng dẫn này:
+Đầu tiên là giao diện:

+Tiếp đó là cách thức hoạt động:

Trang 99
Chương 6 Một số bài toán ứng dụng với Visual Studio

Mạch mô phỏng Proteus:

Trang 100
Chương 6 Một số bài toán ứng dụng với Visual Studio

Chương trình C:
#include <16f877a.h>
#fuses NOWDT, HS, NOPUT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG, NOPROTECT,PUT
#device pic16f877a*=16 adc=10
#include <stdlib.h>

#use delay(clock =20 Mhz)


#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stop=1)
#use fast_io(a)
#use fast_io(b)
#use fast_io(d)
#use fast_io(e)
#byte portb=0x06
#byte portd=0x08
#byte porte=0x09

int
led[10]={0b11000000,0b11111001,0b10100100,0b10110000,0b10011001,0b10010010,0b10000010,0b1
1111000,0b10000000,0b10010000};
int tram,chuc,dvi;
int8 dtn;
int16 adc,count;
int32 x;
char string[3];

#int_timer0
void interrupt_timer0()
{++count;set_timer0(5);
if(count == 500)
{count=0;itoa(x,10, string);
printf(string);}}

#INT_RDA
void nhan()
{ if (kbhit())
{dtn = getc();
if(dtn=='x')
{bit_clear(portb,0);}
if(dtn=='y')
{bit_set(portb,0);}}}

void main()
{enable_interrupts(int_RDA);
enable_interrupts(global);

enable_interrupts(int_timer0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
set_timer0(6);// T_dinhthi = 2*(256 - 6)*1us = 500us

set_tris_b(0);
set_tris_d(0);
set_tris_e(0);

setup_adc(adc_clock_div_4);
setup_adc_ports (an0);
set_adc_channel(0);

Trang 101
Chương 6 Một số bài toán ứng dụng với Visual Studio
delay_us(1000);

while(true)
{adc=read_adc();
x=adc/2.046;
tram=x/100;
chuc=(x/10)%10;
dvi=x%10;

porte=0b110;
portd=led[tram];
delay_us(6666);

porte=0b101;
portd=led[chuc];
delay_us(6666);

porte=0b011;
portd=led[dvi];
delay_us(6666);}}

Trang 102
Chương 6 Một số bài toán ứng dụng với Visual Studio

Xây dựng giao diện và viết chương trình C#:


Mở Visual Studio lên, và tạo một project C# mới:

Trang 103
Chương 6 Một số bài toán ứng dụng với Visual Studio

Chọn Windows Forms Application và đặt tên cho Project.

Sau khi nhấn nút OK, màn hình sẽ xuất hiện giao diện của lập trình Form.

Trang 104
Chương 6 Một số bài toán ứng dụng với Visual Studio

Tiếp đến chúng ta sẽ dùng các Control trong Toolbox (vùng 1) để xây dựng
giao diện

Trang 105
Chương 6 Một số bài toán ứng dụng với Visual Studio

Và đây là kết quả:

Bước kế tiếp chúng ta sẽ điều chỉnh Text hiển thị và các thuộc tính cho các
Control, sử dụng Properties (vùng 5)

+Form:
Click chuột vào khung Form, bảng Properties cho Form sẽ hiện ra:

Trang 106
Chương 6 Một số bài toán ứng dụng với Visual Studio

Trang 107
Chương 6 Một số bài toán ứng dụng với Visual Studio

Trên Properties sẽ xuất hiện những thuộc tính mặc định, bạn có thể thay đổi
chúng phù hợp với mong muốn của bản thân.
Để thay đổi các Control khác ta cũng làm tương tự, Click chuột và điều
chỉnh.

Có rất nhiều thuộc tính có thể điều chỉnh như: icon, hình nền, màu chữ, kích
thước, tên hiển thị,…………….Tuy nhiên, đối với 1số Control được sử dụng lại
nhiều lần thì ta nên đổi phần (Name) sao cho vừa nhìn vào là ta biết ngay đó là
Control gì, hoặc với các Control dùng để hiển thị thì ta phải thay đổi một số thuộc
tính nhất định các Control đó mới có thể thay đổi màu sắc như chúng ta mong
muốn.

Ví dụ:

Trang 108
Chương 6 Một số bài toán ứng dụng với Visual Studio

Với overShape, để có thể thay đổi BackColor để phục vụ cho việc hiển thị
thì ta phải đổi thuộc tính BackStyle lại thành Opaque

Phần (Name) của các Control sử dụng trong bài này:


+Button Kết nối/Ngắt: btKetNoi
+ComboBox COM: cbCom
+ComboBox BaudRate: cbRate
+Button Set/Reset giới hạn trên: btTR
+Button Set/Reset giới hạn dưới: btDU
+TextBox điền giới hạn trên: txtTR
+TextBox điền giới hạn dưới: txtDU
+Label cảnh báo Giới hạn: lbCanhBao
+Label hiển thị nhiệt độ: lbNhietDo
+statusStrip hiển thị trạng thái: status
+overShape h.thị trạng thái quạt: txMoQuat
+overShape h.thị trạng thái quạt: txMoQuat

Trang 109
Chương 6 Một số bài toán ứng dụng với Visual Studio

Cuối cùng ta được một giao diện hoàn chỉnh:

Lập trình code cho giao diện C# vừa tạo:


Để lập trình cho một Control ta click chuột 2 lần vào Control đó, màn hình
sẽ tự động chuyển qua giao diện code và con trỏ chuột sẽ nhấp nháp ngay tại khu
vực lậptrình dành riêng cho Control đã chọn

Trang 110
Chương 6 Một số bài toán ứng dụng với Visual Studio

Giải thích:

+Khi có “sự kiện” btKetNoi được nhấn (btKetNoi_Click) thì chương


trình con này sẽ được gọi ra sử dụng, và nó sẽ thực hiện lần lượt từng dòng lệnh
nằm trong khu vực của chương trình con đó (giới hạn bởi cặp dấu ”{}” )
+Mỗi chương trình con tương ứng chỉ được gọi khi một “sự kiện”
tương ứng xuất hiện.

Để tránh rối loạn thứ tự của các Control ta nên doubleclick 1 lượt từ trên
xuống dưới theo thứ tự sao cho dễ nhớ, rồi sau đó sẽ viết code sau

Các control như label,groupBox,overShape,statusStrip trong bài này ko


cần gọi chương trình con nên cũng không cần doubleclick tạo sự kiện

Để dùng SerialPort, ta chuyển qua giao diện code, thêm vào dòng khai báo
dùng IO.Port vào phần khai báo thư viện
using System.IO.Ports;// dòng này là khai báo thư viện, để sử dụng SeriaPort

Cài đặt các thông số SerialPort và BaudRate


public partial class Form1 : Form
{
SerialPort P = new SerialPort();// Khai báo 1 Object SerialPort mới
string InputData = String.Empty;
Int16 setTR=0;
Int16 setDU=0;
Int16 ND=0;

public Form1()
{
InitializeComponent();
// Cài đặt các thông số
// Mảng string port để chứa tất cả các cổng COM đang có trên máy
string[] ports = SerialPort.GetPortNames();// Thêm toàn bộ các COM đã tìm
được vào combox cbCom
cbCom.Items.AddRange(ports);
P.ReadTimeout = 1000;
string[] BaudRate = { "1200", "2400", "4800", "9600", "19200", "38400",
"57600", "115200" };
cbRate.Items.AddRange(BaudRate);
P.DataReceived += new SerialDataReceivedEventHandler(Received);
}

Trang 111
Chương 6 Một số bài toán ứng dụng với Visual Studio

Viết code lần lượt cho từng chương trình con

Chương trình con Form_Load này sẽ tự động chạy khi có “sự kiện” Form1
được bắt đầu, nghĩa là khi chạy giao diện thì đoạn code cũng sẽ đồng thời được gọi
ra sử dụng
private void Form1_Load(object sender, EventArgs e)
{
cbCom.SelectedIndex = 0;//giá trị chọn sẵn ban đầu cho combobox cbCom
cbRate.SelectedIndex = 3;//.............................combobox cbRate
btTR.Enabled = true; //
btDU.Enabled = true; //các button sẽ bị khóa khi
txtTR.Enabled = true; //cổng COM chưa kết nối
txtDU.Enabled = true; //
status.Text = "Chưa kết nối";//...trạng thái lúc đầu của cổng COM
}

Khi comboBox của cổng COM và BaudRate (cbCom và cbRate) thay đổi thì
đoạn code sẽ chạy và gán giá trị mới cho PortName và BaudRate

private void cbCom_SelectedIndexChanged(object sender, EventArgs e)


{
P.PortName = cbCom.SelectedItem.ToString;
}

private void cbRate_SelectedIndexChanged(object sender, EventArgs e)


{
P.BaudRate = Convert.ToInt32(cbRate.Text);
}

Chương trình con của nút “Kết nối/Ngắt”:


Phần này kết hợp 2 nút nhấn trong 1 nút nhấn nên ta sử dụng cấu trúc if…else

private void btKetNoi_Click(object sender, EventArgs e)


{
if (btKetNoi.Text == "Kết nối") //nếu phần Text của nút đang là chữ “Kết nối”
{
try //thử thực hiện các công việc bên dưới

{
P.Open();//mở cổng COM đã chọn
cbCom.Enabled = false; // ẩn 2 combox đi
cbRate.Enabled = false;
btTR.Enabled = true; //hiện các button và textbox
btDU.Enabled = true; //
txtTR.Enabled = true; //
txtDU.Enabled = true; //

Trang 112
Chương 6 Một số bài toán ứng dụng với Visual Studio
btKetNoi.Text = "Ngắt"; //đổi phần Text của btKetNoi thành “Ngắt”
status.Text = "Đã kết nối với " + cbCom.SelectedItem.ToString();
//thay đổi phần Text của dòng statusStrip
}
catch (Exception) //nếu có xảy ra lỗi thì thực hiện
//ở đây do phần “thử thực hiện” (try) dòng P.Open(); được viết đầu tiên nên nếu ko mở đc
cổng Com chương trình sẽ nhảy ngay xuống chỗ này mà ko thực hiện các công việc bên dưới
dòng P.Open();
{
MessageBox.Show("Không kết nối được.", "Thử lại",
MessageBoxButtons.OK, MessageBoxIcon.Error); //xuất hiện bảng thông báo lỗi
}
}
Else //ngược lại, nếu Text của btKetNoi đang là chữ “Ngắt” thì
{
btKetNoi.Text = "Kết nối"; //đổi Text lại thành “Kết nối”
P.Close(); //đóng cổng COM
btDU.Enabled = false; //
btTR.Enabled = false; //
txtTR.Enabled = false; //
txtDU.Enabled = false; //
cbCom.Enabled = true; //hiện và cho phép thay đổi thông số của 2 comboBox
cbRate.Enabled = true;
status.Text = "Đã ngắt kết nối"; //thay đổi Text của dòng statusStrip
}
}

Giao tiếp thông qua nút nhấn: (Set/Reset giới hạn)

private void btTR_Click(object sender, EventArgs e)


{
if (btTR.Text == "Set")
{
setTR = Int16.Parse(txtTR.Text);
btTR.Text = "Reset";
txtTR.Enabled = false;
}
else
{
btTR.Text = "Set";
txtTR.Enabled = true;
}
}

Nút Set giới hạn dưới ta làm tương tự


Nhận, xử lý và hiển thị dữ liệu:

private void Received(object sender, System.IO.Ports.SerialDataReceivedEventArgs


e)
{

Trang 113
Chương 6 Một số bài toán ứng dụng với Visual Studio

Control.CheckForIllegalCrossThreadCalls = false;
InputData = P.ReadExisting(); //đọc dữ liệu từ cổng Com
if (InputData.Length == 2) //nếu độ dài dữ liệu hận là 2
ND = Int16.Parse(InputData); //thì chuyển đổi sang Int16 (dữ liệu nhận được
là dạng String, cần chuyển sang dạng Int16 để so sánh với giới hạn)
//ND = Convert.ToInt16(InputData);
}

private void timer_Tick(object sender, EventArgs e)


{
lbNhietDo.Text = ND.ToString() ; //gán dữ liệu nhận đc vào lbNhietDo để
hiển thị

if (P.IsOpen) //so sánh và hiển thị label lbCanhBao và hiện đèn cảnh báo ở
Pic (truyền “x” đèn mở, truyền “y” đèn tắt)
{
if (((btTR.Text == "Reset") && (ND >= setTR)) || ((btDU.Text == "Reset")
&& (ND <= setDU)))
{
lbCanhBao.Visible = true;
P.Write("x");
}
else
{
lbCanhBao.Visible = false;
P.Write("y");
}
}
}

Bên dưới là toàn bộ code của bài này

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;
using System.Xml;

namespace nhietdo
{
public partial class Form1 : Form
{
SerialPort P = new SerialPort();
string InputData = String.Empty;
Int16 setTR=0;
Int16 setDU=0;
Int16 ND=0;

Trang 114
Chương 6 Một số bài toán ứng dụng với Visual Studio
public Form1()
{
InitializeComponent();
string[] ports = SerialPort.GetPortNames();
cbCom.Items.AddRange(ports);
P.ReadTimeout = 1000;
string[] BaudRate = { "1200", "2400", "4800", "9600", "19200", "38400",
"57600", "115200" };
cbRate.Items.AddRange(BaudRate);
P.DataReceived += new SerialDataReceivedEventHandler(Received);
}

private void Form1_Load(object sender, EventArgs e)


{
cbCom.SelectedIndex = 0;
cbRate.SelectedIndex = 3;
btTR.Enabled = false;
btDU.Enabled = false;
txtTR.Enabled = false;
txtDU.Enabled = false;
lbCanhBao.Visible = false;
status.Text = "Chưa kết nối";

private void cbCom_SelectedIndexChanged(object sender, EventArgs e)


{
P.PortName = cbCom.SelectedItem.ToString();
}

private void cbRate_SelectedIndexChanged(object sender, EventArgs e)


{
P.BaudRate = Convert.ToInt32(cbRate.Text);
}

private void btKetNoi_Click(object sender, EventArgs e)


{
if (btKetNoi.Text == "Kết nối")
{
try
{
P.Open();
cbCom.Enabled = false;
cbRate.Enabled = false;
btTR.Enabled = true;
btDU.Enabled = true;
txtTR.Enabled = true;
txtDU.Enabled = true;
btKetNoi.Text = "Ngắt";
status.Text = "Đã kết nối với " + cbCom.SelectedItem.ToString();
}
catch (Exception)
{
MessageBox.Show("Không kết nối được.", "Thử lại",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else

Trang 115
Chương 6 Một số bài toán ứng dụng với Visual Studio
{
btKetNoi.Text = "Kết nối";
P.Close();
btDU.Enabled = false;
btTR.Enabled = false;
txtTR.Enabled = false;
txtDU.Enabled = false;
cbCom.Enabled = true;
cbRate.Enabled = true;
status.Text = "Đã ngắt kết nối";
}
}

private void btTR_Click(object sender, EventArgs e)


{
if (btTR.Text == "Set")
{
setTR = Int16.Parse(txtTR.Text);
btTR.Text = "Reset";
txtTR.Enabled = false;
}
else
{
btTR.Text = "Set";
txtTR.Enabled = true;
}
}

private void btDU_Click(object sender, EventArgs e)


{
if (btDU.Text == "Set")
{
setDU = Int16.Parse(txtDU.Text);
btDU.Text = "Reset";
txtDU.Enabled = false;
}
else
{
btDU.Text = "Set";
txtDU.Enabled = true;
}
}

private void Received(object sender, System.IO.Ports.SerialDataReceivedEventArgs


e)
{

Control.CheckForIllegalCrossThreadCalls = false;
InputData = P.ReadExisting();
if (InputData.Length == 2)
ND = Int16.Parse(InputData);
//ND = Convert.ToInt16(InputData);
}

private void timer_Tick(object sender, EventArgs e)


{
lbNhietDo.Text = ND.ToString() ;

Trang 116
Chương 6 Một số bài toán ứng dụng với Visual Studio
if (P.IsOpen)
{
if (((btTR.Text == "Reset") && (ND >= setTR)) || ((btDU.Text == "Reset")
&& (ND <= setDU)))
{
lbCanhBao.Visible = true;
P.Write("x");
}
else
{
lbCanhBao.Visible = false;
P.Write("y");
}
}
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)


{
if (P.IsOpen)
P.Close();
}
}
}

Bài toán 3: Đo nhiệt độ giao tiếp máy tính sử dụng board Arduino:

Trang 117
Chương 6 Một số bài toán ứng dụng với Visual Studio

+ Cài đặt cho cổng Com ảo trên Proteus

Giao diện trên Windown Form:

Name của các đối tượng cần lập trình:

ketnoi : nút nhấn kết nối


ngat : nút nhấn ngắt kết nối
set : nút nhấn đặt giá trị giới hạ
save : nút nhấn lưu dữ liệu
Trang 118
Chương 6 Một số bài toán ứng dụng với Visual Studio

canhbao : label cảnh báo quá giới hạn trên


canhbao1 : label cảnh báo quá giới hạn dưới
nhiedo : label hiển thị nhiệt độ
txtUP : textBox nhập giới hạn trên
txtDOWN : textBox nhập giới hạn dưới
data_lb : textBox hiển thị nhiệt độ theo thời gian thực
serialPort1 : cổng SerialPort
timer1,timer2,timer3 : các timer đếm

Trang 119
Chương 6 Một số bài toán ứng dụng với Visual Studio

Lập trình cho dao diện:

+ Để lập trình cho 1 control ta click đúp chuột vào control đó, màn hình tự động chuyển
sang giao diện code và con trỏ chuột sẽ nháy ngay tại khu vực để viết code cho control
vừa chọn.
private void ketnoi_Click(object sender, EventArgs e)
{
//khu vực sẽ viết code cho nút nhấn “Kết Nối”//
}

VD: khi chạy giao diện ta click chuột vào button “Kết Nối” , khi đó sẽ có sự kiện ketnoi
được nhấn (ketnoi_Click) , chương trình con sẽ được gọi ra sử dụng và thực hiện từng
dòng lệnh nằm trong khu vực của chương trình con đó.

Nút nhấn Kết Nối và Ngắt Kết Nối


private void ketnoi_Click(object sender, EventArgs e)
{
serialPort1.Open(); //mở cổng serialPort
timer3.Start(); //cho phép các timer chạy
timer2.Start();
}

private void ngat_Click(object sender, EventArgs e)


{
serialPort1.Close(); //đóng cổng serialPort
nhietdo.Text = "XX";//lable hiển thị nhiệt độ sẽ hiển thị
// XX khi ngắt kết nối
timer3.Stop(); //ngừng các timer
timer2.Stop();
}

Nút nhấn Set/Reset


private void set_Click(object sender, EventArgs e)
{
if (set.Text == "Set")
{
UP = Int16.Parse(txtUP.Text);// gán giá trị trong texBox vào
biến UP để so sánh
set.Text = "Reset"; // chuyển nút nhấn sang thành Reset
txtUP.Enabled = false; // khóa textBox lại không cho nhập dữ
liệu

DOWN = Int16.Parse(txtDOWN.Text);//gán giá trị trong texBox vào


biến DOWN để so
//sánh

Trang 120
Chương 6 Một số bài toán ứng dụng với Visual Studio

txtDOWN.Enabled = false; // khóa textBox lại không cho nhập dữ


liệu
}
else
{
set.Text = "Set"; //trả nút nhấn về Set
txtUP.Enabled = true; //cho phép nhập dữ liệu vào các
textBox
txtDOWN.Enabled = true;
}
}

Hiển thị nhiệt độ lên lable


+ Để nhận được dữ liệu từ cổng COM ta phải tạo sự kiện nhận dữ liệu (Received) cho
serialPort1

+ Trong mục Properties chon tab Event có hình


tia sét, đặt tên Event “DataRceived” là Received
Sau đó nhấp đúp chuột vào để chuyển sang giao
diện code sau đó viết code như sau

private void Received(object sender,


System.IO.Ports.SerialDataReceivedEventArgs e)

Control.CheckForIllegalCrossThreadCalls = false;
x = serialPort1.ReadExisting(); //nhận dữ liệu từ
serialPort
t = Int16.Parse(x); //chuyển sang dạng Int16 để so
sánh

Trang 121
Chương 6 Một số bài toán ứng dụng với Visual Studio

Để cho giá trị đọc được hiển thị liên tục lên label ta dùng timer

private void timer2_Tick(object sender, EventArgs e)


{
nhietdo.Text = t.ToString(); //chuyển biến t sang dạng
String
// để hiển thị lên label
}

So sánh nhiệt độ và cảnh báo


+ Ta cũng dung timer để quá trình so sánh được liên tục

private void timer1_Tick(object sender, EventArgs e)


{
if (serialPort1.IsOpen)
{
if ((set.Text == "Reset") && (t >= UP))//nếu vượt giới hạn trên
{
canhbao.Visible = true; //cảnh báo quá giới hạn trên
canhbao1.Visible = false;
serialPort1.Write("0");//gửi tín hiệu báo động xuống Arduino
}
else if ((set.Text == "Reset") && (t <= DOWN))
{
canhbao.Visible = false;
canhbao1.Visible = true;//cảnh báo vượt giới hạn dưới
serialPort1.Write("0");// gửi tín hiệu báo động xuống
Arduino
}
Else // không vượt giới hạn thì không cảnh báo
{
canhbao.Visible = false;
canhbao1.Visible = false;
serialPort1.Write("1");
}
}
}

Trang 122
Chương 6 Một số bài toán ứng dụng với Visual Studio

Hiển thị nhiệt độ theo thời gian thực và lưu lại bảng dữ liệu
+ Hiển thị

- Tạo event để hiển thị lên textBox theo thời gian thực

private void timer3_Tick(object sender, EventArgs e)


{
this.Invoke(new EventHandler(dispaly_evnent));
}

private void dispaly_evnent(object sender, EventArgs e)


{
datetime = DateTime.Now;//lấy dữ liệu thời gian từ máy
tính

string time = datetime.Day + "/" + datetime.Month + "/" +


datetime.Year +"___" + datetime.Hour + ":" + datetime.Minute + ":" +
datetime.Second;
//định dạng cho thời gian

data_lb.AppendText(time+"\t---------------\t "+t+" °C
"+"\n");
//hiển thị ngày giờ và nhiệt độ lên textBox
}

+ Lưu dữ liệu

private void save_Click(object sender, EventArgs e)


{
try
{
string pathfile = @"C:\Users\Administrator\Desktop\Temperature\";
// đường dẫn tới thư mục chứa file txt

string filename = "Temperature_Data.txt";// tên file

System.IO.File.WriteAllText(pathfile + filename, data_lb.Text);


// lệnh in toàn bộ dữ liệu trong textBox ra file txt

MessageBox.Show("Đã lưu vào: " + pathfile);// thông báo lưu thành


công

Trang 123
Chương 6 Một số bài toán ứng dụng với Visual Studio

}
catch (Exception ex3)
{
MessageBox.Show(ex3.Message, "Error");//thông báo lỗi nếu lưu
không được
}
}

Trang 124
Chương 6 Một số bài toán ứng dụng với Visual Studio

Cài đặt thông số cố định cho serialPort1


+ Trong muc properties của serialPort1 đặt các thông số như sau
 Tại mục PortName: là cổng COM mà
Arduno kết nối với máy tính
 BaundRate là 9600 có thể thay đổi tùy
theo phần cứng khác nhau

Cài đặt các timer

Trang 125
Chương 6 Một số bài toán ứng dụng với Visual Studio

ở mục Interval là thời gian giữa hai lần xảy ra sự kiện timer_Tick , đơn vị là ms , có thể
thay đổi tùy vào mục đích sử dụng.
Chương trình cho bài toán 7:
Code Visua studio
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;
using System.Xml;
using System.Threading.Tasks;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
Int16 UP = 0;
Int16 DOWN = 0;
Int32 t = 0;
string x = String.Empty;
private DateTime datetime;
private EventHandler display_event;
public Form1()
{
InitializeComponent();
}
private void ketnoi_Click(object sender, EventArgs e)
{
serialPort1.Open(); //mở cổng serialPort
timer3.Start();
timer2.Start();
}
private void ngat_Click(object sender, EventArgs e)
{
serialPort1.Close(); //đóng cổng serialPort
nhietdo.Text = "XX";
timer3.Stop();
timer2.Stop();
}
private void set_Click(object sender, EventArgs e)
{
if (set.Text == "Set")

Trang 126
Chương 6 Một số bài toán ứng dụng với Visual Studio

{
UP = Int16.Parse(txtUP.Text);
set.Text = "Reset";
txtUP.Enabled = false;

DOWN = Int16.Parse(txtDOWN.Text);
txtDOWN.Enabled = false;
}
else
{
set.Text = "Set";
txtUP.Enabled = true;
txtDOWN.Enabled = true;
}
}
private void timer2_Tick(object sender, EventArgs e)
{
nhietdo.Text = t.ToString(); //hiển thị lên label
//this.Invoke(new EventHandler(dispaly_evnent));
}

private void timer1_Tick(object sender, EventArgs e)


{
if (serialPort1.IsOpen)
{
if ((set.Text == "Reset") && (t >= UP))
{
canhbao.Visible = true;
canhbao1.Visible = false;
serialPort1.Write("0");
}
else if ((set.Text == "Reset") && (t <= DOWN))
{
canhbao.Visible = false;
canhbao1.Visible = true;
serialPort1.Write("0");
}
else
{
canhbao.Visible = false;
canhbao1.Visible = false;
serialPort1.Write("1");
}
}
}

Trang 127
Chương 6 Một số bài toán ứng dụng với Visual Studio

private void Received(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)


{
Control.CheckForIllegalCrossThreadCalls = false;
x = serialPort1.ReadExisting(); //nhận dữ liệu từ serialPort
if (x.Length == 2)
{ t = Int16.Parse(x); } //chuyển sang dạng Int16 để so sánh
else { t = t + 0; }
}

private void dispaly_evnent(object sender, EventArgs e)


{
datetime = DateTime.Now;
string time = datetime.Day + "/" + datetime.Month + "/" + datetime.Year +"___" +
datetime.Hour + ":" + datetime.Minute + ":" + datetime.Second;
data_lb.AppendText(time+"\t---------------\t "+t+" °C "+"\n");

}
private void save_Click(object sender, EventArgs e)
{
try
{
string pathfile = @"C:\Users\Administrator\Desktop\Temperature\";
string filename = "Temperature_Data.txt";
System.IO.File.WriteAllText(pathfile + filename, data_lb.Text);
MessageBox.Show("Đã lưu vào: " + pathfile);
}
catch (Exception ex3)
{
MessageBox.Show(ex3.Message, "Error");
}
}

private void timer3_Tick(object sender, EventArgs e)


{
this.Invoke(new EventHandler(dispaly_evnent));
}

private void Form1_Load(object sender, EventArgs e)


{
timer3.Stop();
}

private void canhbao1_Click(object sender, EventArgs e)


{

Trang 128
Chương 6 Một số bài toán ứng dụng với Visual Studio

} //end form
} //end main

Code Arduino
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
int AnalogPin=0;
long t=0;
int x;
int ngat;
//Khởi tạo LCD với các chân
LiquidCrystal lcd(3, 2, 12, 11, 10, 9);
//RS=pin D3 E=pin D2 D4->D7 LCD to pin D12->pin D9

void setup()
{
pinMode(13,OUTPUT);
digitalWrite(13,LOW);
Serial.begin(9600);
lcd.begin(16, 2); //LCD 16x2
lcd.print("Test LCD & LM35");
lcd.setCursor(0, 1); //(cột, dòng)
lcd.print("Temperature: ");
}

void loop()
{

t = analogRead(AnalogPin)/2.048;
delay(50);
lcd.setCursor(13,1);
lcd.print(t);
Serial.print(t);
if (Serial.available() > 0)
{
ngat = Serial.read();
if (ngat <= 48)
{
digitalWrite(13,HIGH);
}
if (ngat >= 49)
{
digitalWrite(13,LOW); } } }

Trang 129

You might also like