You are on page 1of 25

Hệ thống cảnh báo khí ga

 Môn học: Vi xử lý  Mã lớp: 145807


 Sinh viên thực hiện:
 Tạ Quang Nam - 20205383

 Khổng Hữu Ngọc Cương - 20205263


 GVHD: TS. Nguyễn Hữu Quang
I. Lý do chọn đề tài
II. Linh kiện và thiết bị sử dụng
III. Vẽ mạch trên protues
IV. Code chương trình
V. Kết quả
I. Lý do chọn đề tài:

1.Tính ứng dụng cao: Hệ thống cảnh báo


khí ga là một ứng dụng thực tế và quan
trọng trong nhiều lĩnh vực như công
nghiệp, gia đình, hoặc các môi trường đặc
biệt như nhà máy, các khu vực nguy hiểm.
2.An toàn và sức khỏe: Nó liên quan trực
tiếp đến việc bảo vệ sức khỏe và an toàn
của con người. Việc phát hiện sớm và cảnh
báo về khí gas có hại giúp tránh được nguy
cơ ngộ độc, cháy nổ, hoặc các tai nạn đáng
tiếc.
3.Kỹ thuật số và vi xử lý: Đề tài này sẽ
giúp em áp dụng và phát triển các kiến thức
về vi xử lý vào thực tế. Có thể thực hiện
việc xử lý dữ liệu từ các cảm biến, xuất tín
hiệu lên màn hình LCD, và bật cảnh báo
bằng còi nếu nồng độ khí ga cao.
II. Linh kiện, thiết bị sử dụng:

1.Arduino Uno R3

STT​ Tên thông số​ Đặc tính​

1.​ Vi xử lý ATMega 328P​


2.​ Điện áp hoạt động​ 1.8 – 5.5V​
3.​ Digital I/O pin​ 14​
4.​ PWM Digital I/O Pin​ 6​
5.​ Analog Input Pin​ 6​
6.​ Cường độ dòng điện ngõ 20mA​
ra​
7.​ Flash Memory​ 32 KB (ATMega 328P)​
8.​ SRAM​ 2 KB (ATMega 328P)​
9.​ EEPROM​ 1 KB (ATMega 328P)​
10.​ Tốc độ​ 16 MHz​
II. Linh kiện, thiết bị sử dụng:

Các chân phục vụ cho


chức năng giao tiếp với
1.Arduino Uno R3 còi và đèn

Các chân phục vụ cho


chức năng giao tiếp với
LCD
Chân phục vụ cho chức
năng giao tiếp với
cảm biến khí ga
II. Linh kiện, thiết bị sử dụng:

2.Màn hình LCD 16x2

Thông số kỹ thuật:
• Điện áp hoạt động là 5V.
• Kích thước: 80 x 36 x 12.5mm
• Chữ trắng, nền xanh dương
• 16 chân.
II. Linh kiện, thiết bị sử dụng:

2.Màn hình LCD 16x2


Chân Ký hiệu Mô tả Giá trị
1 VSS GND 0V
2 VCC 5V
3 V0 Độ tương phản
4 RS Lựa chọn thanh ghi RS=0 (mức thấp) chọn
thanh ghi lệnh
RS=1 (mức cao) chọn
thanh ghi dữ liệu

5 R/W Chọn thanh ghi đọc/viết dữ liệu R/W=0 thanh ghi viết
R/W=1 thanh ghi đọc

6 E Enable
7 DB0 Chân truyền dữ liệu 8 bit: DB0DB7
8 DB1
9 DB2
10 DB3
11 DB4
12 DB5
13 DB6
14 DB7
15 A Cực dương led nền 0V đến 5V

16 K Cực âm led nền 0V


II. Linh kiện, thiết bị sử dụng:

2.Màn hình LCD 16x2


II. Linh kiện, thiết bị sử dụng:

3. Cảm biến khí ga MQ2


Thông số kĩ thuật :
• Điện áp hoạt động: 3.3V-5V
• Kích thước PCB: 3.2cm * 2cm
• Led đỏ báo nguồn vào, Led xanh báo gas
•VCC: 3.3V-5V
•GND: 0V
•DO: Đầu ra tín hiệu số (0 và 1)
•AO: Đầu ra Analog (Tín hiệu tương tự)
II. Linh kiện, thiết bị sử dụng:

