【人脸识别】[ESP32Cam]2024最新-断电记忆-人脸识别-门禁模块 简易开源教程 解决 fr_flash:Not found

合集地址:Arduino中文社区

CSDN作为备份,最新看↑arduino.me

打开方式

本系列教程建议在电脑端打开更快

手机端切换文章请点击左下角专题目录

文章内切换章节请点击左下角文章大纲

资料下载、教程持续更新:

点灯开源项目分享群2:QQ 913319679

效果视频

【完美解决 fr_flash:Not found 没有分区表导致fr_flash.c报错人脸无法储存的bug】www.bilibili.com/video/BV1m64y1A7AS

本次修复fr_flash:Not found错误,方法见第三章,已有20多名群友复现成功

目录

时间戳

前言

资料下载

硬件购买

说明书:

一、程序由来

二、环境安装

三、flash版操作步骤(新版,推荐)

分区表实现flash存储原理

人脸识别原理

接线参考视频

代码注释版

四、SD卡版操作步骤(旧版,不推荐)

时间戳

上一期更新:2024年2月1日(更新flash分区表版免插卡)2024年2月19日(更新安信可ESP32cam文档)

本文更新时间:2024年3月14日添加文末注意事项

代码资源更新时间:2024年1月24日

前言

开发环境必须按照此教程第二章《软件开发环境搭建》进行配置

不按该方法配置,库版本不对必出问题

纯新手先做一遍【新手入门】[Blinker]2024-最新开发环境+温湿度节点+继电器  详细开源教程比较好

地址:Arduino中文社区

上述新手教程找新手测试过,步骤截图全,本教程未测试,出现问题群里找群主

本人全部合集https://arduino.me/s/35?aid=2757

资料下载

1.资料内容

人脸识别爆改成功.rar

包含

face_test.ino

ESP32 的1.0.6库安装包(新库从2.0.1开始不支持人脸识别,所以必须要换1.0.6)

其它官方资料

安信可官网

ESP32-CAM 摄像头开发板

https://docs.ai-thinker.com/camera_development_board_esp32-cam

2.下载方式

暂时仅能从QQ 群的群文件下载

点灯开源项目分享群2:QQ913319679

此群只提供各类开源分享,可向群主投稿,为避免打扰,不聊天

教程等任何问题都可找群主,免费调试,有空就回

群文件:

3.资料注意

调试出现任何问题先看【新手必看】[Blinker]2024最新-常见问题大全

如有咨询需要,也可前往点灯官网>开发文档>加点灯2000人官方群。

硬件购买方案

只要是安信可的ESP32Cam开发板(带烧录底板)都可以

目前找到的最便宜、质量最好的是这家:阿里巴巴1688 APP捷兴泰电子https://qr.1688.com/s/AI50hpUY只要¥27包邮就可以拿下开发板和烧录底板

链接失效可以搜店铺

其它店多是¥30以上,质量还没他好,之前别的淘宝店买过两次,各坏一半气得我半死,拼多多都没这损坏率

为了摄像头装门外可以配合

24芯宽12.5mm长度14cm同向FPC排线

24pin排线转接板(均为0.5mm间距)

只留摄像头在门外效果:配合人体感应灯+贴纸面板

使用说明书(资料附带Word档说明书)

一、程序由来

(建议观看以下视频后再食用本教程)

1.原视频

【基于esp32cam人脸识别开锁完整教程&独家教程】 

www.bilibili.com/video/BV1mS4y137Q5/?share_source=copy_web&vd_source=43a31abdbf3a9adbc8907c51881a1423

此视频附带程序基于ESP官方库开发,未实现修改flash分区表来存储人脸ID,断电即丢失,程序来自ESP官方

2.二创文章

单片机开发---基于ESP32-CAM的人脸识别应用

http://t.csdnimg.cn/ojpi5

此文章

也未实现修改flash分区表来存储人脸ID

但是自己写了一段复现比较困难的SD卡驱动存储人脸ID

3.本文(三创)添加分区表

效果展示【¥27超低成本人脸识别模块-哔哩哔哩】

通过修改flash分区记忆人脸ID,断电不丢失,不需要插SD卡(推荐)

