Skip to content

Quick Start Guide for Multi-Camera Adapter Board

Hardware


Abstract

Arducam offers multi-camera adapters to accommodate up to 4 camera modules on a single Raspberry Pi and switch between them quickly. The HAT-style quadruple adapter fits well with the Raspberry Pi A&B series, and the double adapter is perfect for the Pi Zero. You will read more about it in the following chapters.

  • Hardware Structure(Example as B012001)
  • Connect and Insert the Multi-Camera Adapter Board into Raspberry Pi
  • Connect the cameras to Multi-Camera Adapter Board
  • Pinout Definition

Multi-Camera Adapter Board V2.1/V2.2 (SKU: B012001)

Software


Warning

We currently only guarantee that the Camera Adaptation is supported on Raspberry Pi Bullseye and Bookworm OS.

Supported Platforms and OS


Note for Supported Platform and OS
Platform Bookworm(rpicam/libcamera) Bullseye(libcamera) Buster(raspistill)
Raspberry Pi 5    
Raspberry Pi 4B / 3B+ / 3A+ / Zero / Zero 2 W  
Raspberry Pi CM3 / CM3+ / CM4
(extra adapter board required)
 

Update Kernel Version

Note: Please make sure your kernel version is up to date (at least 5.15.63 or later)

m1

How to update the Kernel bersion:

sudo apt-get update
sudo apt-get upgrade

Supported Cameras

The following cameras will need the corresponding driver to be accessed:

Sensor Resolution
OV5647 5MP
IMX219 8MP
IMX477 12MP
IMX708 12MP
IMX519 16MP
64MP Camera 64MP

Modify the Config.txt

For Quad-Camera Adapter Board(B012001):

sudo nano /boot/config.txt
#add Following content: 
dtoverlay=camera-mux-4port,cam0-<camera sensor name>,cam1-<camera sensor name>,cam2-<camera sensor name>,cam3-<camera sensor name>

#Find the line "camera_auto_detect=1" and modify it: 
camera_auto_detect=0

Note

Please manually add the number of cam according to the number of cameras you have connected.
Example: if you have three IMX219 cameras connected, enter:
dtoverlay=camera-mux-4port,cam0-imx219,cam1-imx219,cam2-imx219

Demo(64mp)

m2

dmesg

m3


For Dual-Camera Adapter Board(B016601):

sudo nano /boot/config.txt
add: 
dtoverlay=camera-mux-2port,cam0-<you camera sensor>,cam1-<you camera sensor>

Note

Please manually add the number of cam according to the number of cameras you have connected.
Example: if you only have one IMX219 cameras connected, enter:
dtoverlay=camera-mux-2port,cam0-imx219

Run the Multi-Camera

Use libcamera apps to access the Multi-Camera

libcamera-still -t 0 --camera <choose camera num>

Example:

libcamera-still -t 0 --camera 2

m6

Attention

For another libcamera apps like libcamera-raw, libcamera-vide, etc. You will need to manually add --camera <choose camera num> behind the command

python demos


previewOpencv.py source code:

from ast import Try
from PyQt5.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout, QApplication, QWidget
from picamera2 import Picamera2
from PyQt5.QtGui import QImage,QPixmap
from PyQt5.QtCore import QThread
import RPi.GPIO as gp
import time
import os

width = 320
height = 240 

adapter_info = {  
    "A" : {   
        "i2c_cmd":"i2cset -y 10 0x70 0x00 0x04",
        "gpio_sta":[0,0,1],
    }, "B" : {
        "i2c_cmd":"i2cset -y 10 0x70 0x00 0x05",
        "gpio_sta":[1,0,1],
    }, "C" : {
        "i2c_cmd":"i2cset -y 10 0x70 0x00 0x06",
        "gpio_sta":[0,1,0],
    },"D" : {
        "i2c_cmd":"i2cset -y 10 0x70 0x00 0x07",
        "gpio_sta":[1,1,0],
    }
}

class WorkThread(QThread):

    def __init__(self):
        super(WorkThread,self).__init__()
        gp.setwarnings(False)
        gp.setmode(gp.BOARD)
        gp.setup(7, gp.OUT)
        gp.setup(11, gp.OUT)
        gp.setup(12, gp.OUT)


    def select_channel(self,index):
        channel_info = adapter_info.get(index)
        if channel_info == None:
            print("Can't get this info")
        gpio_sta = channel_info["gpio_sta"] # gpio write
        gp.output(7, gpio_sta[0])
        gp.output(11, gpio_sta[1])
        gp.output(12, gpio_sta[2])

    def init_i2c(self,index):
        channel_info = adapter_info.get(index)
        os.system(channel_info["i2c_cmd"]) # i2c write

    def run(self):
        global picam2
        # picam2 = Picamera2()
        # picam2.configure( picam2.still_configuration(main={"size": (320, 240),"format": "BGR888"},buffer_count=1))

        flag = False

        for item in {"A","B","C","D"}:
            try:
                self.select_channel(item)
                self.init_i2c(item)
                time.sleep(0.5) 
                if flag == False:
                    flag = True
                else :
                    picam2.close()
                    # time.sleep(0.5) 
                print("init1 "+ item)
                picam2 = Picamera2()
                picam2.configure(picam2.create_still_configuration(main={"size": (320, 240),"format": "BGR888"},buffer_count=2)) 
                picam2.start()
                time.sleep(2)
                picam2.capture_array(wait=False)
                time.sleep(0.1)
            except Exception as e:
                print("except: "+str(e))

        while True:
            for item in {"A","B","C","D"}:
                self.select_channel(item)
                time.sleep(0.02)
                try:
                    buf = picam2.capture_array()
                    buf = picam2.capture_array()
                    cvimg = QImage(buf, width, height,QImage.Format_RGB888)
                    pixmap = QPixmap(cvimg)
                    if item == 'A':
                        image_label.setPixmap(pixmap)
                    elif item == 'B':
                        image_label2.setPixmap(pixmap)
                    elif item == 'C':
                        image_label3.setPixmap(pixmap)
                    elif item == 'D':
                        image_label4.setPixmap(pixmap)
                except Exception as e:
                    print("capture_buffer: "+ str(e))

app = QApplication([])
window = QWidget()
layout_h = QHBoxLayout()
layout_h2 = QHBoxLayout()
layout_v = QVBoxLayout()
image_label = QLabel()
image_label2 = QLabel()
image_label3 = QLabel()
image_label4 = QLabel()

# picam2 = Picamera2()

work = WorkThread()

if __name__ == "__main__":
    image_label.setFixedSize(320, 240)
    image_label2.setFixedSize(320, 240)
    image_label2.setFixedSize(320, 240)
    image_label2.setFixedSize(320, 240)
    window.setWindowTitle("Qt Picamera2 Arducam Multi Camera Demo")
    layout_h.addWidget(image_label)    
    layout_h.addWidget(image_label2)
    layout_h2.addWidget(image_label3)
    layout_h2.addWidget(image_label4)
    layout_v.addLayout(layout_h,20)
    layout_v.addLayout(layout_h2,20)
    window.setLayout(layout_v)
    window.resize(660, 500)

    work.start()

    window.show()
    app.exec()
    work.quit()
    picam2.close()

For more details and source code, please refer to:

Github -- Multi-camera-Adapter-board-v2.2-python

Troubleshooting


1. Time-error-occurs-when-using-multi-camera-adapter-board-on-pi5