该门锁作为2023年我的毕业设计,没有怎么优化,漏洞比较多,可以参考,但不要全抄哦
功能描述
1、矩阵按键密码解锁
2、指纹解锁
3、点灯科技手机APP解锁
4、接入米家,唤醒小爱同学解锁
所需器材
1、AS608指纹模块(RX–>TX2,TX–>RX2)
2、ESP32单片机
3、12V升压模块
4、电磁锁
5、0.96寸OLED显示屏(4针)(P4–>SDA,P5–>SCL)
6、矩阵按键(P13,P12,P14,P27,P26,P25,P33,P32)
7、兼容3.3v驱动继电器模块
原理图
电磁锁连接线路
电磁锁接线图比较粗糙,仅供参考
*下面开始写代码 *
主文件
#include "fingerprint.h"
#include "keymat.h"
#include "text.h"
#include "task.h"
#include "blinke.h"
void setup() {
//串口初始化
Serial.begin(115200);
while (!Serial); // For Yun/Leo/Micro/Zero/...
delay(100);
Serial.println("\n\nAdafruit finger detect test");
xMutexInventory = xSemaphoreCreateMutex();//创建互斥锁
if (xMutexInventory == NULL) {
printf("No Enough Ram, Unable to Create Semaphore.");
} else {
//创建指纹扫描任务 任务暂停句柄
xTaskCreatePinnedToCore(fingerPrintTask, "fingerPrint Task", 1024 * 4, NULL, 1, &finPrHandle, 1); //将该任务放在核心1上运行,核心0一般用于运行wifi
//创建KEY任务
xTaskCreatePinnedToCore(keyTask, "KEY Task", 1024 * 6, NULL, 1, NULL, 1); //将该任务放在核心1上运行,核心0一般用于运行wifi
//创建KEY任务
xTaskCreatePinnedToCore(blinkeTask, "Blinke Task", 1024 * 6, NULL, 1, NULL, 0); //将该任务放在核心1上运行,核心0一般用于运行wifi
}
vTaskDelete(NULL);
}
void loop() {
}
fingerprint.h
#ifndef _FINGERPRINT_H_
#define _FINGERPRINT_H_
#include <Adafruit_Fingerprint.h>
#include "task.h"
#include "lock.h"
#include "keymat.h"
#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);
#else
// On Leonardo/M0/etc, others with hardware serial, use hardware serial!
// #0 is green wire, #1 is white
#define mySerial Serial2
#endif
extern Adafruit_Fingerprint finger;
uint8_t getFingerprintID();//搜索并获取指纹ID
int getFingerprintIDez();//搜索并获取指纹ID,精简版
void fingerprint_init_correlaton();//指纹初始化后相关打印
void fingerPrintTask(void * pvParam);//指纹搜索任务
uint8_t getFingerprintEnroll(uint8_t id); //指纹注册
uint8_t deleteFingerprint(uint8_t id); //指纹删除
#endif
fingerprint.cpp
#include "fingerprint.h"
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
uint8_t getFingerprintID() {//获取指纹ID
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!");//从flash找到了指纹
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FINGERPRINT_NOTFOUND) {
Serial.println("Did not find a match");//没有从flash中找到指纹
return p;
} else {
Serial.println("Unknown error");
return p;
}
// found a match!找到指纹后显示ID
Serial.print("Found ID #"); Serial.print(finger.fingerID);
Serial.print(" with confidence of "); Serial.println(finger.confidence);
return finger.fingerID;
}
// returns -1 if failed, otherwise returns ID #
//查询指纹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);//匹配程度
password_input_success();
unlocking();
oled_show(1,1,0);
return finger.fingerID;
}
void fingerprint_init_correlaton()//指纹初始化后相关打印
{
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");
}
}
/*-------------------------------------------
作用:指纹注册
参数:
id:将要注册的指纹id
-------------------------------------------*/
uint8_t getFingerprintEnroll(uint8_t id) {
int p = -1;
Serial.print("Waiting for valid finger to enroll as #"); Serial.println(id);
while (p != FINGERPRINT_OK) {
p = finger.getImage();
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;
}
}
// OK success!
fingerprint_press_show();
p = finger.image2Tz(1);
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;
}
Serial.println("Remove finger");
delay(2000);
p = 0;
while (p != FINGERPRINT_NOFINGER) {
p = finger.getImage();
}
Serial.print("ID "); Serial.println(id);
p = -1;
Serial.println("Place same finger again");
while (p != FINGERPRINT_OK) {
p = finger.getImage();
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;
}
}
// OK success!
p = finger.image2Tz(2);
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!
Serial.print("Creating model for #"); Serial.println(id);
p = finger.createModel();
if (p == FINGERPRINT_OK) {
Serial.println("Prints matched!");
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FINGERPRINT_ENROLLMISMATCH) {
Serial.println("Fingerprints did not match");
return p;
} else {
Serial.println("Unknown error");
return p;
}
Serial.print("ID "); Serial.println(id);
p = finger.storeModel(id);
if (p == FINGERPRINT_OK) {
Serial.println("Stored!");
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FINGERPRINT_BADLOCATION) {
Serial.println("Could not store in that location");
return p;
} else if (p == FINGERPRINT_FLASHERR) {
Serial.println("Error writing to flash");
return p;
} else {
Serial.println("Unknown error");
return p;
}
return true;
}
/*-----------------------------------------
作用:指纹数据删除
参数:
id:需要删除的指纹id
-----------------------------------------*/
uint8_t deleteFingerprint(uint8_t id)
{
uint8_t p = -1;
p = finger.deleteModel(id);
if (p == FINGERPRINT_OK) {
Serial.println("Deleted!");
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
} else if (p == FINGERPRINT_BADLOCATION) {
Serial.println("Could not delete in that location");
} else if (p == FINGERPRINT_FLASHERR) {
Serial.println("Error writing to flash");
} else {
Serial.print("Unknown error: 0x"); Serial.println(p, HEX);
}
return p;
}
/*指纹搜索任务*/
void fingerPrintTask(void * pvParam)
{
//指纹串口初始化
finger.begin(57600);
vTaskDelay(5);
fingerprint_init_correlaton();//相关显示
int fingerPrintID = 0;
while(1){
//互斥锁上锁
if (xSemaphoreTake(xMutexInventory, timeOut) == pdPASS) {
fingerPrintID = getFingerprintIDez();//搜索指纹
//互斥锁开锁
xSemaphoreGive(xMutexInventory);
vTaskDelay(100);
}
}
}
text.h
#ifndef _TEXT_H_
#define _TEXT_H_
static const uint8_t text[][60] =
//开(0) 锁(1) 管(2) 理(3) 员(4) 改(5) 密(6) 码(7) 录(8) 指(9) 纹(10) 删(11) 指(12) 纹(13)
{
{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x01,0x04,0x04,0x01,0x02,0x04,0x01,0x01,0x04,0xC1,0x00,0xF8,0x3F,0x00,0xF8,0x07,0x00,0x04,0x01,0x00,0x04,0x01,0x00,0x04,0x01,0x00,0x04,0x01,0x00,0xF8,0xFF,0x07,0xF8,0xFF,0x03,0x04,0x01,0x00,0x04,0x01,0x00,0x06,0x01,0x00,0x84,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00},/*"开",0*/
{0x00,0x00,0x00,0x00,0x01,0x00,0xC0,0x08,0x00,0xB8,0x08,0x00,0x1E,0xFF,0x03,0x90,0x08,0x01,0x90,0x88,0x04,0x90,0x48,0x04,0x00,0x08,0x04,0xC4,0x7F,0x02,0x58,0x00,0x02,0x40,0x00,0x01,0x40,0xE0,0x00,0x7E,0x3F,0x00,0x40,0x80,0x00,0x50,0x00,0x01,0xCC,0x7F,0x01,0x40,0x00,0x02,0x00,0x00,0x06,0x00,0x00,0x00},/*"锁",1*/
{0x00,0x00,0x00,0x40,0x02,0x00,0x20,0x03,0x00,0x90,0x00,0x00,0x8E,0x00,0x00,0x88,0xFE,0x07,0xF0,0x4A,0x02,0x88,0x4A,0x02,0x88,0x4A,0x02,0xE8,0x4A,0x02,0xD0,0x4A,0x02,0x88,0x4A,0x02,0x8E,0x4A,0x02,0x88,0x5E,0x02,0xB0,0xC2,0x03,0x88,0x00,0x00,0x88,0x02,0x00,0x88,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"管",2*/
{0x00,0x00,0x00,0x00,0x80,0x00,0x08,0x81,0x00,0x08,0x41,0x00,0xF0,0x7F,0x00,0x08,0x41,0x00,0x08,0x21,0x00,0x08,0x21,0x02,0x00,0x20,0x02,0xFC,0x27,0x02,0x44,0x22,0x02,0x44,0x22,0x02,0x44,0x22,0x02,0xF8,0xFF,0x03,0x44,0x22,0x02,0x44,0x22,0x02,0xFC,0x27,0x02,0x00,0x20,0x02,0x00,0x00,0x02,0x00,0x00,0x00},/*"理",3*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x04,0x80,0x3F,0x04,0xC2,0x00,0x02,0xFE,0x00,0x02,0xA2,0x00,0x01,0xA2,0xC0,0x00,0xA2,0x7E,0x00,0xA2,0x0E,0x00,0xA2,0x40,0x00,0xA2,0x40,0x00,0xA2,0x80,0x00,0xFE,0x80,0x01,0x80,0x3F,0x03,0x80,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"员",4*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xFF,0x03,0x08,0x01,0x01,0x08,0x01,0x01,0x08,0x81,0x00,0x08,0x81,0x00,0x08,0x41,0x04,0xF8,0x41,0x04,0x00,0x01,0x02,0xC0,0x00,0x02,0xB8,0x07,0x01,0x2E,0x98,0x00,0x20,0x60,0x00,0x20,0xF0,0x00,0xA0,0x8F,0x01,0x40,0x00,0x03,0x20,0x00,0x06,0x00,0x00,0x02,0x00,0x00,0x00},/*"改",5*/
{0x00,0x00,0x00,0x00,0x10,0x00,0x30,0x10,0x00,0x08,0x12,0x00,0x88,0xC9,0x03,0x08,0x08,0x02,0xC8,0x0F,0x02,0x08,0x0C,0x02,0x10,0x0C,0x02,0xEE,0xFA,0x03,0x0C,0x29,0x02,0x88,0x09,0x02,0xC8,0x08,0x02,0x68,0x0E,0x02,0x08,0x00,0x02,0x88,0xC0,0x07,0x10,0x03,0x00,0x18,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"密",6*/
{0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x03,0x00,0xE4,0xFF,0x01,0x98,0x40,0x00,0x84,0x40,0x00,0x84,0xFF,0x00,0x06,0x00,0x00,0x04,0x00,0x00,0x02,0x22,0x00,0xFA,0x23,0x00,0x02,0x22,0x00,0x02,0x22,0x00,0x02,0x22,0x00,0x02,0x22,0x02,0xF2,0x23,0x06,0x0E,0x02,0x06,0x00,0xFE,0x01,0x00,0x02,0x00,0x00,0x00,0x00},/*"码",7*/
{0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x80,0x01,0x80,0x80,0x00,0x82,0x82,0x00,0x82,0x4C,0x00,0x92,0x5C,0x00,0x92,0x20,0x02,0x92,0x20,0x02,0x12,0xFF,0x07,0x12,0xFF,0x01,0x92,0x0C,0x00,0x92,0x10,0x00,0x92,0x68,0x00,0xFE,0xC4,0x00,0x80,0x86,0x01,0x80,0x00,0x01,0xC0,0x00,0x03,0x80,0x00,0x01,0x00,0x00,0x00},/*"录",8*/
{0x00,0x00,0x00,0x00,0x08,0x00,0x20,0x08,0x02,0x20,0x08,0x02,0x22,0x04,0x06,0xFC,0xFF,0x03,0x20,0x02,0x00,0x20,0x01,0x00,0x20,0x00,0x00,0xFE,0x04,0x06,0x24,0xFD,0x03,0x20,0x25,0x01,0x10,0x25,0x01,0x10,0x25,0x01,0x18,0x25,0x01,0x08,0x25,0x01,0x08,0xFD,0x07,0xE0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"指",9*/
{0x00,0x00,0x00,0x80,0x00,0x01,0xC0,0x39,0x01,0xA0,0x9C,0x00,0x98,0x92,0x00,0x86,0x91,0x04,0xC0,0x50,0x04,0x60,0x48,0x02,0x10,0x00,0x02,0x10,0x00,0x01,0xE0,0x83,0x00,0x12,0xCC,0x00,0x1C,0x70,0x00,0x18,0xF8,0x00,0x10,0x87,0x01,0xE0,0x01,0x01,0x10,0x00,0x03,0x10,0x00,0x06,0x10,0x00,0x02,0x00,0x00,0x00},/*"纹",10*/
{0x00,0x00,0x00,0x00,0x00,0x02,0x00,0xE1,0x01,0xFC,0x1F,0x01,0x04,0x01,0x01,0xFC,0xFF,0x01,0x04,0x01,0x02,0x00,0xE1,0x01,0xFC,0x1F,0x02,0x04,0x01,0x02,0x04,0x01,0x06,0xFC,0xFF,0x01,0x00,0x01,0x00,0x00,0x01,0x00,0xF8,0x3F,0x00,0x00,0x00,0x02,0x00,0x00,0x06,0xFE,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00},/*"删",11*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x84,0x00,0x01,0x98,0xFF,0x01,0x00,0xC0,0x00,0x00,0x20,0x00,0x80,0x00,0x00,0x88,0x00,0x00,0xA8,0xFC,0x07,0xA8,0x4A,0x00,0xA8,0x4A,0x00,0xFE,0x4A,0x00,0xA8,0x4A,0x02,0xA8,0x4A,0x02,0xA8,0x4A,0x06,0xA8,0xFE,0x01,0x88,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00},/*"请",12*/
{0x00,0x00,0x00,0x00,0x42,0x00,0xD0,0x43,0x00,0x38,0x22,0x00,0x14,0x22,0x00,0x90,0xFF,0x07,0x10,0x23,0x00,0x90,0x12,0x00,0x80,0xFF,0x07,0x40,0x29,0x00,0x70,0x29,0x02,0x98,0x29,0x06,0x86,0xFF,0x01,0x88,0x00,0x00,0x50,0xFC,0x02,0xA0,0x00,0x02,0x40,0x00,0x06,0xC0,0xFE,0x03,0x00,0x00,0x00,0x00,0x00,0x00},/*"输",13*/
{0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x01,0x00,0x80,0x00,0x00,0x40,0x00,0x00,0x20,0x00,0x02,0x18,0x00,0x02,0x0C,0x00,0x84,0x03,0x00,0xF8,0x00,0x00,0x60,0x00,0x00,0x80,0x03,0x00,0x00,0x0C,0x00,0x00,0x38,0x00,0x00,0x60,0x00,0x00,0xC0,0x00,0x00,0x80,0x01,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*"入",14*/
{0x00,0x00,0x00,0x00,0x00,0x02,0x80,0x80,0x01,0x90,0x68,0x00,0xE8,0x28,0x02,0x8A,0x08,0x06,0x8C,0xFF,0x03,0xE8,0x28,0x00,0x98,0x48,0x04,0x88,0xC8,0x02,0x80,0x00,0x01,0x00,0xE0,0x00,0xFC,0x1F,0x00,0x84,0x00,0x00,0x84,0x00,0x00,0x04,0xFF,0x07,0x86,0x00,0x00,0x82,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00},/*"新",15*/
{0x00,0x00,0x00,0x00,0x01,0x00,0xC0,0x08,0x00,0xB8,0x08,0x00,0x1E,0xFF,0x03,0x90,0x08,0x01,0x90,0x08,0x01,0x10,0x88,0x00,0x10,0x08,0x00,0x10,0x09,0x04,0x10,0xF9,0x07,0xFE,0x49,0x02,0x10,0x49,0x02,0x10,0x49,0x02,0xFE,0x49,0x02,0xFC,0x49,0x02,0x10,0xF9,0x03,0x10,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00},/*"错",16*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x82,0x00,0x00,0x9C,0xFF,0x01,0x00,0xC0,0x00,0x00,0x60,0x04,0x00,0x10,0x04,0x00,0x09,0x02,0x7E,0x09,0x01,0x22,0x89,0x00,0x22,0x71,0x00,0x22,0x1E,0x00,0x22,0x31,0x00,0x22,0xC9,0x00,0x7E,0x89,0x01,0x32,0x09,0x03,0x00,0x09,0x06,0x00,0x00,0x02,0x00,0x00,0x00},/*"误",17*/
{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x03,0xE0,0xFF,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x82,0x00,0x20,0x82,0x01,0x20,0xFE,0x04,0x20,0x00,0x02,0x3E,0x00,0x01,0xFC,0x07,0x01,0x20,0xF8,0x00,0x22,0x60,0x00,0x24,0xB8,0x00,0x38,0x0E,0x01,0x20,0x03,0x03,0x20,0x00,0x02,0x00,0xC0,0x07,0x00,0x00,0x00},/*"成",18*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xC0,0x00,0x10,0x40,0x00,0x10,0x40,0x00,0xE0,0x3F,0x00,0x10,0x20,0x04,0x10,0x20,0x02,0x10,0x20,0x02,0x10,0x10,0x01,0x40,0xC0,0x00,0x40,0x70,0x00,0x82,0x1F,0x00,0x7E,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x06,0x40,0x80,0x03,0xC0,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"功",19*/
{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x01,0x00,0xC0,0x00,0x00,0xF8,0xFF,0x07,0x06,0x00,0x00,0xE0,0xFF,0x00,0x20,0x00,0x04,0x40,0x00,0x04,0x20,0x92,0x04,0x18,0x92,0x02,0x16,0x49,0x02,0xAA,0x48,0x02,0xC8,0x24,0x01,0xC8,0x22,0x01,0x28,0x91,0x00,0x18,0x93,0x00,0x00,0x42,0x00,0x00,0x40,0x00,0x00,0x00,0x00},/*"修",20*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xFF,0x03,0x08,0x01,0x01,0x08,0x01,0x01,0x08,0x81,0x00,0x08,0x81,0x00,0x08,0x41,0x04,0xF8,0x41,0x04,0x00,0x01,0x02,0xC0,0x00,0x02,0xB8,0x07,0x01,0x2E,0x98,0x00,0x20,0x60,0x00,0x20,0xF0,0x00,0xA0,0x8F,0x01,0x40,0x00,0x03,0x20,0x00,0x06,0x00,0x00,0x02,0x00,0x00,0x00},/*"改",21*/
{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x01,0x00,0x80,0x00,0x00,0xF0,0xFF,0x07,0x1E,0x00,0x04,0x04,0x00,0x02,0x00,0x04,0x01,0xFC,0x85,0x00,0x84,0x44,0x00,0x84,0x34,0x00,0x84,0x08,0x00,0x04,0xFF,0x07,0x84,0x08,0x00,0x84,0x34,0x00,0x84,0x44,0x00,0xFC,0x84,0x00,0x00,0x04,0x01,0x00,0x04,0x01,0x00,0x00,0x00},/*"保",22*/
{0x00,0x00,0x00,0x00,0x10,0x00,0x08,0x10,0x00,0x08,0x08,0x00,0x08,0x06,0x00,0x88,0xFF,0x07,0xC8,0x00,0x00,0x68,0x00,0x00,0x5C,0x10,0x00,0x4E,0x10,0x00,0x48,0x10,0x02,0x48,0x10,0x02,0x48,0xFE,0x07,0x48,0x16,0x00,0x48,0x11,0x00,0xC8,0x10,0x00,0xC8,0x10,0x00,0x08,0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x00},/*"存",23*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x04,0x10,0x00,0xE4,0xFF,0x07,0x24,0x11,0x00,0x24,0x11,0x00,0x24,0x11,0x00,0x24,0x11,0x00,0xF8,0x1F,0x00,0x24,0x11,0x00,0x24,0x11,0x00,0x24,0x11,0x02,0x24,0x11,0x02,0x24,0x11,0x06,0xE4,0xFF,0x03,0x06,0x10,0x00,0x04,0x18,0x00,0x00,0x10,0x00,0x00,0x00,0x00},/*"再",24*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x10,0x00,0x08,0xF0,0x01,0x38,0x0E,0x00,0x80,0x01,0x04,0x60,0x04,0x02,0x00,0x02,0x02,0x80,0x01,0x01,0x60,0x80,0x00,0x3E,0x60,0x00,0x44,0x1F,0x00,0xA0,0x03,0x00,0x20,0x1C,0x00,0x20,0x60,0x00,0x20,0x81,0x01,0xE0,0x00,0x03,0x60,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x00},/*"次",25*/
{0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x00,0x01,0x20,0xF0,0x00,0xC2,0x0F,0x01,0x2C,0x01,0x01,0x38,0x01,0x03,0x20,0x81,0x03,0x20,0xFF,0x04,0x20,0x01,0x02,0x20,0x01,0x02,0xE0,0x03,0x01,0x3E,0x9C,0x00,0x20,0x60,0x00,0x20,0xF0,0x00,0xA0,0x8F,0x01,0xC0,0x00,0x03,0x20,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x00},/*"放",26*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0xF0,0xFF,0x07,0x08,0x01,0x00,0x08,0x01,0x00,0x08,0x02,0x00,0x08,0x02,0x00,0x08,0x06,0x00,0x08,0x0C,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"下",27*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x04,0x00,0x48,0x04,0x00,0x48,0x04,0x00,0x48,0x04,0x00,0x44,0x04,0x02,0x44,0x04,0x06,0xFC,0xFF,0x03,0x44,0x04,0x00,0x44,0x04,0x00,0x44,0x04,0x00,0x44,0x04,0x00,0x46,0x04,0x00,0x66,0x04,0x00,0x44,0x04,0x00,0x00,0x06,0x00,0x00,0x04,0x00,0x00,0x00,0x00},/*"手",28*/
};
#endif
keymat.h
#ifndef _KEYMAT_H_
#define _KEYMAT_H_
#include <Preferences.h>
#include "Adafruit_Keypad.h"
#include "task.h"
#include "text.h"
#include "SSD1306Wire.h"//oled头文件包含
#include "fingerprint.h"
#include "lock.h"
extern uint8_t getFingerprintEnroll(uint8_t id);
extern Adafruit_Keypad customKeypad;
//引脚初始化
void key_init(void);
//oled初始化
void oled_init(void);
/*菜单显示*/
void oled_show(uint8_t interface_control,uint8_t cursor,uint8_t input_sign);
//密码输入错误显示
void password_input_error(void);
//密码输入成功
void password_input_success(void);
//指纹ID输入错误显示 指纹保存数量1~20
void ID_input_error(void);
//指纹ID输入成功显示
void ID_input_success(void);
//指纹删除成功显示
void finger_delete_success(void);
//密码修改成功显示
void password_amend_success(void);
//按键输入显示
void input_show(uint8_t interface_control, uint8_t cursor, char *str);
//参数运算,用于光标计算
uint8_t cursor_operation_add(uint8_t interface_control,uint8_t cursor);
uint8_t cursor_operation_sub(uint8_t cursor);
//flash密码查询
bool flash_inquire(int password_flash_inquire);
//再次按下手指
void fingerprint_press_show(void);
//密码保存
void password_save(int password_flash_save);
//界面功能实现
bool interface_function_reailze(char *str_password,uint8_t interface_control,uint8_t cursor);
void keyTask(void * pvParam);//oled任务
extern void unlocking(void);//开锁
#endif
keymat.cpp
#include "keymat.h"
/*---------------------
按键相关
---------------------*/
const byte ROWS = 4; // 行
const byte COLS = 4; // 列
//按键定义
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {13, 12, 14, 27}; //引脚接口
byte colPins[COLS] = {26, 25, 33, 32}; //引脚接口
//initialize an instance of class NewKeypad
Adafruit_Keypad customKeypad = Adafruit_Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);
//-----------------------
//-----------------------
/*------------------------
设置oled屏幕的相关信息
------------------------*/
const int I2C_ADDR = 0x3c; // oled屏幕的I2c地址
#define SDA_PIN 4 // SDA引脚,默认gpio4(D2)
#define SCL_PIN 5 // SCL引脚,默认gpio5(D1)
/* 新建一个oled屏幕对象,需要输入IIC地址,SDA和SCL引脚号 */
SSD1306Wire oled(I2C_ADDR, SDA_PIN, SCL_PIN);
//-----------------------
//按键引脚初始化
void key_init(void)
{
customKeypad.begin();//初始化
}
//oled初始化
void oled_init(void)
{
oled.init();
oled.flipScreenVertically(); // 设置屏幕翻转
oled.setContrast(255); // 设置屏幕亮度
oled.clear();
oled.display(); // 清除屏幕
}
/*------------------------------------------------------
作用:界面的显示
参数:
interface_control:界面标志
cursor:光标设置
input_sign: 为0界面显示,为1按键输入娴熟
------------------------------------------------------*/
void oled_show(uint8_t interface_control,uint8_t cursor,uint8_t input_sign)
{
oled.clear();
if(interface_control == 1 && input_sign == 0){//显示第一个页面
oled.drawFastImage(32, 10, 20, 20, text[0]);
oled.drawFastImage(32+1*20, 10, 20, 20, text[1]);
oled.drawFastImage(32, 30, 20, 20, text[2]);
oled.drawFastImage(32+1*20, 30, 20, 20, text[3]);
oled.drawFastImage(32+2*20, 30, 20, 20, text[4]);
if(cursor == 1){
oled.setFont(ArialMT_Plain_16); // 设置字体
oled.drawString(16, 10, ">"); // 将要显示的文字写入缓存
}
if(cursor == 2){
oled.setFont(ArialMT_Plain_16); // 设置字体w
oled.drawString(16, 30, ">"); // 将要显示的文字写入缓存
}
}
if(interface_control == 2 && input_sign == 0){//显示第2个页面
oled.drawFastImage(32, 1, 20, 20, text[5]);
oled.drawFastImage(32+1*20, 1, 20, 20, text[6]);
oled.drawFastImage(32+2*20, 1, 20, 20, text[7]);
oled.drawFastImage(32, 22, 20, 20, text[8]);
oled.drawFastImage(32+1*20, 22, 20, 20, text[9]);
oled.drawFastImage(32+2*20, 22, 20, 20, text[10]);
oled.drawFastImage(32, 43, 20, 20, text[11]);
oled.drawFastImage(32+1*20, 43, 20, 20, text[9]);
oled.drawFastImage(32+2*20, 43, 20, 20, text[10]);
if(cursor == 1){
oled.setFont(ArialMT_Plain_16); // 设置字体
oled.drawString(16, 1, ">"); // 将要显示的文字写入缓存
}
if(cursor == 2){
oled.setFont(ArialMT_Plain_16); // 设置字体w
oled.drawString(16, 22, ">"); // 将要显示的文字写入缓存
}
if(cursor == 3){
oled.setFont(ArialMT_Plain_16); // 设置字体w
oled.drawString(16, 43, ">"); // 将要显示的文字写入缓存
}
}
oled.display();
}
void password_input_error(void)
{
oled.clear();
oled.drawFastImage(2, 12, 20, 20, text[13]);
oled.drawFastImage(2 + 1*20, 12, 20, 20, text[14]);
oled.drawFastImage(2 + 2*20, 12, 20, 20, text[16]);
oled.drawFastImage(2 + 3*20, 12, 20, 20, text[17]);
oled.setFont(ArialMT_Plain_16); // 设置字体w
oled.drawString(2 + 4*20, 12, "!"); // 将要显示的文字写入缓存
oled.display();
}
void password_input_success(void)
{
oled.clear();
oled.drawFastImage(2, 12, 20, 20, text[6]);
oled.drawFastImage(2 + 1*20, 12, 20, 20, text[7]);
oled.drawFastImage(2 + 2*20, 12, 20, 20, text[13]);
oled.drawFastImage(2 + 3*20, 12, 20, 20, text[14]);
oled.drawFastImage(2 + 4*20, 12, 20, 20, text[18]);
oled.drawFastImage(2 + 5*20, 12, 20, 20, text[19]);
oled.display();
}
void ID_input_error(void)
{
oled.clear();
oled.setFont(ArialMT_Plain_16); // 设置字体w
oled.drawString(2, 12, "ID"); // 将要显示的文字写入缓存
oled.display();
oled.drawFastImage(2 + 2*20, 12, 20, 20, text[13]);
oled.drawFastImage(2 + 3*20, 12, 20, 20, text[14]);
oled.drawFastImage(2 + 4*20, 12, 20, 20, text[16]);
oled.drawFastImage(2 + 5*20, 12, 20, 20, text[17]);
oled.display();
}
void ID_input_success(void)
{
oled.clear();
oled.drawFastImage(2 + 0*20, 12, 20, 20, text[9]);
oled.drawFastImage(2 + 1*20, 12, 20, 20, text[10]);
oled.drawFastImage(2 + 2*20, 12, 20, 20, text[22]);
oled.drawFastImage(2 + 3*20, 12, 20, 20, text[23]);
oled.drawFastImage(2 + 4*20, 12, 20, 20, text[18]);
oled.drawFastImage(2 + 5*20, 12, 20, 20, text[19]);
oled.display();
}
void finger_delete_success(void)
{
oled.clear();
oled.drawFastImage(2, 12, 20, 20, text[9]);
oled.drawFastImage(2 + 1*20, 12, 20, 20, text[10]);
oled.drawFastImage(2 + 2*20, 12, 20, 20, text[11]);
oled.drawFastImage(2 + 3*20, 12, 20, 20, text[9]);
oled.drawFastImage(2 + 4*20, 12, 20, 20, text[18]);
oled.drawFastImage(2 + 5*20, 12, 20, 20, text[19]);
oled.display();
}
void password_amend_success(void)//密码修改
{
oled.clear();
oled.drawFastImage(2, 12, 20, 20, text[6]);
oled.drawFastImage(2 + 1*20, 12, 20, 20, text[7]);
oled.drawFastImage(2 + 2*20, 12, 20, 20, text[20]);
oled.drawFastImage(2 + 3*20, 12, 20, 20, text[21]);
oled.drawFastImage(2 + 4*20, 12, 20, 20, text[18]);
oled.drawFastImage(2 + 5*20, 12, 20, 20, text[19]);
oled.display();
}
void fingerprint_press_show(void)
{
oled.clear();
oled.drawFastImage(2, 12, 20, 20, text[24]);
oled.drawFastImage(2 + 1*20, 12, 20, 20, text[25]);
oled.drawFastImage(2 + 2*20, 12, 20, 20, text[26]);
oled.drawFastImage(2 + 3*20, 12, 20, 20, text[27]);
oled.drawFastImage(2 + 4*20, 12, 20, 20, text[28]);
oled.drawFastImage(2 + 5*20, 12, 20, 20, text[9]);
oled.display();
}
void input_show(uint8_t interface_control, uint8_t cursor, char *str)
{
oled.clear();
if(interface_control == 1){
oled.drawFastImage(2, 12, 20, 20, text[12]);
oled.drawFastImage(2+1*20, 12, 20, 20, text[13]);
oled.drawFastImage(2+2*20, 12, 20, 20, text[14]);
oled.drawFastImage(2+3*20, 12, 20, 20, text[6]);
oled.drawFastImage(2+4*20, 12, 20, 20, text[7]);
oled.setFont(ArialMT_Plain_16); // 设置字体w
oled.drawString(2+5*20, 12, ":"); // 将要显示的文字写入缓存
}
if(interface_control == 2 && cursor == 1){
oled.drawFastImage(2, 12, 20, 20, text[12]);
oled.drawFastImage(2+1*20, 12, 20, 20, text[13]);
oled.drawFastImage(2+2*20, 12, 20, 20, text[14]);
oled.drawFastImage(2+3*20, 12, 20, 20, text[15]);
oled.drawFastImage(2+4*20, 12, 20, 20, text[6]);
oled.drawFastImage(2+5*20, 12, 20, 20, text[7]);
}
if(interface_control == 2 && cursor == 2){
oled.drawFastImage(2, 12, 20, 20, text[12]);
oled.drawFastImage(2+1*20, 12, 20, 20, text[13]);
oled.drawFastImage(2+2*20, 12, 20, 20, text[14]);
oled.setFont(ArialMT_Plain_16); // 设置字体w
oled.drawString(2+3*20, 12, "ID:"); // 将要显示的文字写入缓存
}
if(interface_control == 2 && cursor == 3){
oled.drawFastImage(2, 12, 20, 20, text[12]);
oled.drawFastImage(2+1*20, 12, 20, 20, text[13]);
oled.drawFastImage(2+2*20, 12, 20, 20, text[14]);
oled.setFont(ArialMT_Plain_16); // 设置字体w
oled.drawString(2+3*20, 12, "ID:"); // 将要显示的文字写入缓存
}
oled.setFont(ArialMT_Plain_24); // 设置字体w
oled.drawString(2, 34, str); // 将要显示的文字写入缓存
oled.display();
}
/*-------------------------------------------------------
作用:参数运算,用于每个界面的光标显示标志运算
参数:
interface_control:界面标志
cursor:选项标志
--------------------------------------------------------*/
uint8_t cursor_operation_add(uint8_t interface_control,uint8_t cursor)
{
cursor++;
if(cursor>=2 && interface_control == 1)
cursor = 2;
if(cursor>=3 && interface_control == 2)//管理员界面有3个选项
cursor = 3;
return cursor;
}
uint8_t cursor_operation_sub(uint8_t cursor)
{
cursor--;
if(cursor <=1)
cursor = 1;
return cursor;
}
/*------------------------------------------------
用于查询flash中的数据
password_flash_inquire:刚输入好的字符串
cursor:光标
return 0: 没有查询到
return 1:查询到
------------------------------------------------*/
bool flash_inquire(int password_flash_inquire)
{
int flash_data_save = 0;
Preferences preferences;//声明一个命名空间的对象
preferences.begin("my-app", false);//打开命名空间
if(preferences.isKey("counter")) { // 如果当前命名空间中有键名为"counter"的元素
//Serial.printf("counter: %d\n\n", preferences.getUInt("counter"));
flash_data_save = preferences.getUInt("counter");//保存一下flash查询到的数据
preferences.end();
}
if(password_flash_inquire == flash_data_save){//查询到flash中的数据
Serial.printf("flash inquire success ! :%d\n\n", password_flash_inquire);
return 1;
} else {
Serial.printf("flash inquire error ! :%d\n\n", password_flash_inquire);
return 0;
}
return 0;
}
/*---------------------------------------------
作用:用于密码保存
参数:
password_flash_save:要保存的密码
返回值:无
---------------------------------------------*/
void password_save(int password_flash_save)
{
Preferences preferences;//声明一个对象
preferences.begin("my-app", false);//打开命名空间,设置读写权限
//保存到首选项
preferences.putUInt("counter", password_flash_save);//保存
// 关闭
preferences.end();
}
/*-----------------------------------------------
作用:界面功能实现
参数:
str_password:密码,用于输入密码时与flash存入的密码配对
interface_control:界面序号
cursor:光标选项
-----------------------------------------------*/
bool interface_function_reailze(char *str_password,uint8_t interface_control,uint8_t cursor)
{
if((interface_control == 1 || interface_control == 2) && cursor == 1 && strlen(str_password) != 6){
Serial.printf("password input long or shirt!\n\n");
return 0;
}
if(interface_control == 1 && (cursor == 1 || cursor == 2) && flash_inquire(atoi(str_password))==1){ //密码已经找到
Serial.printf("password input success!\n\n");
return 1;
} else if (interface_control == 1 && (cursor == 1 || cursor == 2) && flash_inquire(atoi(str_password))==0){
Serial.printf("password input error!\n\n");
return 0;
}
if(interface_control == 2 && cursor == 1){//密码修改
password_save(atoi(str_password));
Serial.printf("password modification success!\n\n");
}
return 0;
}
//按键任务
void keyTask(void * pvParam) {
char msg;//按键字符
key_init();//引脚初始化
oled_init();//oled相关初始化
uint8_t interface_control = 1; //界面序号
uint8_t cursor = 1; //光标
uint8_t function_sign = 0; //功能实现标志 0.界面光标显示处理 1.密码输入
char str_password[10];
if( interface_control == 1 && cursor == 1){
oled_show(interface_control,cursor,0);//界面1,光标1
}
while (1) {
//互斥锁上锁
if (xSemaphoreTake(xMutexInventory, timeOut) == pdPASS) {
customKeypad.tick();
while(customKeypad.available()){
keypadEvent e = customKeypad.read();
Serial.print((char)e.bit.KEY);//按键打印
if(e.bit.EVENT == KEY_JUST_PRESSED)
Serial.println(" press");
else if (e.bit.EVENT == KEY_JUST_RELEASED) { //松开,任务处理 按键按下的宏 --> KEY_JUST_PRESSED
Serial.println(" released");
msg = (char)e.bit.KEY;
Serial.print(msg); //按键打印
if(function_sign == 1){//功能实现标志执行密码输入
if(msg == '#'){
if(interface_function_reailze(str_password,interface_control,cursor) == 1 && interface_control == 1 && cursor == 1){ //界面1,光标1,密码输入正确,开锁
function_sign = 0; memset(str_password, 0, sizeof(str_password));/*字符串清空*/
password_input_success(); unlocking();/*开锁*/vTaskDelay(2000); oled_show(interface_control,cursor,0); continue;
} else if(interface_function_reailze(str_password,interface_control,cursor)==0 && interface_control == 1 && cursor == 1){
function_sign = 0; memset(str_password, 0, sizeof(str_password));
password_input_error(); vTaskDelay(2000); oled_show(interface_control,cursor,0); continue;} //j界面1开锁密码匹配不对
if(interface_function_reailze(str_password,interface_control,cursor)==1 && interface_control == 1 && cursor == 2){ //界面1,光标2,密码输入正确,进入管理员界面
interface_control = 2;cursor = 1;function_sign = 0; memset(str_password, 0, sizeof(str_password));/*清除密码输入保存*/
password_input_success(); vTaskDelay(2000); oled_show(interface_control,cursor,0); /*显示界面2*/ continue;
} else if(interface_function_reailze(str_password,interface_control,cursor)==0 && interface_control == 1 && cursor == 2){
function_sign = 0; memset(str_password, 0, sizeof(str_password));
password_input_error(); vTaskDelay(2000); oled_show(interface_control,cursor,0); continue;}//界面2管理员密码匹配不对
if(interface_control == 2 && cursor == 1 && strlen(str_password) == 6){ /*界面2,选项1,按下'#' 号键 --> 密码更改*/
interface_function_reailze(str_password, interface_control, cursor);
memset(str_password, 0, sizeof(str_password));
interface_control = 1; function_sign = 0; cursor = 1;
password_amend_success(); vTaskDelay(2000); oled_show(interface_control,cursor,0);
continue;
} else if(interface_control == 2 && cursor == 1 && strlen(str_password) != 6){
memset(str_password, 0, sizeof(str_password));
interface_control = 1; function_sign = 0; cursor = 1;
password_input_error(); vTaskDelay(2000); oled_show(interface_control,cursor,0);
continue;
}
if(interface_control == 2 && cursor == 2){ //开始录指纹
if(strlen(str_password)<=0 || atoi(str_password) >= 20){//如果没有输入将要存储的指纹ID,或者ID号大于20
interface_control = 2; function_sign = 0; cursor = 1;
Serial.printf("fingerprint ID input error! %d\n\n",atoi(str_password));
ID_input_error(); vTaskDelay(2000); oled_show(interface_control,cursor,0);
memset(str_password, 0, sizeof(str_password));
continue;
}
if(strlen(str_password)>=0 && atoi(str_password) <= 20){
Serial.printf("fingerprint ID input %d!\n\n",atoi(str_password));
//暂停指纹搜索任务
vTaskSuspend(finPrHandle);//任务暂停
while( !getFingerprintEnroll(atoi(str_password)) );
vTaskResume(finPrHandle); //任务恢复
memset(str_password, 0, sizeof(str_password));
interface_control = 1; function_sign = 0; cursor = 1;
ID_input_success(); vTaskDelay(2000); oled_show(interface_control,cursor,0);
continue;
}
}
if(interface_control == 2 && cursor == 3){ //开始删除指纹
if(strlen(str_password)<=0 || atoi(str_password) >= 20){//如果没有输入将要删除的指纹ID,或者ID号大于20,退出键盘输入模式
interface_control = 2; function_sign = 0; cursor = 1;
Serial.printf("fingerprint ID input error! %d\n\n",atoi(str_password));
memset(str_password, 0, sizeof(str_password));
ID_input_error(); vTaskDelay(2000); oled_show(interface_control,cursor,0);
continue;
}
if(strlen(str_password)>=0 && atoi(str_password) <= 20){
Serial.printf("fingerprint ID delete %d!\n\n",atoi(str_password));
//暂停指纹搜索任务
vTaskSuspend(finPrHandle);//任务暂停
deleteFingerprint(atoi(str_password));
vTaskResume(finPrHandle); //任务恢复
memset(str_password, 0, sizeof(str_password));
interface_control = 1; function_sign = 0; cursor = 1;
finger_delete_success(); vTaskDelay(2000); oled_show(interface_control,cursor,0);
continue;
}
}
}
if(msg == '*'){ //清空字符串
memset(str_password, 0, sizeof(str_password)); input_show(interface_control,cursor,str_password);continue;}
if(msg == 'A' || msg == 'B' || msg == 'C' || msg == 'D'){//退出
oled_show(interface_control,cursor,0);
function_sign = 0;memset(str_password, 0, sizeof(str_password));continue;}
sprintf(str_password,"%s%c",str_password,msg); //字符串拼接
Serial.printf("str_password: %s\n\n", str_password);
input_show(interface_control,cursor,str_password);
} else { //光标选择处理 及 光标显示处理
if(msg == 'A' || msg == 'C'){ //1号界面光标选项只有两个,2号界面光标选项有三个
cursor = cursor_operation_sub(cursor);
oled_show(interface_control,cursor,0);
}
if(msg == 'B' || msg == 'D'){ //1号界面光标选项只有两个,2号界面光标选项有三个
cursor = cursor_operation_add(interface_control,cursor);
oled_show(interface_control,cursor,0);
}
if(msg == '#'){ //确认
input_show(interface_control, cursor, str_password);
function_sign = 1;continue;
}
if(interface_control == 2 && msg == '*'){ //返回主界面
interface_control = 1;cursor = 1;
oled_show(interface_control,cursor,0);
continue;
}
}
}
}
//互斥锁开锁
xSemaphoreGive(xMutexInventory);
vTaskDelay(10);
}
}
}
/* flash数据读取
preferences.begin("my-app", false);//打开命名空间
if(preferences.isKey("counter")) { // 如果当前命名空间中有键名为"counter"的元素
Serial.printf("counter: %d\n\n", preferences.getUInt("counter"));
preferences.end();
function_sign = 0;
}
int num = atoi(str);
*/
task.h
#ifndef _TASK_H_
#define _TASK_H_
#include <Arduino.h>
//互斥锁相关
extern SemaphoreHandle_t xMutexInventory;
extern TickType_t timeOut;
//消息队列相关
extern QueueHandle_t queueMsg;
extern TaskHandle_t finPrHandle;
#endif
task.cpp
/*
该文件用于任务创建时所需要用到的TimeOut等一些变量
*/
#include "task.h"
/* 互斥锁定义 */
SemaphoreHandle_t xMutexInventory = NULL;
TickType_t timeOut = 1000; //用于获取信号量的Timeout 1000 ti
QueueHandle_t queueMsg = xQueueCreate(8, sizeof(char[20]));
TaskHandle_t finPrHandle = NULL; //指纹Task Handler
/*if (finPrHandle != NULL) {
vTaskSuspend(finPrHandle);//任务暂停
vTaskResume(finPrHandle); //任务恢复
}
*/
blink.h
#ifndef _BLINKE_H_
#define _BLINKE_H_
#include "task.h"
#include "lock.h"
void blinkeTask(void * pvParam);
void button1_callback(const String & state);//按键回调函数
#endif
blink.cpp
#include "blinke.h"
#define BLINKER_WIFI
#define BLINKER_PRINT Serial
#define BLINKER_MIOT_LIGHT
#include <Blinker.h>/*无法将其放入.h头文件中,原因不明*/
const char *auth = "57135528a92d";
const char *ssid = "Redmi K40 Pro";
const char *pswd = "05260526";
// 新建组件对象
BlinkerButton Button1("btn-abc");
BlinkerNumber Number1("num-abc");
int counter = 0;
// 按下按键即会执行该函数
void button1_callback(const String & state) {
BLINKER_LOG("get button state: ", state);
//digitalWrite(23, !digitalRead(23));
unlocking();//开锁
Button1.print(state);
}
// 如果未绑定的组件被触发,则会执行其中内容
void dataRead(const String & data)
{
BLINKER_LOG("Blinker readString: ", data);
counter++;
Number1.print(counter);
}
/*小爱智能家居回调函数*/
void miotPowerState(const String & state)
{
BLINKER_LOG("need set power state: ", state);
if (state == BLINKER_CMD_ON) {
digitalWrite(23, HIGH);
BlinkerMIOT.powerState("on");
BlinkerMIOT.print();
}
else if (state == BLINKER_CMD_OFF) {
digitalWrite(23, LOW);
BlinkerMIOT.powerState("off");
BlinkerMIOT.print();
}
vTaskDelay(2000);
digitalWrite(23, LOW);
}
void blinkeTask(void * pvParam)
{
#if defined(BLINKER_PRINT)
BLINKER_DEBUG.stream(BLINKER_PRINT);
#endif
// 初始化blinker
Blinker.begin(auth, ssid, pswd);
Blinker.attachData(dataRead);
Button1.attach(button1_callback);/*注册按键回调函数*/
BlinkerMIOT.attachPowerState(miotPowerState);/*注册小爱语音回调函数*/
//测试
pinMode(23,OUTPUT);
digitalWrite(23,LOW);
while(1){
//互斥锁上锁
if (xSemaphoreTake(xMutexInventory, timeOut) == pdPASS) {
Blinker.run();
//互斥锁开锁
xSemaphoreGive(xMutexInventory);
vTaskDelay(10);
}
}
}
lock.h
#ifndef _LOCK_H_
#define _LOCK_H_
#include <Arduino.h>
void unlocking(void);//开锁2S
#endif
lock.cpp
#include "lock.h"
#define LOCK_PIN 23
void unlocking(void)
{
digitalWrite(LOCK_PIN, HIGH);
vTaskDelay(2000);
digitalWrite(LOCK_PIN, LOW);
}
总结:1、代码花了大约一周草草了事,没有将重心及代码思路放在模块化以及优化上,像界面显示函数就直接放在了key.cpp文件处理,一些相关界面处理可以参考其他大佬博客的oled多界面处理思路更加清晰,相关处理可以基于他们那种编写,
2、本次工程运用到了freeRTOS,只创建了3个任务并行运行,按键任务是整个代码的核心,也像我在第一条总结所说,关于按键处理界面的可以参考其他大佬博客
3、该项目接入到了米家,由于点灯科技免费给开发者5种常见的家居控制方式,更多功能需要用到专业版,所以我们再喊小爱同学的时候叫开门是没有用的,叫她打开灯光是有用的,所以暂时用这种方式代替