Getting an ArduCam IMX519 16MP Autofocus working with Motion

Having had a bit of a fun ride getting an ArduCam IMX519 16MP Autofocus camera working with Motion (link) on a Raspberry Pi 3B+, I thought I’d share what I did and a couple of discoveries:

I installed the latest version of Raspberry Pi OS (Bullseye Lite 32 bit - Debian 11.6) via the Raspberry Pi Imager tool. As the Pi I’m using is run headless, I also set up ssh etc. prior to writing the SD card image.
The kernel version on my Pi 3B+ is: 5.15.84-v7+ #1613 SMP Thu Jan 5 11:59:48 GMT 2023 armv7l GNU/Linux

I installed Motion 4.5.1-1 (latest revision at time of posting):

Install dependencies (I’m not sure this is necessary):
sudo apt install autoconf automake autopoint build-essential pkgconf libtool libzip-dev libjpeg-dev git libavformat-dev libavcodec-dev libavutil-dev libswscale-dev libavdevice-dev libwebp-dev gettext libmicrohttpd-dev

Download the software:

Install the installer:
sudo apt install gdebi-core

Install Motion:
sudo gdebi bullseye_motion_4.5.1-1_armhf.deb

Installing software for ArduCam IMX519: (see: Quick Start - Arducam Wiki)
(these steps are all as listed in the Quick Start Guide)

Add the following to /boot/config.txt:


Get the software:

wget -O
chmod +x
./ -p libcamera_dev
./ -p libcamera_apps


Run raspi-config to enable Glamour and select the GL driver:

  • sudo raspi-config

  • Advanced Options

  • Enable Glamor graphic acceleration

  • Reboot

  • sudo raspi-config

  • Advanced Options

  • Navigate to GL Driver

  • Select GL (Full KMS)

  • Reboot

Install the camera driver:
./ -p imx519_kernel_driver_low_speed


Edit /etc/motion/motion.conf:

The motion software runs the camera as a /dev/video0 device, so there are no MMAL settings needed. The only ‘funny’ is the default motion ‘input’ parameter needs changing from ‘-1’ to ‘0’ for the video streaming to work. This is done via the ‘video_params’ setting (ie)

video_params palette=17,input=0

I started with the following width/height settings. Unfortunately, this seems to max out the Pi 3B (load average 1.6), so I used the PiCamera V2 settings instead, which brought the load average down to 0.55. This needs further investigation as of course it means I can’t use the camera’s full resolution.

width 3840; height 2160 changed to: width 1640; height 1232

Motion is then run with the following command:

sudo libcamerify motion -n &

Getting autofocus to work was interesting.

Firstly, I had to install pip for ‘’ to work.
sudo apt install python3-pip

Then I downloaded the focus software:
git clone

To run the software, change directory:
cd Arducam-Pivariety-V4L2-Driver/focus

If you run the software using the ArduCam instructions, the Python script fails with a ‘no autofocus’ message:
python3 -d /dev/v4l-subdev0

I then went down a rabbit hole following this posting (how-is-it-possible-to-get-autofocus-working-along-with-picamera2-for-imx519) which led me to attempt to remove python3-libcamera. In retrospect, this may not have been necessary as it doesn’t appear to have been installed anyway.
This didn’t fix the issue, so investigating further I found:
v4l2-ctl -l -d /dev/v4l-subdev0
doesn’t show autofocus but
v4l2-ctl -l -d /dev/v4l-subdev1

So I ran python3 -d /dev/v4l-subdev1 instead and manual focus now works.

I hope the above is useful to someone. Observations/comments welcome!

Many thanks to you, bro!
@Edward Come here to learn from the OP about specialties and carefulness.

I ought to point out the reason I run libcamerify motion as root is because scripts I run when movies start and end require root privileges. Under most circumstances, ‘libcamerify motion -n &’ would be fine, or you can edit the service file which gets installed as part of the motion package (ie)

sudo nano /lib/systemd/system/motion.service
change the ExecStart line to ExecStart=/usr/bin/libcamerify motion
Save and close.
Follow with:

sudo systemctl daemon-reload
sudo systemctrl start motion.service

Investigating this further shows I can increase the resolution up to the 3840x2160 and keep the processor load below 100% by reducing the frames captured per second parameter to 1 (from 10). This isn’t ideal but is probably adequate for my purposes. It’s also possible I may have an unintended format conversion going on in motion which is adding to the load but I’m parking this for the moment.