中大计赛-基于生物特征识别的IOT门禁系统-代码开源(电控)

中大计赛-基于生物特征识别的IOT门禁系统-代码开源(电控)


Arduino-1

  • 控制密码输入与对比
#include<IRremote.h> //第三方红外解码库
#include <TTP229.h> //第三方触摸键盘库
#include <SoftwareSerial.h> //软串口库

SoftwareSerial Serial_terminal(14,15);//RX,TX,设置模块的软串口

#define SHOW_IN_SERIAL

bool ray_or_TTP = 1;
/*************************处理触摸键盘**************************/
const int TTP229_sclPin = 2;  // 触摸时钟IO
const int TTP229_sdoPin = 3;  // 触摸数据IO
TTP229 ttp229(TTP229_sclPin,TTP229_sdoPin);

/************************处理红外信号***************************/
int recvPin = 5; //红外IO

IRrecv irrecv(recvPin);     //定义该io为红外接收口
decode_results results;    //使用decode_results类,用于存储解码结果

const byte ROWS = 7;        //解码含义表行列数
const byte COLS = 3;

long remote_Code[ROWS][COLS] = {  //遥控红外信号码值
  {0x00FFA25D,0x00FF629D,0x00FFE21D},
  {0x00FF22DD,0x00FF02FD,0x00FFC23D},
  {0x00FFE01F,0x00FFA857,0x00FF906F},
  {0x00FF6897,0x00FF9867,0x00FFB04F},
  {0x00FF30CF,0x00FF18E7,0x00FF7A85},
  {0x00FF10EF,0x00FF38C7,0x00FF5AA5},
  {0x00FF42BD,0x00FF4AB5,0x00FF52AD}
};
char remote_Mean[ROWS][COLS] = { //遥控码值对应意义
  {'A','B','C'},
  {'D','E','F'},
  {'G','H','#'},
  {'0','#','*'},
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'}
};
/*********************处理密码问题*************************/
#define pass_admin_len_MAX 64     //密码最大长度

char password_custom[pass_admin_len_MAX] = {NULL};   //用户输入密码
char password_admin[pass_admin_len_MAX] = {NULL};    //初始标准密码
int pass_admin_len = 0; //用户所输入初始密码的长度


/**************************自定义函数**********************/
char get_ray_key(){ //通过红外线接收密码
  irrecv.enableIRIn();  //红外端口使能,准备接受红外信号
  while(1){
    if(irrecv.decode(&results)){  //接收到信号并解码成功,把数据放入results变量中
      for(int i = 0;i<ROWS;i++){
        for(int j = 0;j<COLS;j++){
          if((results.value) == remote_Code[i][j]){ //该信号有效,返回信号含义
            Serial_terminal.print(remote_Mean[i][j]);
            #ifdef SHOW_IN_SERIAL
              Serial.print(remote_Mean[i][j]);
            #endif

            return (remote_Mean[i][j]); 
          }
        }
      }
      irrecv.resume();  //继续等待接收下一组信号 
    }
  }
}

char get_TTP229_key(){  //通过键盘接收密码
  int key = ttp229.ReadKey16(); // Blocking
  char key_c;
  if (key){
    switch(key){
      case 10:
        key_c = '0';
        break;
      case 11:
        key_c = 'A';
        break;
      case 12:
        key_c = 'B';
        break;
      case 13:
        key_c = 'C';
        break;
      case 14:
        key_c = 'D';
        break;
      case 15:
        key_c = 'E';
        break;
      case 16:
        key_c = '#';
        break;
      default:
        key_c = key+48;
    }
    ttp229.ReadKey16(); //清空缓存区,解决choice被计入密码的bug
    Serial_terminal.print(key_c);
    #ifdef SHOW_IN_SERIAL
      Serial.print(key_c);
    #endif
    
    return key_c;
  }
}

void password_change(){
  pass_admin_len = 0;
  #ifdef SHOW_IN_SERIAL
    Serial.println("Input your init_key:");
  #endif
  char customKey;
  //接受用户输入的初始密码,以"EQ"作为结束符

  if(ray_or_TTP)
    customKey = get_ray_key();
  else
    customKey = get_TTP229_key();

  while(customKey != '#'){
    password_admin[pass_admin_len++] = customKey;
    if(ray_or_TTP)
      customKey = get_ray_key();
    else
      customKey = get_TTP229_key();
  }
  #ifdef SHOW_IN_SERIAL
    Serial.println("The initial password is set.");
  #endif
  Serial_terminal.print('P');
  //Serial.println(pass_admin_len);
}

void password_unlock(){
  int pass_custom_len = 0;  //用户输入密码长度
  #ifdef SHOW_IN_SERIAL
    Serial.print("Input your passward:");
  #endif
  char customKey;
  //先将用户输入密码保存,以"#"作为结束符

  if(ray_or_TTP)
    customKey = get_ray_key();
  else
    customKey = get_TTP229_key();

  while(customKey != '#'){
    password_custom[pass_custom_len++] = customKey;
    if(ray_or_TTP)
      customKey = get_ray_key();
    else
      customKey = get_TTP229_key();
  }
  //Serial.println(pass_custom_len);

//判断密码是否正确,flag为标志位,flag_invert为逆序输入,用于报警信息
  bool flag = 0,flag_invert = 0;  //密码是否正确标志位,1为正确
  int custom_i = 0,admin_j = 0;
  bool last_same = 0;
  while((custom_i<pass_custom_len) && (admin_j<pass_admin_len)){
    if((password_custom[custom_i] != password_admin[admin_j]) && (last_same == 0)){
      custom_i++;
      last_same = 0;
    }
    else if((password_custom[custom_i] != password_admin[admin_j]) && (last_same == 1)){
      admin_j = 0;
      last_same = 0;
    }
    else if(password_custom[custom_i] == password_admin[admin_j]){
      custom_i++;
      admin_j++;
      last_same = 1;
    }
    if(admin_j == pass_admin_len)
      flag = 1;
  }
  if(!flag){
    custom_i = 0,admin_j = pass_admin_len-1;
    last_same = 0;
    while((custom_i<pass_custom_len) && (admin_j >= 0)){
      if((password_custom[custom_i] != password_admin[admin_j]) && (last_same == 0)){
        custom_i++;
        last_same = 0;
      }
      else if((password_custom[custom_i] != password_admin[admin_j]) && (last_same == 1)){
        admin_j = pass_admin_len-1;
        last_same = 0;
      }
      else if(password_custom[custom_i] == password_admin[admin_j]){
        custom_i++;
        admin_j--;
        last_same = 1;
      }
      if(admin_j == -1)
        flag_invert = 1;
    }
	}
//判断完成执行的操作
  if(flag){
    #ifdef SHOW_IN_SERIAL
      Serial.println("  PASS!");
    #endif
    Serial_terminal.print('O');
  }
  if(flag_invert){//逆序输入密码,报警
    #ifdef SHOW_IN_SERIAL
      Serial.println("urgency");
    #endif
    Serial_terminal.print('U');
  }
  if(!flag && !flag_invert){
    #ifdef SHOW_IN_SERIAL
      Serial.println("  ERROR!");
    #endif
    Serial_terminal.print('L');
  }
//执行完毕后,破坏原数组
  for(int i = 0;i<pass_admin_len;i++){
     password_custom[i] = {"x"}; 
  }
 
}


