智能门锁技术在物联网中的应用

基于物联网的智能门锁

该系统可分别通过密码、指纹、RFID刷卡、WiFi四种方式进行开锁

一、项目背景

在飞速发展的科技社会,智能设备的应用与发展,从根本上提高了社会居民的生活质量。通常,目前中国家庭使用的家用门锁多为机械锁,需与其完全匹配的钥匙才能将门锁开启,但机械锁在安全性能方面有所缺失,门锁安全性难以保证,且开锁方式单一。但在物联网时代,智能门锁被广泛应用于家用门锁中。智能锁的优势在于不再需要钥匙,可通过远程控制来开启家用房门,且保密性极好,提高了居住安全及便捷性。此外,智能门锁还具备记录、提醒等科技功能,能够对家人出门及回家时间进行相关的数据整理与记录,对门锁安全状态进行实时提醒,从而使智能门锁的安全性与实用性能得到发挥。

二、项目设计

三 、硬件设计

主控板 Arduino UNO
舵机 SG-5010、TBS-K20 (SG90也行)
WIFI模块 TTL-WiFi DT-06
指纹识别模块 ATK-AS608
刷卡模块 RFID
矩阵按键 4×4矩阵按键

成本大概100多一点,还行,当个校级,市级大创项目挺不错的

1 Arduino UNO

本项目中使用的单片机为Arduino UNO,芯片为ATMEL公司的ATMEGA328P,使用其IDE软件编译、烧录代码即可。

2 TBS-K20

舵机是由直流电机、减速齿轮组、传感器和控制电路组成的一套自动控制系统。通过发送信号,指定输出轴旋转角度。舵机一般而言都有最大旋转角度(比如180度,360度),本产品采用SG-5010、TBS-K20(如图2-3),舵机连接旋转轴逆时针旋转,控制门锁的开合。

3 RFID

RFID,即射频识别技术。把数字信息编码到RFID标签中,阅读器通过无线电波读取到这些信息。

4 ATK-AS608

ATK-AS608模块采用了AS608 指纹识别芯片。芯片内置DSP运算单元,集成了指纹识别算法,能高效快速采集图像并识别指纹特征。模块配备了串口、USB通讯接口,用户无需研究复杂的图像处理及指纹识别算法,只需通过简单的串口、USB 按照通讯协议便可控制模块,

5 DT-06

该模块基于ESP-M2无线模块的开发,实现了模块串口与WiFi数据的实时透传,可以实现WiFi STA模式下重连机制、TCP Client模式下重连机制,保证数据链路的稳定连接与传输。本次项目中使用TTL-WiFi模块模块实现硬件设备与小程序的连接。

6 4×4矩阵按键

4×4矩阵按键是单片机外部设备中所使用的排布类似于矩阵的按键组,通过行列的电平变化判断是否按下某个键,多用于安全硬件方面

(自己修改了一下外观,把数字写上去了,都说丑,我觉得还行)

四、硬件接线

接线这里没什么注意的,就是烧录程序的时候,TTL-WiFi和主控板之间的RX和TX连线要拔下来,不然程序烧录不进去。其他外设就正常接。这里只给出指纹模块的相关接口定义,其他的外设如何与主控板接线相信大家也都能在丰富的网络资源里找到,这里就不一一赘述了。

超过3V,就有可能烧坏!!!

五 、软件设计及其实现

这里是指纹验证代码,指纹录入没了,网上有很多,去官网和其他文章都可以学习到。(这个项目做完好久了,这里代码缺少一点,大家见谅)
#include <Adafruit_Fingerprint.h>
#include <Servo.h>       //调用舵机库函数
Servo my_servo;           //设置舵机名称
SoftwareSerial mySerial(2, 3); // RX,TX(UNO)
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
uint8_t id;      //unsigned char, 数值范围是0-255, 占1个字节
void setup()   
{
  Serial.begin(9600);
  my_servo.attach(12);    //设置舵机控制引脚
  while (!Serial);  // For Yun/Leo/Micro/Zero/...
  delay(100);
  Serial.println("\n\nAdafruit Fingerprint sensor enrollment");
  // set the data rate for the sensor serial port
  finger.begin(57600);
  if (finger.verifyPassword()) {
    Serial.println("Found fingerprint sensor!");
  } else {
    Serial.println("Did not find fingerprint sensor :(");
    while (1) { delay(1); }
  }
}

