Chế khoá cửa sử dụng thẻ RFID và Arduino

Một ngày đẹp trời, bạn nhìn cánh cửa cũ kỹ đã chục năm rồi của nhà mình và chợt nảy sinh ý tưởng biến nó trở nên “lạ hơn” (chưa chắc đã ngon hơn =.=!), đó là lúc bạn bắt đầu đọc bài này 😛

Chuẩn bị

Bắt đầu

Mach RFID CR522 sử dụng để đọc và ghi dữ liệu cho thẻ NFC. Với thiết kế nhỏ gọn, đây là lựa chon hàng đầu cho việc ứng dụng đọc ghi thẻ RFID. Trong bài hôm nay, chúng ta sử dụng module này để đọc ID của thẻ NFC, coi như là mật khẩu để đăng nhập vào phòng.

Pinout module RFID RC522:

Trong bài hôm nay, chúng ta sẽ kết nối module trên với Arduino qua giao thức SPI.

Việc đầu tiên chúng ta cần phải làm là tải thư viện MFRC522. Sau đó là đọc ID của thẻ bạn định dùng làm Master:

Các bạn lắp như sơ đồ trên và upload code sau lên Arduino:

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10
#define RST_PIN 9
#define SPEAKER 8


MFRC522 RC522(SS_PIN, RST_PIN);       

void setup() {
  Serial.begin(9600);     
 
  SPI.begin();            
  RC522.PCD_Init(); 
}

void loop() {
  if (RC522.PICC_IsNewCardPresent()) {
    if (RC522.PICC_ReadCardSerial()) {
      tone(SPEAKER ,500);
      
      Serial.println("================================================");
      Serial.println("Hex:");
      for (byte i = 0; i < RC522.uid.size; i++) {
        Serial.print(RC522.uid.uidByte[i]<0x10?" 0":" ");    
        Serial.print(RC522.uid.uidByte[i],HEX);
      } 
      Serial.println();
  
      Serial.println("Dec:");
      for (byte i = 0; i < RC522.uid.size; i++) {
      Serial.print(RC522.uid.uidByte[i]<100?RC522.uid.uidByte[i]<10?" 00":" 0" :" ");    
      Serial.print(RC522.uid.uidByte[i]);
      } 
      Serial.println();
      noTone(SPEAKER);
      
      RC522.PICC_HaltA();                       
    }
  }
}

Sau khi nạp xong, bạn mở Serial Monitor lên và đưa thẻ lại gần bộ đọc. Bạn sẽ thấy kết quả tương sự như sau:

Vậy là bạn đã biết mã số ID của thẻ mình định làm Master rồi 🙂

Tiếp theo, bạn upload code sau lên Arduino, nhớ thay dòng

const byte Master[]={0x7A, 0x03, 0x92, 0xAB};

bằng ID của thẻ Master mình đã lấy ở trên nhé.

#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>

#define SS_PIN 10
#define RST_PIN 9
#define SPEAKER 8
#define LED_STT 7
#define SERVO 6
#define BUTTON_CL 5
#define BUTTON_PW 4
#define LED_CL 3
#define RELAY 2

MFRC522 RC522(SS_PIN, RST_PIN);       
Servo Lock;

const byte Master[]={0x7A, 0x03, 0x92, 0xAB};

bool LogIn = false;
bool Door =false;
bool Relay = false;

byte resultRFID;
byte logCaution = 0;
/*---------------------------------------------------------------
 * RFID 
 * Input: mảng RFID cần so sánh
 * Output:
 *    0: không có thẻ
 *    1: thẻ đúng
 *    2: thẻ sai
 --------------------------------------------------------------*/
byte ReadRFID(byte RFID[]){
   byte Test = 0;
   if (RC522.PICC_IsNewCardPresent()) {
    if (RC522.PICC_ReadCardSerial()) {
      for (byte i = 0; i < RC522.uid.size; i++) {    
        if (RFID[i] == RC522.uid.uidByte[i]){
          Test = 1;
        } else { 
          Test = 2;
          break;
        }
      } 
      RC522.PICC_HaltA();                       
    }
  }
  return Test;
}
/*---------------------------------------------------------------
 * Sound
 --------------------------------------------------------------*/
void makeTone(byte pin, int hect, int second){
  tone(pin,hect);
  delay(second);
  noTone(pin);
}

