Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quirc esp-eye example (IEC-51) #240

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
9 changes: 9 additions & 0 deletions quirc/examples/esp32-s3-eye-qrcode/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)

set(COMPONENTS main) # "Trim" the build. Include the minimal set of components; main and anything it depends on.
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(ESP32-S3-EYE-QRCODE)
12 changes: 12 additions & 0 deletions quirc/examples/esp32-s3-eye-qrcode/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ------ | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
| | | | | | | | X|
# ESP32-S3-EYE QR-CODE with QUIRC

In this example the [ESP32-S3-EYE](https://github.com/espressif/esp-who/blob/master/docs/en/get-started/ESP32-S3-EYE_Getting_Started_Guide.md) takes a picture every few ms, show them on the display and check if the image contains valid qr-codes. If detected, it shows a message on the terminal (e.g. `Data: This is an esp-eye test`). It may not decode correctly the qr-code and in this case an error message is shown (`DECODE FAILED: ECC failure`).

Quirc requires a grayscale image, hence the picture is directly taken grayscale. Since the `lvgl` expects a color picture, the grayscale image is converted to RGB565 before giving it to the `lv_canvas_set_buffer`. The conversion is done by setting all three RGB values to the grayscale value (reduced to 5 or 6 bit respectively).

## How to use example

Build and flash on an esp32-s3-eye. Start a monitor and watch for decoding messages. It may work with small changes also on ESP32-CAM and ESP-EYE.
2 changes: 2 additions & 0 deletions quirc/examples/esp32-s3-eye-qrcode/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
idf_component_register(SRCS "esp32-s3-eye-example"
INCLUDE_DIRS ".")
126 changes: 126 additions & 0 deletions quirc/examples/esp32-s3-eye-qrcode/main/esp32-s3-eye-example.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/

#include <stdio.h>
#include "sdkconfig.h"
#include "bsp/esp-bsp.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "driver/spi_master.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_vendor.h"
#include "esp_lcd_panel_ops.h"
#include "esp_camera.h"
#include "quirc.h"

static const char *TAG = "example";

lv_obj_t *camera_canvas = NULL;

void grayscale_to_rgb565(uint8_t *grayscale_buf, uint8_t *rgb565_buf, uint16_t length)
{
uint8_t reduced = 0;
uint32_t rgb565_counter = 0;
uint16_t k = 0;
for (k = 0; k < length; k++) {
reduced = (grayscale_buf[k] >> 3) & 0b00011111;
rgb565_buf[rgb565_counter] = ((reduced << 3) | (reduced >> 2));
rgb565_counter++;
rgb565_buf[rgb565_counter] = ((reduced << 6) | (reduced));
rgb565_counter++;
}
}

static void decode_task(void *args)
{
bsp_i2c_init();
bsp_display_start();
bsp_display_backlight_on(); // Set display brightness to 100%

// Initialize the camera
camera_config_t camera_config = BSP_CAMERA_DEFAULT_CONFIG;
camera_config.pixel_format = PIXFORMAT_GRAYSCALE; // required by quirc
esp_err_t err = esp_camera_init(&camera_config);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Camera Init Failed");
exit(1);
}

sensor_t *s = esp_camera_sensor_get();
s->set_vflip(s, 1);
s->set_hmirror(s, 1);
s->set_contrast(s, 2);
ESP_LOGI(TAG, "Camera Init done");

// Create LVGL canvas for camera image
bsp_display_lock(0);
camera_canvas = lv_canvas_create(lv_scr_act());

assert(camera_canvas);
lv_obj_center(camera_canvas);
bsp_display_unlock();

camera_fb_t *pic = esp_camera_fb_get();
uint8_t *buf_shown = (uint8_t *)lv_mem_alloc(pic->len * 2); // double the size because the canvas requires a RGB565, i.e. 2 bytes per pixel
esp_camera_fb_return(pic);

/* Initializing the quirc handle */
struct quirc *q = quirc_new();
if (!q) {
ESP_LOGE(TAG, "Failed to allocate memory");
exit(1);
}
if (quirc_resize(q, pic->width, pic->height) < 0) {
ESP_LOGE(TAG, "Failed to allocate video memory\n");
exit(1);
}

struct quirc_code code;
struct quirc_data data;
quirc_decode_error_t q_err;
uint16_t num_codes;

while (1) {
pic = esp_camera_fb_get();

if (pic) {
bsp_display_lock(0);
grayscale_to_rgb565(pic->buf, buf_shown, pic->len);
lv_canvas_set_buffer(camera_canvas, buf_shown, pic->width, pic->height, LV_IMG_CF_TRUE_COLOR);
bsp_display_unlock();

memcpy(quirc_begin(q, NULL, NULL), pic->buf, pic->len);
quirc_end(q);

num_codes = quirc_count(q);
for (uint16_t i = 0; i < num_codes; i++) {

quirc_extract(q, i, &code);
/* Decoding stage */
q_err = quirc_decode(&code, &data);
if (q_err != 0) {
printf("%d/%d] DECODE FAILED: %s\n", i + 1, num_codes, quirc_strerror(q_err));
} else {
printf("%d/%d] DATA: %s\n", i + 1, num_codes, data.payload);
}
}

esp_camera_fb_return(pic);
} else {
ESP_LOGE(TAG, "Get frame failed");
exit(1);
}

}
}
void app_main(void)
{
xTaskCreatePinnedToCore(decode_task, TAG, 40 * 1024, NULL, 6, NULL, 0);
}

6 changes: 6 additions & 0 deletions quirc/examples/esp32-s3-eye-qrcode/main/idf_component.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
description: Quirc example using ESP32-S3-EYE board

dependencies:
espressif/esp32_s3_eye: "^3.0.2"
espressif/quirc:
version: "^1.2.0"
Loading