代码来自原视频的ESP官方程序

4.请注意:

ESP32算力有限,做人脸识别只能将图像和脚本传到浏览器,识别后返回人脸ID,所以无法脱离上位机运行,没有电脑或手机的浏览器开着,人脸识别计算就停了,所以表面是20元实际还要带上一个安卓平板或开着的电脑或旧手机,只适用于有上位机的门禁/智能家居系统

二、软件开发环境搭建

下载完资料包解压,然后打开文件夹,其中exe尽量管理员身份运行

1.安装Arduino

1.右键管理员身份运行

装过的忽略,Arduino2.0亦可,后面几步基本一样

2.安装硬件库(必须V1.0.6)

Arduino开发板库添加有两种方式,Arduino库管理器

或点灯官网资源下载栏的离线安装包

1.右键管理员身份运行esp32_package_1.0.6_arduino.cn.exe即可

注:ESP32不做人脸识别,则安装2.0.7; 做人脸识别安装1.0.6(2.0版库开始不支持人脸识别)

2.安装完硬件库后检查开发板库的位置

自动前往在地址栏粘贴%LOCALAPPDATA%/Arduino15/packages/esp32/hardware/esp32

并回车

亦可手动点击文件夹C:\用户\用户名\AppData\Local\Arduino15\packages\esp32\hardware\esp32

注:用户名是你自己的Windows用户名!

注:AppData是隐藏文件夹,要点击查看

开启隐藏的项目

才能查看

注:不管Arduino装在哪,这个硬件库都装到了C盘的用户文件夹!

3.如果安装过其他版本的esp32 package,请先删除或剪切走,再使用本安装包

删除方法:文件管理器地址栏粘贴%LOCALAPPDATA%/Arduino15/packages/esp32/hardware/esp32

即可进入C:\Users\这里替换为用户名\AppData\Local\Arduino15\packages\esp32\hardware\esp32

ESP32文件夹剪切走新版1.0.7文件夹,贴外部(2.0以上没有人脸识别,只能留1.0.6)

贴别的地方也可以

3.安装软件库(有的环境自带了不装也能编译,最好装上)

1.手动复制(推荐):

复制或剪切到C:\Users\用户名\Documents\Arduino\libraries

注:不管Arduino装在哪,这个软件库都在C盘的用户文件夹!

2.自动添加(不推荐):Arduino>项目>加载库>添加.ZIP库

4.设置Arduino——管理网址、行号、折叠、编译信息

打开Arduino>文件>首选项>附加开发板管理器网址>

,粘贴:

https://arduino.esp8266.com/stable/package_esp8266com_index.json

http://x.iaoye.xin/package_esp8266com_index.json

http://wechat.doit.am/package_esp8266com_index.json

https://github.com/esp8266/Arduino/releases/download/2.5.0/package_esp8266com_index.json

https://raw.githubusercontent.com/DFRobot/FireBeetle-ESP8266/master/package_firebeetle8266_index.json

https://dl.espressif.com/dl/package_esp32_index.json

https://arduino.me/packages/esp32.json

https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

三、flash版程序使用步骤

1.确保您已经配置好上述开发环境

2.打开face_test文件夹的face_test.ino(见前文资料下载)

如图选择AI Thinker(安信可)开发板(在正中间,不太好找)选不了重启Arduino或者重启电脑

连接USB线,选择好端口

4.修改为自己的WiFi名、密码、开门引脚(接线见资料包图片)

5.上传

上传详细步骤见入门教程第八章《烧录》

【新手入门】[Blinker]2024-最新开发环境+温湿度节点+继电器  详细开源教程

Arduino中文社区

以下为简版步骤:

上传前打开Arduino串口监视器确认通信

按住烧录底板RST和IO0按钮

插USB线

打开arduino串口监视器

先松开RST按钮,再松开IO0按钮

看到语句:waiting for download 等待下载

即可点击arduino右箭头上传代码

若没有则在工具里面切换端口,直到有,没端口说明要重装串口驱动

若出现报错,显示ESP32库问题

则在地址栏粘贴%LOCALAPPDATA%/Arduino15/packages/esp32/hardware/esp32