/*************************主函数******************************/
void setup(){
  Serial_terminal.begin(9600);
  Serial.begin(115200);

  irrecv.enableIRIn();
  if(ray_or_TTP)//解决reset后不同步的问题
    get_ray_key();
  else
    get_TTP229_key();
}
void loop(){
  static char data_in;
  if(Serial_terminal.available()>0){//接收终端指令
    switch(data_in = Serial_terminal.read()){
      case '@':
        if(ray_or_TTP)
          get_ray_key();
        else
          get_TTP229_key();
      break;
      case 'K':
        ray_or_TTP = 0;
        break;
      case 'R':
        ray_or_TTP = 1;
        break;
      case 'P': //密码解锁
        password_unlock();
        break;
      case 'C': //更换密码
        password_change();
        break;
      //default:
    }
  }
}

Arduino-2

  • 指纹、人脸数据传输、物联网传输
#include <Adafruit_Fingerprint.h>

// #define SHOW_IN_SERIAL
SoftwareSerial mySerial(14,15);      //RX,TX 与指纹传感器通信
SoftwareSerial Serial_terminal(8,9);//RX,TX 与终端通信
int reset_Pin = 5;

Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

uint8_t id;
void setup(){
  Serial_terminal.begin(9600);
  Serial.begin(9600);
  pinMode(reset_Pin,INPUT);
 
  while(!Serial_terminal)
    #ifdef SHOW_IN_SERIAL
      Serial.println("Can't open serial_terminal");
    #endif
  while (!Serial);                                                                  
  delay(100);
  finger.begin(57600);//设置传感器串口波特率
  finger_init();
}

void loop(){
  Serial_terminal.listen();
  char data_in;
  if(Serial_terminal.available()>0){
    data_in = Serial_terminal.read();//从终端接收消息,执行功能函数 
    mySerial.listen();
    switch (data_in){
      //指纹指令
      case 'Y':
        finger_unlock();
        break;
      case 'N':
        finger_new();
        break;
      case 'M':
        finger_delete();
        break;
      case 'Z':
        finger.getTemplateCount();    
        Serial_terminal.print(finger.templateCount);
        break;
      //人脸指令,只传输
      case 'X': //关闭人脸识别
      case 'F': //开启人脸识别
      case 'Q': //新建人脸
      case 'T': //查看人脸数量
        Serial.print(data_in);
        break;
      //记录指令,传输2位
      case 'C':
        Serial.print('C');  //密码开锁记录
        break;
      case 'A':
        Serial.print('A');  //刷卡开锁记录
        break;
      case 'U':
        Serial.print('U');  //报警
        break;
      default:
        delay(500);
        Serial.print(data_in);
        break;
    }
  }
  Serial_terminal.listen();
  if(Serial.available()>0){
    Serial_terminal.print(data_in = Serial.read());
    // Serial.print(data_in);
  }
}

void finger_unlock(){
  while(1){//RESET终止
    mySerial.listen();
    finger_matching();//默认一直匹配指纹
    
    if(digitalRead(reset_Pin)<=0){//按下任意键就RESET
      return;
    }
  }
}

//指纹模块初始化
void finger_init(){ 
  #ifdef SHOW_IN_SERIAL
    Serial.println("Fingerprint init over");
  #endif
  if (finger.verifyPassword()) {
    #ifdef SHOW_IN_SERIAL
      Serial.println("Found fingerprint sensor!");
    #endif
  } 
  else {
    #ifdef SHOW_IN_SERIAL 
      Serial.println("Did not find fingerprint sensor :(");
    #endif
    while(1){
      delay(1);
    }
  }
  
  finger.getTemplateCount();
  #ifdef SHOW_IN_SERIAL 
    Serial.print("The number of fingerprints is "); 
    Serial.print(finger.templateCount); 
    Serial.println("Waiting for valid finger...");
  #endif
}

//指纹匹配
void finger_matching(){
  int finger_label = getFingerprintIDez();
  if(finger_label != -1 && finger_label != 0){
    Serial_terminal.print('O');//给终端发数据开锁
    //给linux发送数据记录开锁记录
    Serial.print('B');
    delay(500);
    Serial.print(finger_label); 

    #ifdef SHOW_IN_SERIAL
      Serial.println('');
      Serial.println('O');
    #endif
  }
    
  delay(50);//最高速率
}

