You are on page 1of 32

TRƯỜNG CƠ KHÍ

ĐẠI HỌC BÁCH KHOA HÀ NỘI


---------------------------

BÁO CÁO BÀI TẬP LỚN


Kỹ thuật lập trình trong Cơ điện tử
Đề tài:
Hệ thống cảnh báo nhiệt độ
Giảng viên hướng dẫn: Ts. Dương Văn Lạc
Nhóm thực hiện: Nhóm 11

Lưu Thành Phong (TN) 20195135 Cơ điện tử 06 – K64


Lê Anh Trung 20195206 Cơ điện tử 06 – K64
Trương Xuân Tùng 20195226 Cơ điện tử 05 – K64

Trần Sơn Việt 20195233 Cơ điện tử 05 – K64
Nguyễn Công Tuấn Vinh 20195234 Cơ điện tử 06 - K64
nội, 7/2022

Mục lục
LỜI MỞ ĐẦU...........................................................................................4

1
PHẦN I : LẬP KẾ HOẠCH THỰC HIỆN PHẦN MỀM........................5
I. LẬP KẾ HOẠCH..............................................................................5
1. Khởi tạo dự án...............................................................................5
2. Phân tích tính khả thi.....................................................................5
II. LỊCH BIỂU DIỄN CÔNG VIỆC....................................................5
1. Thành viên.................................................................................5
2. Thời gian tổng thể......................................................................6
PHẦN 2: PHÂN TÍCH HỆ THỐNG........................................................7
1. SƠ ĐỒ THIẾT KẾ.......................................................................7
2. LINH KIỆN SỬ DỤNG...............................................................7
Sơ Đồ Kết Nối Của Màn Hình LCD1602:.....................................11
3. LẬP TRÌNH ADRUINO............................................................13
4. LẬP TRÌNH GIAO DIỆN C#....................................................17
PHẦN 3: THỬ NGHIỆM VÀ KẾT LUẬN............................................19
1. THỬ NGHIỆM........................................................................19
2. KẾT LUẬN.............................................................................20
Phần 4: Bài học kinh nghiệm:.................................................................20
1. Về triển khai kế hoạch bài tập lớn...........................................20
2. Về thiết kế hệ thống.................................................................20
3. Về lập trình Arduino................................................................20
4. Về lập trình GUI......................................................................21
LỜI CẢM ƠN.........................................................................................22

Không tìm thấy mục nhập nào của bảng hình minh họa.

2
LỜI MỞ ĐẦU

Những năm gần đây, khoa học công nghệ phát triển nhanh như vũ bão, đặc biệt là
lĩnh vực công nghệ thông tin. Có thể nói, công nghệ thông tin đã len lỏi vào hầu hết
tất cả mọi lĩnh vực trong cuộc sống của chúng ta. Trong đó, công nghệ phần mềm
luôn luôn đóng vai trò tiên phong, dẫn đầu trong quá trình đó. Các phần mềm đã
đang và sẽ được ứng dụng ngày càng nhiều trong công việc cũng như cuộc sống
thường ngày của con người.
Nắm bắt được xu hướng đó, trong khuôn khổ nội dung của chương trình học học
phần Kĩ thuật lập trình trong Cơ điện tử, nhóm chúng em đã quyết định tìm hiểu và
xây dựng một đề tài đơn giản và gần gũi với thực tế: Hệ thống quản lí tiền điện của
một xã.
Qua quá trình tìm hiểu và xây dựng phần mềm trên thực tế, cùng với những kiến
thực được học trên giảng đường, chúng em mới thực sự cảm nhận được những khó
khăn khi xây dựng và phát triển một phần mềm hoàn chỉnh. Để có thể xây dựng được
một phần mềm hoàn thiện, không chỉ đơn thuần là lập trình, mà còn rất nhiều công
việc khác cần phải thực hiện. Các công việc này được sắp xếp trong các pha với trình
tự rất hợp lí, khoa học.
Phần mềm này được nhóm em xây dựng nhằm hỗ trợ cho người sử dụng có thể
nhanh chóng dễ dàng hơn trong việc cập nhật tình hình nhiệt độ, độ ẩm tại môi
trường xác định và trong thời gian thực một cách nhanh chóng và dễ dàng lưu trữ
thông số đo đạt được với độ chính xác cao mà rất tiện lợi.
Đây là phần mềm đầu tiên mà nhóm em xây dựng nên không thể tránh khỏi những
hạn chế và thiếu sót, kính mong cô giáo và các bạn bổ sung, góp ý để phần mềm
ngày càng hoàn thiện và thực sự hữu ích với người sử dụng.
Chúng em xin chân thành cảm ơn!