即可进入C:\Users\这里替换为用户名\AppData\Local\Arduino15\packages\esp32\hardware\esp32

ESP32文件夹剪切走新版1.0.7文件夹,贴外部(2.0以上没有人脸识别,只能留1.0.6)

6.调试

正常编译并上传后出现连接WiFi、检测flash分区(如图)

若串口监视器无信息,波特率115200,并按RST重置

得如下调试记录

复制上图最后一行网页地址粘贴手机或电脑浏览器(必须在同一个WiFi下)

进入界面,例如 http://192.168.1.102

点击STREAM CAMERA开启视频流

DETECT FACES识别人脸(绿色框显示是否识别)

白色输入框输入英文名,点击ADD USER,等待添加人脸(闪光灯闪5次,绿色框显示成功即可)

SCCESS CONTROL 开启门禁模式,识别到人脸电脑发出响声,按资料包图片接线,或通过UDP发送到门禁机(下次更新)

录好人脸,断电,不会丢失,就完成了

7.模块IP地址固定

默认IP地址路由器自动分配,如需固定,请在setup函数外添加

    //上联路由器的静态IP   WiFi.config
    IPAddress sip(192,168,1,200);      //手动设置静态IP 连接网络ip
    IPAddress sip1(192,168,1,1);       //本地网关
    IPAddress sip2(255,255,255,0);     //本地子网掩码

并在setup函数内的WiFi.begin前添加

    //上联路由器wifi
    WiFi.config(sip,sip1,sip2);  //设置上联路由器网络参数

如图所示:

完成后同样上传

连不上WiFi请注意

无论路由器还是手机热点还是 电脑热点,都不可以使用5G Wi-Fi,路由器不可以开启5G优选,或者是双频合一,必须使用路由器2.4G信号,必须使用有密码的Wi-Fi,校园网那种要登陆的必须转接路由器或电脑热点。

人脸识别网页无法访问解决方法: 电脑通过网线连接路由器或使用手机热点作为路由。

AP隔离:无线接入路由器的设备相互之间不能访问,即使在一个子网也不行,以防无线入侵。(设备叫STA 也就是Station,无线路由器叫接入点,也就是AP,Access Point)

故障现象: ESP32Cam无线连接小米路由器时,电脑无线连到小米路由器不能访问ESP32Cam,电脑有线连小米路由器可以访问ESP32Cam;

而ESP32Cam连手机或电脑热点时则无AP隔离限制。

解决方法: 如果您的小米路由器固件无法关闭AP隔离,下载小米路由APP也关不掉,就只能电脑网线连接路由器来规避AP隔离,或更换手机、电脑热点进行中转;

除此之外部分光猫以及其他品牌也有此设置,大多可以在后台关闭。

调试信息查看方法

将开发板用USB- TTL连接至电脑(自带烧录器的直接用USB线连接)

Arduino工具一栏中选择好COM口,

再在工具栏中打开Arduino串口监视器。

3.根据如图所示的程序将串口波特率调整为115200,或9600等数值(setup里设定的多少就是多少),左下角取消自动滚屏,按下rst重启开发版,

4.获得的结果判断设备卡在哪一步

添加分区表partitions.csv实现flash存储原理(参考)

官方没给分区表,导致官方flash存储功能失效,我查了好久,2023.3改SD卡版,2024.1再次分析fr_flash.h,终于找出来怎么分区

分区大小可以自己改,用计算器程序员模式十六进制计算即可,目前容量存几十个人应该够用

修改时不要超出4MB(0X400000),偏移不写默认在上一分区结尾开始

存ino一个文件夹即可,编译器会吃进去

人脸识别代码原理

ESP官方静态库函数(编译成了二进制,改不了,位置在硬件库源码部分,github上倒是可以搜到fr_flash.c这个文件,上面分区表原理分析截图里面就是)

把网页、脚本、人脸发送到电脑或手机的浏览器去计算ID,然后返回ESP32Cam

意味着无法脱离上位机运行,没有浏览器开着人脸识别计算就停了

ESP官方用到的是一些开源算法,可以自己去查MTMN开源项目