//指纹录入
void finger_new(){
  #ifdef SHOW_IN_SERIAL
    Serial.println("Ready to enroll a fingerprint!");
    Serial.println("Please type in the ID # (from 1 to 127) you want to save this finger as...");
  #endif
  finger.getTemplateCount();
  #ifdef SHOW_IN_SERIAL
    Serial.println(finger.templateCount+1);
  #endif
  id = finger.templateCount + 1;
  // if (id == 0) {// ID #0 not allowed, try again!
  //    return;
  // }
  #ifdef SHOW_IN_SERIAL
    Serial.print("Enrolling ID #");
    Serial.println(id);
  #endif
  Serial_terminal.print((char)92);  //提示用户按下手指
  while (!getFingerprintEnroll() );
}

//指纹删除
void finger_delete(){
  #ifdef SHOW_IN_SERIAL
    Serial.println("Please type in the ID # (from 1 to 127) you want to delete...");
  #endif
  Serial_terminal.print((char)92);  //提示用户按下手指
  int finger_label = -1;
  while (finger_label == -1){ //等待按下有效指纹
    finger_label = getFingerprintIDez();
    if(finger_label == 0){
      Serial_terminal.print((char)124);  //按下的指纹没有被录入,删除失败
    }
  }
  uint8_t id = (uint8_t)finger_label;
  // if (id == 0) {// ID #0 not allowed, try again!
  //    return;
  // }

  #ifdef SHOW_IN_SERIAL
    Serial.print("Deleting ID #");
    Serial.println(id);
  #endif
  
  deleteFingerprint(id);
}

//指纹匹配核心
//返回0即为没有匹配到指纹,-1为没有指纹,其他为指纹标签
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 0;
  
  //匹配到指纹
  #ifdef SHOW_IN_SERIAL
    Serial.print("Found ID #"); Serial.print(finger.fingerID); 
    Serial.print(" with confidence of "); Serial.println(finger.confidence);
  #endif
  return finger.fingerID; 
}


uint8_t getFingerprintEnroll() {//指纹录入核心
  int p = -1;
  Serial_terminal.print((char)92);//发送显示指令
  #ifdef SHOW_IN_SERIAL
    Serial.print("Waiting for valid finger to enroll as #"); 
    Serial.println(id);
  #endif 
  while (p != FINGERPRINT_OK) {
    p = finger.getImage();
    #ifdef SHOW_IN_SERIAL
      switch (p) {
        case FINGERPRINT_OK:
          Serial.println("Image taken");
          break;
        case FINGERPRINT_NOFINGER:
          Serial.println(".");
          break;
        case FINGERPRINT_PACKETRECIEVEERR:
          Serial.println("Communication error");
          break;
        case FINGERPRINT_IMAGEFAIL:
          Serial.println("Imaging error");
          break;
        default:
          Serial.println("Unknown error");
          break;
      }
    #endif 
  }
  // OK success!

  p = finger.image2Tz(1);
  #ifdef SHOW_IN_SERIAL
    switch (p) {
      case FINGERPRINT_OK:
        Serial.println("Image converted");
        break;
      case FINGERPRINT_IMAGEMESS:
        Serial.println("Image too messy");
        Serial_terminal.print((char)96);//发送显示指令
        return 1;
      case FINGERPRINT_PACKETRECIEVEERR:
        Serial.println("Communication error");
        Serial_terminal.print((char)96);//发送显示指令
        return 1;
      case FINGERPRINT_FEATUREFAIL:
        Serial.println("Could not find fingerprint features");
        Serial_terminal.print((char)96);//发送显示指令
        return 1;
      case FINGERPRINT_INVALIDIMAGE:
        Serial.println("Could not find fingerprint features");
        Serial_terminal.print((char)96);//发送显示指令
        return 1;
      default:
        Serial.println("Unknown error");
        Serial_terminal.print((char)96);//发送显示指令
        return 1;
    }
  #endif

  Serial_terminal.print((char)93);//发送显示指令
  #ifdef SHOW_IN_SERIAL
    Serial.println("Remove finger");
  #endif
  delay(500);
  p = 0;
  while (p != FINGERPRINT_NOFINGER) {
    p = finger.getImage();
  }
  #ifdef SHOW_IN_SERIAL
    Serial.print("ID "); Serial.println(id);
  #endif
  p = -1;
  Serial_terminal.print((char)94);//发送显示指令
  #ifdef SHOW_IN_SERIAL
    Serial.println("Place same finger again");
  #endif
  while (p != FINGERPRINT_OK) {
    p = finger.getImage();
    #ifdef SHOW_IN_SERIAL
      switch (p) {
      case FINGERPRINT_OK:
        Serial.println("Image taken");
        break;
      case FINGERPRINT_NOFINGER:
        Serial.print(".");
        break;
      case FINGERPRINT_PACKETRECIEVEERR:
        Serial.println("Communication error");
        break;
      case FINGERPRINT_IMAGEFAIL:
        Serial.println("Imaging error");
        break;
      default:
        Serial.println("Unknown error");
        break;
      }
    #endif
  }

  // OK success!

  p = finger.image2Tz(2);
  #ifdef SHOW_IN_SERIAL
    switch (p) {
      case FINGERPRINT_OK:
        Serial.println("Image converted");
        break;
      case FINGERPRINT_IMAGEMESS:
        Serial.println("Image too messy");
        Serial_terminal.print((char)96);//发送显示指令
        return 1;
      case FINGERPRINT_PACKETRECIEVEERR:
        Serial.println("Communication error");
        Serial_terminal.print((char)96);//发送显示指令
        return 1;
      case FINGERPRINT_FEATUREFAIL:
        Serial.println("Could not find fingerprint features");
        Serial_terminal.print((char)96);//发送显示指令
        return 1;
      case FINGERPRINT_INVALIDIMAGE:
        Serial.println("Could not find fingerprint features");
        Serial_terminal.print((char)96);//发送显示指令
        return 1;
      default:
        Serial.println("Unknown error");
        Serial_terminal.print((char)96);//发送显示指令
        return 1;
    }
  #endif
  
  // OK converted!
  #ifdef SHOW_IN_SERIAL
    Serial.print("Creating model for #");  Serial.println(id);
  #endif
  p = finger.createModel();
  
  if (p == FINGERPRINT_OK) {
    #ifdef SHOW_IN_SERIAL
      Serial.println("Prints matched!");
    #endif
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    #ifdef SHOW_IN_SERIAL
      Serial.println("Communication error");
    #endif
    Serial_terminal.print((char)96);//发送显示指令
    return 1;
  } else if (p == FINGERPRINT_ENROLLMISMATCH) {
    #ifdef SHOW_IN_SERIAL
      Serial.println("Fingerprints did not match");
    #endif
    Serial_terminal.print((char)96);//发送显示指令
    return 1;
  } else {
    #ifdef SHOW_IN_SERIAL
      Serial.println("Unknown error");
    #endif
    Serial_terminal.print((char)96);//发送显示指令
    return 1;
  }   
  
  #ifdef SHOW_IN_SERIAL
    Serial.print("ID "); Serial.println(id);
  #endif
  p = finger.storeModel(id);
  if (p == FINGERPRINT_OK) {
    Serial_terminal.print((char)95);//发送显示指令
    #ifdef SHOW_IN_SERIAL
      Serial.println("Stored!");
    #endif
    return 1;
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    Serial_terminal.print((char)96);//发送显示指令
    #ifdef SHOW_IN_SERIAL
      Serial.println("Communication error");
    #endif
    return 1;
  } else if (p == FINGERPRINT_BADLOCATION) {
    Serial_terminal.print((char)96);//发送显示指令
    #ifdef SHOW_IN_SERIAL
      Serial.println("Could not store in that location");
    #endif
    return 1;
  } else if (p == FINGERPRINT_FLASHERR) {
    Serial_terminal.print((char)96);//发送显示指令
    #ifdef SHOW_IN_SERIAL
      Serial.println("Error writing to flash");
    #endif
    return 1;
  } else {
    #ifdef SHOW_IN_SERIAL
      Serial.println("Unknown error");
    #endif
    Serial_terminal.print((char)96);//发送显示指令
    return 1;
  }   
}
//指纹删除核心
uint8_t deleteFingerprint(uint8_t id) {
  uint8_t p = -1;
  
  p = finger.deleteModel(id);

  if (p == FINGERPRINT_OK) {
    #ifdef SHOW_IN_SERIAL
      Serial.println("Deleted!");
    #endif
    Serial_terminal.print((char)123);//发送显示指令
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    #ifdef SHOW_IN_SERIAL
      Serial.println("Communication error");
    #endif
    Serial_terminal.print((char)124);//发送显示指令
    return p;
  } else if (p == FINGERPRINT_BADLOCATION) {
    #ifdef SHOW_IN_SERIAL
      Serial.println("Could not delete in that location");
    #endif
    Serial_terminal.print((char)124);//发送显示指令
    return p;
  } else if (p == FINGERPRINT_FLASHERR) {
    #ifdef SHOW_IN_SERIAL
      Serial.println("Error writing to flash");
    #endif
    Serial_terminal.print((char)124);//发送显示指令
    return p;
  } else {
    #ifdef SHOW_IN_SERIAL
      Serial.print("Unknown error: 0x"); Serial.println(p, HEX);
    #endif
    Serial_terminal.print((char)124);//发送显示指令
    return p;
  }   
}