3
PHẦN I : LẬP KẾ HOẠCH THỰC HIỆN PHẦN MỀM

I. LẬP KẾ HOẠCH

1. Khởi tạo dự án
Mong muốn có một sản phẩm có thể quản lí nhiệt độ, độ ẩm nhằm
nâng cao hiệu quả quản lý để đạt được những yêu cầu đầu ra của đối
tượng, nhóm sinh viên chúng em đã nghiên cứu và xây dựng đề tài X để
hỗ trợ các người quản lý và nhân viên của họ trong công việc quản lý
nhiệt độ, độ ẩm một cách hiện đại và chuyên nghiệp. Sản phẩm sẽ giúp
tiết kiệm một lượng lớn thời gian đo đạc thủ công cũng như thống kê
khảo sát tình hình của môi trường trong thời gian thực.

2. Phân tích tính khả thi


2.1. Tính khả thi về mặt kỹ thuật
- Sản phẩm được phát triển dựa trên công cụ C# và Adruino là công cụ
hỗ trợ thông dụng, mạnh để lập trình giao diện và lập trình vi điều khiển.
- Sản phầm được thiết kế chạy trên nền window đảm bảo phù hợp với
đa số người dùng.
- Linh kiện không quá phức tạp.
2.2. Tính khả thi về mặt kinh tế
- Linh kiện không khó để tìm kiếm và không đắt đỏ.
2.3. Tính khả thi về mặt tổ chức
- Phần mềm sau khi hoàn thành dễ dàng sử dụng, thân thiện với người
dung, ngay cả người mới.

II. LỊCH BIỂU DIỄN CÔNG VIỆC

1. Thành viên
STT Tên MSSV Lớp
1 Trần Quang Trung (TN) 20134191 KT ĐT-TT 06 K58
2 Trịnh Hữu Trường 20134237 KT ĐT-TT 07 K58
3 Nguyễn Đăng Anh Tú 20136796 CN-Điện tử TT 02 K58
4 Nguyễn Thị Cẩm Tú 20134495 KT ĐT-TT 09 K58
4
5 Phạm Mạnh Tuấn 20134328 KT ĐT-TT 06 K58

2. Thời gian tổng thể


Tổng thời gian dự kiến là 15-17 tuần (kéo dài trong thời gian học)
hoàn thành trước thời hạn bàn giao phần mềm là 1 tuần được phân bổ
như sau:
+ Phân tích và thiết kế hệ thống phần mềm : 4-5 tuần.
+ Lập trình, kiểm thử các hệ thống phần mềm, sửa lỗi, nộp báo
cáo : 11-12 tuần.

5
PHẦN 2: PHÂN TÍCH HỆ THỐNG
1. SƠ ĐỒ THIẾT KẾ

2. LINH KIỆN SỬ DỤNG


a) Adruino Uno R3

