FastBond3挑战部分-基于ESP32的保险柜智能锁
该项目使用了M5 CoreS3,实现了保险柜智能锁的设计,它的主要功能为:可通过人脸识别进行解锁的保险柜智能锁。
标签
嵌入式系统
zxfeng02
更新2024-10-31
24

项目和创意

本项目计划设计一款可通过人脸识别进行解锁的保险柜智能锁,它基于M5 CoreS3,采用ESP32-S3作为核心处理器,具备出色的计算性能和低功耗特性。智能锁配备了高清人脸识别摄像头,从而实现准确的生物识别,从而达到较高的安全性。此外,还配有一个显示屏和输入按键,用于用户交互。该设备内置Wi-Fi功能,能够实时上传开锁记录和入侵检测,方便管理人员随时查看和分析。并且还支持添加、删除或更新面部信息的功能。这款智能锁适用于多种应用场景,提供了更安全、便捷的解决方案。

项目项目方案

该项目使用CoreS3作为主控,通过摄像头采集人脸信息。使用ADC按键来实现人机交互,实现录入人脸、删除人脸、识别人脸等功能,并将识别结果等信息通过MQTT上传至阿里云物联网平台。若人脸比对成功,则开锁(使用LED进行模拟)。

设计中用到的指定厂商元器件及介绍

CoreS3是M5Stack开发套件系列的第三代主机,其核心主控采用ESP32-S3方案,双核Xtensa LX7处理器,主频240MHz,自带WiFi功能,板载16MFLASH和8M-PSRAM,可通过TYPE-C接口下载程序,支持OTG和CDC功能,方便外接usb设备和烧录固件,正面搭载一块2.0寸电容触摸IPS屏,面板采用高强度玻璃材质,屏幕下方内置一个30万像素的摄像头GC0308,附带接近传感器LTR-553ALS-WA,电源部分采用AXP2101电源管理芯片及4路电源流向控制回路,整体采用低功耗设计,板载六轴姿态传感器BMI270和磁力计BMM150,板载TF-card(microSD)卡槽,板载BM8563 RTC芯片,提供精确计时及休眠-定时唤醒功能,声音输出方面采用高保真16bits-I2S功放芯片AW88298,机身内置1w扬声器,声音输入方面采用ES7210音频解码芯片+双麦克风输入,在机身侧边配有独立电源按键与重启(RST)按键,自建延时电路,长按复位键便可进入程序下载模式。CoreS3套装默认附带DinBase底座,方便实现Din导轨、挂墙以及螺丝固定,可外部DC 12V(支持9~24V)或者内部500mAh锂电池供电,DinBase预留多处proto的位置,方便用户DIY。本成品适用于物联网开发、各种DIY项目开发、智能家居控制系统和工业自动化控制系统等场景。

原理图及PCB设计介绍

image.png


image.png

关键代码及说明

wifi连接

static void event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
static int s_retry_num = 0;
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
} else {
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
}
ESP_LOGI(TAG,"connect to the AP fail");
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
}


void wifi_connect(void)
{
s_wifi_event_group = xEventGroupCreate();
nvs_flash_init();
esp_netif_init();
esp_event_loop_create_default();


esp_netif_create_default_wifi_sta();


wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));


esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&event_handler,
NULL,
&instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
&event_handler,
NULL,
&instance_got_ip));


wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_ESP_WIFI_SSID,
.password = EXAMPLE_ESP_WIFI_PASS,
/* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (password len => 8).
* If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value
* to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to
* WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards.
*/
.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
.sae_pwe_h2e = ESP_WIFI_SAE_MODE,
.sae_h2e_identifier = EXAMPLE_H2E_IDENTIFIER,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
ESP_ERROR_CHECK(esp_wifi_start() );


ESP_LOGI(TAG, "wifi_init_sta finished.");


/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY);


/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
* happened. */
if (bits & WIFI_CONNECTED_BIT) {
ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
} else if (bits & WIFI_FAIL_BIT) {
ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
} else {
ESP_LOGE(TAG, "UNEXPECTED EVENT");
}
vEventGroupDelete(s_wifi_event_group);
}


人脸识别

void face_recognition(uint8_t *img_buff)
{
static char error_times = 0;
Tensor<uint8_t> image_rgb888;
image_rgb888.set_element((uint8_t *)img_buff).set_shape({width_target, width_target, 3}).set_auto_free(false);

face_info_t recognize = recognizer.recognize(image_rgb888);
cout << "[recognition result] id: " << recognize.id << ", name: " << recognize.name << ", similarity: " << recognize.similarity << "\n";


if(recognize.similarity > FACE_SIMILARITY_THRESHOLD) {
gpio_set_level(GPIO_OUTPUT_IO_0, 1);
vTaskDelay(1000 / portTICK_PERIOD_MS);
gpio_set_level(GPIO_OUTPUT_IO_0, 0);
mqtt_send(SEND_UNLOCK_NOTIFICATION, 0);
}else{
mqtt_send(SEND_UNLOCK_NOTIFICATION, 1);
error_times++;
if(error_times >= 3){
error_times = 0;
mqtt_send(SEND_ALARM_STATUS, 1);
}
}
}

人脸录入

void face_enroll(uint8_t *img_buff)
{
static uint8_t id_index = 0;
string name = "face";
int id = -1;
Tensor<uint8_t> image_rgb888;
image_rgb888.set_element((uint8_t *)img_buff).set_shape({width_target, width_target, 3}).set_auto_free(false);


id = recognizer.enroll_id(image_rgb888, name + to_string(id_index));
id_index++;
cout << "enrolled name: face " << to_string(id_index) << ", id: " << id << "\n";
cout << "write " << recognizer.write_ids_to_flash() << " ids to flash.\n";
mqtt_send(SEND_FACE_ID, id);
}


功能展示及说明

a773babf4a4ea77af518f677a22ef0f.jpg


d4dd8c1b9e445792d154a5e94c782f9.jpg

心得体会

非常感谢硬禾学堂举办的FastBond3活动,让我有机会通过这个活动使用M5Stack CoreS3来做一个有趣的项目。这之中虽然遇到了很多难题,比如CoreS3引出的IO口较少,如何实现多按键输入等,我通过使用ADC按键,从而实现了在IO口资源紧张的情况下,提供多个输入按键。虽然项目较为简单,还有所改进空间,但是我也从中学到了很多知识。

KiCad文件
使用说明
全屏
附件下载
main.zip
代码文件
cores3_key.zip
原理图ocb
团队介绍
一个人的队伍
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号