https://blog.csdn.net/qq_39217004/article/details/128129391

接线(借视频做参考)

电源必须5V2A ~5V 3A

实际接线参考视频

【esp32 人脸识别门禁系统 保姆级教程由于接触不久为了改进断网也能运行肝了两天】 www.bilibili.com/video/BV1KN4y1B7ui/?share_source=copy_web&vd_source=43a31abdbf3a9adbc8907c51881a1423

【esp32人脸识别 门禁 最终上门实战】 https://www.bilibili.com/video/BV1i94y1M7xv/?share_source=copy_web&vd_source=43a31abdbf3a9adbc8907c51881a1423

高电平触发继电器

高/低电平触发继电器

无论用哪款继电器模组,记得:

高电平触发的模组平常是低电平0V,单片机输出3.3V高电平才吸合,使用推挽输出:

pinMode(RELAYPIN_1, OUTPUT);

低电平触发的模组平常是高电平5V,单片机输出0V高电平才吸合,避免5V灌入单片机3.3V回路,使用开漏输出

pinMode(RELAYPIN_1, OUTPUT_OPEN_DRAIN);

参考资料:【NodeMcu-ESP8266】引脚使用参考指南http://t.csdnimg.cn/OtETF

代码注释版

//B站找 :arduino捣鼓室 欢迎大家评论区一起交流!如有不足请大家指正 共同进步!
//案例仅供参考,如有代码细节问题对照教程检测相应的开发板和库安装 

#include <ArduinoWebsockets.h> // 引入WebSocket库,用于实现网络通信
#include "esp_http_server.h" // 引入ESP32的HTTP服务器库
#include "esp_timer.h" // 引入ESP32的定时器库
#include "esp_camera.h" // 引入ESP32的相机库
#include "camera_index.h" // 引入相机的HTML界面
#include "Arduino.h" // 引入Arduino核心库
#include "fd_forward.h" // 引入人脸检测的库
#include "fr_forward.h" // 引入人脸识别的库
#include "fr_flash.h" // 引入人脸ID存储到闪存的库

//写上你连接的无线WiFi账号密码  
const char* ssid     = "IoT"; // 设置WiFi的SSID
const char* password = "1234567890"; // 设置WiFi的密码

//定义开门引脚
#define relay_pin 2 // 继电器控制引脚,用于控制开门操作

//开启UDP广播,接收端收到广播
//后期更新

#define ENROLL_CONFIRM_TIMES 5 // 注册时确认次数
#define FACE_ID_SAVE_NUMBER 7 // 可以保存的人脸ID数量

// Select camera model
//#define CAMERA_MODEL_WROVER_KIT
//#define CAMERA_MODEL_ESP_EYE
//#define CAMERA_MODEL_M5STACK_PSRAM
//#define CAMERA_MODEL_M5STACK_WIDE
#define CAMERA_MODEL_AI_THINKER // 定义相机模型,这里选择AI_THINKER模型
#include "camera_pins.h" // 引入相机的引脚配置

using namespace websockets; // 使用websockets命名空间
WebsocketsServer socket_server; // 创建WebSocket服务器对象

camera_fb_t * fb = NULL; // 声明相机帧缓冲区指针

long current_millis; // 当前时间(毫秒)
long last_detected_millis = 0; // 最后一次检测到人脸的时间

unsigned long door_opened_millis = 0; // 开门的时间
long interval = 5000;           // 开锁持续时间(毫秒)
bool face_recognised = false; // 人脸是否被识别的标志

// 函数声明
void app_facenet_main(); // 人脸网络初始化函数
void app_httpserver_init(); // HTTP服务器初始化函数

// 结构定义:用于处理图像结果
typedef struct
{
  uint8_t *image; // 图像数据
  box_array_t *net_boxes; // 人脸检测结果的边界框数组
  dl_matrix3d_t *face_id; // 人脸ID数据
} http_img_process_result;