6
Thông số kỹ thuật Adruino Uno R3
Vi điều khiển ATmega328 họ 8bit
Điện áp hoạt động 5 - 12V DC ( khuyên dùng )
Tần số hoạt động 16 MHz
Dòng tiêu thụ Khoảng 30mA
Điện áp vào giới hạn 19V DC
Số chân Digital I/O 14 ( 6 chân PWM )
Số chân Analog 6 ( độ phân giải 10bit )
Dòng tối đa trên mỗi chân I/O 30 mA
Dòng ra tối đa ( 5V ) 500 mA
Dòng ra tối đa ( 3.3 ) 50 mA
Bộ nhớ Flash 32 KB ( ATmega328 ) với 0.5 KB dùng
bởi bootloader
SRAM 2 KB
EEPROM 1KB
Khối lượng 25 gram

7
b) Cảm biến nhiệt độ, độ ẩm DHT11

Cảm biến nhiệt độ, độ ẩm DHT11

8
Thông số kỹ thuật Cảm biến nhiệt độ độ ẩm DHT 11
 Nguồn: 3 -> 5 VDC.
 Dòng sử dụng: 2.5mA max (khi truyền dữ liệu).
 Khoảng đo độ ẩm: 20%-90% RH (sai số 5%RH) 
 Khoảng đo nhiệt độ: 0-50°C (sai số 2°C) 
 Tần số lấy mẫu tối đa: 1Hz (1 giây / lần)
 Kích thước 15mm x 12mm x 5.5mm.

Cảm biến độ ẩm và nhiệt độ DHT11 Temperature Humidity


Sensor là cảm biến rất thông dụng hiện nay vì chi phí rẻ và rất dễ lấy dữ
liệu thông qua giao tiếp 1 wire (giao tiếp digital 1 dây truyền dữ liệu duy
nhất). Bộ tiền xử lý tín hiệu tích hợp trong cảm biến giúp bạn có được dữ
liệu chính xác mà không phải qua bất kỳ tính toán nào. So với cảm biến
đời mới hơn là DHT22 thì DHT11 cho khoảng đo và độ chính xác kém
hơn rất nhiều.

c) Màn hình LCD 16x2 và giao tiếp I2C

9
LCD 16×2 được sử dụng để hiển thị trạng thái hoặc các thông số.
 LCD 16×2 có 16 chân trong đó 8 chân dữ liệu (D0 – D7) và 3
chân điều khiển (RS, RW, EN).
 5 chân còn lại dùng để cấp nguồn và đèn nền cho LCD 16×2.
 Các chân điều khiển giúp ta dễ dàng cấu hình LCD ở chế độ
lệnh hoặc chế độ dữ liệu.
 Chúng còn giúp ta cấu hình ở chế độ đọc hoặc ghi.

LCD 16×2 có thể sử dụng ở chế độ 4 bit hoặc 8 bit tùy theo ứng dụng ta
đang làm.

Module I2C Arduino

Module I2C LCD 16×2

LCD có quá nhiều nhiều chân gây khó khăn trong quá trình đấu nối và
chiếm dụng nhiều chân trên vi điều khiển. 

Module I2C LCD ra đời và giải quyết vấn để này cho bạn.

Thay vì phải mất 6 chân vi điều khiển để kết nối với LCD 16×2 (RS,
EN, D7, D6, D5 và D4) thì module IC2 bạn chỉ cần tốn 2 chân (SCL,
SDA) để kết nối.

Module I2C hỗ trợ các loại LCD sử dụng driver HD44780(LCD 16×2,
LCD 20×4, …) và tương thích với hầu hết các vi điều khiển hiện nay.

10
Ưu điểm
 Tiết kiệm chân cho vi điều khiển.
 Dễ dàng kết nối với LCD.

Thông số kĩ thuật
 Điện áp hoạt động: 2.5-6V DC.
 Hỗ trợ màn hình: LCD1602,1604,2004 (driver HD44780).
 Giao tiếp: I2C.
 Địa chỉ mặc định: 0X27 (có thể điều chỉnh bằng ngắn mạch
chân A0/A1/A2).
 Tích hợp Jump chốt để cung cấp đèn cho LCD hoặc ngắt.
 Tích hợp biến trở xoay điều chỉnh độ tương phản cho LCD.
