QR Code Scanner With ESP32 CAM Module & OpenCV
Maybe your like
Overview
This project is about QR Code Scanner or Reader designed using ESP32 CAM Module & OpenCV. We will develop a program and device using ESP32 Camera module and python libraries with which we can scan QR codes. Earlier we used Maikrt QR Code Scanning Module with Arduino to read QR or barcode but the module is very expensive. Using ESP32 CAM the project becomes little cheaper.
QR Codes have now become a part of our everyday lives as we use them almost everywhere say it for payments or reaching a website or a link. Also, people add them to their resumes to share the link to their social profiles. Not just personally but large tracking and shipping companies use them to differentiate their products.

QR code is an image-like print that is encoded in a specific format that a program can decipher and decode the meaning or message in it.

Although the code is decoded by detecting the different zones and arranging the dark boxes in a specific understandable alignment. Each Dark box represents a selection or not selected. The dark spot could contain a value of 0,1,2,4,8,16,32,64 or 128,etc.
Bill of Materials
The following is the list of Bill of Materials for building an QR Code Scanner using ESP32 CAM Module. You can purchase all these components from Amazon.
| S.N. | Components | Quantity | Purchase Links |
|---|---|---|---|
| 1 | ESP32-CAM Board AI-Thinker | 1 | Amazon | AliExpress |
| 2 | FTDI Module | 1 | Amazon | AliExpress |
| 3 | Micro-USB Cable | 1 | Amazon | AliExpress |
| 4 | Jumper Wires | 10 | Amazon | AliExpress |
ESP32 CAM Module
The ESP32 Based Camera Module developed by AI-Thinker. The controller is based on a 32-bit CPU & has a combined Wi-Fi + Bluetooth/BLE Chip. It has a built-in 520 KB SRAM with an external 4M PSRAM. Its GPIO Pins have support like UART, SPI, I2C, PWM, ADC, and DAC.

The module combines with the OV2640 Camera Module which has the highest Camera Resolution up to 1600 × 1200. The camera connects to the ESP32 CAM Board using a 24 pins gold plated connector. The board supports an SD Card of up to 4GB. The SD Card stores capture images.
To learn in detail about the ESP32 Camera Module you can refer to our previous Getting Started Tutorial.
ESP32-CAM FTDI Connection
The board doesn’t have a programmer chip. So In order to program this board, you can use any type of USB-to-TTL Module. There are so many FTDI Module available based on CP2102 or CP2104 Chip or any other chip.
Make a following connection between FTDI Module and ESP32 CAM module.

| ESP32-CAM | FTDI Programmer |
| GND | GND |
| 5V | VCC |
| U0R | TX |
| U0T | RX |
| GPIO0 | GND |
Connect the 5V & GND Pin of ESP32 to 5V & GND of FTDI Module. Similarly, connect the Rx to UOT and Tx to UOR Pin. And the most important thing, you need to short the IO0 and GND Pin together. This is to put the device in programming mode. Once programming is done you can remove it.
Project PCB Gerber File & PCB Ordering Online
If you don’t want to assemble the circuit on a breadboard and you want PCB for the project, then here is the PCB for you. The PCB Board for ESP32 CAM Board is designed using EasyEDA online Circuit Schematics & PCB designing tool. The PCB looks something like below.

The Gerber File for the PCB is given below. You can simply download the Gerber File and order the PCB from ALLPCB at 1$ only.
Download Gerber File: ESP32-CAM Multipurpose PCB
You can use this Gerber file to order high quality PCB for this project. To do that visit the ALLPCB official website by clicking here: https://www.allpcb.com/.

You can now upload the Gerber File by choosing the Quote Now option. From these options, you can choose the Material Type, Dimensions, Quantity, Thickness, Solder Mask Color and other required parameters.

After filling all details, select your country and shipping method. Finally you can place the order.
You can assemble the components on the PCB Board.

Installing ESP32CAM Library
Here we will not use the general ESP webserver example rather another streaming process. Therefore we need to add another ESPCAM library. The esp32cam library provides an object oriented API to use OV2640 camera on ESP32 microcontroller. It is a wrapper of esp32-camera library.