// 配置人脸检测网络参数的函数
static inline mtmn_config_t app_mtmn_config()
{
  mtmn_config_t mtmn_config = {0}; // 初始化mtmn_config结构体
  mtmn_config.type = FAST; // 设置检测类型为FAST
  mtmn_config.min_face = 80; // 最小人脸尺寸
  mtmn_config.pyramid = 0.707; // 金字塔缩放比例
  mtmn_config.pyramid_times = 4; // 金字塔缩放次数
  mtmn_config.p_threshold.score = 0.6; // P网络得分阈值
  mtmn_config.p_threshold.nms = 0.7; // P网络非极大值抑制(NMS)阈值
  mtmn_config.p_threshold.candidate_number = 20; // P网络候选框数量
  mtmn_config.r_threshold.score = 0.7; // R网络得分阈值
  mtmn_config.r_threshold.nms = 0.7; // R网络NMS阈值
  mtmn_config.r_threshold.candidate_number = 10; // R网络候选框数量
  mtmn_config.o_threshold.score = 0.7; // O网络得分阈值
  mtmn_config.o_threshold.nms = 0.7; // O网络NMS阈值
  mtmn_config.o_threshold.candidate_number = 1; // O网络候选框数量
  return mtmn_config; // 返回配置好的结构体
}
mtmn_config_t mtmn_config = app_mtmn_config(); // 初始化人脸检测网络配置

face_id_name_list st_face_list; // 人脸ID列表
static dl_matrix3du_t *aligned_face = NULL; // 对齐后的人脸数据

httpd_handle_t camera_httpd = NULL; // HTTP服务器句柄

// 枚举定义:有限状态机的状态
typedef enum
{
  START_STREAM, // 开始流媒体传输
  START_DETECT, // 开始检测人脸
  SHOW_FACES, // 显示人脸
  START_RECOGNITION, // 开始识别人脸
  START_ENROLL, // 开始注册人脸
  ENROLL_COMPLETE, // 完成注册
  DELETE_ALL, // 删除所有人脸数据
} en_fsm_state;
en_fsm_state g_state; // 当前状态

// 结构定义:用于HTTP服务器响应值
typedef struct
{
  char enroll_name[ENROLL_NAME_LEN]; // 注册名
} httpd_resp_value;

httpd_resp_value st_name; // HTTP响应值实例