Để sử dụng màn hình LCD giao tiếp I2C sử dụng Arduino thì ta cần cài
đặt thư viện Liquidcrystal_I2C

3. LẬP TRÌNH ADRUINO

Sử dụng công cụ lập trình Arduino IDE.


o Ưu điểm
- Phần mềm lập trình mã nguồn mở miễn phí

11
- Sử dụng ngôn ngữ lập trình C/C++ thân thiện với các
lập trình viên
- Hỗ trợ lập trình tốt cho bo mạch Arduino
- Thư viện hỗ trợ phong phú (~700 thư viện)
- Giao diện đơn giản dễ sử dụng
- Hỗ trợ đa nền tảng như Windows, MacOS, Linux
Arduino IDE là một phần mềm được phân phối chính hãng, tải
miễn phí và giao diện thân thiện với người dùng. Phần mềm liên tục
được nhà phát hành cập nhật dưới sự giúp đỡ của Cộng đồng người dùng
Arduino đông đảo nên độ bảo mật là rất cao. Arduino IDE là phần mềm
nên sử dụng nhất để tải code vào bo mạch Arduino.

4. LẬP TRÌNH GIAO DIỆN C#

Sử dụng công cụ lập trình C# và môi trường Visual Studio.


o Ưu điểm:
- Giao diện và cấu trúc gần gũi, phổ biến, dễ dàng tiếp cận
- C# có thể biên dịch trên nhiều nền tảng máy tính khác nhau.
Nhờ sự hỗ trợ của .NET
- Cải tiến các khuyết điểm trước kia của C++ và Java
- Đồng thời, dựa trên các nền tảng ngôn ngữ lập trình có sẵn,
C++ được thừa hưởng những thế mạnh trước đó của các
ngôn ngữ C++, Java, Pascal

12
o Nhược điểm:
- C# là chỉ chạy trên nền tảng Windows và có cài .NET
Framework. Nên đây được xem là nhược điểm lớn nhất của
C#
- Thao tác với phần cứng hầu hết phải dựa vào Windows
C#, QT là một trong những phần mềm thông dụng để lập trình
giao diện GUI trên Windows. Với những sự thừa kế của các ngôn
ngữ lập trình tiền than, C# rất than thiện với người lập trình.
Phần code C#:

13
PHẦN 3: THỬ NGHIỆM VÀ KẾT LUẬN
1. THỬ NGHIỆM
a. Sơ đồ mạch
b. Giao diện điều khiển
(1)

(3)

(2)

(1) Thanh công cụ:


a. COM: cổng kết nối với thiệt bị
b. Connect: Kết nối với thiết bị
c. Run: Khởi động thiết bị
d. Pause: Tạm dừng
e. Clear: Xóa dữ liệu, trở về cài đặt gốc
f. Save: Lưu các giá trị ở bảng (2) về file Excel
g. Exit: Thoát
(2) Bảng hiện thời gian thực và giá trị độ ẩm/nhiệt độ
(3) Biểu đồ giá trị độ ẩm/nhiệt độ theo thời gian thực
c. Các bước tiến hành
1. Kết nối Kit Arduino với cổng COM, sau đó
nhấn Connect để xác nhận kết nối
2. Nhấn Run để khởi động hệ thống

14
2. KẾT LUẬN
a. Kết quả đạt được:
- Linh kiện hệ thống rẻ, dễ dàng mua được
- Hệ thống Cơ điện tử đã được hoàn thiện
- Giao diện được thiết kế thông qua Visual Studio dựa
theo kiến thức học được
- Sản phẩm được chạy bình thường và theo yêu cầu đề
ra
b. Khó khăn:
- Độ nhạy của cảm biến chưa thực sự cao
c. Phương hướng phát triển:
- Có thể ứng dụng vào trong công nghiệp như đo nhiệt
độ, độ ẩm trong môi trường khép kín
- Thêm thiết bị điều khiển nhiệt độ, độ ẩm như máy
sưởi, quạt, máy phun sương để đạt được yêu cầu
nhiệt độ độ ẩm mong muốn
- Thay thế cảm biến tốt hơn để tăng tốc độ xử lý
- Thay thế bộ vi xử lí để giảm giá thành, tăng bộ nhớ

