【宿舍指纹解锁】Arduino+光学指纹模块+舵机

发布于 2022-12-25  4483 次阅读


1、说在前面

点击查看视频演示

在宿舍条件有限制,不能更改门的锁体,不能破坏门的结构。
需要在门外安装指纹识别模块(需要有门缝走线),门把手适当位置安装固定舵机。
通过识别指纹开发板控制舵机硬拉门把手达到开门的目的。
需要购买的材料价格大概在100元左右。(22年12月价格)

2、准备材料

我使用的材料是:
1个充电宝(需要2个充电孔5V供电,也可使用充电器供电)
1卷电工胶布(包裹和固定电线,非必要)
1根USB线(给大力舵机独立供电)
1块UNO  R3开发板(带打印线)
1个AS608指纹识别模块(带USB转TTL板)
1个MG996舵机180度(根据开门力度选择合适的舵机)(大力舵机需要独立供电)
若干根合适长度的杜邦线(公对公、母对母、公对母)

3、指纹调试

使用USB转TTL板连接指纹模块和电脑。


1、Vi模块电源正输入端——TTL板3.3V(红)
2、Tx串行数据输出——TTL板Rx(黄)
3、Rx串行数据输入——TTL板Tx(白)
4、GND信号地——TTL板GND(黑)
(接线图如下)

打开“设备管理器”查看并记录TTL板的端口号。
运行买模块附赠的指纹程序(我这里使用Synodemo_v2.7)打开该端口的指纹模块。
录入指纹速度慢可以取消勾选“显示图像”。
(建议录入指纹时,波特率选择57600)。
录入指纹完成后拔掉TTL板,使用杜邦线连接开发板指纹模块和舵机。

4、线路连接

准备红、黄、蓝、绿、白、黑、橙颜色合适长度的杜邦线若干。
舵机上红色为电源线,棕黑色为地线,橙黄色为信号线。
1、指纹模块红色绿色线延长接成一根红色线上接R3板3.3V口。(供电)。
2、指纹模块黑色线接R3板GND接口(地线)。
3、指纹模块黄色线接R3板数字2号口(串行数据输出)。
4、指纹模块白色线接R3板数字3号口(串行数据输入)。
5、指纹模块蓝色线接R3板数字4号口(感应信号输出)。
6、舵机棕黑色线接R3板GND接口(地线)。
7、舵机红色接R3板5V接口(供电)。
8、舵机橙黄色线接R3板9号口(信号)。
如果使用独立供电请使用以下接线方式。剥开一根USB线,红色电源,黑色地线。
电源红色接线到舵机的电源红色供电。
地线黑色接开发板GND和舵机黑色地线。(独立供电需要共地)。

5、刷写程序