uint8_t readnumber(void) {
  uint8_t num = 0;
  while (num == 0) {
    while (! Serial.available());
    num = Serial.parseInt();
  }
  return num;
}
void loop()                    
{
  getFingerprintIDez();
  delay(50);         

uint8_t getFingerprintID() {
uint8_t p = finger.getImage();
  switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image taken");
      break;
    case FINGERPRINT_NOFINGER:
      Serial.println("No finger detected");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      return p;
    case FINGERPRINT_IMAGEFAIL:
      Serial.println("Imaging error");
      return p;
    default:
      Serial.println("Unknown error");
      return p;
  }

 

  p = finger.image2Tz();
  switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image converted");
      break;
    case FINGERPRINT_IMAGEMESS:
      Serial.println("Image too messy");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      return p;
    case FINGERPRINT_FEATUREFAIL:
      Serial.println("Could not find fingerprint features");
      return p;
    case FINGERPRINT_INVALIDIMAGE:
      Serial.println("Could not find fingerprint features");
      return p;
    default:
      Serial.println("Unknown error");
      return p;
  }
  
 
  p = finger.fingerFastSearch();
  if (p == FINGERPRINT_OK) {
    Serial.println("Found a print match!");
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    Serial.println("Communication error");
    return p;
  } else if (p == FINGERPRINT_NOTFOUND) {
    Serial.println("Did not find a match");
    return p;
  } else {
    Serial.println("Unknown error");
    return p;
  }   
  
 
  Serial.print("Found ID #"); Serial.print(finger.fingerID); 
  Serial.print(" with confidence of "); Serial.println(finger.confidence); 
  
}


int getFingerprintIDez() {
  uint8_t p = finger.getImage();
  if (p != FINGERPRINT_OK)  return -1;

  p = finger.image2Tz();
  if (p != FINGERPRINT_OK)  return -1;

  p = finger.fingerFastSearch();
  if (p != FINGERPRINT_OK)  return -1;
  // found a match!
  Serial.print("Found ID #"); Serial.print(finger.fingerID); 
  Serial.print(" with confidence of "); Serial.println(finger.confidence);
  my_servo.write(0);     
  delay(1000);
  my_servo.write(90);    //设置舵机角度
  delay(1000);
  return finger.fingerID; 
}


这里是指纹开锁+键盘开锁代码**

#include <Keypad.h>
#include <Adafruit_Fingerprint.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>       //调用库函数
Servo my_servo;           //设置舵机名称
SoftwareSerial mySerial(2, 3); // RX,TX(UNO)
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
uint8_t id;      //unsigned char, 数值范围是0-255, 占1个字节
LiquidCrystal_I2C mylcd(0x27,16,2);
const int ROWS = 4; 
const int COLS = 4; 
char keys[ROWS][COLS] = {
  {'1','2','3','4'},
  {'5','6','7','8'},
  {'9','A','B','C'},
  {'D','E','F','0'}
};
char initialpassword[6]="123456";//这里密码设置为123456
char password[6];
byte rowPins[ROWS] = {12,10,9,8}; //定义键盘接口
byte colPins[COLS] = {7,6,5,4}; 
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup()
{
  Serial.begin(9600);
  my_servo.attach(11);    //设置控制引脚
  while (!Serial); 
  delay(100);
  Serial.println("\n\nAdafruit Fingerprint sensor enrollment");
  finger.begin(57600);
  if (finger.verifyPassword()) {
    Serial.println("Found fingerprint sensor!");
  } else {
    Serial.println("Did not find fingerprint sensor :(");
    while (1) { delay(1); }
  }
  mylcd.init();//初始化LCD
  mylcd.backlight();//设置LCD背景等亮
}

uint8_t readnumber(void) {
  uint8_t num = 0;
  while (num == 0) {
    while (! Serial.available());
    num = Serial.parseInt();
  }
  return num;
}

void loop(){
  mylcd.setCursor(0,0);//设置光标位置/列/行
  mylcd.print("A/B openway:");
  char key_pressed = keypad.getKey();
  if (key_pressed != NO_KEY){
    Serial.println(key_pressed);
    mylcd.print(key_pressed);
    switch (key_pressed)
  {
    case 'A': KeyWay(); break;
    case 'B': getFingerprintIDez();break;
    }
  }
   getFingerprintIDez();
}


