Hệ thống này có khả năng ứng dụng để cảnh báo rò rỉ khí gas, thu th p và bi u di n ậểễbằng đồ thị các chỉ số về nhiệt độ - độ ẩm, đồng thời điều khiển được các thi t b qua giao ế ịdiện..
Trang 1ĐẠ I H C BÁCH KHOA HÀ N I Ọ Ộ TRƯỜNG CƠ KHÍ
Môn: K thu t l ỹ ậ ập trình trong Cơ điện tử
Đề tài: Smart Home
Giáo viên hướng dẫn: TS Dương Văn Lạc Nhóm sinh viên th c hi ự ện: Nhóm 2
3 Trần Ngọc Thao 20195187
Hà N i, 8-2022 ộ
Trang 2Phân chia công vi c ệ
hợp, chỉnh sửa
Hoàn thành
Trang 3Mục l c ụ
Chương 1: Đặ ấn đề t v
1.1 Gi i thi ớ ệu chung
1.2 Các yêu cầu cơ bản
1.3 Phương pháp, phạm vi và gi i h n nghiên c ớ ạ ứu
Chương 2: Linh kiện và ph n c ầ ứng
2.1 Linh kiện
2.1.1 Arduino Uno R3
2.1.2 Cảm biến DHT11
2.1.3 Cảm biến MQ2
2.1.4 Màn hình LCD 16x2 (I2C)
2.2 Sơ đồ kh ối, sơ đồ ho ạt độ ng
2.3 Sơ đồ nối mạch
Chương 3: Giao tiếp gi a các linh ki ữ ện
Chương 4: Winforms và Code lập trình
Chương 5: Sản phẩm và ứng dụng
Trang 42
Chương 1: Đặt vấn đề 1.1 Gi ới thi u chung ệ
Ngày nay, các c m t "nhà thông minh" và "Internet v n v ụ ừ ạ ật kết n ối" thườ ng xuyên được nh ắc đến như là một xu hướ ng tiên ti ến, hướng con người đến với cuộ c s ng ti n nghi ố ệ
và tho i mái do công ngh mang l ả ệ ại Đó không còn là những thứ trong tương lai xa mà đã hiện di n kh ệ ở ắp nơi trên thế ớ gi i và ngay c ả ở Vi ệt Nam cũng đang có một thị trường c c ự
kỳ sôi động
Áp d ng nh ng ki n th ụ ữ ế ức đã học vào th c t ự ế, nhóm chúng em đã lự a ch ọn đề tài: “Smart Home” Hệ thống này có khả năng ứng dụng để cảnh báo rò rỉ khí gas, thu th p và bi u di n ậ ể ễ bằng đồ thị các chỉ số về nhi ệt độ - độ ẩm, đồng th ời điề u khi ển đượ c các thi t b qua giao ế ị diện
1.2 Các yêu cầu cơ bản
Hệ th ng phù h p v i nhu c u c ố ợ ớ ầ ủa người tiêu dùng, hướng đến đối tượng là h ộ gia đình
Hệ th ống đả m b ảo được độ chính xác
Giá thành phù h p, k ợ ết cấu nhỏ ọ g n
Hoạt độ ng ổn định trong các điề u kiện khác nhau
1.3 Phương pháp, phạm vi và gi i h n nghiên c u ớ ạ ứ
1.3.1 Phương pháp
Phương pháp lý thuyết
Đề xuất và nghiên c u các linh ki ứ ện đã có trong mạ ch qua các tài li u trên ệ Internet
Đưa ra cách giao tiếp giữa giao di n winforms và Arduino ệ
Phương pháp thực nghi m ệ
Tham kh ảo các mô hình trên Internet để ả c i ti n thi t k và m ế ế ế ục đích sử ụ d ng
1.3.2 Ph ạm vi đề tài và gi i h ớ ạn nghiên cứu
Được s d ử ụng trong các hộ gia đình, có thể ứng dụng trong công nghi ệp để ph c v an ụ ụ toàn và ti n l i cho các ho ệ ợ ạt độ ng t xa ừ
2.1 Linh ki n ệ
2.1.1 Arduino Uno R3
Trang 5Thông số cần lưu ý:
Chip điều khiển
chính ATmega328 h 8bit ọ
Nguồn nuôi mạch 5V từ cổng USB
Nguồn ngoài (cắm từ
giắc tròn DC) Khuyên dùng 7-9V để đảm bảo mạch hoạt động tốt Nếu bạn cắm 12V thì IC ổn áp rất dễ chết và gây hư hỏng mạch Dòng ra tối đa (5V) 500 mA
Số chân Digital 14 (hỗ trợ 6 chân PWM)
Số chân Analog 6
Dòng ra trên chân
digital tối đa 40 mA
Dòng ra trên chân
Dung lượng bộ nhớ
Flash 32 KB (ATmega328) 0.5 KB được sử dụng bootloader
EEPROM 1 KB (ATmega328)
Một số chân năng lượng:
Trang 64
GND (Ground): c c âm c a ngu ự ủ ồn điệ n c p cho Arduino UNO Khi b n dùng các ấ ạ thiết bị sử d ng nh ụ ững ngu ồn điệ n riêng bi t thì nh ng chân này ph i ệ ữ ả đượ c n i ố với nhau
5V: c ấp điện áp 5V đầ u ra Dòng t ối đa cho phép ở chân này là 500mA
3.3V: c ấp điện áp 3.3V đầ u ra Dòng t ối đa cho phép ở chân này là 50mA VIN (Voltage Input) : để ấ c p ngu n ngoài cho Arduino UNO, b n n i c ồ ạ ố ực dương của ngu n v ồ ới chân này và c c âm c a ngu n v i chân GND ự ủ ồ ớ
IOREF : điệ n áp ho ạt độ ng c ủa vi điề u khi n trên Arduino UNO có th ể ể được đo ở chân này Và dĩ nhiên nó luôn là 5V Mặc dù vậy bạn không được lấy ngu n 5V ồ
từ chân này để sử dụng b i ch ở ức năng củ a nó không ph i là c p ngu n ả ấ ồ RESET: vi c nh n nút Reset trên ệ ấ board để reset vi điều khiển tương đương với việc chân RESET đượ c nối v ới GND qua 1 điệ n trở 10K.
2.1.2 C m bi n DHT11 ả ế
Các đặc tính k thu ỹ ật quan tr ng: ọ
Nguồn điện 3,5v đến 5v
Mức tiêu thụ hiện tại 2,5mA
Tín hiệu đầu ra kỹ thuật số
Phạm vi nhiệt độ từ 0ºC đến 50ºC
Độ chính xác để đo nhiệt độ ở 25ºC, dao động khoảng 2ºC
Độ phân giải để đo nhiệt độ là 8-bit, 1ºC
Độ ẩm có thể đo từ 20% RH đến 90% RH
Độ ẩm chính xác 5% RH cho nhiệt độ từ 0-50ºC
Độ phân giải là 1% RH, nó không thể nhận các biến thể dưới mức đó
Các chân của DHT11:
Gồm 2 chân cấp nguồn (VCC, GND) và 1 chân tín hiệu (DATA)
Công dụng:
Dùng để đo nhiệt độ và độ ẩm với độ tin cậy và độ ổn định cao
2.1.3 Cảm biến MQ2
Trang 7Thông số kỹ thuật:
Công dụng
MQ2 là cảm biến khí, có thể phát hiện các loại khí (Metan, khói, …), khí có thể gây cháy
Nguyên lý hoạt động
Cảm biến được cấu tạo từ chất bán dẫn SnO2 Chất này có độ nhạy cảm thấp với không khí sạch Nhưng khi trong môi trườ ng có ch ất gây cháy, độ dẫn của nó thay đổ i ngay Cảm bi ến khí gas MQ2 đưa ra chân A0 điệ n áp t ừ 0V đến 5V tương ứ ng v i n ớ ồng độ ch t ấ gây cháy trong không khí Chúng ta có th k t h p v i các b chuy ể ế ợ ớ ộ ển đổi để đọ c tín hi u ệ điện áp này và đo lườ ng ch ất lượ ng không khí
Ngoài ra, module đượ c tích hợp bộ so sánh lm393 để đưa ra điện áp mức 0 hoặc mức 1 Bi n tr ế ở điều ch ỉnh độ nh y c a c m bi n, khi tín hi u t ạ ủ ả ế ệ ừ chân A0 vượ t quá giá tr ị
mà ta cài đặ t ở biến trở Module sẽ đưa ra mứ c 1 ở chân DO
2.1.4 Màn hình LCD 16x2 (I2C)
Trang 86
Thông s k thu t: ố ỹ ậ
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 ể ử ụ ở ế độ 4bit ho c 8bit tùy theo ng d ặ ứ ụng ta đang làm 2.2 Sơ đồ khối và sơ đồ thuật toán
Sơ đồ khối:
Khối x lý trung tâm ử
Giao di n ệ
Trang 9Sơ đồ ho ạt độ ng:
Cảm bi n ế
Biểu di n s ễ ố liệu và đồ thị
Biểu di n s ễ ố liệu trên màn hình LCD
So sánh với n ng ồ
độ gas cho phép
Còi Lớn hơn
Nhỏ hơn
Cổng Serial
Cổng Serial HIGH
LOW
HIGH Điều khiển
đèn, quạt
Trang 108
Sơ đồ nối mạch:
Trang 11Chương 3: Giao tiếp giữa Module I2C và Arduino Uno R3
Hoạt động
I2C s d ng 2 dây giao ti p là SCL và SDA Dây SCL (vi t t t c a Serial Clock Data) là ử ụ ế ế ắ ủ dây truy n xung clock phát t thi t b master ng b v i vi c truy n d ề ừ ế ị đồ ộ ớ ệ ề ữ li u Dây SDA ệ (Serial Data) là dây truy n d li u ề ữ ệ
Mạch v t lý I2C là m ậ ạch c c thu h ự ở, do đó để ạng I2C có th ho m ể ạt động được, cần tối thiểu 2 c ặp điệ n tr ở pull-up như trên hình, thông thường các giá trị điện trở 4k7 ho c ặ 1k2 được sử dụng, tùy thu c vào t ộ ốc độ truy n và kho ng cách truy n ề ả ề
Truyền nhận bit trong I2C
Các d li ữ ệu đượ c truy n trong I2C d ng các chu i 8 bit Sau khi bit ề ạ ỗ Start đầu tiên đượ c truyền, 8 bit ti p theo ch ế ứa thông tin về địa chỉ c a thi t b ủ ế ị sẽ được truy n ti ề ếp Sau đó, một bit ACK ẽ được truy s ền để xác nh n vi c truy n bit thành công Sau khi truy n ậ ệ ề ề bit ACK , 8 bit ti p theo ch ế ứa thông tin địa chỉ thanh ghi n i c a thi t b slave s ộ ủ ế ị ẽ đượ c truyền Sau khi hoàn t t vi ấ ệc định đị a ch ỉ với 8 bit này, một bit ACK ữ ẽ n a s được truy n ề
để xác nhận Sau đó, 8 bit Data sẽ được truy n ti p theo Cu i cùng, quá trình truy n k ề ế ố ề ết thúc v i 1 bit ớ ACK và 1 bit Stop xác nh n vi c truy n d ậ ệ ề ữ li u k t thúc ệ ế
Trang 1210
Với màn hình LCD 16x2 có h tr chu n giao ti p I2C thì s có 2 chân có tên SCL và ỗ ợ ẩ ế ẽ SDA, tương ứng với 2 dây SCL, SDA cho giao ti p I2C V i board Arduino Uno, chân ế ớ A4 là chân SDA và chân A5 là chân SCL, 2 chân A4, A5 này cũng được nối tới 2 chân SDA, SCL tương ứng ở header sử dụng với OLED c a board Arduino Uno V i các IC ủ ớ
và vi điề u khi ển đượ c sản xu ất ngày nay đề u có hỗ trợ điện tr n ở ội kéo lên do đó trong việc k t n ế ối dây không c ần thêm điệ n tr n ở ội kéo lên V i các module h tr I2C ch có 1 ớ ỗ ợ ỉ tính năng như OLED SSD1306, LCD 1602 hi n th , c m bi n AM2315 để ể ị ả ế để đọ c nhi t ệ
độ, độ ẩm của môi trường,… thường ho ạt độ ng ch ở ế độ slave và có 4 chân: SDA, SCL, GND và VCC
Trang 13Chương 4: Winforms và code lập trình Code Arduino:
#include <MQ2.h>
#include <DHT.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0X27,16,2);
const int DHTPIN = 2;
const int DHTTYPE = DHT11;
const int pin = A3;
int led1 =3;
int led2 =5;
int coi =4;
int val;
int tt1=0;
int tt2=0;
DHT dht(DHTPIN, DHTTYPE);
MQ2 mq2(pin);
void setup() {
Serial.begin(57600);
lcd.init();
lcd.backlight();
pinMode(led1,OUTPUT);
pinMode(coi,OUTPUT);
pinMode(led2,OUTPUT);
pinMode(6,INPUT_PULLUP); //led1
pinMode(7,INPUT_PULLUP); //led2
dht.begin();
mq2.begin();
}
void loop() {
int bled1=digitalRead(6);
int bled2=digitalRead(7);
while (Serial.available()) {
val = Serial.read();
}
if(bled1 == LOW ) {
if(tt1 == 0)
{tt1 = 1;
digitalWrite(led1,HIGH);
}
else {
digitalWrite(led1,LOW);
tt1=0;
}
}
if(bled2 == LOW ) { if(tt2 == 0) {tt2 = 1;
digitalWrite(led2,HIGH);
} else { digitalWrite(led2,LOW);
tt2=0;
} }
if (val == '1' ) { tt1 = 0;
digitalWrite(led1, LOW);
} else if (val == '2' ) { tt1 = 1;
digitalWrite(led1, HIGH);
}
if (val == '3') { digitalWrite(led2, LOW);
} else if (val == '4') { digitalWrite(led2, HIGH);
} float t = dht.readTemperature(); float h = dht.readHumidity();
float ppm = mq2.readSmoke()/20000;
if(ppm > 0.005) digitalWrite(coi,HIGH);
else digitalWrite(coi,LOW);
lcd.setCursor(0,0);
lcd.print("Nhiet Do:");
lcd.print(t); lcd.print(" C");
lcd.setCursor(0,1);
lcd.print("Do am: ");
lcd.print(h); lcd.print(" %RH"); lcd.write(1);
if(isnan(h) || isnan(t) || isnan(ppm) || isnan(tt1) || isnan(tt2)) {return;}
Serial.print("@");
Serial.print(t); Serial.print("A"); Serial.print(h); Serial.print("B"); Serial.print(ppm); Serial.print("C"); Serial.print("\n");
delay(500);
Trang 1412
- Code l p trình: ậ
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.Ports;
namespace demosmh
{
publicpartialclassForm1 : Form //Xây dựng class trên nhi u form v t lí ề ậ
{ //khai báo các biến
double temperature = 0, humidity = 0, ppm = 0;
bool updateData = false;
bool led = false;
bool fan = false;
double tt1;
double tt2;
public Form1()
{
InitializeComponent(); //khởi tạo các đối tượng trên form
}
private void Form1_Load(object sender, EventArgs e)
{
button_open.Enabled = true; // khai báo true cho button open
button_close.Enabled = false; // khai báo false cho button close
chart1.Series["Temperature"].Points.AddXY(1, 1); //Lấy dữ li u tệ ừ Tampertature
cho đồ ị th
chart1.Series["Humidity"].Points.AddXY(1, 1); //Lấy dữ li u t Humidity cho ệ ừ
đồ ị th
chart1.Series["PPM"].Points.AddXY(1, 1);
}
private void comboBox_portLists_DropDown(object sender, EventArgs e) // T o chân ạ
Port
{
string[] portLists = SerialPort.GetPortNames();
comboBox_portLists.Items.Clear();
comboBox_portLists.Items.AddRange(portLists);
}
private void button_open_Click(object sender, EventArgs e) // Khi n nút k t nấ ế ối
{
try
{
serialPort1.PortName = comboBox_portLists.Text;
serialPort1.BaudRate = Convert.ToInt32(comboBox_baudRate.Text);
Trang 15button_open.Enabled = false;
button_close.Enabled = true;
chart1.Series["Temperature"].Points.Clear();
chart1.Series["Humidity"].Points.Clear();
chart1.Series["PPM"].Points.Clear();
MessageBox.Show("Kết nối thành công !");
}
catch (Exception error)
{
MessageBox.Show(error.Message);
}
}
private void button_close_Click(object sender, EventArgs e) // Khi n nút ng t k t ấ ắ ế
nối
{
try
{
serialPort1.Close();
button_open.Enabled = true;
button_close.Enabled = false;
MessageBox.Show("Ngắt kết nối !");
}
catch (Exception error)
{
MessageBox.Show(error.Message);
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
serialPort1.Close();
}
catch (Exception error)
{
MessageBox.Show(error.Message);
}
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
// Nh n dậ ữ li u tệ ừ Serial
{
string dataIn = serialPort1.ReadTo("\n");
Data_Parsing(dataIn);
this.BeginInvoke(newEventHandler(Show_Data));
}
private void Show_Data(object sender, EventArgs e) // Hi n th d li u l y t ể ị ữ ệ ấ ừ
Serial
{
(updateData == if true)
Trang 1614
label_temperature.Text = string.Format("Temperature = {0}°C",
temperature.ToString());
label_humidity.Text = string.Format("Humidity = {0}%RH",
humidity.ToString());
label_ppm.Text = string.Format("Smoke = {0} ppm", ppm.ToString());
chart1.Series["Temperature"].Points.Add(temperature);
chart1.Series["Humidity"].Points.Add(humidity);
chart1.Series["PPM"].Points.Add(ppm);
}
}
private void Data_Parsing(string data) // Gi i mã d liả ữ ệu
{
sbyte indexOf_startDataCharacter = (sbyte)data.IndexOf("@");
sbyte indexOfA = (sbyte)data.IndexOf("A");
sbyte indexOfB = (sbyte)data.IndexOf("B");
sbyte indexOfC = (sbyte)data.IndexOf("C");
(indexOfA != -1 && indexOfB != -1 && indexOfC != -1 && if
indexOf_startDataCharacter != -1)
{
try
{
string str_temperature = data.Substring(indexOf_startDataCharacter + 1,
(indexOfA - indexOf_startDataCharacter) - 1); //láy d liữ ệu từ dãy mã hóa
string str_humidity = data.Substring(indexOfA + 1, (indexOfB - indexOfA)
- 1);
string str_ppm = data.Substring(indexOfB + 1, (indexOfC - indexOfB) -
1);
temperature = Convert.ToDouble(str_temperature);
humidity = Convert.ToDouble(str_humidity);
ppm = Convert.ToDouble(str_ppm);
updateData = true;
}
catch (Exception)
{
}
}
else
{
updateData = false;
}
}
private void label3_Click(object sender, EventArgs e){}
private void button1_Click(object sender, EventArgs e)
{
(led == if false)
{
serialPort1.Write("2");
button1.Text = "ON";
button1.BackColor = Color.Lime;
led = true;
}
else
{
serialPort1.Write("1");