Arduino-3

  • 主控
#include <Servo.h>  //官方舵机控制库
#include <Adafruit_SSD1306.h> //第三方oled库
#include <SoftwareSerial.h> //软串口库
#include <SPI.h>
#include <MFRC522.h>
#include <HardwareSerial.h>

#define MAXSIZE_IC_UID 8
#define SS_PIN 10
#define RST_PIN 9
// #define SHOW_RFID_IN_SERIAL

/********************各功能状态*************/
bool state_face=0,state_finger=1,state_password=1,state_rfid=1,state_app = 1; 
bool state_input_way = 1; //1:默认红外,2:触摸键盘
SoftwareSerial Serial_key(2,3);   //RX,TX,与密码模块通信的软串口
/*************************处,理蜂鸣器***************************/
int buzzerPin = 7;  //蜂鸣器IO
/**************************处理舵机***************************/
Servo servo_door; //定义舵机变量名
int servoPin = 8; //舵机IO
/**********************处理oled************************/
#define OLED_RESET 4  //UNO:SDA=a4 SCL=a5 ;pro micro:SDA=2 SCL=3
Adafruit_SSD1306 display(OLED_RESET);
#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif


/**********************************处理RFID函数*************************/
MFRC522 rfid(SS_PIN, RST_PIN); //实例化类
// 初始化数组用于存储读取到的NUID 
void printUID(byte *buffer, byte bufferSize = 4, bool form = 0) {
  for (byte i = 0; i < bufferSize; i++) {
    //Serial.print(buffer[i] < 0x10 ? " 0" : "");
    Serial.print(buffer[i], form == 0? HEX : DEC);
    Serial.print(' ');
  }
}

class IC_UID{
  public:
  /*IC_UID(){
    data = (byte**)malloc(sizeof(byte*) * MAXSIZE_IC_UID);
    for(int i = 0; i < MAXSIZE_IC_UID; i++) {
      data[i] = (byte*)malloc(sizeof(byte) * 4);
    }
  }
    
    void print_All_Uid(){
      Serial.println("all data:");
      for(int i = 0;i < size;i++){
        Serial.print(i);
        Serial.print(": ");
        printUID(data[i]);
        Serial.println();
      }
    }*/
    // byte **data;
    byte data[MAXSIZE_IC_UID][4];
    int size = 0;
};
IC_UID icUid;

/********************************处理舵机函数******************************/
void servo_open(){  
  for(int jiao=50;jiao<170;jiao++){
     servo_door.write(jiao); 
     delay(10);   
   }
   delay(5000);
   for(int jiao=170;jiao>50;jiao--){
     servo_door.write(jiao); 
     delay(10);   
   }
}