uint8_t getFingerprintID() {
uint8_t p = finger.getImage();
  switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image taken");
      break;
    case FINGERPRINT_NOFINGER:
      Serial.println("No finger detected");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      return p;
    case FINGERPRINT_IMAGEFAIL:
      Serial.println("Imaging error");
      return p;
    default:
      Serial.println("Unknown error");
      return p;
  }


  p = finger.image2Tz();
  switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image converted");
      break;
    case FINGERPRINT_IMAGEMESS:
      Serial.println("Image too messy");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      return p;
    case FINGERPRINT_FEATUREFAIL:
      Serial.println("Could not find fingerprint features");
      return p;
    case FINGERPRINT_INVALIDIMAGE:
      Serial.println("Could not find fingerprint features");
      return p;
    default:
      Serial.println("Unknown error");
      return p;
  }
  
  
  p = finger.fingerFastSearch();
  if (p == FINGERPRINT_OK) {
    Serial.println("Found a print match!");
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    Serial.println("Communication error");
    return p;
  } else if (p == FINGERPRINT_NOTFOUND) {
    Serial.println("Did not find a match");
    return p;
  } else {
    Serial.println("Unknown error");
    return p;
  }   
  
  Serial.print("Found ID #"); Serial.print(finger.fingerID); 
  Serial.print(" with confidence of "); Serial.println(finger.confidence); 

  return finger.fingerID;
}


int getFingerprintIDez() {
  uint8_t p = finger.getImage();
  if (p != FINGERPRINT_OK)  return -1;

  p = finger.image2Tz();
  if (p != FINGERPRINT_OK)  return -1;

  p = finger.fingerFastSearch();
  if (p != FINGERPRINT_OK)  return -1;
  // found a match!
  Serial.print("Found ID #"); Serial.print(finger.fingerID); 
  Serial.print(" with confidence of "); Serial.println(finger.confidence);
   my_servo.write(0);     
  delay(1000);
  my_servo.write(90);    //设置舵机角度
  delay(1000);
  return finger.fingerID; 
}

void KeyWay(){
  int i=0;
  int count=0;
  while(1){
    char key_pressed = keypad.getKey();
    if (key_pressed != NO_KEY){
      password[i]=key_pressed;
      Serial.print(password[i]);
      mylcd.setCursor(0,1);//设置光标位置/列/行
      mylcd.print(password[i]);
      delay(500);
     //密码开锁
      if(password[i]==initialpassword[i]){
        count++;
        if(count==6){
          delay(500);
          my_servo.write(0);     
          delay(1000);
          my_servo.write(90);    //设置舵机角度
          delay(1000);
          
        }
      }
      i++;
      if(i==6) break;
    } 
  }
}
这里是小程序+WiFi开锁代码(这个小程序是用的亚博智能公司的小程序)
#include <SPI.h> //RFID库文件  
#include <MFRC522.h>//RFID库文件
#include <Servo.h>  


String CardInfo[4][2] ={
{"d320c90e", "lisa"},
{"63672db7", "Tom"},
{"b076b156", "yahboom"},
{"a075f1a2", "xiaojie"},
};
int MaxNum = 4; 


#define Servo_Pin       6      //模拟开门
#define Beep_Pin        7      //蜂鸣器成功提示
#define LED_RED         A0      //红灯
#define LED_Green       A1       //绿灯

#define RST_PIN         9      
#define SS_PIN          10     

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

MFRC522::MIFARE_Key key;

Servo myservo;      //定义舵机对象myservo
boolean g_boolSuccess = false; 
/*通信协议*/
int incomingByte = 0;       // 接收到的 data byte
String inputString = "";         // 用来储存接收到的内容
boolean newLineReceived = false; // 前一次数据结束标志
boolean startBit  = false;  //协议开始标志
String returntemp = ""; //存储返回值 

void Beep_Success()         //刷卡成功铃声
{
  for(int i = 0; i < 3; i++)  //鸣叫三次
  {
    digitalWrite(Beep_Pin, LOW); //打开蜂鸣器
    delay(100);//延时100
    digitalWrite(Beep_Pin, HIGH); //关闭蜂鸣器  
    delay(100);//延时100
  }
}