// 初始化函数
void setup() {
  Serial.begin(115200); // 开始串行通信,波特率115200
  Serial.setDebugOutput(true); // 设置调试输出为true
  Serial.println();

  digitalWrite(relay_pin, LOW); // 设置继电器引脚为低电平
  pinMode(relay_pin, OUTPUT); // 设置继电器引脚为输出模式

  camera_config_t config; // 定义相机配置结构体
  config.ledc_channel = LEDC_CHANNEL_0; // 设置LEDC通道
  config.ledc_timer = LEDC_TIMER_0; // 设置LEDC定时器
  // 设置相机引脚配置
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  // ... (省略其余引脚配置)
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000; // 设置XCLK频率
  config.pixel_format = PIXFORMAT_JPEG; // 设置像素格式为JPEG
  //
  if (psramFound()) { // 如果找到PSRAM
    config.frame_size = FRAMESIZE_UXGA; // 设置帧大小为UXGA
    config.jpeg_quality = 10; // 设置JPEG质量
    config.fb_count = 2; // 设置帧缓冲区数量
  } else {
    config.frame_size = FRAMESIZE_SVGA; // 设置帧大小为SVGA
    config.jpeg_quality = 12; // 设置JPEG质量
    config.fb_count = 1; // 设置帧缓冲区数量
  }

#if defined(CAMERA_MODEL_ESP_EYE)
  // 如果定义了ESP_EYE模型,设置GPIO13和GPIO14为上拉输入
  pinMode(13, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
#endif

  // 相机初始化
  esp_err_t err = esp_camera_init(&config); // 初始化相机并获取错误码
  if (err != ESP_OK) { // 如果初始化失败
    Serial.printf("Camera init failed with error 0x%x", err); // 打印错误信息
    return; // 返回,不继续执行后续代码
  }

  sensor_t * s = esp_camera_sensor_get(); // 获取相机传感器对象
  s->set_framesize(s, FRAMESIZE_QVGA); // 设置传感器的帧大小为QVGA

#if defined(CAMERA_MODEL_M5STACK_WIDE)
  // 如果定义了M5STACK_WIDE模型,设置垂直翻转和水平镜像
  s->set_vflip(s, 1);
  s->set_hmirror(s, 1);
#endif

  // 连接到WiFi
  WiFi.begin(ssid, password); // 使用SSID和密码开始连接
  while (WiFi.status() != WL_CONNECTED) { // 等待直到连接成功
    delay(500); // 延时500毫秒
    Serial.print("."); // 打印点表示正在连接
  }
  Serial.println(""); // 打印换行
  Serial.println("WiFi connected"); // 打印WiFi连接成功

  app_httpserver_init(); // 初始化HTTP服务器
  app_facenet_main(); // 初始化人脸网络
  socket_server.listen(82); // WebSocket服务器监听82端口

  Serial.print("Camera Ready! Use 'http://"); // 打印相机就绪信息
  Serial.print(WiFi.localIP()); // 打印本地IP地址
  Serial.println("' to connect"); // 打印连接信息
}

// 处理HTTP请求的函数
static esp_err_t index_handler(httpd_req_t *req) {
  httpd_resp_set_type(req, "text/html"); // 设置响应类型为HTML
  httpd_resp_set_hdr(req, "Content-Encoding", "gzip"); // 设置内容编码为gzip
  return httpd_resp_send(req, (const char *)index_ov2640_html_gz, index_ov2640_html_gz_len); // 发送响应
}

httpd_uri_t index_uri = {
  .uri       = "/", // 设置URI为根目录
  .method    = HTTP_GET, // 设置方法为GET
  .handler   = index_handler, // 设置处理函数为index_handler
  .user_ctx  = NULL // 用户上下文为NULL
};

void app_httpserver_init ()
{
  httpd_config_t config = HTTPD_DEFAULT_CONFIG(); // 获取默认HTTP服务器配置
  if (httpd_start(&camera_httpd, &config) == ESP_OK) // 启动HTTP服务器
    Serial.println("httpd_start"); // 打印服务器启动信息
  {
    httpd_register_uri_handler(camera_httpd, &index_uri); // 注册URI处理函数
  }
}

// 人脸网络初始化函数
void app_facenet_main()
{
  face_id_name_init(&st_face_list, FACE_ID_SAVE_NUMBER, ENROLL_CONFIRM_TIMES); // 初始化人脸ID列表
  aligned_face = dl_matrix3du_alloc(1, FACE_WIDTH, FACE_HEIGHT, 3); // 分配对齐人脸的内存
  read_face_id_from_flash_with_name(&st_face_list); // 从闪存读取人脸ID
}

// 注册人脸的函数
static inline int do_enrollment(face_id_name_list *face_list, dl_matrix3d_t *new_id)
{
  ESP_LOGD(TAG, "START ENROLLING"); // 打印开始注册日志
  // 将新的人脸ID注册到闪存,并返回剩余需要采样的次数
  int left_sample_face = enroll_face_id_to_flash_with_name(face_list, new_id, st_name.enroll_name);
  ESP_LOGD(TAG, "Face ID %s Enrollment: Sample %d",
           st_name.enroll_name,
           ENROLL_CONFIRM_TIMES - left_sample_face); // 打印注册信息
  return left_sample_face; // 返回剩余次数
}

// 发送人脸列表到客户端的函数
static esp_err_t send_face_list(WebsocketsClient &client)
{
  client.send("delete_faces"); // 发送删除所有人脸指令
  face_id_node *head = st_face_list.head; // 获取人脸列表头节点
  char add_face[64]; // 定义添加人脸的字符串
  for (int i = 0; i < st_face_list.count; i++) // 遍历当前的人脸列表
  {
    sprintf(add_face, "listface:%s", head->id_name); // 格式化人脸信息
    client.send(add_face); // 发送人脸信息到客户端
    head = head->next; // 移动到下一个节点
  }
}

// 删除所有人脸的函数
static esp_err_t delete_all_faces(WebsocketsClient &client)
{
  delete_face_all_in_flash_with_name(&st_face_list); // 在闪存中删除所有人脸ID
  client.send("delete_faces"); // 发送删除所有人脸指令到客户端
}

// 处理WebSocket消息的函数
void handle_message(WebsocketsClient &client, WebsocketsMessage msg)
{
  // 根据收到的消息内容设置不同的状态,并给客户端发送相应的消息
  if (msg.data() == "stream") {
    g_state = START_STREAM;
    client.send("STREAMING");
  }
  if (msg.data() == "detect") {
    g_state = START_DETECT;
    client.send("DETECTING");
  }
  // ... (省略其余消息处理)
}

// 开门的函数
void open_door(WebsocketsClient &client) {
  if (digitalRead(relay_pin) == LOW) {
    digitalWrite(relay_pin, HIGH); // 切换继电器状态,解锁门
    Serial.println("Door Unlocked"); // 打印门已解锁
    client.send("door_open"); // 发送门已打开的消息到客户端
    door_opened_millis = millis(); // 记录门打开的时间
  }
}

// 主循环函数
void loop() {
  auto client = socket_server.accept(); // 接受WebSocket客户端的连接
  client.onMessage(handle_message); // 设置消息处理函数
  dl_matrix3du_t *image_matrix = dl_matrix3du_alloc(1, 320, 240, 3); // 分配图像矩阵内存
  http_img_process_result out_res = {0}; // 初始化图像处理结果结构体
  out_res.image = image_matrix->item; // 设置图像数据指针

  send_face_list(client); // 发送人脸列表到客户端
  client.send("STREAMING"); // 发送流媒体状态消息到客户端

  while (client.available()) { // 当客户端可用时循环
    client.poll(); // 轮询客户端

    // ... (省略人脸检测、识别、注册等逻辑和WebSocket消息发送)

    client.sendBinary((const char *)fb->buf, fb->len); // 以二进制形式发送相机帧数据

    esp_camera_fb_return(fb); // 返回相机帧缓冲区
    fb = NULL; // 清空帧缓冲区指针
  }
}
/*请注意,由于代码较长,部分代码被省略(用 ... 表示)。此外,代码中有一些宏定义和条件编译指令,如 #if defined(CAMERA_MODEL_ESP_EYE),这些部分的注释需要根据实际使用的硬件来进行相应的注释。*/

预告:智能门禁其它8个开门方式和开门动作机构将于今年年底前发布在开源群

连不上WiFi请注意

无论路由器还是手机热点还是 电脑热点,都不可以使用5G Wi-Fi,路由器不可以开启5G优选,或者是双频合一,必须使用路由器2.4G信号,必须使用有密码的Wi-Fi,校园网那种要登陆的必须转接路由器或电脑热点。

人脸识别网页无法访问解决方法: 电脑通过网线连接路由器或使用手机热点作为路由。

AP隔离:无线接入路由器的设备相互之间不能访问,即使在一个子网也不行,以防无线入侵。(设备叫STA 也就是Station,无线路由器叫接入点,也就是AP,Access Point)

故障现象: ESP32Cam无线连接小米路由器时,电脑无线连到小米路由器不能访问ESP32Cam,电脑有线连小米路由器可以访问ESP32Cam;

而ESP32Cam连手机或电脑热点时则无AP隔离限制。

解决方法: 如果您的小米路由器固件无法关闭AP隔离,下载小米路由APP也关不掉,就只能电脑网线连接路由器来规避AP隔离,或更换手机、电脑热点进行中转;

除此之外部分光猫以及其他品牌也有此设置,大多可以在后台关闭。

1.     首先确认程序中有执行

Serial.begin(115200);//硬件串口0初始化,波特率115200

BLINKER_DEBUG.stream(Serial);//开启串口调试流到硬件串口0

BLINKER_DEBUG.debugAll();//打开所有调试信息

2.将开发板用USB- TTL连接至电脑(自带烧录器的直接用USB线连接)

Arduino工具一栏中选择好COM口,

再在工具栏中打开Arduino串口监视器。

3.根据如图所示的程序将串口波特率调整为115200,或9600等数值(setup里设定的多少就是多少),左下角取消自动滚屏,按下rst重启开发版,

4.获得的结果根据后面两张图片进行分析来判断设备卡在哪一步

  • 22
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值