ESP32-CAM QR Code Reader/Scanner (Arduino IDE)

Learn how to build a QR code reader/scanner with the ESP32-CAM board programmed with Arduino IDE. The ESP32-CAM is constantly using its camera to scan for new QR codes using the ESP32QRCodeReader library and a modified version of the quirc library. When it detects a valid QR code, it prints the QR code data in the Serial Monitor.

ESP32-CAM QR Code Reader Scanner Arduino IDE

Project Overview

Here is a quick overview of how the project works.

ESP32-CAM QR Code Scanner Project Overview
  • The ESP32-CAM is constantly scanning for new QR Codes
  • When it detects a valid QR Code, it prints its data in the Arduino IDE Serial Monitor

This project can be used for a ticket attendance system, for product tracking, to act as an access system by checking QR codes to unlock doors or lockers, and many other applications.

Parts Required

We’ll be using the ESP32-CAM board labeled as AI-Thinker module, but other modules should also work by making the correct pin assignment in the code. Another example is the Freenove ESP32-Wrover CAM Board.

The ESP32-CAM board is a $9 device (or less) that combines an ESP32-S chip, an OV2640 camera, a microSD card slot, and several GPIO pins.

ESP32-CAM board is a $9 device with an OV2640 camera, microSD card slot and several GPIO pins

To follow this tutorial you need the following components:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

For an introduction to the ESP32-CAM, you can follow the next tutorials:

Preparing the Arduino IDE

We’ll program the ESP32 board using Arduino IDE. So you need the Arduino IDE installed as well as the ESP32 add-on. You can follow the next tutorial to install the ESP32 add-on, if you haven’t already:

Installing the ESP32QRCodeReader

For this tutorial, we’ll use the ESP32QRCodeReader library by Alvarowolfx, which makes it easy to read QR codes with the ESP32-CAM board.

Then, in the Arduino IDE, go to Sketch > Include Library > Add .ZIP library and install the library that you’ve just downloaded in the previous link.

Arduino Install Library Sketch include library add zip library

Code – ESP32-CAM QR Code Reader/Scanner

Copy the QR Code Scanner code to your Arduino IDE.

/*********
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/esp32-cam-qr-code-reader-scanner-arduino/
*********/

#include <Arduino.h>
#include <ESP32QRCodeReader.h>

// FOR THIS PROJECT, YOUR ESP32-CAM NEEDS TO HAVE PSRAM.
// Some of the compatible boards: CAMERA_MODEL_AI_THINKER | CAMERA_MODEL_WROVER_KIT | CAMERA_MODEL_ESP_EYE
// CAMERA_MODEL_M5STACK_PSRAM | CAMERA_MODEL_M5STACK_V2_PSRAM | CAMERA_MODEL_M5STACK_WIDE  
ESP32QRCodeReader reader(CAMERA_MODEL_AI_THINKER);