Go to the following Github Link and download the zip library as in the image
Once downloaded add this zip library to Arduino Libray Folder. To do so follow the following steps: Open Arduino -> Sketch -> Include Library -> Add .ZIP Library… -> Navigate to downloaded zip file -> add
Source Code/Program for ESP32 CAM Module
Here is a source code for Object Counting with ESP32 CAM Module. Copy the code and paste it in the Arduino IDE.
#include <WebServer.h> #include <WiFi.h> #include <esp32cam.h> const char* WIFI_SSID = "ssid"; const char* WIFI_PASS = "password"; WebServer server(80); static auto loRes = esp32cam::Resolution::find(320, 240); static auto midRes = esp32cam::Resolution::find(350, 530); static auto hiRes = esp32cam::Resolution::find(800, 600); void serveJpg() { auto frame = esp32cam::capture(); if (frame == nullptr) { Serial.println("CAPTURE FAIL"); server.send(503, "", ""); return; } Serial.printf("CAPTURE OK %dx%d %db\n", frame->getWidth(), frame->getHeight(), static_cast<int>(frame->size())); server.setContentLength(frame->size()); server.send(200, "image/jpeg"); WiFiClient client = server.client(); frame->writeTo(client); } Void handleJpgLo() { if (!esp32cam::Camera.changeResolution(loRes)) { Serial.println("SET-LO-RES FAIL"); } serveJpg(); } Void handleJpgHi() { if (!esp32cam::Camera.changeResolution(hiRes)) { Serial.println("SET-HI-RES FAIL"); } serveJpg(); } Void handleJpgMid() { if (!esp32cam::Camera.changeResolution(midRes)) { Serial.println("SET-MID-RES FAIL"); } serveJpg(); } Void setup(){ Serial.begin(115200); Serial.println(); { using namespace esp32cam; Config cfg; cfg.setPins(pins::AiThinker); cfg.setResolution(hiRes); cfg.setBufferCount(2); cfg.setJpeg(80); bool ok = Camera.begin(cfg); Serial.println(ok ? "CAMERA OK" : "CAMERA FAIL"); } WiFi.persistent(false); WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASS); while (WiFi.status() != WL_CONNECTED) { delay(500); } Serial.print("http://"); Serial.println(WiFi.localIP()); Serial.println(" /cam-lo.jpg"); Serial.println(" /cam-hi.jpg"); Serial.println(" /cam-mid.jpg"); server.on("/cam-lo.jpg", handleJpgLo); server.on("/cam-hi.jpg", handleJpgHi); server.on("/cam-mid.jpg", handleJpgMid); server.begin(); } Void loop() { server.handleClient(); }| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 | #include <WebServer.h>#include <WiFi.h>#include <esp32cam.h>constchar*WIFI_SSID="ssid";constchar*WIFI_PASS="password";WebServer server(80);staticauto loRes=esp32cam::Resolution::find(320,240);staticauto midRes=esp32cam::Resolution::find(350,530);staticauto hiRes=esp32cam::Resolution::find(800,600);voidserveJpg(){auto frame=esp32cam::capture();if(frame==nullptr){Serial.println("CAPTURE FAIL");server.send(503,"","");return;}Serial.printf("CAPTURE OK %dx%d %db\n",frame->getWidth(),frame->getHeight(),static_cast<int>(frame->size()));server.setContentLength(frame->size());server.send(200,"image/jpeg");WiFiClient client=server.client();frame->writeTo(client);}VoidhandleJpgLo(){if(!esp32cam::Camera.changeResolution(loRes)){Serial.println("SET-LO-RES FAIL");}serveJpg();}VoidhandleJpgHi(){if(!esp32cam::Camera.changeResolution(hiRes)){Serial.println("SET-HI-RES FAIL");}serveJpg();}VoidhandleJpgMid(){if(!esp32cam::Camera.changeResolution(midRes)){Serial.println("SET-MID-RES FAIL");}serveJpg();}Voidsetup(){Serial.begin(115200);Serial.println();{using namespaceesp32cam;Config cfg;cfg.setPins(pins::AiThinker);cfg.setResolution(hiRes);cfg.setBufferCount(2);cfg.setJpeg(80);boolok=Camera.begin(cfg);Serial.println(ok?"CAMERA OK":"CAMERA FAIL");}WiFi.persistent(false);WiFi.mode(WIFI_STA);WiFi.begin(WIFI_SSID,WIFI_PASS);while(WiFi.status()!=WL_CONNECTED){delay(500);}Serial.print("http://");Serial.println(WiFi.localIP());Serial.println(" /cam-lo.jpg");Serial.println(" /cam-hi.jpg");Serial.println(" /cam-mid.jpg");server.on("/cam-lo.jpg",handleJpgLo);server.on("/cam-hi.jpg",handleJpgHi);server.on("/cam-mid.jpg",handleJpgMid);server.begin();}Voidloop(){server.handleClient();} |
Before Uploading the code you have to make a small change to the code. Change the SSID and password variable and in accordance with your WiFi network.
Now compile and upload it to the ESP32 CAM Board. But during uploading, you have to follow few steps every time.
- Make sure the IO0 pin is shorted with the ground when you have pressed the upload button.
- If you see the dots and dashes while uploading press the reset button immediately
- Once the code is uploaded, remove the I01 pin shorting with Ground and press the reset button once again.
- If the output is the Serial monitor is still not there then press the reset button again.
Now you can see a similar output as in the image below.