Phần 4: Bài học kinh nghiệm:


1. Về triển khai kế hoạch bài tập lớn
Cả nhóm cần nhanh chóng thống nhất được đề tài sớm hơn, vì mỗi
người có một ý tưởng nhưng lại chưa tìm hiểu rõ đề tài của mình để
bảo vệ ý tưởng, dẫn đến mất một thời gian mới chốt được đề tài.
Cả nhóm nên có chia nhỏ những kế hoạch với thời gian cụ thể và
thôi thúc các thành viên hoàn thành đúng tiến độ.

2. Về thiết kế hệ thống
Cần phải chỉn chu hơn nữa để có thể tối ưu đường dây dẫn, nhìn
khoa học hơn, bắt mắt hơn.

3. Về lập trình Arduino


Trang web wokwi.com là một trang web rất hữu ích để giả lập
Arduino. Việc sử dụng trang web không tiết kiệm được chi phí thử

15
nghiệm sản phẩm mà độ hiệu quả mang lại khá tốt. Có thể thử trước
khi quyết định thêm một linh kiện để xem tính khả thi của nó như thế
nào.

4. Về lập trình GUI


Có thể sử dụng QT hoặc C# để lập trình giao diện. Việc học lập
trình giao diện trở nên dễ dàng hơn khi có sự hướng dẫn của giáo
viên, nhiều phương tiện tìm hiểu và sự giúp đỡ của những thành viên
trong nhóm. Sản phẩm trên không phải là sản phẩm tốt nhất nhưng sẽ
là nền tảng tốt để tiếp tục học tập, nghiên cứu và phát triển liên quan
đến ngành Cơ điện tử trong tương lai.

16
LỜI CẢM ƠN

Chúng em xin chân thành cảm ơn thầy Dương Văn Lạc đã tận tình hướng dẫn , giải đáp thắc
mắc và chỉ bảo nhóm em trong suốt thời gian nhóm em hoàn thành bài tập lớn .
Mặc dù đã cố gắng hoàn thành đề tài tốt nhất nhưng do thời gian và kiến thức còn có hạn
nên chúng em sẽ không thể tránh khỏi những thiếu sót nhất định, rất mong nhận được sự cảm
thông, chia sẻ và tận tình đóng góp chỉ bảo của thầy cũng như các bạn.

17
CODE lập trình arduino

Phần code Arduino:


#include <DHT.h>
#include <DHT_U.h>
const int DHTPIN = 7;
const int DHTTYPE = DHT11;
DHT dht(DHTPIN, DHTTYPE);
#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);
byte degree[8] = {
0B01110,
0B01010,
0B01110,
0B00000,
0B00000,
0B00000,
0B00000,
0B00000
};

int state = 0;
long time_now = 0;
long time_start = 0;

float gettemp();
float data = 0;
18
void setup() {
Serial.begin(9600);
dht.begin();
lcd.init();
lcd.backlight();
lcd.print("Nhiet do: ");
lcd.setCursor(0,1);
lcd.print("Do am: ");
lcd.createChar(1, degree);
pinMode(2,OUTPUT);
}

