Skip to main content
Version: Torizon OS 7.x.y

First Steps with Arducam CSI Camera Module 5MP OV5640 (Torizon)

Arducam CSI Camera Module

(Double-Click to Zoom)

Introduction

This article provides information on how to start working with the CSI Camera Module based on the OV5640 image sensor from Arducam on Torizon OS.

The scope of this article is specific to the Arducam OV5640. For more information on how cameras work on Torizon OS in general, container permissions, bind mounts, GStreamer pipeline structure, and OpenCV examples, refer to How to use Cameras on Torizon.

The following topics will be covered:

Features

The OV5640 is a high-performance CMOS image sensor designed for a wide range of imaging applications. It offers a combination of high resolution, advanced imaging features, and versatility, making it a popular choice for mobile and embedded camera systems.

Arducam has designed the OV5640 camera module and integrated it into the Toradex carrier boards via the MIPI protocol. The camera circuit board, after being improved by the Arducam technical team, has reached a mini size of 24x25mm, which makes it easier for visual projects to be applied in narrow spaces with limited size.

Sensor Features:

  • Image Sensor: OV5640 from OmniVision
  • Still Resolution: 5 Megapixels
  • Interface: MIPI CSI-2
  • Output Format: 8-/10-bit RGB RAW, RGB, YUV, JPEG
  • Max Pixel Array: 2592 x 1944 pixels
  • Sensor Image Area: 6.287mm x 4.712mm (7.9mm diagonal)
  • Pixel Size: 1.4μm x 1.4μm
  • Optical Size: 1/4"

Lens Features:

  • IR Sensitivity: Integral IR-cut Filter, visible light only
  • Focal length: 4.22mm
  • Aperture: F2.0 ±5%
  • Field of View (FOV): 84.2°(D)×71.7°(H)×57°(V)
  • Lens Mount: Stock Lens

Datasheets

Arducam CSI Camera Module OV5640 Datasheet

Compatible Products

Hardware

The Arducam CSI Camera Module 5MP OV5640 is sold together with a flat connector cable.

The following Toradex carrier boards support the MIPI CSI-2 interface and are compatible with the camera kit out of the box:

This camera module is supported for the following SoMs:

Software

Torizon OS includes the OV5640 device tree overlays, already pre-built inside the image.

To enable the camera, you need to activate the required overlay(s) and bring up a containerized GStreamer pipeline, as shown in the Camera Usage section.

Hardware Setup

What I need to order

You can have the Arducam OV5640 CSI Camera Module working with specific Toradex computers on modules and carrier boards. See the compatible products.

Arducam OV5640 CSI Camera Module, cable, and carrier board

Besides the Module and the Carrier Board, you will need to order:

  • The Arducam OV5640 Camera Module;
  • The flat cable for connecting the Camera Module to the Carrier Board.

Where do I order

You can order the Toradex computer on Modules and the carrier boards online in the Toradex Webshop.

You can order the Arducam Camera Module and the needed accessories on the Arducam Shop.

Please refer to the instructions below for connecting the camera module to your specific carrier board.

Cable Connection

Connect the flat cable to the camera module as shown in the following pictures:

Flat Cable Connection Detail (Front)

Flat Cable Connection Detail (Back)

(Double-Click to Zoom)
danger

Please disconnect any power and USB cables from the board before connecting the flat cable to the MIPI-CSI bus to avoid any damage to the camera!

Connection to Dahlia Carrier Board

Connect the camera to the Dahlia Carrier Board, assuring that the flat cable contacts are on the correct side, as indicated in the figures below.

Dahlia Carrier Board Connected to the Camera Module

Dahlia Carrier Board Connected to the Camera Module (other angle)

(Double-Click to Zoom)

Connection to Mallow Carrier Board

Connect the camera to the Mallow Carrier Board, assuring that the flat cable contacts are on the correct side, as indicated in the figures below.

Mallow Carrier Board Connected to the Camera Module

Flat Cable Connected to the Carrier Board (Detail)