Now the ESP32-CAM is transmitting the live video, make sure that you copy this IP address is displayed.
Python Library Installation
For the live stream of video to be visible on our computer we need to write a Python script that will enable us to retrieve the frames of the video. The first step is to install Python. Go to python.org and download Python.
Once downloaded, install Python. Then Go to the command prompt and install NumPy, OpenCV & pyzbar libraries.
- type: pip install numpy and press enter. After the installation is done.
- type: pip install opencv-python and press enter.
- type: pip install pyzbar and press enter, close the command prompt.
Python Code + QR Code Scanner ESP32 CAM
Now open Idle code editor or any other python code editor.
Now Create a new folder. Inside the folder, create a new python file and paste the code below.
import cv2 import numpy as np import pyzbar.pyzbar as pyzbar import urllib.request #cap = cv2.VideoCapture(0) font = cv2.FONT_HERSHEY_PLAIN url='http://192.168.1.61/' cv2.namedWindow("live transmission", cv2.WINDOW_AUTOSIZE) prev="" pres="" while True: img_resp=urllib.request.urlopen(url+'cam-hi.jpg') imgnp=np.array(bytearray(img_resp.read()),dtype=np.uint8) frame=cv2.imdecode(imgnp,-1) #_, frame = cap.read() decodedObjects = pyzbar.decode(frame) for obj in decodedObjects: pres=obj.data if prev == pres: pass else: print("Type:",obj.type) print("Data: ",obj.data) prev=pres cv2.putText(frame, str(obj.data), (50, 50), font, 2, (255, 0, 0), 3) cv2.imshow("live transmission", frame) key = cv2.waitKey(1) if key == 27: break cv2.destroyAllWindows()| 123456789101112131415161718192021222324252627282930313233343536373839 | import cv2import numpy asnpimport pyzbar.pyzbar aspyzbarimport urllib.request #cap = cv2.VideoCapture(0)font=cv2.FONT_HERSHEY_PLAIN url='http://192.168.1.61/'cv2.namedWindow("live transmission",cv2.WINDOW_AUTOSIZE) prev=""pres=""whileTrue:img_resp=urllib.request.urlopen(url+'cam-hi.jpg')imgnp=np.array(bytearray(img_resp.read()),dtype=np.uint8)frame=cv2.imdecode(imgnp,-1)#_, frame = cap.read() decodedObjects=pyzbar.decode(frame)forobj indecodedObjects:pres=obj.dataifprev==pres:passelse:print("Type:",obj.type)print("Data: ",obj.data)prev=prescv2.putText(frame,str(obj.data),(50,50),font,2,(255,0,0),3) cv2.imshow("live transmission",frame) key=cv2.waitKey(1)ifkey==27:break cv2.destroyAllWindows() |
Change the IP address copied from Arduino Serial Monitor and update it in the URL variable in the above code. Then save the code and run it.
Note: If facing an issue in pyzbar library go ahead and download Microsoft Visual C++ 2013 Redistributable (x64) – 12.0.30501 from here
Now to test the working of the project, show some QR Codes in front of the ESP32 CAM module. The computer screen will display the QR Code detail as shown in the image below.

This is how you can build your own QR Code Scanner or Reader with ESP32 CAM Module & OpenCV Python libraries.
Video Tutorial & Guide
QR Code Reader/Scanner with ESP32 Camera Module & OpenCV Watch this video on YouTube.Tag » Arduino Ov7670 Qr Code
-
Need Help Read QR Code Using OV7670 And Arduino Uno
-
Scanning QR Code With Ov7670 And Arduino Uno And Sending It To ...
-
Barcode Reader - Project Guidance - Arduino Forum
-
[SOURCE CODE] Sensor Camera OV7670 With Arduino UNO Part 2-3
-
Reading QR Or Bar Codes - Hardware - Particle Community
-
How To Use OV7670 Camera Module With Arduino - Circuit Digest
-
OV7670 Arduino Camera Sensor Module Framecapture Tutorial
-
Trying To Read A QR Code With Arduino Uno - Reddit
-
Mạch OV7670 Camera Module
-
Visual Capturing With OV7670 On Arduino
-
Ηλεκτρονικά :: Αισθητήρες :: Κάμερες - Hellas Digital
-
Beginning Arduino Ov7670 Camera Development By Robert Chin ...
-
How To Design A QR Code Scanner With ESP32 CAM Module ...