Transforming Raspberry Pi 4 into a Barcode Scanner with a C++ App, USB Camera, and OLED Display
The Raspberry Pi 4, with its enhanced performance and connectivity features, offers a myriad of possibilities for DIY enthusiasts and developers. One such application is turning this compact computer into a fully functional barcode scanner. In this article, we’ll guide you through the process of setting up a barcode scanner using a C++ application, a USB camera, and an I2C OLED display module on a Raspberry Pi 4.
This article is Part 12 in a 16-Part Series.
- Part 1 - Building a C/C++ Barcode & QR Code Reader for Raspberry Pi with Dynamsoft SDK
- Part 2 - CMake: Build C++ Project for Windows, Linux and macOS
- Part 3 - How to Port Visual Studio C++ Project to Linux with CMake
- Part 4 - Insight Into Dynamsoft Barcode SDK Decoding Performance
- Part 5 - Building ARM64 Barcode and QR Code Scanner on Nvidia Jetson Nano
- Part 6 - How to Decode QR Code on Mac with Apple Silicon
- Part 7 - How to Develop a Desktop GUI Barcode Reader with Qt and C/C++
- Part 8 - How to Build a Desktop Barcode Scanner with Webcam Support Using Qt QCamera
- Part 9 - Building Command-line Barcode and QR Code Reader in C++
- Part 10 - How to Build Linux ARM32 and Aarch64 Barcode QR Scanner in Docker Container
- Part 11 - How to Link MSVC DLLs with MinGW GCC in Windows
- Part 12 - Transforming Raspberry Pi 4 into a Barcode Scanner with a C++ App, USB Camera, and OLED Display
- Part 13 - Building Windows Desktop Barcode Reader with Win32 API and Dynamsoft C++ Barcode SDK
- Part 14 - How to Build a Command-Line Barcode Reader with Rust and C++ Barcode SDK
- Part 15 - How to Decode Barcode and QR Code from WebP Images in C++ and Python
- Part 16 - Building a Desktop C++ Barcode Scanner with Slimmed-Down OpenCV and Webcam
Raspberry Pi 4 Specifications
- Broadcom BCM2711, Quad core Cortex-A72 (ARM v8) 64-bit SoC @ 1.5GHz
- 2GB, 4GB or 8GB LPDDR4-3200 SDRAM (depending on model)
- 2.4 GHz and 5.0 GHz IEEE 802.11ac wireless, Bluetooth 5.0, BLE
- Gigabit Ethernet
- 2 USB 3.0 ports; 2 USB 2.0 ports.
- 2 × micro-HDMI ports (up to 4kp60 supported)
Prerequisites
- Raspberry Pi 4 (4GB model)
- Raspberry Pi RGB Cooling HAT with adjustable fan and OLED display
- Micro-HDMI to HDMI cable
- HDMI Female to HDMI Female Coupler Connector (used to extend Micro-HDMI to HDMI cable)
- SanDisk Ultra 32GB MicroSDHC UHS-I Card
- USB Webcam
Raspberry Pi OS Installation and Configuration
Installation
- Download Raspberry Pi OS.
- Write the OS image to an SD card with Win32 Disk Imager.
- Insert the SD card into Raspberry Pi 4 and connect to power via USB-C connector (minimum 3A).
Configuration
Launch the OS and then enable the I2C, VNC, and SSH interfaces.
If you want to use Windows Remote Desktop Connection, you can install tightvncserver and xrdp:
sudo apt update
sudo apt install tightvncserver xrdp
Check the disk space:
df -H
Filesystem Size Used Avail Use% Mounted on
/dev/root 32G 8.9G 21G 30% /
devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs 2.1G 0 2.1G 0% /dev/shm
tmpfs 2.1G 9.1M 2.1G 1% /run
tmpfs 5.3M 4.1k 5.3M 1% /run/lock
tmpfs 2.1G 0 2.1G 0% /sys/fs/cgroup
/dev/mmcblk0p1 265M 54M 211M 21% /boot
tmpfs 405M 4.1k 405M 1% /run/user/1000
If not all of the SD card storage is available, run sudo raspi-config
and select Advanced Options:
Then select A1 to expand disk storage. A reboot is required to make it work:
Install OpenCV on Raspberry Pi OS
OpenCV is used for grabbing frames from the USB camera. Here are the steps to install OpenCV 4.3.0 on Raspberry Pi OS:
-
Download the latest OpenCV source code: https://github.com/opencv/opencv/releases
-
Install the following required packages:
sudo apt install build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev libv4l-dev libjpeg-dev libpng-dev libtiff-dev
-
Build (takes more than 1 hour) and install OpenCV:
mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local -DOPENCV_GENERATE_PKGCONFIG=ON .. make -j4 sudo make install
C/C++ Barcode Reader Project
Let’s create a CMake project named raspberry-pi-cpp-barcode under /home/pi directory:
cd /home/pi
mkdir raspberry-pi-cpp-barcode
Download Dynamsoft C++ Barcode SDK to get shared libraries for Linux ARM.
Link the barcode recognition library, WiringPi library and OpenCV libraries in CMakeLists.txt:
link_directories("${PROJECT_SOURCE_DIR}/platforms/linux/")
find_package(OpenCV REQUIRED)
include_directories("${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/include/")
# Add the executable
add_executable(BarcodeReader ssd1306_i2c.c BarcodeReader.cxx)
target_link_libraries (BarcodeReader "DynamsoftBarcodeReader" ${OpenCV_LIBS} wiringPi)
Here is the OpenCV C/C++ code for grabbing frames from webcam:
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
Mat frame;
VideoCapture capture(0);
for (;;)
{
int key = waitKey(10);
if ((key & 0xff) == 27/*ESC*/) break;
capture >> frame; // read the next frame from camera
if (frame.empty())
{
cerr << "ERROR: Can't grab camera frame." << endl;
break;
}
imshow("Dynamsoft Barcode Reader", frame);
}
To decode barcodes from camera frames, we can utilize the barcode video APIs. These manage a frame queue and perform barcode detection on a worker thread:
#include "DynamsoftBarcodeReader.h"
#include "BarcodeReaderConfig.h"
void textResultCallback(int frameId, TextResultArray *pResults, void * pUser)
{
char * pszTemp = NULL;
pszTemp = (char*)malloc(4096);
if (pResults->resultsCount == 0)
{
snprintf(pszTemp, 4096, "No barcode found.\r\n\r\n");
printf(pszTemp);
free(pszTemp);
CBarcodeReader::FreeTextResults(&pResults);
return;
}
for (int iIndex = 0; iIndex < pResults->resultsCount; iIndex++)
{
snprintf(pszTemp, 4096, "Barcode %d:\r\n", iIndex + 1);
printf(pszTemp);
snprintf(pszTemp, 4096, "Type: %s, Value: %s\r\n", pResults->results[iIndex]->barcodeFormatString, pResults->results[iIndex]->barcodeText);
printf(pszTemp);
draw_OLED(pszTemp);
}
free(pszTemp);
CBarcodeReader::FreeTextResults(&pResults);
}
CBarcodeReader reader;
int iRet = reader.InitLicense("LICENSE-KEY");
reader.SetTextResultCallback(textResultCallback,NULL);
capture >> frame;
int width = capture.get(CAP_PROP_FRAME_WIDTH);
int height = capture.get(CAP_PROP_FRAME_HEIGHT);
iRet = reader.StartFrameDecoding(10, 10, width, height, frame.step.p[0], IPF_RGB_888, "");
for (;;)
{
int key = waitKey(10);
if ((key & 0xff) == 27/*ESC*/) break;
capture >> frame; // read the next frame from camera
if (frame.empty())
{
cerr << "ERROR: Can't grab camera frame." << endl;
break;
}
reader.AppendFrame(frame.data);
imshow("Dynamsoft Barcode Reader", frame);
}
reader.StopFrameDecoding();
You need to request a free trial license and replace the placeholder with your own license key:
int iRet = reader.InitLicense("LICENSE-KEY");
After obtaining the barcode decoding results, we can display the text on the OLED screen:
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include "ssd1306_i2c.h"
void draw_OLED(char* content)
{
ssd1306_clearDisplay();
ssd1306_drawString(content);
ssd1306_display();
}
Finally, compile and execute the C/C++ barcode reader program:
mkdir build
cd build
cmake ..
cmake –build .
./BarcodeReader
How to AutoStart the Barcode Scanner Program on Raspberry Pi OS
If you wish to launch the barcode scanner program upon OS startup, create a script file at /home/pi/autostart.sh:
#!/bin/sh
/home/pi/raspberry-pi-cpp-barcode/build/BarcodeReader
Additionally, you’ll need to modify the file permissions to make it executable:
chmod a+x autostart.sh
Subsequently, create a file at /home/pi/.config/autostart/autostart.desktop:
[Desktop Entry]
Type=Application
Exec=sh /home/pi/autostart.sh
Now you can reboot the OS to verify whether the barcode program will run automatically:
sudo reboot
Source Code
https://github.com/yushulx/cmake-cpp-barcode-qrcode-mrz/tree/main/examples/9.x/raspberry_pi_oled