void servo_init(){
  servo_door.write(50);
  delay(1000);
}
/********************************处理声音函数*****************************/
void voice_error(){
  int i;
  for (i = 0; i < 100; i++) {
    digitalWrite(buzzerPin, HIGH);
    delay(1);
    digitalWrite(buzzerPin, LOW);
    delay(1);
  }
  for (i = 0; i < 100; i++) {
    digitalWrite(buzzerPin, HIGH);
    delay(2);
    digitalWrite(buzzerPin, LOW);
    delay(2);
  }
}

void voice_pass(){
  int i;
  for (i = 0; i < 100; i++) {
    digitalWrite(buzzerPin, HIGH);
    delay(1);
    digitalWrite(buzzerPin, LOW);
    delay(1);
  }
  for (i = 0; i < 50; i++) {
    digitalWrite(buzzerPin, HIGH);
    delay(2);
    digitalWrite(buzzerPin, LOW);
    delay(2);
  } 
  for (i = 0; i < 100; i++) {
    digitalWrite(buzzerPin, HIGH);
    delay(1);
    digitalWrite(buzzerPin, LOW);
    delay(1);
  }
}

void voice_input(){
  for (int i = 0; i < 60; i++) {
    digitalWrite(buzzerPin, HIGH);
    delay(1);
    digitalWrite(buzzerPin, LOW);
    delay(1);
  }
}
/******************************   NEW_OLED_DISPLAY  *********************************/
//显示输入的字符,不清屏
void oled_display_char(char x,int _size = 1,unsigned int _color = 1){
  display.setTextSize(_size);//字体大小
  if(_color){
    display.setTextColor(WHITE);//文字颜色
  }
  else{
    display.setTextColor(BLACK, WHITE);
  }
  display.print(x);
  display.display(); 
}

//清屏显示字符串
void oled_display_string(char *str,int _delayTime = 1000,int _size = 1,bool _color = 1){
  display.clearDisplay();
  display.setCursor(0,0);
  if(_color){
    display.setTextColor(WHITE);//文字颜色
  }
  else{
    display.setTextColor(BLACK, WHITE);
  }

  display.setTextSize(_size);
  display.println(str);
  display.display(); 
  if(_delayTime){
    delay(_delayTime);
    display.setCursor(0,0);
    display.clearDisplay();
  }
}

//主界面
void oled_Main_interface(unsigned char choice,bool setting_flag = 0){
  display.clearDisplay();
  display.setCursor(0,0);
  display.setTextSize(1);

  display.setTextColor(WHITE);
  if(setting_flag)
    display.println("    SYSTEM-SETTING");
  else
    display.println("    ACCESS-CONTROL");

  if(choice == 1){
    display.setTextColor(BLACK,WHITE);
  }
  display.print("1.Password");

  display.setTextColor(WHITE);
  display.print("  ");
  if(choice == 2){
    display.setTextColor(BLACK,WHITE);
  }
  display.println("2.Finger");

  display.setTextColor(WHITE);
  if(choice == 3){
    display.setTextColor(BLACK,WHITE);
  }
  display.print("3.Face");

  display.setTextColor(WHITE);
  display.print("      ");
  if(choice == 4){
    display.setTextColor(BLACK,WHITE);
  }
  display.println("4.Rfid");

  display.setTextColor(WHITE);
  if(choice == 5){
    display.setTextColor(BLACK,WHITE);
  }
  display.print("5.APP");

  display.setTextColor(WHITE);
  display.print("       ");
  if(choice == 6){
    display.setTextColor(BLACK,WHITE);
  }
  if(setting_flag)
    display.println("6.<--Exit");
  else
    display.println("6.Setting");
  display.display();
  if(choice != 0){
    delay(500);
    display.setCursor(0,0);
    display.clearDisplay();
  }
}

void oled_func_setting(char *func,unsigned char choice = 0){
  display.clearDisplay();
  display.setCursor(0,0);
  display.setTextSize(1);

  display.setTextColor(WHITE);
  display.print("    ");
  display.print(func);
  display.println("-SETTING");
  if(choice == 1)
    display.setTextColor(BLACK,WHITE);
  display.print("1.New");

  display.setTextColor(WHITE);
  display.print("      ");
  if(choice == 2)
    display.setTextColor(BLACK,WHITE);
  display.println("2.Delete");

  display.setTextColor(WHITE);
  if(choice == 3)
    display.setTextColor(BLACK,WHITE);
  display.print("3.Number");

  display.setTextColor(WHITE);
  display.print("   ");
  if(choice == 4)
    display.setTextColor(BLACK,WHITE);
  display.println("4.<-Back");

  display.setTextColor(WHITE);
  display.print("5.Change state:  ");
  switch (func[1]){ //显示该功能开关状态
    case 'A':
      if(state_face)
        display.print("ON");
      else
        display.print("OFF");
      break;
    case 'I':
      if(state_finger)
        display.print("ON");
      else
        display.print("OFF");
      break;
    case 'F':
      if(state_rfid)
        display.print("ON");
      else
        display.print("OFF");
      break;
    default:
      break;
  }
  display.display();

  if(choice > 0 && choice <5){
    delay(500);
    display.setCursor(0,0); 
    display.clearDisplay();
  }
}

