ESP32CAM使用Quirc识别二维码并连接WIFI
网上有教程,但是是要做出来很难,或者说做出来报错识别不了。
前提:搭建好ESP-IDF环境 CAMERA能成功初始化
此处用的二维码识别库是用的quirc,如下
这个和Github下载的差不多,加了个CMakeList,我会把这个传到我的Github上,感兴趣去下载Lesterbor/ESP32-QUIRC: 对ESP32CAM的二维码识别 (github.com)
下载到这个包之后放到自己工程目录下的components文件夹下,之后在main文件夹中新建app_qrcode.c这个文件,其内容如下
/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : app_qrcode.c * @brief : app_qrcode驱动库 * @author :「千樊」 * @time : 2024/03/03 ****************************************************************************** * @attention * * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "app_qrcode.h" /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ uint8_t dump_info(struct quirc *q, uint8_t count, char *WifiStrBuff); /* USER CODE END PV */ /* Function definition -------------------------------------------------------*/ /* USER CODE BEGIN FD */ /** * @Function name QF_Camera_Init * @Introduce Camera初始化 * @Return NULL */ uint8_t QF_QrReadWifiData(char *WifiStrBuff){ camera_config_t *camera_config = (camera_config_t *)esp_camera_fb_get(); // Save image width and height, avoid allocate memory repeatly. uint16_t old_width = 0; uint16_t old_height = 0; struct quirc *qr_recognizer; camera_fb_t *fb = NULL; uint8_t *image = NULL; int id_count = 0; //判断当前摄像头输出画幅 if (camera_config->frame_size > FRAMESIZE_VGA) { printf("Camera Frame Size err %d", (camera_config->frame_size)); } //构造一个二维码识别器 printf("Construct a new QR-code recognizer(quirc)."); qr_recognizer = quirc_new(); if (!qr_recognizer) { printf("Can't create quirc object\r\n"); } //获取不到正确结果不退出 while (1) { fb = esp_camera_fb_get(); if (!fb) { printf("Camera capture failed\r\n"); continue; } if (old_width != fb->width || old_height != fb->height) { printf("Recognizer size change w h len: %d, %d, %d\r\n", fb->width, fb->height, fb->len); printf("Resize the QR-code recognizer.\r\n"); // Resize the QR-code recognizer. if (quirc_resize(qr_recognizer, fb->width, fb->height) < 0) { printf("Resize the QR-code recognizer err.\r\n"); continue; } else { old_width = fb->width; old_height = fb->height; } } image = quirc_begin(qr_recognizer, NULL, NULL); memcpy(image, fb->buf, fb->len); quirc_end(qr_recognizer); // Return the number of QR-codes identified in the last processed image. id_count = quirc_count(qr_recognizer); if (id_count == 0) { printf("..||"); esp_camera_fb_return(fb); continue; } printf("\n"); esp_camera_fb_return(fb); //判断解析是否成功 如果成功则返回true并且此时WifiStrBuff有效 if(dump_info(qr_recognizer, id_count, WifiStrBuff)){ return true; } } quirc_destroy(qr_recognizer); } uint8_t dump_info(struct quirc *q, uint8_t count, char *WifiStrBuff){ for (int i = 0; i < count; i++) { struct quirc_code code; struct quirc_data data; quirc_extract(q, i, &code); quirc_decode_error_t err = quirc_decode(&code, &data); if (err) { printf("Decoding error:\n"); return false; } else { printf("Decoding successful:\n"); memcpy(WifiStrBuff, data.payload, data.payload_len); return true; } printf("\n"); } return false; } /* USER CODE END FD */ /************************ (C) COPYRIGHT 「千樊」 *****END OF FILE****/
之后再main/inlcude文件夹下新建app_qrcode.h其内容如下
/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : app_qrcode.h * @brief : Header for app_qrcode.c file. * This file provides code for the configuration * of the app_qrcode instances * @author : 「千樊」 * @time : 2024/03/03 ****************************************************************************** * @attention * * ****************************************************************************** */ /* USER CODE END Header */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __APP_QRCODE_H_ #define __APP_QRCODE_H_ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_camera.h" #include "quirc.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PT */ /* USER CODE END PT */ /* Exported functions prototypes ---------------------------------------------*/ /* USER CODE BEGIN EFP */ uint8_t QF_QrReadWifiData(char *WifiStrBuff); /* USER CODE END EFP */ #endif /* __APP_QRCODE_H_ */ /************************ (C) COPYRIGHT 「千樊」 *****END OF FILE*************/
之后再main文件夹中的CMakeList.txt中注册组件引用app_qrcode.c,如下图所示
ok这样我们就可以调用QF_QrReadWifiData该函数来获取二维码解析之后的字符串,在main中声明以下函数即可解析扫描到的Wifi信息
void parse_string(const char *input, char *ssid, char *password) { // 寻找SSID开始的位置 char *ssid_start = strstr(input, "S:"); if (ssid_start) { ssid_start += 2; // 跳过 "S:" // 寻找SSID结束的位置,即下一个分号 char *ssid_end = strchr(ssid_start, ';'); if (ssid_end) { // 提取SSID size_t ssid_len = ssid_end - ssid_start; strncpy(ssid, ssid_start, ssid_len); ssid[ssid_len] = '\0'; // 确保字符串以null字符结尾 } } // 寻找密码开始的位置 char *password_start = strstr(input, "P:"); if (password_start) { password_start += 2; // 跳过 "P:" // 寻找密码结束的位置,即下一个分号 char *password_end = strchr(password_start, ';'); if (password_end) { // 提取密码 size_t password_len = password_end - password_start; strncpy(password, password_start, password_len); password[password_len] = '\0'; // 确保字符串以null字符结尾 } } } void QF_WifiQrConfig(void){ uint8_t userWifiStrBuff[100] = {0}; QF_QrReadWifiData(&userWifiStrBuff); printf("---M---:WifiBuffStr:%s\r\n",userWifiStrBuff); parse_string(&userWifiStrBuff,&wifi_config.sta.ssid,&wifi_config.sta.password); printf("---M---:WIFI SSID:%s\r\n",wifi_config.sta.ssid); printf("---M---:WIFI PASS:%s\r\n",wifi_config.sta.password); QF_WifiLink(wifi_config); }
对了wifi_config这个变量需要你自己定义以下,这个变量可以直接传给esp_wifi_set_config,之后调用esp_wifi_start即可开始连接WIFI
当然,需要你自己理解去写,直接复制应该是有部分报错的,理解之后什么都就好写了。
这里说一下过程中遇到的坑
1.初始化的时候不要翻转图像,也就是不要执行这句话s->set_vflip(s, 1);,需要把1改成0,因为该二维码识别库不支持镜像
2.图像格式必须为灰度图像也就是.pixel_format = PIXFORMAT_GRAYSCALE,该库只能识别灰度图像
3.图像大小设置为640*480,也就是.frame_size = FRAMESIZE_VGA,其他的可能应该也行?我使用的是该大小所以其他的也没试
标签:CODE,ESP32CAM,ssid,WIFI,quirc,fb,printf,Quirc,password From: https://www.cnblogs.com/lesterbor/p/18054809