首页 > 其他分享 >ESP32CAM使用Quirc识别二维码并连接WIFI

ESP32CAM使用Quirc识别二维码并连接WIFI

时间:2024-03-11 18:33:26浏览次数:30  
标签:CODE ESP32CAM ssid WIFI quirc fb printf Quirc password

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

相关文章

  • WIFI&蓝牙(ESP32)转CAN总线&串口TTL模块-C1-设备作为Modbus Slave实现RS485 Modbus RT
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/ESP32_CAN"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p> 说明这节测试的是让设备作为Modbus......
  • 支持DDR5-8000!华硕ROG STRIX B760-G GAMING WIFI S小吹雪图赏
    近日华硕发布了ROGSTRIXB760-GGAMINGWIFIS小吹雪主板。相比此前非S版本,S版主板内存支持DDR5-8000,外观有新的设计调整,散热片面积增大,加入了即插即用的易拆式天线。现在这款新品已经来到我们评测室,下面为大家带来图赏。产品沿用了吹雪系列标志性的银白二次元设计风格,在供电......
  • AndroidStudio扫描局域网下的ESP32CAM并获取IP地址
    大概想法如下: 在ESP32CAM端直接下载示例代码udp_server这个历程,修改默认的WIFI和密码,启动之后会输出如下结果 由此我们知道了UDP的地址和端口IP地址为192.168.2.3,端口为3333此时我们使用小工具NetAssist.exe来测试,选择UDP协议之后向ESP32CAM的地址发送广播,如下图所示 ......
  • WIFI&蓝牙(ESP32)转CAN总线&串口TTL模块-B1-设备作为TCP客户端连接TCP服务器,实现RS48
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/ESP32_CAN"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p>说明这节测试的是让设备连接路由器,然后设备以......
  • WiFi协议的调制技术介绍
    ​ 调制技术是WiFi协议的核心部分,它负责将数据转换成可以在无线信道中传输的信号。WiFi协议采用正交频分复用(OFDM)调制技术,该技术通过将数据分成多个子载波进行传输,提高了信道利用率和抗干扰能力。OFDM调制的工作原理是将高速数据流分割成多个低速子数据流,然后在多个子载波上同......
  • linux连接wifi
    1.ifconfigwlan0up启动wifi2.iwlistwlan0scanning搜寻wifi(接天线)3.默认情况下,开发板根文件系统/etc目录下会有一个名为“wpa_supplicant.conf”的配置文件,没有的话就自行创建。此文件用于配置要连接的WIFI热点以及对应的密钥。“=”前后一定不能有空格,缩进应该采用空格......
  • 开发板开机自动连wifi
    点击查看代码#!/bin/bash#FunctiontoscansurroundingWiFinetworksscan_wifi(){iwlistwlan0scan>/tmp/wifi_scan.txt}#FunctiontoconnecttoaWiFinetworkconnect_to_wifi(){SSID=$1PASSWORD=$2echo"连接到WiFi,SSID:$SSID&quo......
  • wifi是无线电波还是电磁波
     wifi是无线电波还是电磁波电磁波WiFi是一种无线网络技术,它使用的是电磁波。具体来说,WiFi工作在2.4GHz的频段,这是一个微波频段。电磁波可以在真空中传播,而WiFi、无线通信、网络通信都是利用电磁波来传递信息的。因此,可以确认WiFi是电磁波的一种形......
  • 高颜值小板!华硕ROG STRIX B760-G GAMING WIFI S小吹雪评测:稳上8000!
    一、前言:连细节都尽善尽美的高颜值小吹雪主板在一众B760主板中,华硕的B760小吹雪在颜值、性能和做工方面做到了很好的平衡,很多想要打造白色小型主机的玩家都会首选这块主板。现在,升级版的ROGSTRIXB760-GGAMINGWIFIS小吹雪来了。ROGSTRIXB760-GGAMINGWIFIS小吹雪主板......
  • 基于WIFI指纹的室内定位算法matlab仿真
    1.算法运行效果图预览  2.算法运行软件版本matlab2022a 3.算法理论概述        随着移动互联网和物联网技术的飞速发展,位置服务(LBS)已成为许多应用的核心功能,如导航、社交网络和智能物流等。室外定位技术,如全球定位系统(GPS),已相当成熟并广泛应用。然而,由于建......