void play(byte type){
  switch (type){
    case 1:
      makeTone(SPEAKER, 300, 300);
      delay(50);
      makeTone(SPEAKER, 1000, 300);
      break;
    case 2:
      makeTone(SPEAKER, 1000, 300);
      delay(50);
      makeTone(SPEAKER, 300, 300);
      break;
    case 3:
      makeTone(SPEAKER, 1500, 300);
      delay(50);
      makeTone(SPEAKER, 1500, 300);
      break; 
    case 4:
      makeTone(SPEAKER, 100, 300);
      delay(50);
      makeTone(SPEAKER, 100, 300);
      break;
    default:
      break;
  }
}
/*---------------------------------------------------------------
 * LogIn/Out
 --------------------------------------------------------------*/
void logIn(){
    digitalWrite(LED_STT, HIGH);
    play(1);
    ChangeRelay(Relay);
    LockDoor(false);
    logCaution = 0;
    LogIn = true;
    
    
    Serial.println("  >> Dang nhap...");
}
void logOut(){
    digitalWrite(LED_STT, LOW);
    play(2);
    LockDoor(true);
    digitalWrite(RELAY, LOW);
    LogIn = false;
    
    Serial.println("  >> Dang xuat...");
}

void cautionLog(){
  if (logCaution < 3){
    Serial.println("  >> The sai!");
    logCaution++;
    for (byte i = 0; i < 4; i++) { 
      digitalWrite(LED_STT, HIGH);
      delay(100);
      digitalWrite(LED_STT, LOW);
      delay(100);
      play(3);
    } 
    digitalWrite(LED_STT, LogIn);  
  } else {
    Serial.println("  >> BAO DONG !");
    if(LogIn){ logOut(); }
    
    for (byte i = 0; i < 40; i++) { 
      digitalWrite(LED_STT, HIGH);
      delay(100);
      digitalWrite(LED_STT, LOW);
      delay(100);
      play(3);
    }
  }
}

void LockDoor(bool Status){
  if (Status) {
    Lock.write(0);
    digitalWrite(LED_CL, LOW);
    Door = true;
    Serial.println("  >> Dong cua... ");
  } else {
    Lock.write(180);
    digitalWrite(LED_CL, HIGH);
    Door = false;
    Serial.println("  >> Mo cua...");
  }
  delay(500);
}

void ChangeRelay(bool Status){
  if (Status){
    digitalWrite(RELAY, HIGH);
    Relay=true;
    Serial.println("  >> Den mo !");
  } else {
    digitalWrite(RELAY, LOW);
    Relay=false;
    Serial.println("  >> Den tat !");
  }
  delay(500);
}
  
void setup() {
  Serial.begin(9600);     
 
  SPI.begin();            
  RC522.PCD_Init();
  Lock.attach(SERVO); 
  pinMode(LED_STT, OUTPUT);
  pinMode(BUTTON_CL, INPUT_PULLUP);
  pinMode(BUTTON_PW, INPUT_PULLUP);
  pinMode(LED_CL, OUTPUT);
  pinMode(RELAY, OUTPUT);
  
  digitalWrite(LED_STT, LOW);
  digitalWrite(RELAY, LOW);
  LockDoor(true);
  ChangeRelay(false);
}
void loop(){
  resultRFID = ReadRFID(Master);

  if (LogIn){
   if (!digitalRead(BUTTON_CL)){
    LockDoor(!Door);
   }
   if (!digitalRead(BUTTON_PW)){
    ChangeRelay(!Relay);
   }
   switch (resultRFID){
    case 1:
       Serial.println("Doc the: Trung voi Master !");
      if (logCaution == 0){ logOut();} else {
        logCaution = 0;
        play(4);
        Serial.println("  >> Xoa lich su truy cap sai");
      }
      delay(500);
      break;
    case 2:
    Serial.println("Doc the: Khac voi Master !");
      cautionLog(); 
      break;
    default:
      break;
   } 
  } else {
    switch (resultRFID){
    case 1:
      Serial.println("Doc the: Trung voi Master !");
      logIn();
      delay(500);
      break;
    case 2: 
     Serial.println("Doc the: Khac voi Master !"); 
      cautionLog();
      break;
     default:
      break;
    }
  }
}

Các bạn lắp theo sơ đồ sau nhé:

Các thiết bị như RC Servo bạn có thể thay bằng chốt cửa điện, hay motor bằng đèn trong phòng bạn, vậy là chỉ qua những thao tác trên, chúng ta đã có được một mô hình căn phòng bảo mật với RFID một cách đơn giản rồi.