void oled_passward_setting(unsigned char choice = 0){
  display.clearDisplay();
  display.setCursor(0,0);
  display.setTextSize(1);

  display.setTextColor(WHITE);
  display.println("  PASSWORD-SETTING");
  if(choice == 1)
    display.setTextColor(BLACK,WHITE);
  display.println("1.Change password");
  
  display.setTextColor(WHITE);
  display.print("2.Change state:  ");
  if(state_password)
    display.println("ON");
  else
    display.println("OFF");

  display.setTextColor(WHITE);
  if(choice == 3)
    display.setTextColor(BLACK,WHITE);
  display.print("3.<-Back");

  display.setTextColor(WHITE);
  display.print("   4.");
  if(state_input_way)
    display.println("Remote");
  else
    display.println("Keyboard");

  display.display();
  if(choice == 3 || choice == 4){
    delay(500);
    display.setCursor(0,0); 
    display.clearDisplay();
  }
}
/**********************************密码**********************************/
void password_unlock(){
  Serial_key.print('P');//向主控板1发送用密码解锁指令
  char data_in;
  oled_display_string("Enter your password:",0);
  while(1){
    if(Serial_key.available()>0){  //Arduino1-密码
      data_in = Serial_key.read();
      //Serial.println(data_in);
      switch (data_in){
        case 'O': //密码匹配成功,开门
          Serial.print('C');
          voice_pass(); 
          oled_display_string("Welcome.    :)",1000,2);
          servo_open();
          return;
        case 'L': //密码匹配失败,锁定
          voice_error();
          oled_display_string("Error! :(",1000,2);
          servo_init();
          return;
        case 'U': //密码匹逆序输入,报警
          Serial.print('U');
          voice_pass(); 
          oled_display_string("Welcome.    :)",1000,2);
          servo_open();
          return;
        default:  //显示输入的密码
          voice_input();
          oled_display_char(data_in,1,1);
          break;
      }
    }
  }
}

bool password_setting(){
  char data_in;
  oled_passward_setting(0);
  Serial_key.print('@');
  while(1){ //接收到用户输入就返回,1,2,3有效
    if(Serial_key.available()>0){
      switch (data_in = Serial_key.read()){
        case '1': //更换密码
          voice_input();
          oled_passward_setting(1);
          password_change();
          break;
        case '2': //功能开关
          voice_input();
          state_password = !state_password;
          break;
        case '3': //返回
          voice_input();
          oled_passward_setting(3);
          return 1;
        case '4': //输入方式开关
          voice_input();
          state_input_way = !state_input_way;
          if(state_input_way) //向主控板1发送默认输入方式
            Serial_key.print('R');
          else
            Serial_key.print('K');
          break;
        default:
          voice_error();
          oled_display_string("Invalid!",1000,2);
          break;
      }
      return 0;
    }
  }
}

void password_change(){
  Serial_key.print('C');
  oled_display_string("Input your key:",0);
  char data_in;
  while(1){ //接收到密码设定成功就返回,P有效
    if(Serial_key.available()>0){
      data_in = Serial_key.read();
      if(data_in == 'P'){ //接收到p即密码设定完成
        voice_pass();
        oled_display_string("OK! :)",1000,2);
        servo_init();
        return;
      }
      else{ //显示输入的密码
        voice_input();
        oled_display_char(data_in,1,1);
      }
    }
  }
}
/*************************************指纹***********************************/
bool finger_unlock(bool verify = 0){
  digitalWrite(4,HIGH);
  Serial.print('Y');  //向arduino2发送指令,开始识别
  Serial_key.print('@');  //向arduino1发送指令,准备接收任意键返回
  oled_display_string("Verify finger,any key to exit...");
  char data_in;
  while(1){
    if(Serial_key.available()>0){//按任意键返回,并RESET指纹Arduino
      Serial_key.read();
      voice_input();
      //通过D4口RESET Arduino2,解决双软串口无法同时监视的问题
      digitalWrite(4,LOW);
      return 0;
    }
    if(Serial.available()>0){      //Arduino2-指纹
      data_in = Serial.read();
      if(data_in == 'O'){
        digitalWrite(4,LOW);
        voice_pass();  
        if(!verify){
          oled_display_string("Welcome.    :)",1000,2);
          servo_open();
        }
        return 1;
      }
      oled_display_string("Verify finger,any key to exit...");
      while(Serial.read()>=0){}//清空指纹和人脸识别结果的缓存区
    }
  }
}

bool finger_setting(){
  char data_in;
  oled_func_setting("FINGER",0);
  Serial_key.print('@');
  while(1){ //接收到用户输入就返回,1,2,3有效
    if(Serial_key.available()>0){
      switch (data_in = Serial_key.read()){
        case '1':
          voice_input();
          oled_func_setting("FINGER",1);
          Serial.print('N');//向主控板2发送新建指纹指令
          finger_judge();
          break;
        case '2':
          voice_input();
          oled_func_setting("FINGER",2);
          Serial.print('M');//向主控板2发送删除指纹指令
          finger_judge();
          break;
        case '3':
          voice_input();
          oled_func_setting("FINGER",3);
          Serial.print('Z');//向主控板2发送查看指纹数量指令
          while(1){
            if(Serial.available()>0){
              oled_display_char(Serial.read(),4);
              delay(1000);
              break;
            }
          }
          break;
        case '4':
          voice_input();
          oled_func_setting("FINGER",4);
          return 1;
        case '5':
          voice_input();
          state_finger = !state_finger;
          break;
        default:
          voice_error();
          oled_display_string("Invalid!",1000,2);
          break;
      }
      return 0;
    }
  }
}

bool finger_judge(){
  int ID;
  char data_in;
  while(1){
    if(Serial.available()>0){
      data_in = Serial.read();
      switch (data_in)
      {
        case 92:
          oled_display_string("Press finger...");
          break;
        case 93:
          oled_display_string("Move finger away.");
          break;
        case 94:
          oled_display_string("Press finger again...");
          break;
        case 95:
          oled_display_string("Succeed :)",1000,2);
          return 1;
          break;
        case 96:
          oled_display_string("Failed,try again! :(");
          return 0;
          break;
        case 123:
          oled_display_string("Succeed :)",1000,2);
          break;
        case 124:
          oled_display_string("Failed,try again! :(");
          break;
        case 'S':
          oled_display_string("Put your face close...");
          break;
        case 'W':
          oled_display_string("Succeed :)",1000,2);
          return 1;
        default:
          break;
      }
      if(data_in >=95 && data_in <= 123)
        break;
    }
  }
}
/***************************************人脸*****************************/
bool face_setting(){
  char data_in;
  oled_func_setting("FACE",0);
  Serial_key.print('@');
  while(1){ //接收到用户输入就返回,1,2,3有效
    if(Serial_key.available()>0){
      switch (data_in = Serial_key.read()){
        case '1':
          voice_input();
          oled_func_setting("FACE",1);
          Serial.print('Q');//向主控板2发送新建人脸指令
          finger_judge();
          break;
        case '2':
          voice_input();
          Serial.print('D');//向主控板2发送新建人脸指令
          finger_judge();
          break;
        case '3':
          voice_input();
          oled_func_setting("FACE",3);
          Serial.print('T');//向主控板2发送查看人脸数量指令
          while(1){
            if(Serial.available()>0){
              oled_display_char(Serial.read(),4);
              delay(1000);
              break;
            }
          }
          break;
        case '4':
          voice_input();
          oled_func_setting("FACE",4);
          return 1;
        case '5':
          voice_input();
          state_face = !state_face;
          if(state_face)
            Serial.print('F');  //开启人脸识别
          else
            Serial.print('X');  //关闭人脸识别
          break;
        default:
          voice_error();
          oled_display_string("Invalid!",1000,2);
          break;
      }
      return 0;
    }
  }
}


