Arducam UC 512 RevD1 start_preview RuntimeError on Raspberry Pi while Rev.C works

Having trouble with an Arducam UC 512 RevD1 board. My capture program throws this:

RuntimeError: start_preview() unexpected result

The exact same code run from the exact same Raspberry Pi works fine on a different UC 512 Rev.C board - the preview shows up normally. The only difference is the board itself.

Any pointers on what might be going on or how to troubleshoot this?

Can you share the specific camera module SKU or product link? There are a lot of modules that use the UC-512 board, so that’ll help narrow things down. Also, can you post the exact code or command you’re using for the preview?

In the meantime, could you run our bug report tool so we can collect some diagnostics? With the UC 512 RevD1 connected:

  1. Reboot the Pi.
  2. Run:

wget -O arducam-camera-bug-report https://github.com/ketai-dhr/arducam-camera-bug-report/releases/download/tools/arducam-camera-bug-report
chmod +x ./arducam-camera-bug-report
./arducam-camera-bug-report

That should produce an arducam-bug-report.txt in the current directory. You can attach it here, or send it over via private message if that’s easier.

Thanks for the quick reply. I’m using SKU B0265R - the Arducam 12MP*2 Synchronized Stereo Camera Bundle Kit for Raspberry Pi (two 12.3MP IMX477 modules with CS lens and the Camarray Stereo Camera HAT).

When I tried to run the bug report tool it crashed:

./arducam-camera-bug-report
Traceback (most recent call last):
File “./arducam-camera-bug-report”, line 142, in
cmd_out = run_prog(args.c, args.t)
File “./arducam-camera-bug-report”, line 55, in run_prog
stderr=subprocess.STDOUT, errors=‘ignore’)
File “/usr/lib/python3.7/subprocess.py”, line 775, in init
restore_signals, start_new_session)
File “/usr/lib/python3.7/subprocess.py”, line 1522, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: ‘libcamera-still’: ‘libcamera-still’

I also tried sudo apt install libcamera-still but apt reports there’s no package called libcamera-still. Has libcamera-still been renamed to rpicam?

Here’s the full Python code I’m running:

import arducam_mipicamera as arducam
import time
import os
import cv2
import numpy as np
import tkinter as tk
from tkinter import messagebox