Chúc các bạn thành công! 😛

14
Leave a Reply

Please Login to comment
3 Comment threads
11 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
6 Comment authors
Bùi Hữu HảiTrườngTrungNguyễn Thuậnthành tân Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Trung
Guest
Trung

Chào bạn! IDE báo lỗi khi nạp code xuống arduino bạn giúp mình khác phục với
Nó tô đậm dòng này ” resultRFID = ReadRFID(Master);”
và báo lỗi: invalid conversion from ‘const byte* {aka const unsigned char*}’ to ‘byte* {aka unsigned char*}’ [-fpermissive]
Thank bạn!

Nguyễn Thuận
Guest
Nguyễn Thuận

Bạn xem lại xem đã nhập đúng mã RFID trả về chưa. Nhớ mã HEX phải có tiền tố 0x nhé ^^
Nếu không được bạn thử nâng cấp IDE lên. Ko được nữa bạn bỏ chữ const ở dòng const byte Master[]={0x7A, 0x03, 0x92, 0xAB}; nhé. Chứ mình vẫn bình thường @@.

Trung
Guest
Trung

Hi Nguyễn Thuận!
Cảm ơn bạn đã phản hồi, hiện tại đã khắc phục được lỗi mình thay const byte Master = unsigned char. Mình xài bản IDE 1.6.7 có thể nó đã cũ. Mình cũng có câu hỏi giống Thành Tân là muốn thêm nhiều thẻ nữa nhưng mò hoài chưa được!

thành tân
Guest
thành tân

bạn trung ơi bạn biết cách thêm thẻ hông dạ bạn trung bạn chỉ mình với

Nguyễn Thuận
Guest
Nguyễn Thuận

Mình đã tl ở dưới r nha b ^^

Trung
Guest
Trung

Thành Tân chắc cũng ngu ngon rồi ha!? Vậy Tân úp luôn code full chổ Tân chia sẽ bài của bạn Thuận luôn cho ae khác học hỏi!

thành tân
Guest
thành tân

làm sao thêm 2 thẻ dc dạ bạn

Nguyễn Thuận
Guest
Nguyễn Thuận

dòng resultRFID = ReadRFID(Master); bạn có th thay bằng resultRFID = ReadRFID(Master1)+ReadRFID(Master2)….; Với các biến Master1, Master2, … khai báo như biến Master: const byte Master[]={0x7A, 0x03, 0x92, 0xAB}; nhé. Tại cùng 1 thời điểm thì chỉ có 1 thẻ được đọc thôi nên bạn cứ yên tâm. Còn nếu bạn muốn làm kiểu 1 thẻ 1 chức năng khác nhau thì bạn dùng : resultRFID1 = ReadRFID(Master1); resultRFID2 = ReadRFID(Master2); switch (resultRFID1){ case 1: // cv khi thẻ 1 đúng break; case 2: // cv khi thẻ 1 sai break; default: break; } switch (resultRFID2){ case 1: // cv… Read more »

Trung
Guest
Trung

😀 ôi thật tuyệt! Cảm ơn bạn Thuận nhiều! Do mình cũng mới tiếp cận arduino nên còn yếu, code của bạn mình đọc từ 26 tây tới hay nay luôn nhưng chưa được. Mình dùng hàm || ở phía sau lệnh resultRFID = ReadRFID(Master) nhưng khi không quẹt thẻ nó vẫn cứ đóng rồi mở liên tục. Vậy là tối nay ngủ ngon rồi! 😊

thành tân
Guest
thành tân

cũng cung lời như bạn trung thật lòng cảm ơn bạn rất nhiều

Nguyễn Thuận
Guest
Nguyễn Thuận

Không có gì đâu bạn, bạn muốn dùng || thì hàm ReadRFID phải trả về logic là 0 hoặc 1 . Còn mình viết hàm đó là trả về 1 hoặc 2 nên không chạy được là đúng ^^

Trường
Guest
Trường

bạn Trung cho mình xin code đầy đủ thêm thẻ với. như lời bạn thuận nói nhưng mò mãi không ra.

Trung
Guest
Trung

Mình đã viết code y như bạn hướng đẫn để thêm thẻ nhưng nó chạy không ổn định lúc nhận lúc báo thẻ sai, bạn xem lại giúp với.tks 😀

Bùi Hữu Hải
Guest
Bùi Hữu Hải

ad có code mạch này nhưng bổ sung thêm LCD với bàn phím 4×4 ko a?