/***********************************刷卡*********************************/
bool rfid_setting(){
  char data_in;
  oled_func_setting("RFID",0);
  Serial_key.print('@');
  while(1){ //接收到用户输入就返回,1-5有效
    if(Serial_key.available()>0){
      switch (data_in = Serial_key.read()){
        case '1':
          voice_input();
          oled_func_setting("RFID",1);
          new_uid();
          break;
        case '2':
          voice_input();
          oled_func_setting("RFID",2);
          delete_uid();
          break;
        case '3':
          voice_input();
          oled_func_setting("RFID",3);
          oled_display_char(icUid.size+48,4);
          delay(1000);
          break;
        case '4':
          voice_input();
          oled_func_setting("RFID",4);
          return 1;
        case '5':
          voice_input();
          state_rfid = !state_rfid;
          break;
        default:
          voice_error();
          oled_display_string("Invalid!",1000,2);
          break;
      }
      return 0;
    }
  }
}

void new_uid(){
  oled_display_string("Place your card...",0);
  static int label = 0; 
  /*Serial.print("Input your label:");
  while(Serial.available()<=0){}*/
  //while(Serial.read()<0){};
  #ifdef SHOW_RFID_IN_SERIAL
    Serial.println(label);
    Serial.println("Put your card... ...");
  #endif
  while(1){
    //找卡
    if ( ! rfid.PICC_IsNewCardPresent())
      continue;
  
    // 验证NUID是否可读
    if ( ! rfid.PICC_ReadCardSerial())
      continue;
  
    MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
    
    // 将NUID保存到数组
    for (byte i = 0; i < 4; i++) {
      icUid.data[label][i] = rfid.uid.uidByte[i];
    }   
    icUid.size++;
    #ifdef SHOW_RFID_IN_SERIAL
      Serial.print("十六进制UID:");
      printUID(icUid.data[label]);
      Serial.println();
    #endif
    /*Serial.print("十进制UID:");
    printUID(rfid.uid.uidByte, rfid.uid.size, 1);
    Serial.println();*/
    
    // 使放置在读卡区的IC卡进入休眠状态,不再重复读卡
    rfid.PICC_HaltA();
  
    // 停止读卡模块编码
    rfid.PCD_StopCrypto1();
    label++;
    voice_pass();
    oled_display_string("Successfully created! :)");
    return;
  }
}

//匹配卡
int match_uid(){
  //找卡
  if (!rfid.PICC_IsNewCardPresent())
    return -1;

  // 验证NUID是否可读
  if (!rfid.PICC_ReadCardSerial())
    return -1;

  //读卡,保存卡id
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  byte temp_uid[4];
  for (int i = 0; i < 4; i++){
    temp_uid[i] = rfid.uid.uidByte[i];
  }

  //匹配
  for (int i = 0; i < icUid.size; i++){
    for (int j = 0; j < 4; j++){
      if (temp_uid[j] != icUid.data[i][j]){
        continue;
      }
      //匹配成功,并返回卡在icUid.data中的索引
      if (j == 3){
        // 使放置在读卡区的IC卡进入休眠状态,不再重复读卡
        rfid.PICC_HaltA();
        // 停止读卡模块编码
        rfid.PCD_StopCrypto1();
        return i;
      }
    }
  }
  // 使放置在读卡区的IC卡进入休眠状态,不再重复读卡
  rfid.PICC_HaltA();
  // 停止读卡模块编码
  rfid.PCD_StopCrypto1();
  return -1;
}

//删除已保存的卡
void delete_uid() {
  oled_display_string("Place your card...",0);
  int index;  
  while(1){
    index = match_uid();
    if(index >= 0)
      break;
  }
  for (int i = index + 1; i < icUid.size; i++){
    int j = i - 1;
    for(unsigned char k = 0;k<4;k++)
      icUid.data[j][k] = icUid.data[i][k];
  }
  icUid.size--;
  voice_pass();
  oled_display_string("Successfully deleted! :)");
}
/**************************************主函数***************************************/

bool system_setting(){
  char data_in;
  Serial_key.print('@');//向主控板1发送用接收选择信息指令
  oled_Main_interface(0,1);

  while(1){ //接收到用户输入就返回,1-6有效
    if(Serial_key.available()>0){
      switch (data_in = Serial_key.read()){
        case '1': //密码设置
          voice_input();
          oled_Main_interface(1,1);
          while(!password_setting());
          break;
        case '2': //指纹设置
          voice_input();
          oled_Main_interface(2,1);
          while(!finger_setting());
          break;
        case '3': //人脸设置
          voice_input();
          oled_Main_interface(3,1);
          while(!face_setting());
          break;
        case '4': //刷卡设置
          voice_input();
          oled_Main_interface(4,1);
          while(!rfid_setting());
          break;
        case '5': //APP设置
          voice_input();
          oled_Main_interface(5,1);
          if(state_app)
            oled_display_string("ON -->",1000,2);
          else{
            oled_display_string("OFF -->",1000,2);
          }
          state_app = !state_app;
          if(state_app)
            oled_display_string("ON",1000,2);
          else{
            oled_display_string("OFF",1000,2);
          }
          break; 
        case '6': //退出管理模式
          voice_input();
          oled_Main_interface(6,1);
          system_init();
          return 1;
        default:
          voice_error();
          oled_display_string("Invalid!",1000,2);
          break;
      }
      return 0;
    }
  }
}