void loop()
{
// Điều khiển Arduino qua giá trị của biến state
if(Serial.available())
{
char temp = Serial.read();
if(temp == '0')
state = 0;
if(temp == '1')
state = 1;
if(temp == '2')
state = 2;
}

// Thực thi các trường hợp với các giá trị của biến state
19
switch(state)
{
// state = 0: dừng Arduino
case 0:
break;
case 1:
gettemp();
Serial.print(time_now);
Serial.print("|");
Serial.println(round(data));
break;
// state = 2: Reset dữ liệu và thời gian về 0
case 2:
data = 0;
time_now = 0;
state = 0;
break;
}
float h = dht.readHumidity();
float t = dht.readTemperature();
if (t > 33)
{
digitalWrite(2,HIGH);
digitalWrite(3,LOW);

}
else
{
digitalWrite(2,LOW);
20
digitalWrite(3,HIGH);
}
if (isnan(t) || isnan(h)) {
}
else {
lcd.setCursor(10,0);
lcd.print(round(t));
lcd.print(" ");
lcd.write(1);
lcd.print("C");
lcd.setCursor(10,1);
lcd.print(round(h));
lcd.print(" %");
}
}
float gettemp()
{
time_start = millis();
data = dht.readTemperature();
delay(100);
time_now = time_now + millis() - time_start;
}

21
Code lập trình giao diện
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.IO.Ports;
using System.Xml;
using ZedGraph;

namespace GraphRealTime
{
public partial class Form1 : Form
{
string SDatas = String.Empty; // Khai báo chuỗi để lưu dữ liệu cảm biến gửi qua Serial
string SRealTime = String.Empty; // Khai báo chuỗi để lưu thời gian gửi qua Serial
int status = 0; // Khai báo biến để xử lý sự kiện vẽ đồ thị
double realtime = 0; //Khai báo biến thời gian để vẽ đồ thị
double datas = 0; //Khai báo biến dữ liệu cảm biến để vẽ đồ thị
public Form1()
{
InitializeComponent();
}
private
void Form1_Load(object sender, EventArgs e)
{

22
comboBox1.DataSource = SerialPort.GetPortNames(); // Lấy nguồn cho comboBox là tên
của cổng COM
comboBox1.Text = Properties.Settings.Default.ComName;

// Khởi tạo ZedGraph


GraphPane myPane = zedGraphControl1.GraphPane;
myPane.Title.Text = "Đồ thị dữ liệu theo thời gian";
myPane.XAxis.Title.Text = "Thời gian (s)";
myPane.YAxis.Title.Text = "Dữ liệu";

RollingPointPairList list = new RollingPointPairList(60000);


LineItem curve = myPane.AddCurve("Dữ liệu", list, Color.Red, SymbolType.None);

myPane.XAxis.Scale.Min = 0;
myPane.XAxis.Scale.Max = 30;
myPane.XAxis.Scale.MinorStep = 1;
myPane.XAxis.Scale.MajorStep = 5;
myPane.YAxis.Scale.Min = -100;
myPane.YAxis.Scale.Max = 100;

myPane.AxisChange();
}

// Hàm Tick này sẽ bắt sự kiện cổng Serial mở hay không


private
void timer1_Tick(object sender, EventArgs e)
{
if (!serialPort1.IsOpen)
{
progressBar1.Value = 0;
}
else if (serialPort1.IsOpen)

23
{
progressBar1.Value = 100;
Draw();
Data_Listview();
status = 0;
}
}

// Hàm này lưu lại cổng COM đã chọn cho lần kết nối
private
void SaveSetting()
{
Properties.Settings.Default.ComName = comboBox1.Text;
Properties.Settings.Default.Save();
}

// Nhận và xử lý string gửi từ Serial


private
void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
string[] arrList = serialPort1.ReadLine().Split('|'); // Đọc một dòng của Serial, cắt chuỗi
khi gặp ký tự gạch đứng
SRealTime = arrList[0]; // Chuỗi đầu tiên lưu vào SRealTime
SDatas = arrList[1]; // Chuỗi thứ hai lưu vào SDatas

double.TryParse(SDatas, out datas); // Chuyển đổi sang kiểu double


double.TryParse(SRealTime, out realtime);
realtime = realtime / 1000.0; // Đối ms sang s
status = 1; // Bắt sự kiện xử lý xong chuỗi, đổi starus về 1 để hiển thị dữ liệu trong
ListView và vẽ đồ thị

24
}
catch
{
return;
}
}