(Double-Click to Zoom)

Connection to Ixora Carrier Board

Connect the camera to the Ixora Carrier Board, assuring that the flat cable contacts are on the correct side, as indicated in the figures below.

The MIPI-CSI interface is underneath the SoM

Board Connected to the Camera Module

(Double-Click to Zoom)

Connection to Verdin Development Board

Connect the camera to the Verdin Development Board, assuring that the flat cable contacts are on the correct side, as indicated in the figures below:

Verdin Development Board Connected to the Camera Module on Native CSI

Verdin Development Board Connected to the Camera Module on Native CSI - Close-up

Flat Cable Connected to the Development Board (Detail)

(Double-Click to Zoom)

Connection to Mezzanine and Dual-Camera Setup

The Verdin iMX8M Plus Mezzanine is an add-on board that mounts on the Verdin Development Board and exposes a second MIPI-CSI connector (X5). You can connect a camera to the mezzanine port on its own, or alongside the native carrier board port for a dual-camera setup.

Connecting the Camera to the Mezzanine

Connect the camera to the mezzanine as indicated in the figures below:

Verdin Development Board Connected to the Camera Module on Mezzanine CSI

Camera Module Connected to Mezzanine CSI

(Double-Click to Zoom)
  • The mezzanine MIPI-CSI Camera interface is on connector X5.

Mezzanine Jumper Configuration

The mezzanine includes jumpers on the MIPI-CSI interface that must be configured according to the intended use:

  • Default: use this position when operating the mezzanine camera port alone.
  • Alternate: use this position when using the mezzanine together with the native carrier board port simultaneously.
Jumper in Default position

Jumper in Alternate position

(Double-Click to Zoom)

Dual-Camera Setup

To use both cameras simultaneously, connect one camera to the native CSI connector (X47) and the other to the mezzanine connector (X5), and make sure the mezzanine jumper is set to the Alternate position.

Verdin Development Board with Two OV5640 Cameras Connected

(Double-Click to Zoom)
info

The flat cable (used to connect the carrier board and the camera adaptor) is fragile. If your camera does not work, make sure to test the cable connections on the flat cable.

Camera Usage

This article covers three possible configurations for using the camera:

  • Native port only: connect the camera directly to the native MIPI-CSI port on the carrier board.
  • Mezzanine only: connect the camera to the mezzanine port, with the jumper in either Default or Alternate position.
  • Native + Mezzanine: for dual camera support using both ports simultaneously, with the mezzanine jumper set to Alternate.
info

For hardware setup and jumper configuration of the mezzanine, see the Connection to Mezzanine section.

We recommend using a display to be able to visualize the captured image during camera testing.

Connect to the SoM

After completing the hardware setup for your intended configuration, connect to the device via SSH or a serial terminal.

Apply the Device Tree Overlay

On Torizon OS there are two ways to apply the overlay(s) required to enable the camera:

For more background on overlays in Torizon OS, see Device Tree Overlays on Torizon.

Approach 1: Using TorizonCore Builder

For development and production workflows, the recommended method is to bake the overlay into a custom Torizon OS image with TorizonCore Builder.

Prerequisites:

Step 1 — Get a base Torizon OS image

Place the .tar file for the desired Torizon OS image in your TorizonCore Builder working directory.

You can get this image in two ways:

  • Download it manually:

Grab a Torizon OS 7 image for your SoM from the Toradex Download Links page, and save the .tar in your working directory.

  • Pull it from a running board:

If a board already runs Torizon OS, point TorizonCore Builder at it over SSH and let it fetch the matching image:

  $ torizoncore-builder images download --remote-host <board-ip> --remote-username <user> --remote-password <password>

This reads the version from the device and downloads the matching image into your working directory.

Step 2 — Clone the kernel and overlays repositories

These two repositories supply the device tree sources and the overlay sources. The branch must match your Torizon OS version. Adjust the branch name if you are on a different release.