3. Cảm biến khí ga MQ2


Thông số kĩ thuật :
• Điện áp hoạt động: 3.3V-5V
• Kích thước PCB: 3.2cm * 2cm
• Led đỏ báo nguồn vào, Led xanh báo gas
•VCC: 3.3V-5V
•GND: 0V
•DO: Đầu ra tín hiệu số (0 và 1)
•AO: Đầu ra Analog (Tín hiệu tương tự)
II. Linh kiện, thiết bị sử dụng:

4. Các link kiện khác


III. Vẽ mạch trên protues
IV. Code chương trình

1. Các lệnh tiền xử lý:


#define F_CPU 16000000UL
#include <avr/io.h> // Thư viện định nghĩa và hàm I/O của vi điều khiển AVR
#include <util/delay.h>
#include <stdio.h> // Thư viện chuẩn C cho việc nhập/xuất chuẩn

// Định nghĩa các lệnh điều khiển màn hình LCD


#define LCD_CLEAR 0x01 // Lệnh xóa nội dung trên màn hình LCD
#define LCD_RETURN_HOME 0x02 // Lệnh trả con trỏ về vị trí ban đầu trên màn hình LCD
#define LCD_ENTRY_MODE 0x06 // Lệnh thiết lập chế độ di chuyển của con trỏ sau mỗi ký tự
#define LCD_DISPLAY_ON 0x0C // Lệnh bật hiển thị màn hình LCD và tắt con trỏ
#define LCD_FUNCTION_SET 0x28 // Lệnh thiết lập chức năng cơ bản của màn hình LCD (4-bit data, 2 lines, font 5x8)
#define LCD_SET_CGRAM_ADDR 0x40 // Lệnh thiết lập địa chỉ CGRAM (Character Generator RAM)
#define LCD_SET_DDRAM_ADDR 0x80 // Lệnh thiết lập địa chỉ DDRAM (Display Data RAM)

// Định nghĩa các chân kết nối với màn hình LCD
#define LCD_RS_PIN PD0
#define LCD_RW_PIN PD1
#define LCD_EN_PIN PD2
#define LCD_D4_PIN PD4
#define LCD_D5_PIN PD5
#define LCD_D6_PIN PD6
#define LCD_D7_PIN PD7

// Khai báo các hàm lcd


void lcd_command(uint8_t cmd); // Hàm gửi lệnh tới LCD
void lcd_data(uint8_t data); // Hàm gửi dữ liệu tới LCD
void lcd_init(); // Hàm khởi tạo LCD
void lcd_clear(); // Hàm xóa màn hình LCD
void lcd_set_cursor(uint8_t row, uint8_t col); // Hàm đặt vị trí con trỏ trên LCD
void lcd_write_string(const char* str); // Hàm viết chuỗi lên LCD
IV. Code chương trình

2. Định nghĩa các hàm sử dụng:


void lcd_command(uint8_t cmd) { // Hàm gửi lệnh tới LCD
// Set RS and RW pins to command mode
PORTD &= ~(1 << LCD_RS_PIN); // gửi lệnh
PORTD &= ~(1 << LCD_RW_PIN); // ghi dữ liệu lên LCD
// Send command to LCD in 4-bit mode
PORTD = (PORTD & 0x0F) | (cmd & 0xF0); // Send high nibble
PORTD |= (1 << LCD_EN_PIN);
_delay_us(1);
PORTD &= ~(1 << LCD_EN_PIN);
_delay_us(100);
PORTD = (PORTD & 0x0F) | ((cmd << 4) & 0xF0); // Send low nibble
PORTD |= (1 << LCD_EN_PIN); // tạo ra xung nhấn (pulse) cho màn hình LCD.
_delay_us(1);
PORTD &= ~(1 << LCD_EN_PIN);
_delay_us(200);
}
void lcd_data(uint8_t data) { // Hàm gửi dữ liệu tới LCD
// Set RS pin to data mode
PORTD |= (1 << LCD_RS_PIN); // gửi dữ liệu
PORTD &= ~(1 << LCD_RW_PIN); //ghi dữ liệu lên LCD
// Send data to LCD in 4-bit mode
PORTD = (PORTD & 0x0F) | (data & 0xF0); // Send high nibble
PORTD |= (1 << LCD_EN_PIN);
_delay_us(1);
PORTD &= ~(1 << LCD_EN_PIN);
_delay_us(100);
PORTD = (PORTD & 0x0F) | ((data << 4) & 0xF0); // Send low nibble
PORTD |= (1 << LCD_EN_PIN);
_delay_us(1);
PORTD &= ~(1 << LCD_EN_PIN);
_delay_us(200);
}
IV. Code chương trình

