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.
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