void Beep_Fail()  //刷卡失败铃声
{

    digitalWrite(Beep_Pin, LOW); //打开蜂鸣器
    delay(500);//延时1500
    digitalWrite(Beep_Pin, HIGH); //关闭蜂鸣器  
}
void setup() 
{
    Serial.begin(9600); //波特率9600 (Wifi通讯设定波特率)
    pinMode(Servo_Pin, OUTPUT);  //初始化舵机为输出模式
    pinMode(Beep_Pin, OUTPUT); //初始化蜂鸣器为输出模式    
    pinMode(LED_RED, OUTPUT); //初始化LED为输出模式
    pinMode(LED_Green, OUTPUT); //初始化LED为输出模式
       
    while (!Serial);    // 如果没有打开串行端口,就什么也不做(添加基于ATMEGA32U4的Arduinos)
    SPI.begin();        //初始化SPI
    mfrc522.PCD_Init(); // 初始化 MFRC522
    myservo.attach(Servo_Pin);    //设置舵机控制引脚为3
    myservo.write(0);    //初始化舵机位置0
    digitalWrite(Beep_Pin, HIGH); //关闭蜂鸣器  
    digitalWrite(LED_RED, HIGH); //打开红LED
    digitalWrite(LED_Green, LOW); // 关闭绿LED
}
void loop() {

    
    while (newLineReceived)
    {
       if(inputString.indexOf("RFID") == -1) 
       {
           returntemp = "$RFID,2,#";  //返回不匹配
           Serial.print(returntemp); //返回协议数据包       
           inputString = "";   // clear the string
           newLineReceived = false;
           break;    
       }
      
       if(inputString[6] == '1')  //远程开门
       {
          digitalWrite(LED_RED, LOW); // 关闭红LED
          digitalWrite(LED_Green, HIGH); //打开绿LED
          Beep_Success();//刷卡成功铃声
          myservo.write(90);  //舵机旋转至90度
          delay(3000);  //延时3000
          myservo.write(0);//舵机旋转至90度
          digitalWrite(LED_RED, HIGH); //打开红LED
          digitalWrite(LED_Green, LOW); //关闭绿LED
       }
       returntemp = "$RFID,0,#";  //返回匹配成功
       Serial.print(returntemp); //返回协议数据包       
       inputString = "";   // clear the string
       newLineReceived = false;    
    }
    if ( ! mfrc522.PICC_IsNewCardPresent())
        return;
    if ( ! mfrc522.PICC_ReadCardSerial())
        return;
    String temp,str;  //定义字符串temp,str
    for (byte i = 0; i < mfrc522.uid.size; i++)
    {
        str = String(mfrc522.uid.uidByte[i], HEX);    // 将数据转换成16进制的字符 
        if(str.length() == 1) //保证str的长度有两位
        {
          str = "0" + str;
        }
        temp += str; //将字符str放入temp       
    }
    Serial.print("Card:" + temp + "\n"); 
    for(int i = 0; i < MaxNum; i++)
    {
        if(CardInfo[i][0] == temp) 
        {
          //Serial.print(CardInfo[i][1] + " Open door!\n");
          Serial.print("$RFID," + CardInfo[i][0] + "," + CardInfo[i][1] + ",#"); 
          g_boolSuccess = true;  //刷卡成功标识
        }
    }
    if(g_boolSuccess == true) //如果刷卡成功
    {
        digitalWrite(LED_RED, LOW); //红灯灭
        digitalWrite(LED_Green, HIGH); //绿灯亮
        Beep_Success();//刷卡成功铃声
        myservo.write(90); //舵机旋转至90度
        delay(3000);      // 延时3000ms
        myservo.write(0);//舵机旋转至0度
    }
    else//刷卡失败
    {
        Beep_Fail();//刷卡失败铃声
        digitalWrite(LED_RED, LOW); //红灯灭
    }
    digitalWrite(LED_RED, HIGH); //红灯亮
    digitalWrite(LED_Green, LOW); //绿灯灭
    g_boolSuccess = false;//刷卡失败标识
    mfrc522.PICC_HaltA();      //停止读写
    mfrc522.PCD_StopCrypto1(); //  停止向PCD加密
}
void serialEvent()
{
  while (Serial.available())                    //如果串口接收到数据则进入循环
  {    
    incomingByte = Serial.read();             
    if(incomingByte == '$')                     //如果到来的字节是'$',开始读取 
    {
      startBit= true;
    }
    if(startBit == true)
    {
       inputString += (char) incomingByte;     // 全双工串口可以不用在下面加延时,半双工则要加的//
    }  
    if (incomingByte == '#') 
    {
       newLineReceived = true;                 //如果到来的字节是'#',读取结束
       startBit = false;
    }
  }
}

六、成果展示

附图一 实物WIFI远程小程序开锁演示


附图二 实物俯视图

附图三 实物正视图

附图四 实物内部展示图

七、总结

本项目是基于现代智能控制技术,设计了一款基于Arduino UNO单片机的智能门锁系统。该系统可分别通过密码、指纹、RFID刷卡、WiFi四种方式进行解锁,达到基于物联网的智能家居效果。整体设计具有较高的完整性和实用性,提高了开锁的安全性、便捷性,更为智能化。最后,通过实物进行了实验验证,达到了预期结果。

参考本项目的同学,遇到软硬件问题,大家可在评论区互相讨论解决,我有时间看到也一定会回,谢谢大家,如果觉得我的文章帮到了你,请关注+点赞,本人目前也在努力学习嵌入式,才疏学浅,如有错误,请批评指正,蟹蟹支持。

物联沃分享整理
物联沃-IOTWORD物联网 » 智能门锁技术在物联网中的应用

发表评论