把R3板连接电脑,选择开发板的端口(工具→端口→选择端口),复制以下代码进Arduino程序。
如果缺少库文件,就在“工具→管理库”里面搜索添加提示缺失的库即可
左上角√图标验证没问题,就可以上传至R3板内了。
修改端口之后也要把对应的线接到对应的端口上。
第17行修改行数据输出和串行数据输入接口。
第31行修改舵机信号端口.
第39行设置指纹识别模块波特率速率。
79~86行修改舵机属性。 (源码来自https://www.arduino.cc/reference/en/libraries/)
#include <Adafruit_Fingerprint.h>  //声明调用Adafruit_Fingerprint.h库  指纹
#include <Servo.h>    // 声明调用Servo.h库  舵机
 
Servo myservo;        // 创建一个舵机对象
int pos = 0;          // 变量pos用来存储舵机位置
const int servoDelay = 15;
const int servoStop  = 5000;
const int lowPowerRate = 1;
const int checkDelay = 1000;
const int debug = 0;
 
#if (defined(__AVR__) || defined(ESP8266)) && !defined(__AVR_ATmega2560__)
// For UNO and others without hardware serial, we must use software serial...
// pin #2 is IN from sensor (GREEN wire)
// pin #3 is OUT from arduino  (WHITE wire)
// Set up the serial port to use softwareserial..
SoftwareSerial mySerial(2, 3);//黄色串行数据输出&&白色串行数据输入接口(可修改范围A0~A5,2~13)
 
#else
// On Leonardo/M0/etc, others with hardware serial, use hardware serial!
// #0 is green wire, #1 is white
#define mySerial Serial1
 
#endif
 
 
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
 
void setup()
{
  myservo.attach(9); //舵机信号端口(可修改范围A0~A5,2~13)
  myservo.write(0);
  Serial.begin(9600);
  while (!Serial);  // For Yun/Leo/Micro/Zero/...
  delay(100);
  Serial.println("\n\nAdafruit finger detect test");
 
  // set the data rate for the sensor serial port
  finger.begin(57600);//设置传感器串行端口的数据速率
  delay(5);
  if (finger.verifyPassword()) {
    Serial.println("Found fingerprint sensor!");
  } else {
    Serial.println("Did not find fingerprint sensor :(");
    while (1) { delay(1); }
  }
 
  Serial.println(F("Reading sensor parameters"));
  finger.getParameters();
  Serial.print(F("Status: 0x")); Serial.println(finger.status_reg, HEX);
  Serial.print(F("Sys ID: 0x")); Serial.println(finger.system_id, HEX);
  Serial.print(F("Capacity: ")); Serial.println(finger.capacity);
  Serial.print(F("Security level: ")); Serial.println(finger.security_level);
  Serial.print(F("Device address: ")); Serial.println(finger.device_addr, HEX);
  Serial.print(F("Packet len: ")); Serial.println(finger.packet_len);
  Serial.print(F("Baud rate: ")); Serial.println(finger.baud_rate);
 
  finger.getTemplateCount();
 
  if (finger.templateCount == 0) {
    Serial.print("Sensor doesn't contain any fingerprint data. Please run the 'enroll' example.");
  }
  else {
    Serial.println("Waiting for valid finger...");
    Serial.print("Sensor contains "); Serial.print(finger.templateCount); Serial.println(" templates");
  }
}
 
void loop()                     // run over and over again
{
  Serial.println("Voltage in 4"); Serial.println(digitalRead(4));
  if(!lowPowerRate || digitalRead(4) == HIGH) {
    getFingerprintID();
  }
  delay(checkDelay);            //don't ned to run this at full speed.
}
 
void openAndReset(){
  for(pos = 0; pos < 180; pos += 1){    // 舵机从0°转到180°,每次增加1°          
    myservo.write(pos);       // 给舵机写入角度   
    delay(servoDelay);                    // 延时15ms让舵机转到指定位置
  }
  delay(servoStop);
  for(pos = 180; pos>=1; pos-=1) {    // 舵机从180°转回到0°,每次减小1°                               
    myservo.write(pos);        // 写角度到舵机     
    delay(servoDelay);                 // 延时15ms让舵机转到指定位置
  }
}
 
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;
  }
 
  // OK success!
 
  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;
  }
 
  // OK converted!
  p = finger.fingerSearch();
  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;
  }
 
  // found a match!
  Serial.print("Found ID #"); Serial.print(finger.fingerID);
  Serial.print(" with confidence of "); Serial.println(finger.confidence);
 
  openAndReset();
 
  return finger.fingerID;
}
 
// returns -1 if failed, otherwise returns ID #
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);
  return finger.fingerID;
}

6、安装调试

程序烧录进开发板,先测试能否正常使用。按指纹识别模块,舵机旋转就成功啦。
请使用打印线供电,USB转DC(5.5*2.1给开发板供电舵机无力) 使用热熔胶或者AB胶将舵机固定在门上合适的位置。
要舵机开门力度不够就重新换个大力的舵机,设置方法一模一样就好。
我是琳沐曦,现在叫我香草布丁就好。
最后更新于 2023-03-03