def check_signal():
    # region Variables Declared
    global done_aligning
    done_aligning = False

    preview_name = "Preview Window"
    projector_name = "Projector Window"
    capture_base_path = '/home/pi/AllergyScannerPi/AllergySLS/Images/Intensity_Check/'
    alignment_img = cv2.imread('/home/pi/AllergyScannerPi/AllergySLS/alignment/alignment_targets.png')
    alignment_text = cv2.imread('/home/pi/AllergyScannerPi/AllergySLS/alignment/alignment_text.png')
    GrayImgDir = '/home/pi/AllergyScannerPi/AllergySLS/gray_codes'

    # endregion Variables Declared

    def start_camera():
        global camera
        camera = 0
        camera = arducam.mipi_camera()
        camera.init_camera()
        #fmt = camera.set_resolution(8112, 3040)
        #print("Current resolution is {}".format(fmt))
        try:
            print("Enable Auto Exposure...")
            #camera.software_auto_exposure(enable=True)
            print("Enable Auto White Balance...")
            #camera.software_auto_white_balance(enable=True)
        except Exception as e:
            print(e)
        time.sleep(5)

    def preview():
        camera.start_preview(fullscreen=False, window=(100, 100, 800, 500))

    def projector_window():
        # projector resolution
        projector_width = 1280
        projector_height = 720

        cv2.namedWindow(projector_name, cv2.WINDOW_NORMAL)
        cv2.setWindowProperty(projector_name, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_AUTOSIZE)
        cv2.resizeWindow(projector_name, projector_width, projector_height)
        cv2.moveWindow(projector_name, 1280, 0)

    def preview_window():
        cv2.namedWindow(preview_name, flags=cv2.WINDOW_GUI_NORMAL)
        cv2.resizeWindow(preview_name, 300, 300)
        cv2.moveWindow(preview_name, 900, 200)
        cv2.setMouseCallback(preview_name, onMouse)

    def get_gray_img():  # Create our list of stripes to be projected
        # print('create_gray_list start')
        gray_img = GrayImgDir + "/" + "441.png"
        return gray_img

    def alignment():
        start_camera()
        projector_window()
        preview_window()
        preview()
        # show_alignment()
        camera.stop_preview()
        cv2.destroyAllWindows()

    def project(gray_img):
        # region load stripes into projector
        img = cv2.imread(gray_img, 0)  # read as grayscale
        cv2.imshow(projector_name, img)
        cv2.waitKey(1)
        # endregion load stripes into projector

    def capture():
        # print('project_and_capture start')
        #preview()  # display in preview window on Pi
        #projector_window()
        ###
        filenameCamera = capture_base_path + "/" + 'Signal_Check.jpg'
        save_capture(filenameCamera)  # capture and write image

    def save_capture(filenameCamera):
        frame = camera.capture(encoding='jpeg')
        frame.as_array.tofile(filenameCamera)
        del frame  # originally in terminate_camera

    def terminate_camera():
        global camera
        camera.close_camera()
        print("Close camera...")
        cv2.destroyAllWindows()

    def show_alignment():
        global done_aligning
        while (True):
            cv2.imshow(projector_name, alignment_img)  # Display the preview and alignment images in their frames
            cv2.imshow(preview_name, alignment_text)  # clickable text to end alignment process with dialog
            cv2.waitKey(1) & 0xFF

            if done_aligning == True:
                root = tk.Tk()
                root.wm_withdraw()
                root.geometry("1x1+1+1")
                MsgBox = tk.messagebox.askyesnocancel('Alignment Process', 'Is the alignment complete?', icon='question')
                if MsgBox == True:
                    done_aligning = True
                    root.destroy()
                    return
                elif MsgBox == False:
                    done_aligning = False
                    root.destroy()
                else:
                    exit()

    def onMouse(event, x, y, flags, param):
        global done_aligning
        if event == cv2.EVENT_LBUTTONDOWN:
            done_aligning = True

    def closing_dialog():
        root = tk.Tk()
        root.wm_withdraw()
        root.geometry("1x1+200+200")
        closing_message = 'The scanning process is complete, saved in Signal_Intensity'
        MsgBox = tk.messagebox.showinfo('Complete', closing_message, icon='question')
        print(MsgBox)
        if MsgBox == 'ok':
            root.destroy()
            exit()
        else:
            exit()

    def split_imgs(imagePath):
        # read image
        image = cv2.imread(imagePath)
        height, width = image.shape[0:2]
        # print('height, width dual line 50 ', height, width)
        # Convert to grayscale
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        # split image
        croppedImageL = image[0:height, 0:int(width / 2)]  # this line crops
        croppedImageR = image[0:height, int(width / 2):width]  # this line crops
        print('Signals Seperated Successfully')
        return croppedImageL, croppedImageR

    # Call
    start_camera()
    preview()
    projector_window()
    gray_img = get_gray_img()  # get structured light pattern
    project(gray_img)
    imagePath = '/home/pi/AllergyScannerPi/AllergySLS/Images/Intensity_Check/Signal_Check.jpg'

    while True:
        capture()  # display stripes, capture images
        imgL, imgR = split_imgs(imagePath)
        imgL_mean = imgL.mean()
        imgR_mean = imgR.mean()
        print("The average of the Left sensor is " + str(imgL_mean),
              "The average of the Right sensor is " + str(imgR_mean))

        key = cv2.waitKey(1)
        # ASCII Decimal codes: 27 is the esc key, 113 is the letter 'q', 10 is the Enter key
        if key == 27 or key == 113 or key == 10:
            break
        time.sleep(0.2)  # Rerun 5 times per second
    #camera.stop_preview()
    cv2.destroyAllWindows()
    terminate_camera()


check_signal()

Could you attach the bug-report.txt? It should be sitting in /home/pi.

From the error you’re seeing, your environment doesn’t appear to have a working libcamera install - libcamera-still not being found is the giveaway. Let’s get the libcamera packages installed using the Pivariety script:

wget -O install_pivariety_pkgs.sh https://github.com/ArduCAM/Arducam-Pivariety-V4L2-Driver/releases/download/install_script/install_pivariety_pkgs.sh
chmod +x install_pivariety_pkgs.sh
./install_pivariety_pkgs.sh -p libcamera_dev
./install_pivariety_pkgs.sh -p libcamera_apps

For native cameras, both libcamera-still and rpicam-still are fine to use right now, but the bug report tool is looking for libcamera-still specifically, so we want that binary present first.

Okay, the bug-report.txt is empty, so there’s nothing to attach.

I ran the install script and it errored, then the bug report tool still fails the same way:

===================>] 2.07K --.-KB/s in 0s
2024-01-26 11:51:52 (4.75 MB/s) - ‘libcamera_apps_links.txt’ saved [2115/2115]

./install_pivariety_pkgs.sh: line 543: [: too many arguments
pi@AllergyScanner:~ $ ./arducam-camera-bug-report
Traceback (most recent call last):
File “./arducam-camera-bug-report”, line 142, in
cmd_out = run_prog(args.c, args.t)
File “./arducam-camera-bug-report”, line 55, in run_prog
stderr=subprocess.STDOUT, errors=‘ignore’)
File “/usr/lib/python3.7/subprocess.py”, line 775, in init
restore_signals, start_new_session)
File “/usr/lib/python3.7/subprocess.py”, line 1522, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: ‘libcamera-still’: ‘libcamera-still’
pi@AllergyScanner:~ $

Can you run this and paste the output?

dpkg -l | grep libcamera

That’ll show us exactly which libcamera packages are installed and what state they’re in. Based on that I can tell whether the install actually completed, or whether the too many arguments error at line 543 stopped things before libcamera-still got installed.