HỌC VIỆN CƠNG NGHỆ BƯU CHÍNH VIỄN THƠNG KHOA ĐIỆN – ĐIỆN TỬ * * * * BÁO CÁO ĐỒ ÁN Môn: Đồ án thiết kế hệ thống nhúng Tên đề tài : Thiết kế ổ khóa mở mật điện thoại thông qua wifi GIẢNG VIÊN : TS Nguyễn Ngọc Minh HỌ VÀ TÊN Nguyễn Hải Anh – B17DCDT012 (NT) : Nguyễn Quang Huy – B17DCDT96 Lê Tùng Linh – B17DCDT108 Nguyễn Thị Quỳnh – B17DCDT156 NHÓM : 13 Mục Lục Lời Mở Đầu Trong năm gần đây, ngồi nhà thông minh xuất ứng dụng rộng rãi sống Điểm chung thiết bị thông minh có cho riêng vi xử lý đóng vai trò làm não điều khiển thiết bị Nên bọn em định thực đề tài ổ khóa thơng minh điều khiển mật kết nối wifi với điện thoại Ngoài việc hoàn thành đề tài với u cầu cịn có ý nghĩa với nhóm sinh viên thực chúng em, áp dụng kiến thức học nhà trường để hình thành sản phẩm hoàn thiện, cầm tay thực thứ đọc giấy Trong q trình tiến hành, nhóm em cố gắng để hoàn thiện đề tài cách tốt Nhưng với kinh nghiệm hiểu biết có hạn nên khơng tránh khỏi sai sót mong thầy đóng góp ý kiến cho đề tài nhóm em hồn thiện Nhiệm vụ yêu cầu giao − Thiết kế ổ khóa mở mật qua wifi kết nối với điện thoại, thay đổi trực tiếp mật ổ khóa Sơ đồ khối chức khối Khối nguồn Khối xử lý Khối nhập hiển thị Khối wif − Khối nguồn : adapter 5V cấp nguồn cho toàn hệ thống − Khối nhập hiển thị : keypad để nhập hiển thị lên LCD giao tiếp với người sử dụng − Khối wifi : NodeMCU esp8266 dùng để kết nối wifi, đưa tín hiệu ‘khối xử lý’ − Khối xử lý : Ardunio Nano xử lý liệu từ khối nhập khối wifi Tính datasheet linh kiện khối − Khối nhập hiển thị : • Nhập vào keypad, có tám chân pinout tương ứng với hàng cột • Hiện thị LCD thông qua giao tiếp I2C để tiết kiệm chân, giap tiếp với VXL chân SDA, SCL − Khối Wifi : − • Giao tiếp với điện thoại thông qua wifi ESP 8266 • Tín hiệu điều khiển từ điện thoại gửi đến ESP 8266 từ ESP 8266 chuyển khối xử lý để tính tốn − Khối xử lý : − • Ardunio Nano làm khối xử lý chính, nhân tín hiệu từ khối khác • • • • tính tốn đưa kết phù hợp với điều kiện lập trình sẵn Các chân D2 – D9 dùng xử lý Keypad D10 dùng điều khiển tín hiệu ổ khóa D11 D12 để nhận tín hiệu từ khối ESP chuyền vào để đóng mở khóa A4 A5 để giao tiếp I2C hiển thị lên LCD Sơ đồ nguyên lý hoạt động Lưu đồ thuật toán − Lưu đồ thuật toán Bắt đầu Khởi động khóa Nhấn A Khóa đóng, key = Keypad Điện thoại C.trình nhập “Nhấn pass Blynk app Nhấn “Nhấn Khóa” “Đúng” Nhập “Sai” Báo sai Mở khóa Sai = Nhấn “Nhấn D” “Nhấn B” C.trình đổi Cảnh báo Khóa cửa pass “Sai” “Đúng” Nhập pass Kết thúc “Nhấn C” Hình ảnh sản phẩm thực tế Nhận xét đánh giá sản phẩm sau chạy thử − Sau cho chạy thử nhóm em có nhận xét sau : Mạch đổi mật trực tiếp khơng cần nạp lại code Khóa hoạt động với điều kiện gắn vào phím keypad, chng báo hoạt động Mật sau bị ngắt nguồn lưu không bị Kết nối mở khóa wifi tạm thời bậy sử dùng app blynk − Những điểm tồn có điều kiện nhóm em khắc phục : Khi đổi mật khẩu, sau nhập pass lần chuyển đến phần xác nhận pass bị lỗi, tạm thời khắc phục nhấn “*” để xóa Mở khóa qua điện thoại tạm thời dùng app Blynk, theo yêu cầu kết nối điện thoại với ổ khóa để điều khiển ổ đóng/ mở Thay servo ổ khóa điện để trực quan Kết luận − Mạch báo cáo hoàn thiện yêu cầu thầy giao, nhiên tồn điểm nêu trên, nhóm chúng em cố gắng khắc phục để sản phẩm hồn thiện − Nhờ có đề tài giao lần này, nhóm em có hội tìm hiểu cách ổ khóa thơng minh hoạt động, nhớ lưu trữ Ardunio, giao tiếp wifi từ điện thoại đến node MCU thành phần khác Code #include // Khai báo thư viện sử dụng cho động #include #include #include // Khai báo thư viện LCD sử dụng I2C // Khai báo thư viện Keypad // nhớ lưu mật khẩu, tồn điện LiquidCrystal_I2C lcd(0x27, 16, 2); // 0x27 địa LCD, 16 cột hàng Servo myServo; 10 const byte ROWS = 4; // Bốn hàng const byte COLS = 4; // Bon cột char keys[ROWS][COLS] = { {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'} }; byte rowPins[ROWS] = {2, 3, 4, 5}; // R1 -> R4 -> byte colPins[COLS] = {6, 7, 8, 9}; // C1 -> C4 -> Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS); int i = 0;//biến đếm int KEY = 0;//trạng thái khóa int sai = 0;//dùng báo động int count = 0;//tác dụng biến "vong" int vong = 0;//quyết định chương trình khóa //mật có kí tự char datpass[4] = {' ',' ',' ',' '}; //biến mật nhập vào char nhappass[4] = {' ',' ',' ',' '}; //các biến mật nhập vào muốn đổi char doipass[4] = {' ',' ',' ',' '}; //các biến xác nhận lai mat khau doi pass 11 char xacnhan[4] = {' ',' ',' ',' '}; void setup(){ Serial.begin(9600); myServo.attach(10);// chan 10 dieu khien Servo myServo.write(180);// dong khoa pinMode(11, INPUT);// 11 high = mở khóa ,dieu khien rieng = esp pinMode(12, INPUT);// 12 high = đóng khóa, pinMode(13, OUTPUT);// chân còi báo động lcd.init(); lcd.begin(16, 2); lcd.backlight(); lcd.clear(); lcd.setCursor(3,0); lcd.print("I'M READY "); delay(1000); lcd.clear(); lcd.setCursor(5,0); lcd.print("CLOSED"); myServo.write(180); //pass mặc định 1234, thay đổi sau nạp code //sau đổi mật khẩu, xóa dịng nạp lại code để lưu pass // EEPROM.write(0, '1'); // EEPROM.write(1, '2'); // EEPROM.write(2, '3'); // EEPROM.write(3, '4'); 12 //lấy mật đặt nhớ datpass[0] = EEPROM.read(0); datpass[1] = EEPROM.read(1); datpass[2] = EEPROM.read(2); datpass[3] = EEPROM.read(3); //xem pass Serial.println(datpass[0]); Serial.println(datpass[1]); Serial.println(datpass[2]); Serial.println(datpass[3]); } void loop(){ char key = keypad.getKey();// biến nhập vào gán cho key switch(key){ case 'A':// nhấn A bắt đầu vào nhập pass if(vong == 0){ lcd.clear(); lcd.setCursor(1,0); lcd.print("Nhap Mat Khau"); vong = 1; } break; case '*': // nhấn * xóa hết if(vong == && KEY == 0){ i = 0; lcd.clear(); 13 lcd.setCursor(1,0); lcd.print("Nhap Mat Khau"); } if(vong == 2){ i = 0; lcd.clear(); lcd.setCursor(1,0); lcd.print("Nhap Pass Moi"); } if(vong == 3){ i = 0; lcd.clear(); lcd.setCursor(1,0); lcd.print("Nhap Lai Pass"); } break; case '#':// nhấn # để xác nhận pass if(vong == && KEY == 0){ // xác nhận pass nhập mk mở khóa if(nhappass[0]==datpass[0] && nhappass[1]==datpass[1] && nhappass[2]==datpass[2] && nhappass[3]==datpass[3]){ digitalWrite(13, HIGH);// coi thong bao delay(200); digitalWrite(13, LOW); lcd.clear(); lcd.setCursor(1,0); lcd.print("Mat Khau Dung"); delay(1000); 14 lcd.clear(); lcd.setCursor(5,0); lcd.print("OPENED"); myServo.write(90); i = 0; sai = 0; KEY = 1; } else{ i = 0; ++sai; lcd.clear(); lcd.setCursor(1,0); lcd.print("Mat Khau Sai"); delay(1000); lcd.clear(); lcd.setCursor(1,0); lcd.print("Nhap Mat Khau"); } } if(count == 4){ // vong = 4, sau nhập lại mk if(doipass[0]==xacnhan[0] && doipass[1]==xacnhan[1] && doipass[2]==xacnhan[2] && doipass[3]==xacnhan[3]){ digitalWrite(13, HIGH);// coi thong bao delay(200); digitalWrite(13, LOW); lcd.clear(); lcd.setCursor(3,0); lcd.print("THANH CONG"); 15 datpass[0] = doipass[0]; datpass[1] = doipass[1]; datpass[2] = doipass[2]; datpass[3] = doipass[3]; //ghi lại pass vào nhớ EEPROM EEPROM.write(0,datpass[0]); EEPROM.write(1,datpass[1]); EEPROM.write(2,datpass[2]); EEPROM.write(3,datpass[3]); delay(1000); lcd.clear(); lcd.setCursor(5,0); lcd.print("CLOSED"); myServo.write(180); i = 0; vong = 0; KEY = 0; sai = 0; count = 0; } else{ lcd.clear(); lcd.setCursor(4,0); lcd.print("THAT BAI"); vong = 2; i = 0; count = 0; delay(1000); } } 16 break; case 'D':// khóa mở, nhấn D để đóng khóa if(KEY == && vong != && vong != 3){ digitalWrite(13, HIGH);// coi thong bao delay(200); digitalWrite(13, LOW); lcd.clear(); lcd.setCursor(4,0); lcd.print("Dong Cua"); delay(1000); lcd.clear(); lcd.setCursor(5,0); lcd.print("CLOSED"); myServo.write(180); vong = 0; KEY = 0; nhappass[0] = 0; nhappass[1] = 0; nhappass[2] = 0; nhappass[3] = 0; } break; case 'B': // khóa mở, nhấn nút B đẩy vào chương trình đổi mật if(KEY == 1){ digitalWrite(13, HIGH);// coi thong bao delay(200); digitalWrite(13, LOW); lcd.clear(); 17 vong = 2; // vong = 2, đẩy vào chương trình đổi mật i = 0; } break; case 'C': // nhấn C để khỏi chương trình đổi mật if(vong == 2){ lcd.clear(); lcd.setCursor(4,0); lcd.print(" Back "); delay(700); lcd.clear(); lcd.setCursor(5,0); lcd.print("OPENED"); vong = 1; i = 0; } if(vong == 3){ lcd.clear(); lcd.setCursor(4,0); lcd.print(" Back "); delay(700); lcd.clear(); lcd.setCursor(5,0); lcd.print("OPENED"); vong = 1; i = 0; count = 0; } break; 18 } if(vong == && KEY == 0){// sau nhân A, bắt đầu chương trình nhập pass if(key && key != '*' && key != '#' && key != 'A' && key != 'D' && key != 'B' && key != 'C'){ if(i == && key != '*' && key != '#' && key != 'A' && key != 'D' && key != 'B' && key != 'C'){ nhappass[0] = key; lcd.setCursor(6, 1); lcd.print(nhappass[0]); delay(300); lcd.setCursor(6, 1); lcd.print("*"); } if(i == && key != '*' && key != '#' && key != 'A' && key != 'D' && key != 'B' && key != 'C'){ nhappass[1] = key; lcd.setCursor(7, 1); lcd.print(nhappass[1]); delay(300); lcd.setCursor(7, 1); lcd.print("*"); } if(i == && key != '*' && key != '#' && key != 'A' && key != 'D' && key != 'B' && key != 'C'){ nhappass[2] = key; lcd.setCursor(8, 1); lcd.print(nhappass[2]); delay(300); lcd.setCursor(8, 1); 19 lcd.print("*"); } if(i == && key != '*' && key != '#' && key != 'A' && key != 'D' && key != 'B' && key != 'C'){ nhappass[3] = key; lcd.setCursor(9, 1); lcd.print(nhappass[3]); delay(300); lcd.setCursor(9, 1); lcd.print("*"); } ++i; } } if(vong == 2){ // chương trình đổi mật lcd.setCursor(1,0); lcd.print("Nhap Pass Moi"); if(key && key != '*' && key != '#' && key != 'A' && key != 'D' && key != 'B' && key != 'C'){ if(i == && key != '*' && key != '#' && key != 'A' && key != 'D' && key != 'B' && key != 'C'){ doipass[0] = key; lcd.setCursor(6, 1); lcd.print(doipass[0]); delay(300); lcd.setCursor(6, 1); lcd.print("*"); } 20 if(i == && key != '*' && key != '#' && key != 'A' && key != 'D' && key != 'B' && key != 'C'){ doipass[1] = key; lcd.setCursor(7, 1); lcd.print(doipass[1]); delay(300); lcd.setCursor(7, 1); lcd.print("*"); } if(i == && key != '*' && key != '#' && key != 'A' && key != 'D' && key != 'B' && key != 'C'){ doipass[2] = key; lcd.setCursor(8, 1); lcd.print(doipass[2]); delay(300); lcd.setCursor(8, 1); lcd.print("*"); } if(i == && key != '*' && key != '#' && key != 'A' && key != 'D' && key != 'B' && key != 'C'){ doipass[3] = key; lcd.setCursor(9, 1); lcd.print(doipass[3]); delay(300); lcd.setCursor(9, 1); lcd.print("*"); delay(500); digitalWrite(13, HIGH);// coi thong bao delay(200); digitalWrite(13, LOW); 21 lcd.clear(); i = 0; vong = 3; // sau nhập xog pass mới, đẩy vào chương trình xác nhận pass } ++i; } } if(vong == 3){ // chương trình xác nhận lại mật lcd.setCursor(1,0); lcd.print("Nhap Lai Pass"); if(key && key != '*' && key != '#' && key != 'A' && key != 'D' && key != 'B' && key != 'C'){ if(i == && key != '*' && key != '#' && key != 'A' && key != 'D' && key != 'B' && key != 'C'){ xacnhan[0] = key; lcd.setCursor(6, 1); lcd.print(xacnhan[0]); delay(300); lcd.setCursor(6, 1); lcd.print("*"); } if(i == && key != '*' && key != '#' && key != 'A' && key != 'D' && key != 'B' && key != 'C'){ xacnhan[1] = key; lcd.setCursor(7, 1); lcd.print(xacnhan[1]); delay(300); lcd.setCursor(7, 1); lcd.print("*"); 22 } if(i == && key != '*' && key != '#' && key != 'A' && key != 'D' && key != 'B' && key != 'C'){ xacnhan[2] = key; lcd.setCursor(8, 1); lcd.print(xacnhan[2]); delay(300); lcd.setCursor(8, 1); lcd.print("*"); } if(i == && key != '*' && key != '#' && key != 'A' && key != 'D' && key != 'B' && key != 'C'){ xacnhan[3] = key; lcd.setCursor(9, 1); lcd.print(xacnhan[3]); delay(300); lcd.setCursor(9, 1); lcd.print("*"); count = 4; // nhập xog pass lần 2, đẩy vào chương trình kiểm tra pass } ++i; } } if(sai == 3){ // nhập pass sai lần tạm khóa // coi bao dong lcd.clear(); lcd.setCursor(0,0); lcd.print("Nhap sai lan !"); digitalWrite(13, HIGH); 23 delay(300); digitalWrite(13, LOW); delay(300); digitalWrite(13, HIGH); delay(300); digitalWrite(13, LOW); delay(300);// coi keu lan digitalWrite(13, HIGH); delay(1000); digitalWrite(13, LOW); // còi xong đếm ngược 15s lcd.clear(); lcd.setCursor(4,0); lcd.print("Wait "); for(int x = 15; x >= 0; x ){ if( x