bool system_init(){
  Serial.print('Z');  //向主控板2发送查看指纹数量指令
  if(state_input_way) //向主控板1发送默认输入方式
    Serial_key.print('R');
  else
    Serial_key.print('K');
  unsigned char finger_num;
  while(1){
    if(Serial.available()>0){
      finger_num = Serial.read();
      oled_display_string("Fingerprints:",0);
      oled_display_char(finger_num);
      delay(1000);
      if(finger_num >= '1' && finger_num <= '9'){
        oled_display_string("OK.",500,4);
        return 1;
      }
      if(finger_num == '0'){
        Serial.print('N');
        return (finger_judge());
      }
    }
  }
}

void setup(){
    Serial.begin(9600);//各串口初始化
    while(!Serial){}
    Serial_key.begin(9600);
    pinMode(4,OUTPUT);
    digitalWrite(4,LOW);

    SPI.begin(); // 初始化SPI总线
    rfid.PCD_Init(); // 初始化 MFRC522 
    
    pinMode(buzzerPin,OUTPUT);//蜂鸣器初始化
    servo_door.attach(servoPin);

    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  //oled初始化
    display.display();
    delay(1000);
    display.clearDisplay();
  
    while(!system_init());  //系统初始化,设置初始指纹
}

void loop(){
  while(Serial.read()>=0){}//清空指纹和人脸识别结果的缓存区
  int match_result;
  char data_in;
  Serial_key.print('@');//向主控板1发送用接收选择信息指令
  oled_Main_interface(0);

  while(1){ //接收到用户输入就返回,1,2,3,4有效,其余交接指令判断函数处理
    if(Serial_key.available()>0){
      switch (data_in = Serial_key.read()){
        case '1': //密码解锁,需要进入
          voice_input();
          oled_Main_interface(1);
          if(state_password)
            password_unlock();
          else
            oled_display_string("Disabled. :(",1000,2);
          break;
        case '2': //指纹解锁,需要进入
          voice_input();
          oled_Main_interface(2);
          if(state_finger)
            finger_unlock();
          else
            oled_display_string("Disabled. :(",1000,2);
          break;
        case '3': //人脸解锁,默认开启
          voice_input();
          oled_Main_interface(3);
          if(state_face)
            oled_display_string("Enabled.   :)",1000,2);
          else
            oled_display_string("Disabled. :(",1000,2);
          break;
        case '4': //刷卡解锁,默认开启
          voice_input();
          oled_Main_interface(4);
          if(state_rfid)
            oled_display_string("Enabled.   :)",1000,2);
          else
            oled_display_string("Disabled. :(",1000,2);
          break;
        case '5': //APP解锁,默认开启
          voice_input();
          oled_Main_interface(5);
          if(state_app)
            oled_display_string("Enabled.   :)",1000,2);
          else
            oled_display_string("Disabled. :(",1000,2);
          break;
        case '6': //管理模式,进入系统设置
          voice_input();
          oled_Main_interface(6);
          if(finger_unlock(1))
            while(!system_setting());
          break;
        default:
          voice_error();
          oled_display_string("Invalid!",1000,2);
          break;
      }
      break;
    }
    if(state_rfid){
      match_result = match_uid();
      if(match_result >= 0){
        Serial.print('A');
        Serial.print(match_result);
        voice_pass();  
        oled_display_string("Welcome.    :)",0,2);
        servo_open();
        break;
      }
    }
    if(Serial.available()>0){
      voice_input();
      switch (data_in = Serial.read()){
        case 'O':
          voice_pass();  
          oled_display_string("Welcome.    :)",0,2);
          servo_open();
          break;
        case 'F':
          state_face = 1;
          Serial.print('F');  //开启人脸识别
          break;
        case 'f':
          state_face = 0;
          Serial.print('X');  //关闭人脸识别
          break;
        case 'q':
          Serial.print('Q');  //向主控板2发送新建人脸指令
          finger_judge();
          break;
        case 'd':
          Serial.print('D');//向主控板2发送删除人脸指令
          finger_judge();
          break;
        case 't':
          Serial.print('T');//向主控板2发送查看人脸数量指令
          while(1){
            if(Serial.available()>0){
              display.clearDisplay();
              display.setCursor(0,0);
              oled_display_char(Serial.read(),4);
              delay(1000);
              break;
            }
          }
          break;
        case 'P':
          state_password = 1;
          break;
        case 'p':
          state_password = 0;
          break;
        case 'b':
          password_change();
          break;
        case 'r':
          state_input_way = !state_input_way;
          if(state_input_way) //向主控板1发送默认输入方式
            Serial_key.print('R');
          else
            Serial_key.print('K');
          break;
        case 'Z':
          state_finger = 1;
          break;
        case 'z':
          state_finger = 0;
          break;
        case 'n':
          Serial.print('N');//向主控板2发送新建指纹指令
          finger_judge();
          break;
        case 'm':
          Serial.print('M');//向主控板2发送删除指纹指令
          finger_judge();
          break;
        case 'l':
          Serial.print('Z');//向主控板2发送查看指纹数量指令
          while(1){
            if(Serial.available()>0){
              display.clearDisplay();
              display.setCursor(0,0);
              oled_display_char(Serial.read(),4);
              delay(1000);
              break;
            }
          }
          break;
        case 'C':
          state_rfid = 1;
          break;
        case 'c':
          state_rfid = 0;
          break;
        case 'i':
          new_uid();
          break;
        case 'j':
          delete_uid();
          break;
        case 'k':
          display.clearDisplay();
          display.setCursor(0,0);
          oled_display_char(icUid.size+48,4);
          delay(1000);
          break;
        default:
          break;
      }
      break;
    }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值