void onQrCodeTask(void *pvParameters) {
  struct QRCodeData qrCodeData;

  while (true) {
    if (reader.receiveQrCode(&qrCodeData, 100)) {
      Serial.println("Scanned new QRCode");
      if (qrCodeData.valid) {
        Serial.print("Valid payload: ");
        Serial.println((const char *)qrCodeData.payload);
      }
      else {
        Serial.print("Invalid payload: ");
        Serial.println((const char *)qrCodeData.payload);
      }
    }
    vTaskDelay(100 / portTICK_PERIOD_MS);
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println();

  reader.setup();
  Serial.println("Setup QRCode Reader");

  reader.beginOnCore(1);
  Serial.println("Begin on Core 1");

  xTaskCreate(onQrCodeTask, "onQrCode", 4 * 1024, NULL, 4, NULL);
}

void loop() {
  delay(100);
}

View raw code

How the Code Works

The code starts by including the necessary libraries to perform the QR code scanning with the ESP32-CAM board:

#include <Arduino.h>
#include <ESP32QRCodeReader.h>

Then, create an object called reader for the QR code scanner, for this guide we are using the the AI-Thinker ESP32-CAM model.

// FOR THIS PROJECT, YOUR ESP32-CAM NEEDS TO HAVE PSRAM.
// Some of the compatible boards: CAMERA_MODEL_AI_THINKER | CAMERA_MODEL_WROVER_KIT | CAMERA_MODEL_ESP_EYE
// CAMERA_MODEL_M5STACK_PSRAM | CAMERA_MODEL_M5STACK_V2_PSRAM | CAMERA_MODEL_M5STACK_WIDE

ESP32QRCodeReader reader(CAMERA_MODEL_AI_THINKER);

Note: your board needs to have PSRAM. This code was tested and it should be compatible with these ESP32-CAM board versions:

  • CAMERA_MODEL_AI_THINKER
  • CAMERA_MODEL_WROVER_KIT
  • CAMERA_MODEL_ESP_EYE
  • CAMERA_MODEL_M5STACK_PSRAM
  • CAMERA_MODEL_M5STACK_V2_PSRAM
  • CAMERA_MODEL_M5STACK_WIDE

setup()

In the setup() function start by initializing a Serial communication at 115200 baud rate for debugging purposes.

void setup() {
  Serial.begin(115200);
  Serial.println();

The reader.setup() starts the camera hardware using the library’s default settings for the AI-Thinker board or other board that you chose to define.

reader.setup();
Serial.println("Setup QRCode Reader");

The camera reader will run on CPU core 1 (the ESP32 chip has two cores).

reader.beginOnCore(1);
Serial.println("Begin on Core 1");

Finally, create a FreeRTOS task to run the onQrCodeTask function. This allows us to continue running the QR code scanner in the background.

xTaskCreate(onQrCodeTask, "onQrCode", 4 * 1024, NULL, 4, NULL);

onQrCodeTask()

In the onQrCodeTask function, it keeps constantly scanning for new QR codes with the while (true) and when it detects a valid QR code it prints the data in the Serial Monitor.

void onQrCodeTask(void *pvParameters) {
  struct QRCodeData qrCodeData;

  while (true) {
    if (reader.receiveQrCode(&qrCodeData, 100)) {
      Serial.println("Scanned new QRCode");
      if (qrCodeData.valid) {
        Serial.print("Valid payload: ");
        Serial.println((const char *)qrCodeData.payload);
      }
      else {
        Serial.print("Invalid payload: ");
        Serial.println((const char *)qrCodeData.payload);
      }
    }
    vTaskDelay(100 / portTICK_PERIOD_MS);
  }
}

Upload Code to ESP32-CAM AI-Thinker using ESP32-CAM-MB USB Programmer

To upload code to the ESP32-CAM board, attach the ESP32-CAM-MB micro USB programmer to your board (you can learn how it works by reading this guide).

ESP32-CAM-MB Micro USB Programmer CH340G Serial Chip OV2640 Camera

Then, connect the board to your computer using a USB cable.

After that, in your Arduino IDE, go to Tools Board and select the AI-Thinker ESP32-CAM. Or search for that board on the top bar. You must have the ESP32 add-on installed. Otherwise, this board won’t show up on the Boards menu.

Select the AI-Thinker ESP32-CAM in Arduino IDE

Go to Tools Port and select the COM port the ESP32-CAM is connected to.

Note: if the board doesn’t show up, it means that you probably don’t have the CH340C drivers installed on your computer. Go to Google and search “CH340C drivers” followed by your operating system and install the drivers.

Finally, click the Upload button in your Arduino IDE.

Program ESP32-CAM with Arduino IDE

And that’s it! Your QR code scanner code should be running in your ESP32-CAM.

Demonstration

After uploading the code, open the Serial Monitor at a baud rate of 115200. Press the ESP32-CAM reset button. It should initialize the QR code scanner. Check the Arduino IDE Serial Monitor window to see if everything is working as expected.

ESP32-CAM QR Code Scanner Reader Example Arduino IDE Start ok

Point the ESP32-CAM to a QR code, here’s a sample QR code with the data https://randomnerdtutorials.com/.

QR Code Example RandomNerdTutorials.com
ESP32-CAM Camera QR Code Scanner Reader Testing Arduino IDE Serial Monitor Demonstration

The payload data should be printed in the Arduino IDE Serial Monitor:

ESP32-CAM QR Code Scanner Reader Example Arduino IDE Serial Monitor Demonstration

If in the Arduino IDE Serial Monitor, you keep getting this message:

Invalid payload: ECC failure

You might need to use a smaller QR code, make the camera more stable, and point it directly to the QR code with better lighting conditions.

The ESP32-CAM has some limitations in resolution and struggles with motion, so you need to aim it steadily at the QR code. Also, detecting QR codes can be difficult in poor lighting conditions, whether it’s too bright or too dark.

Troubleshooting and Tips

As we’ve mentioned earlier, this QR Code scanner uses a lot of memory, so your ESP32-CAM must have PSRAM. Here are some boards that were tested and should work with this example:

  • CAMERA_MODEL_AI_THINKER
  • CAMERA_MODEL_WROVER_KIT
  • CAMERA_MODEL_ESP_EYE
  • CAMERA_MODEL_M5STACK_PSRAM
  • CAMERA_MODEL_M5STACK_V2_PSRAM
  • CAMERA_MODEL_M5STACK_WIDE

If you’re getting any of the following errors, read our ESP32-CAM Troubleshooting Guide: Most Common Problems Fixed

  • Failed to connect to ESP32: Timed out waiting for packet header
  • Camera init failed with error 0x20001 or similar
  • Brownout detector or Guru meditation error
  • Sketch too big error – Wrong partition scheme selected
  • Board at COMX is not available – COM Port Not Selected
  • Psram error: GPIO isr service is not installed

Wrapping Up

We hope you’ve found this tutorial useful and you can use it in your projects. If you don’t have an ESP32-CAM board, you can click here to get one.

As mentioned previously, we have other tutorials with the ESP32-CAM that you may like:

Thank you for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Recommended Resources

Build a Home Automation System from Scratch » With Raspberry Pi, ESP8266, Arduino, and Node-RED.

Home Automation using ESP8266 eBook and video course » Build IoT and home automation projects.

Arduino Step-by-Step Projects » Build 25 Arduino projects with our course, even with no prior experience!

What to Read Next…


Enjoyed this project? Stay updated by subscribing our newsletter!

29 thoughts on “ESP32-CAM QR Code Reader/Scanner (Arduino IDE)”

  1. Arduino/libraries/ESP32QRCodeReader/src/openmv/collections.c: In function ‘lifo_alloc’:
    Arduino/libraries/ESP32QRCodeReader/src/openmv/collections.c:25:23: error: implicit declaration of function ‘ps_malloc’; did you mean ‘malloc’? [-Wimplicit-function-declaration]
    25 | ptr->data = (char *)ps_malloc(size * data_len);

    Reply
    • Hi.
      There was an update on the ESP32 core.
      We had to update the library to make it compatible again.

      Please delete the library from the Arduino Libraries folder.
      Click the link to download the .zip file again (it now includes an updated version that is compatible with the latest ESP32 core). Install the library again as per the instructions.
      It should compile now.

      Let me know if this solves the issue.

      Regards,
      Sara

      Reply
  2. Error: 13 INTERNAL: Library install failed: moving extracted archive to destination dir: library not valid
    could you help me?

    Reply
      • I’m getting the same error.

        I downloaded the .zip file from GitHub and saved as ESP32QRCodeReader-master.zip
        I then used Sketch | Include Library | Add Zip library to add it
        Arduino IDE reports: Error: 13 INTERNAL: Library install failed: moving extracted archive to destination dir: library not valid

        I’ve looked inside the ZIP and there are a library.json and library.properties that look ok. There’s an include folder and a src folder.
        I’m not sure what other validation is done by Arduino IDE
        I’m using Arduino IDE 2.3.6 on my desktop and I’ve repeated this with the same results on my laptop using IDE 2.3.2

        Not sure what else to check.

        Reply
          • Oh. I see the library you link is not the original alvarowolfx/ESP32QRCodeReader library. You have fixed the error in the original library where .h files were placed in an ‘include’ folder rather than in ‘src’.

          • Hi.
            We created a fork of the library to fix the issue.
            Is our fork of the library working?
            Regards,
            Sara

          • Yes – your fork is working fine.
            The tutorial said you were using the library by Alvarowolfx so I forked that myself. Didn’t realise the link was to a fork of your own in which you’d corrected the error that I was hitting.

            My current challenge is to make this work using an OV3660 camera instead of OV2640. I get Decoding Failed: ECC failure, Invalid payload: Format data ECC failure or Error: not a valid qrcode

          • Yes – your library is now working on XIAO_ESP32S3 with OV3660 camera
            The trick was to add sensor->set_vflip(sensor, 1); in ::setup()

    • Hi.
      This project is just for QR Codes.
      At the moment, we don’t have any project with bar codes.

      Regards,
      Sara

      Reply
  3. I want to use this to send the QR Code data to an arduino mega. I got the ESP32 working but I want it to send what its reading to my Arduino Mega and be able to use that to activate a servo for a project. Any ideas on how to do this?

    Reply
  4. I’m using this library to read QR codes presented by phones when sharing WiFi credentials (ie Tap to share password). It was working fine on Android phones but not on a friend’s iPhone.
    I reviewed the original quirc library by dlbeer on github and found that quirc/lib/decode.c contained an additional function void quirc_flip() that is missing from the quirc/decode.c in your library. There was also guidance about how to use it in quirc/lib/quirc.h and specifically that you can flip a QR code if it fails to decode normally and try again. This appears to be necessary for processing QR codes as presented on iPhones. Having added a quirc_flip after getting an initial decode error of type QUIRC_ERROR_DATA_ECC I can now decode my friend’s iPhone QR code. Whether this applies to all iPhones remains to be determined.

    Reply
  5. Hi I’m new to this ESP32 cam mb using QR code reader but I did exactly the same on the tutorial but my error is kinda “boot looping”. like it’s always like this in serial monitor as an output.
    ets Jul 29 2019 12:21:46

    rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:1
    load:0x3fff0030,len:4980
    load:0x40078000,len:16612
    load:0x40080400,len:3480
    entry 0x400805b4

    Setup QRCode Reader
    Begin on Core 1
    Guru Meditation Error: Core 0 panic’ed (Unhandled debug exception).
    Debug exception reason: Stack canary watchpoint triggered (cam_task)
    Core 0 register dump:
    PC : 0x40089fd2 PS : 0x00060636 A0 : 0x8008de04 A1 : 0x3ffb2550
    A2 : 0x3ffb0300 A3 : 0xffffffff A4 : 0xb33fffff A5 : 0x3f40f3fc
    A6 : 0x00000000 A7 : 0x00000001 A8 : 0x00060623 A9 : 0x3ffb2550
    A10 : 0x00000003 A11 : 0x00060623 A12 : 0x00060623 A13 : 0x0000001f
    A14 : 0x3ffb2ab0 A15 : 0xff000000 SAR : 0x00000004 EXCCAUSE: 0x00000001
    EXCVADDR: 0x00000000 LBEG : 0x40086d45 LEND : 0x40086d55 LCOUNT : 0xfffffffe
    Backtrace: 0x40089fcf:0x3ffb2550 0x4008de01:0x3ffb2580 0x4008de36:0x3ffb25a0 0x4008dfac:0x3ffb25c0 0x40082fb7:0x3ffb25e0 0x40082fd1:0x3ffb2610 0x40082cc5:0x3ffb2630 0x400894d4:0x3ffb2650 0x4008980d:0x3ffb2670 0x40089a50:0x3ffb2690 0x400835aa:0x3ffb26b0 0x400835f2:0x3ffb26d0 0x40083755:0x3ffb2700 0x400e0271:0x3ffb2720 0x400e2525:0x3ffb2750 0x4000bd83:0x3ffb2770 0x4000182a:0x3ffb2790 0x400e1fc1:0x3ffb27b0 0x400e2525:0x3ffb27d0 0x40086b12:0x3ffb27f0 0x40085fb5:0x3ffb2810 0x40086006:0x3ffb2830 0x40086505:0x3ffb2850 0x400fde4f:0x3ffb2880 0x400fd866:0x3ffb28a0 0x400f459d:0x3ffb2bc0 0x4008f045:0x3ffb2bf0 0x400e599c:0x3ffb2c50 0x40089ecd:0x3ffb2ca0

    ELF file SHA256: 748584b57

    Rebooting…
    ets Jul 29 2019 12:21:46

    rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:1
    load:0x3fff0030,len:4980
    load:0x40078000,len:16612
    load:0x40080400,len:3480
    entry 0x400805b4

    Setup QRCode Reader
    Begin on Core 1
    Guru Meditation Error: Core 0 panic’ed (Unhandled debug exception).
    Debug exception reason: Stack canary watchpoint triggered (cam_task)
    Core 0 register dump:
    PC : 0x40089fd2 PS : 0x00060636 A0 : 0x8008de04 A1 : 0x3ffb2550
    A2 : 0x3ffb0300 A3 : 0xffffffff A4 : 0xb33fffff A5 : 0x3f40f3fc
    A6 : 0x00000000 A7 : 0x00000001 A8 : 0x00060623 A9 : 0x3ffb2550
    A10 : 0x00000003 A11 : 0x00060623 A12 : 0x00060623 A13 : 0x0000001f
    A14 : 0x3ffb2ab0 A15 : 0xff000000 SAR : 0x00000004 EXCCAUSE: 0x00000001
    EXCVADDR: 0x00000000 LBEG : 0x40086d45 LEND : 0x40086d55 LCOUNT : 0xfffffffe
    Backtrace: 0x40089fcf:0x3ffb2550 0x4008de01:0x3ffb2580 0x4008de36:0x3ffb25a0 0x4008dfac:0x3ffb25c0 0x40082fb7:0x3ffb25e0 0x40082fd1:0x3ffb2610 0x40082cc5:0x3ffb2630 0x400894d4:0x3ffb2650 0x4008980d:0x3ffb2670 0x40089a50:0x3ffb2690 0x400835aa:0x3ffb26b0 0x400835f2:0x3ffb26d0 0x40083755:0x3ffb2700 0x400e0271:0x3ffb2720 0x400e2525:0x3ffb2750 0x4000bd83:0x3ffb2770 0x4000182a:0x3ffb2790 0x400e1fc1:0x3ffb27b0 0x400e2525:0x3ffb27d0 0x40086b12:0x3ffb27f0 0x40085fb5:0x3ffb2810 0x40086006:0x3ffb2830 0x40086505:0x3ffb2850 0x400fde4f:0x3ffb2880 0x400fd866:0x3ffb28a0 0x400f459d:0x3ffb2bc0 0x4008f045:0x3ffb2bf0 0x400e599c:0x3ffb2c50 0x40089ecd:0x3ffb2ca0

    ELF file SHA256: 748584b57

    Rebooting…

    Reply
    • Also I had programmed an esp32-cam with this code in late april, and it was working just fine. For testing purposes I reuploaded the code to the same esp32-cam and now this one as well is in a bootloop. I suspect that some new Arduino core update for the esp32 is rendering the QR code reader library incompatible.

      Reply
    • still i can’t solve the problem, guys if anyone who fixed their qr code scanning using this library, maybe ya’ll can share it here. thanks.

      Reply
    • In the Arduino IDE go to Tools > Board > Boards Manager… In the boards manager list look for esp32 by Espressif Systems (NOT the one by Arduino), then click on the drop-down menu. Install and select version 3.2.1. This will essentially downgrade the core. My assumption was proven correct, as this solved the bootloop issue completely. If you want to use the QR code reader library, do not update the core to 3.3.0 yet, as the library is still behind.

      Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.