// Hiển thị dữ liệu trong ListView


private
void Data_Listview()
{
if (status == 0)
return;
else
{
ListViewItem item = new ListViewItem(realtime.ToString()); // Gán biến realtime vào
cột đầu tiên của ListView
item.SubItems.Add(datas.ToString());
listView1.Items.Add(item); // Gán biến datas vào cột tiếp theo của ListView
// Không nên gán string SDatas vì khi xuất dữ liệu sang Excel sẽ là
dạng string, không thực hiện các phép toán được

listView1.Items[listView1.Items.Count - 1].EnsureVisible(); // Hiện thị dòng được gán


gần nhất ở ListView, tức là mình cuộn ListView theo dữ liệu gần nhất đó
}
}

// Vẽ đồ thị
private
void Draw()
{

if (zedGraphControl1.GraphPane.CurveList.Count <= 0)

25
return;

LineItem curve = zedGraphControl1.GraphPane.CurveList[0] as LineItem;

if (curve == null)
return;

IPointListEdit list = curve.Points as IPointListEdit;

if (list == null)
return;

list.Add(realtime, datas); // Thêm điểm trên đồ thị

Scale xScale = zedGraphControl1.GraphPane.XAxis.Scale;


Scale yScale = zedGraphControl1.GraphPane.YAxis.Scale;

// Tự động Scale theo trục x


if (realtime > xScale.Max - xScale.MajorStep)
{
xScale.Max = realtime + xScale.MajorStep;
xScale.Min = xScale.Max - 30;
}

// Tự động Scale theo trục y


if (datas > yScale.Max - yScale.MajorStep)
{
yScale.Max = datas + yScale.MajorStep;
}
else if (datas < yScale.Min + yScale.MajorStep)
{
yScale.Min = datas - yScale.MajorStep;

26
}

zedGraphControl1.AxisChange();
zedGraphControl1.Invalidate();
zedGraphControl1.Refresh();
}

// Xóa đồ thị, với ZedGraph thì phải khai báo lại như ở hàm Form1_Load, nếu không sẽ
không hiển thị
private
void ClearZedGraph()
{
zedGraphControl1.GraphPane.CurveList.Clear(); // Xóa đường
zedGraphControl1.GraphPane.GraphObjList.Clear(); // Xóa đối tượng

zedGraphControl1.AxisChange();
zedGraphControl1.Invalidate();

GraphPane myPane = zedGraphControl1.GraphPane;


myPane.Title.Text = "Đồ thị dữ liệu theo thời gian";
myPane.XAxis.Title.Text = "Thời gian (s)";
myPane.YAxis.Title.Text = "Dữ liệu";

RollingPointPairList list = new RollingPointPairList(60000);


LineItem curve = myPane.AddCurve("Dữ liệu", list, Color.Red, SymbolType.None);

myPane.XAxis.Scale.Min = 0;
myPane.XAxis.Scale.Max = 30;
myPane.XAxis.Scale.MinorStep = 1;
myPane.XAxis.Scale.MajorStep = 5;
myPane.YAxis.Scale.Min = -100;
myPane.YAxis.Scale.Max = 100;

27
zedGraphControl1.AxisChange();
}

// Hàm xóa dữ liệu


private
void ResetValue()
{
realtime = 0;
datas = 0;
SDatas = String.Empty;
SRealTime = String.Empty;
status = 0; // Chuyển status về 0
}

// Hàm lưu ListView sang Excel