$ git clone -b toradex_6.6-2.2.x-imx git://git.toradex.com/linux-toradex.git linux
$ git clone -b toradex_6.6-2.2.x-imx git://git.toradex.com/device-tree-overlays.git device-trees
tip

For other SoM families (e.g., AM62/AM62P with the TI kernel), check Device Tree Overlays on Torizon — Clone The Toradex Repositories for the correct branches.

Step 3 — Create the tcbuild.yaml

In your working directory, create a tcbuild.yaml file using the template below.

Before building the image, update the following fields:

  • Replace <torizon-os-tar> with the name of the Torizon OS image .tar file in your working directory.
  • Replace <output-image-folder> with the directory where TorizonCore Builder should generate the customized image.
  • Update the <base-device-tree> to match your SoM variant and carrier board (see more details below).
  • Check the overlays.add list provided below and leave uncommented only the overlay sources that match your hardware setup.
input:
easy-installer:
local: <torizon-os-tar>.tar

customization:
device-tree:
include-dirs:
- linux/include/
custom: linux/arch/arm64/boot/dts/freescale/<base-device-tree>.dts
overlays:
add:
# Native port only:
- device-trees/overlays/verdin-imx8mp_ov5640-27mhz_overlay.dts
# Mezzanine only (uncomment the one matching your jumper position):
# - device-trees/overlays/verdin-imx8mp_mezzanine_ov5640-27mhz-default-jumpers_overlay.dts
# - device-trees/overlays/verdin-imx8mp_mezzanine_ov5640-27mhz-alt-jumpers_overlay.dts
# Dual camera: use the native overlay above PLUS the mezzanine alternate overlay

output:
easy-installer:
local: <output-image-folder>

The custom: field sets the base device tree for your SoM and carrier board. Replace <base-device-tree>.dts with the file that matches your hardware setup.

To find the correct device tree for your setup, search the cloned kernel tree for your SoM:

# For example, for the Verdin i.MX 8M Plus:
$ find linux -name "*imx8mp-verdin*.dts"

This lists the device trees available for that SoM; pick the one whose module variant and carrier board match your setup, for example:

  • mx8mp-verdin-wifi-dev.dts → Verdin Development Board with Wi-Fi
  • mx8mp-verdin-wifi-dahlia.dts → Dahlia Carrier Board with Wi-Fi
  • mx8mp-verdin-wifi-yavia.dts → Yavia Carrier Board with Wi-Fi
  • mx8mp-verdin-nonwifi-dev.dts → Verdin Development Board without Wi-Fi

Step 4 — Build the custom image

$ torizoncore-builder build

The output image is generated in the directory specified in the tcbuild.yaml created in Step 3.

Step 5 — Deploy

Install the custom image on the device using Toradex Easy Installer, through SSH, or via Torizon Cloud. For deploy options and commands, see Deploy The Custom Toradex Easy Installer Image.

Approach 2: Enabling the Overlay on the Device

The overlays required to enable the Arducam OV5640 camera are already pre-built and shipped inside the Torizon OS image. The fastest way to evaluate the camera is to add them to the overlays.txt file on the device.

Step 1 — Find the active OSTree deployment

Get the <HASH> value of the current OSTree deployment with:

# cat /proc/cmdline

Look for the ostree=/ostree/boot.X/torizon/<HASH>/0 substring in the output.

Copy the <HASH> value from this path. It is used to locate the overlays.txt file for the active Torizon OS deployment.

Step 2 — Edit overlays.txt

Using the <HASH> obtained in the previous step, open the following file with sudo privileges:

/sysroot/boot/ostree/torizon-<HASH>/dtb/overlays.txt

Then, select the tab that matches your intended camera configuration and append the indicated overlays to the fdt_overlays variable.

Append the native overlay for your SoM:

  • Verdin Family SoMs: verdin-[SoM name]_ov5640-27mhz_overlay.dtbo
  • Apalis iMX8: apalis-imx8_ov5640-27mhz_overlay.dtbo

Example for Verdin iMX8MP, preserving default pre-enabled overlays:

cat /sysroot/boot/ostree/torizon-<HASH>/dtb/overlays.txt
fdt_overlays=verdin-imx8mp_hdmi_overlay.dtbo verdin-imx8mp_dsi-to-hdmi_overlay.dtbo verdin-imx8mp_ov5640-27mhz_overlay.dtbo

Step 3 — Sync and Reboot

# sync
# sudo reboot

Step 4 — Verify

After reboot, confirm that the overlays were applied successfully:

# ls /proc/device-tree/chosen/overlays/
# cat /proc/device-tree/chosen/overlays/verdin-imx8mp_ov5640-27mhz_overlay.dtbo

A value of 0 indicates the overlay was applied successfully. For details on this verification, see Checking applied overlays.

Rollback

If an overlay change prevents the kernel from booting, after a few failed attempts (3 by default) Torizon OS automatically rolls back to the previous deployment. See Update Rollbacks.

Set Up the Container Environment

Running camera applications on Torizon OS requires at least two containers:

  • A Weston container, providing the Wayland compositor to display the video output.
  • A GStreamer + V4L2 container, running the pipeline that captures from the camera.

For background on container permissions, bind mounts and GUI containers, refer to Camera usage with containers.

Before launching any containers, stop any other containers that might be running on your device:

# docker stop $(docker ps -a -q)

Build the GStreamer Container

The torizon-samples repository provides a Dockerfile for a GStreamer + V4L2 container. Clone the repository and build the image on your host computer, then push it to your Docker Hub account.

warning

Make sure you have configured your build environment for Torizon containers before running docker build.

$ git clone --branch bookworm https://github.com/toradex/torizon-samples.git
$ cd torizon-samples/gstreamer/bash/simple-pipeline

Since the container image needs to target linux/arm64/v8, you need to enable ARM emulation on your host machine before building. This allows an x86 host to build images for ARM64 transparently.

Run the following command on your host machine:

$ docker run --rm -it --privileged torizon/binfmt
info

ARM emulation is registered at the kernel level and persists until the host machine is rebooted. Re-run the command above after any host reboot.

Then build the image according to your SoM family, replacing <your-dockerhub-username> with your own:

$ docker build --build-arg BASE_NAME=wayland-base-vivante \
--build-arg IMAGE_ARCH=linux/arm64/v8 \
-t <your-dockerhub-username>/gst_example .

After the build completes, push the image to your Docker Hub account:

$ docker push <your-dockerhub-username>/gst_example

For more details about the Dockerfile, refer to How to use Gstreamer on Torizon OS.

Launch the Weston Container

On the target board, launch the Weston container according to your SoM family:

# docker container run -d --name=weston --net=host \
--cap-add CAP_SYS_TTY_CONFIG \
-v /dev:/dev -v /tmp:/tmp -v /run/udev/:/run/udev/ \
--device-cgroup-rule="c 4:* rmw" --device-cgroup-rule="c 253:* rmw" \
--device-cgroup-rule="c 13:* rmw" --device-cgroup-rule="c 226:* rmw" \
--device-cgroup-rule="c 10:223 rmw" --device-cgroup-rule="c 199:0 rmw" \
torizon/weston-imx8:4 \
--developer
info

To learn more about the device-cgroup-rule options used above, refer to the Hardware Access through Control Group Rules (cgroup) section of the Torizon Best Practices Guide.

Find the Capture Device

The OV5640 driver exposes one capture device per active port (/dev/video<N>). The exact node number can vary depending on your SoM and which other devices are present, so the first time you set up the camera it's worth identifying the right node explicitly.

List the video devices on the host:

# ls /dev/video*
/dev/video0  /dev/video1  /dev/video2  /dev/video3

Then start the GStreamer container, adjusting the --device flags to include all the /dev/video* nodes listed previously.

Also, remember to input your <your-dockerhub-username>:

# docker run --rm -it -v /tmp:/tmp -v /var/run/dbus:/var/run/dbus -v /dev:/dev -v /sys:/sys \
--device /dev/video0 --device /dev/video1 --device /dev/video2 --device /dev/video3 \
--device-cgroup-rule='c 81:* rmw' --device-cgroup-rule='c 199:* rmw' --device-cgroup-rule='c 226:* rmw' \
--entrypoint '/bin/bash' \
<your-dockerhub-username>/gst_example

Once inside the container, list and inspect the video devices:

## v4l2-ctl --list-devices

Then check each candidate with v4l2-ctl -D to identify the capture device, for example:

## v4l2-ctl --device /dev/video3 -D
Driver Info:
Driver name : mxc-isi-cap_v1
Card type : mxc-isi-cap_v1
Bus info : platform:32e00000.isi:cap_devic
Driver version : 6.6.23
Capabilities : 0x84201000
Video Capture Multiplanar
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04201000
Video Capture Multiplanar
Streaming
Extended Pix Format
info

When using both MIPI-CSI ports simultaneously, two capture devices will be available, one for each camera.

Once you know the right node(s), you can exit the container and restart it passing only the relevant --device flag(s), as shown in the next section.

Launch the GStreamer Container and View the Video Output

Launch the GStreamer container, passing the capture device(s) identified in the previous step. Replace /dev/<video-device> accordingly.

For a single camera:

# docker run --rm -it -v /tmp:/tmp -v /var/run/dbus:/var/run/dbus -v /dev:/dev -v /sys:/sys \
--device /dev/<video-device> \
--device-cgroup-rule='c 81:* rmw' --device-cgroup-rule='c 199:* rmw' --device-cgroup-rule='c 226:* rmw' \
--entrypoint '/bin/bash' \
<your-dockerhub-username>/gst_example

For the dual camera setup, pass both capture devices with separate --device flags.

Once inside the container, run the pipeline according to your SoM:

For a single camera:

## gst-launch-1.0 -v v4l2src device=/dev/video3 ! video/x-raw ! videoconvert ! waylandsink

For the dual camera setup, the following pipeline displays both cameras side by side in a single output window:

## gst-launch-1.0 compositor name=mix \
sink_0::xpos=0 sink_0::ypos=0 sink_0::width=640 sink_0::height=480 \
sink_1::xpos=640 sink_1::ypos=0 sink_1::width=640 sink_1::height=480 ! \
videoconvert ! waylandsink \
v4l2src device=/dev/video3 ! video/x-raw,width=640,height=480 ! videoconvert ! mix.sink_0 \
v4l2src device=/dev/video4 ! video/x-raw,width=640,height=480 ! videoconvert ! mix.sink_1
info

Remember to replace the /dev/video* node in the commands above with the one corresponding to your camera, as identified in the Find the Capture Device step.

Click here to see a sample of the GStreamer command output. This may vary depending on the used SoM.
## gst-launch-1.0 -v v4l2src device=/dev/video3 ! video/x-raw ! videoconvert ! waylandsink
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
/GstPipeline:pipeline0/GstV4l2Src:v4l2src0.GstPad:src: caps = video/x-raw, format=(string)YUY2, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)1:4:5:1
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = video/x-raw, format=(string)YUY2, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)1:4:5:1
/GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:src: caps = video/x-raw, format=(string)YUY2, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)1:4:5:1
/GstPipeline:pipeline0/GstWaylandSink:waylandsink0.GstPad:sink: caps = video/x-raw, format=(string)YUY2, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)1:4:5:1
/GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:sink: caps = video/x-raw, format=(string)YUY2, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)1:4:5:1
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:sink: caps = video/x-raw, format=(string)YUY2, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)1:4:5:1
Redistribute latency...
0:00:12.3 / 99:99:99.

How to Use Video Streams on Linux - Video4Linux & GStreamer

For more details about using Video4Linux and GStreamer tools to interact with cameras and collect video frames, see Cameras on Toradex System on Modules and How to use Gstreamer on Torizon OS.

Having Trouble?

Please contact our technical support. Various options are listed in the article below.

Send Feedback!