2. Định nghĩa các hàm sử dụng:


// Hàm khởi tạo LCD
void lcd_init() {
// Set LCD pins as outputs
DDRD |= (1 << LCD_RS_PIN) | (1 << LCD_RW_PIN) | (1 << LCD_EN_PIN) |
(1 << LCD_D4_PIN) | (1 << LCD_D5_PIN) | (1 << LCD_D6_PIN) |
(1 << LCD_D7_PIN);
_delay_ms(15);
// Initialize LCD in 4-bit mode
lcd_command(0x02); // Con trỏ trỏ về vị trí ban đầu
lcd_command(LCD_FUNCTION_SET); // Lệnh thiết lập LCD (4-bit data, 2 lines, font 5x8)
lcd_command(LCD_DISPLAY_ON); // Lệnh bật hiển thị màn hình LCD và tắt con trỏ
lcd_command(LCD_ENTRY_MODE);
lcd_clear();
}
// Hàm xóa LCD
void lcd_clear() {
lcd_command(LCD_CLEAR);
_delay_ms(2);
}
// Hàm đặt vị trí con trỏ trên LCD
void lcd_set_cursor(uint8_t row, uint8_t col) {
uint8_t address = 0x80; // Set initial address to 0x80
if (row == 1) {
address += 0x40; // Move to the second row }
address += col; // Set column address
lcd_command(address); // Send command to set cursor position
}
// Hàm viết chuỗi lên LCD
void lcd_write_string(const char* str) {
while (*str) {
lcd_data(*str++); }
}
IV. Code chương trình

2. Định nghĩa các hàm sử dụng:


// Hàm khởi tạo ADC
void init_ADC() {
ADMUX |= (1 << REFS0); // Sử dụng AVCC làm điện áp tham chiếu 5V
ADCSRA |= (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
}

// Hàm đọc giá trị ADC từ cảm biến khí


uint16_t read_gas_sensor() {
ADMUX &= 0xF0;
ADMUX |= 0x00;
ADCSRA |= (1 << ADSC); // Bắt đầu chuyển đổi ADC
while (ADCSRA & (1 << ADSC)); // Chờ cho quá trình chuyển đổi hoàn thành

return ADC; // Trả về giá trị ADC


}
// Hàm kích hoạt còi và led báo độ cao của cảm biến khí
void activate_buzzer() {
DDRB |= (1 << PB0);
DDRB |= (1 << PB1);
// Kích hoạt còi báo và đèn led trong thời gian ngắn
PORTB |= (1 << PB0);
PORTB |= (1 << PB1);
_delay_ms(500);
PORTB &= ~(1 << PB0);
PORTB &= ~(1 << PB1);
}
IV. Code chương trình

3. Hàm main:
int main(void) {
// Khởi tạo LCD
lcd_init();
init_ADC();

while (1) {
// Đọc từ cảm biến khí
uint16_t gasValue = 0;
gasValue = read_gas_sensor();
// Chuyển đổi giá trị khí thành chuỗi
char gasString[10];
sprintf(gasString, "%d", gasValue); // Hàm chuyển đổi giá trị từ số sang kí tự
// Kiểm tra mức khí và kích hoạt còi báo nếu cao
if (gasValue > 45) {
activate_buzzer();
}
// Hiển thị giá trị khí trên LCD
lcd_clear();
lcd_set_cursor(0, 0);
lcd_write_string("Gas Value:");
lcd_set_cursor(1, 0);
lcd_write_string(gasString);
_delay_ms(500); // Độ trễ giữa các đọc giá trị
}
return 0;
}
V. Kết quả đạt được
THANK YOU !
VI. Bộ chuyển đổi ADC
VI. Bộ chuyển đổi ADC

*Có 4 thanh trong bộ ADC trên AVR trong đó có 2 thanh ghi data chứa dữ liệu sau
khi chuyển đổi, 2 thanh ghi điều khiển và chứa trạng thái của ADC.
- ADMUX (ADC Multiplexer Selection Register): là 1 thanh ghi 8 bit điều
khiển việc chọn điện áp tham chiếu, kênh và chế độ hoạt động của ADC.

Bit 7:6- REFS1:0 (Reference Selection Bits): là các bit chọn điện áp tham chiếu cho ADC

Bit 5-ADLAR (ADC Left Adjust Result): là bit cho phép hiệu chỉnh trái kết quả chuyển đổi
Nếu ADLAR=0 kết quả sẽ được hiệu chỉnh về phía phải (thanh ghi ADCL chứa trọn 8 bit thấp và
thanh ghi ADCH chứa 2 bit cao trong 10 bit kết quả), và nếu ADLAR=1 thì kết quả được hiệu chỉnh
trái (thanh ghi ADCH chứa trọn 8 bit cao nhất, các bit từ 9 đến 2, và thanh ADCL chứa 2 bit thấp nhất
trong 10 bit kết quả.
VI. Bộ chuyển đổi ADC

Bits 4:0-MUX4:0 (Analog Channel and Gain Selection Bits): là 5 bit cho phép chọn kênh,
chế độ và cả hệ số khuyếch đại cho ADC

-ADCSRA (ADC Control and Status RegisterA): là thanh ghi chính điều khiển hoạt động
và chứa trạng thái của module ADC.
VI. Bộ chuyển đổi ADC

Từng bit của thanh ghi ADCSRA được mô tả như bên dưới:
•Bit 7 - ADEN(ADC Enable): viết giá trị 1 vào bit này tức bạn đã cho phép module ADC
được sử dụng.
•Bit 6 - ADSC(ADC Start Conversion): set bit này lên 1 là bắt đầu khởi động quá trình
chuyển đổi.
•Bit 2:0 – ADPS2:0(ADC Prescaler Select Bits): các bit chọn hệ số chia xung nhịp cho
ADC. ADC, cũng như tất cả các module khác trên AVR, cần được giữ nhịp bằng một
nguồn xung clock. Xung nhịp này được lấy từ nguồn xung chính của chip thông qua một
hệ số chia. Các bit ADPS cho phép người dùng chọn hệ số chia từ nguồn clock chính đến
ADC. Tham khảo bảng 4 để biết cách chọn hệ số chia.
VI. Bộ chuyển đổi ADC

- ADCL và ADCH (ADC Data Register): 2 thanh ghi chứa giá trị của quá trình chuyển
đổi. Do module ADC trên AVR có độ phân giải tối đa 10 bits nên cần 2 thanh ghi để chứa
giá trị chuyển đổi. Tuy nhiên tổng số bít của 2 thanh ghi 8 bit là 16, con số này nhiều hơn
10 bit của kết quả chuyển đổi, vì thế chúng ta được phép chọn cách ghi 10 bit kết quả vào
2 thanh ghi này. Bit ADLAR trong thanh ghi ADMUX quy định cách mà kết quả được ghi
vào.
ADLAR = 0

ADLAR =1

Thông thường, 2 thanh ghi data được sắp xếp theo định dạng ADLAR=0, ADCL chứa 8
bit thấp và 2 bit thấp của ADCH chứa 2 bit cao nhất của giá trị thu được. Chú ý thứ tự đọc
giá trị từ 2 thanh ghi này, để tránh đọc sai kết quả, bạn cần đọc thanh ghi ADCL trước và
ADCH sau, vì sau khi ADCH được đọc, các thanh ghi data có thể được cập nhật giá trị tiếp
theo.

You might also like