private
void SaveToExcel()
{
Microsoft.Office.Interop.Excel.Application xla = new
Microsoft.Office.Interop.Excel.Application();
xla.Visible = true;
Microsoft.Office.Interop.Excel.Workbook wb =
xla.Workbooks.Add(Microsoft.Office.Interop.Excel.XlSheetType.xlWorksheet);
Microsoft.Office.Interop.Excel.Worksheet ws =
(Microsoft.Office.Interop.Excel.Worksheet)xla.ActiveSheet;

// Đặt tên cho hai ô A1. B1 lần lượt là "Thời gian (s)" và "Dữ liệu", sau đó tự động dãn độ
rộng
Microsoft.Office.Interop.Excel.Range rg =
(Microsoft.Office.Interop.Excel.Range)ws.get_Range("A1", "B1");
ws.Cells[1, 1] = "Thời gian (s)";
ws.Cells[1, 2] = "Dữ liệu";

28
rg.Columns.AutoFit();

// Lưu từ ô đầu tiên của dòng thứ 2, tức ô A2


int i = 2;
int j = 1;

foreach (ListViewItem comp in listView1.Items)


{
ws.Cells[i, j] = comp.Text.ToString();
foreach (ListViewItem.ListViewSubItem drv in comp.SubItems)
{
ws.Cells[i, j] = drv.Text.ToString();
j++;
}
j = 1;
i++;
}
}

private void btConnect_Click(object sender, EventArgs e)


{
if (serialPort1.IsOpen)
{
serialPort1.Write("2"); //Gửi ký tự "2" qua Serial, tương ứng với state = 2
serialPort1.Close();
btConnect.Text = "Kết nối";
btExit.Enabled = true;
SaveSetting(); // Lưu cổng COM vào ComName
}
else
{
serialPort1.PortName = comboBox1.Text; // Lấy cổng COM

29
serialPort1.BaudRate = 9600; // Baudrate là 9600, trùng với baudrate của Arduino
try
{
serialPort1.Open();
btConnect.Text = "Ngắt kết nối";
btExit.Enabled = false;
}
catch
{
MessageBox.Show("Không thể mở cổng" + serialPort1.PortName, "Lỗi",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}

private void btExit_Click(object sender, EventArgs e)


{
DialogResult traloi;
traloi = MessageBox.Show("Bạn có chắc muốn thoát?", "Thoát",
MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
if (traloi == DialogResult.OK)
{
Application.Exit(); // Đóng ứng dụng
}
}

private void btSave_Click(object sender, EventArgs e)


{
DialogResult traloi;
traloi = MessageBox.Show("Bạn có muốn lưu số liệu?", "Lưu",
MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
if (traloi == DialogResult.OK)
{

30
SaveToExcel(); // Thực thi hàm lưu ListView sang Excel
}
}

private void btRun_Click(object sender, EventArgs e)


{
if (serialPort1.IsOpen)
{
serialPort1.Write("1"); //Gửi ký tự "1" qua Serial, chạy hàm tạo Random ở Arduino
}
else
MessageBox.Show("Bạn không thể chạy khi chưa kết nối với thiết bị", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}

private void btPause_Click(object sender, EventArgs e)


{
if (serialPort1.IsOpen)
{
serialPort1.Write("0"); //Gửi ký tự "0" qua Serial, Dừng Arduino
}
else
MessageBox.Show("Bạn không thể dừng khi chưa kết nối với thiết bị", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}

private void btClear_Click(object sender, EventArgs e)


{
if (serialPort1.IsOpen)
{
DialogResult traloi;
traloi = MessageBox.Show("Bạn có chắc muốn xóa?", "Xóa dữ liệu",
MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);

31
if (traloi == DialogResult.OK)
{
if (serialPort1.IsOpen)
{
serialPort1.Write("2"); //Gửi ký tự "2" qua Serial
listView1.Items.Clear(); // Xóa listview

//Xóa đường trong đồ thị


ClearZedGraph();

//Xóa dữ liệu trong Form


ResetValue();
}
else
MessageBox.Show("Bạn không thể dừng khi chưa kết nối với thiết bị", "Thông
báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
MessageBox.Show("Bạn không thể xóa khi chưa kết nối với thiết bị", "Thông báo",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}

32

You might also like