Raspberry Pi Camera Autofocus: The Complete Guide (V1, V2, HQ)
This article explains everything you need to know about the Raspberry Pi camera autofocus.
It applies to all Raspberry Pi Models, and all Raspberry Pi camera modules: V1.3, V2.1, HQ, and V3.
Luckily, you are in the right place. Arducam has the most extensive solution to autofocus on Pi cameras.
So let’s dive right in and clarify this issue once and for all..
- Prerequisites for autofocus
- Do the official Raspberry Pi cameras meet all autofocus prerequisites?
- How does Arducam meet the Raspberry Pi Camera Autofocus prerequisites?
- How to enable the autofocus feature once we’re ready?
- Next Level: Raspberry Pi Camera Autofocus with PTZ (Pan-tilt-zoom) cameras
- Pivariety: Using Raspberry Pi’s Own ISP Tuning Algorithms with Autofocus Cameras
- Suggestions and Recommendations
- Pivariety autofocus camera module for Raspberry Pi
Prerequisites for autofocus
Here is the definition of autofocus from Wikipedia:
An autofocus (or AF) optical system uses a sensor, a control system, and a motor to focus on an automatically or manually selected point or area.Tweet
Easily, we get all the answers we need. Here are the 3 prerequisites for autofocus:
- Sensor
- Focus motor
- Control system

To focus is to move the lens. To autofocus is to automatically move the lens.
The focus motor is the “what” to move the lens, and the control system is the “how” to move the lens. When we focus manually, our hands function like the focus motor, and our brain functions like the control system.
Therefore, autofocus does not mean no focusing process is involved. It’s just that the focus motor and the control system take over the job for your hand and your brain.
Well, do the Raspberry Pi cameras meet these prerequisites?
Do the official Raspberry Pi cameras meet all autofocus prerequisites?
For now, only the Camera Module 3 series has autofocus.
Let’s go over the prerequisites list again and see how the official Raspberry Pi cameras match.
- Sensor – Yes. They have CMOS image sensors.
- Focus motor – The V1.3 is glued and fixed. The V2 and HQ need manual work. All V3 cameras come with autofocus lenses, so yes.
- Control system – Only the V3 series.

The first 3 official Raspberry Pi cameras are not designed with autofocus in mind, instead, they just meet the basic needs.
The idea of the basic needs goes like this: You can get a clear picture with manual focus. The focus motors and control system not only add to the complexity but also add to the cost. Not everyone needs that. No need to meet all autofocus prerequisites.
Does this mean the official Pi cameras can’t do autofocus?
Yes. The first 3 official Raspberry Pi camera modules (V1/V2/HQ) cannot do autofocus themselves, period.
Does this mean there is no hope for Pi cameras to do autofocus?
Absolutely not. Arducam has fixed the issue and made it possible.
How does Arducam meet the Raspberry Pi Camera Autofocus prerequisites?
The logic to fix the issues is simple:
For those Pi cameras that don’t have a focus motor and a control system, then we build variants that do.
Let’s break down the two unmet prerequisites one by one.
1. Add Focus motor to the Pi camera
First, it’s the focus motor.
Let’s consider the focus motor a part of the lens assembly.
In case you don’t know, there are two kinds of lens assembly in Raspberry Pi cameras:
- The V1 and V2 have sealed the lens assembly and the image sensor in one package, then connected to the camera PCB with a board-to-board (BTB) connector. This design is also known as Compact Camera Modules (CCM), and it’s the kind used in smartphones.
- The HQ camera has a dedicated lens mount. Instead of having the image sensor in one package as the lens assembly, the IMX477 image sensor of the HQ camera is on the camera PCB.
This leads us to two methods to design a Pi camera that support autofocus:
- We build a CCM with a focus motor inside, and then connect it to the Raspberry Pi Camera PCB.
- We build a special lens assembly with a focus motor and mount it above the image sensor onboard.
2. Add Control system (so the Pi can control the focus motor)
Second, it’s the control system. The Raspberry Pi should be able to control the focus motor.
Let’s consider how the Raspberry Pi is connected to the focus motor before we set up the connection:
- Raspberry Pi →
- → RPi MIPI CSI connector →
- → Camera Ribbon Cable →
- → Camera Module MIPI CSI Connector →
- → Camera Board →
- → Focus Motor.
From above, we know that the key physical connection is the MIPI CSI camera ribbon cable. If so, do we have anything on the MIPI CSI connection that can help us control the motor?
I2C bus. More specifically, the I2C for the VideoCore processor.
i2c_vc
Set to “on” to enable the i2c interface, usually reserved for the VideoCore processor (default “off”).

So, we use the i2c_vc to control the motor. What we need to do is to add the following line to the /boot/config.txt
.
dtparam=i2c_vc=on
Now that we’ve met the prerequisites, what else is needed?
How to enable the autofocus feature once we’re ready?
The last thing to do is to automate the focus process with a program.
Step 1: Software-controlled motorized focus
Let’s first get the motors moving.
With a simple python program, we can use the keyboard keys to move the focus motor.
If you are interested in how we’ve done that, here is the python code for software motorized focus control.
Software motorized focus Python code
import os
import time
import sys
import threading
import pygame,sys
from pygame.locals import *
from time import ctime, sleep
pygame.init()
screen=pygame.display.set_mode((320,240),0,32)
pygame.key.set_repeat(100)
def runFocus(func):
temp_val = 512
while True:
for event in pygame.event.get():
if event.type ==KEYDOWN:
print temp_val
if event.key == K_UP:
print 'UP'
if temp_val < 1000:
temp_val += 10
else:
temp_val = temp_val
value = (temp_val<<4) & 0x3ff0
dat1 = (value>>8)&0x3f
dat2 = value & 0xf0
os.system("i2cset -y 0 0x0c %d %d" % (dat1,dat2))
elif event.key==K_DOWN:
print 'DOWN'
if temp_val <12 :
temp_val = temp_val
else:
temp_val -= 10
value = (temp_val<<4) & 0x3ff0
dat1 = (value>>8)&0x3f
dat2 = value & 0xf0
os.system("i2cset -y 0 0x0c %d %d" % (dat1,dat2))
def runCamera():
cmd = "sudo raspistill -t 0"
os.system(cmd)
if __name__ == "__main__":
t1 = threading.Thread(target=runFocus,args=("t1",))
t1.setDaemon(True)
t1.start()
runCamera()
Now we get a camera module with a software-controlled focus motor. That’s already a big step forward. You won’t have to focus near the camera module with your bare hands. Instead, you can sit remotely and adjust the focus with software.
However, if we want to enable autofocus, we need the Raspberry Pi to decide whether the camera is in focus, and it should stop moving the focus motors. But how would the Pi know?
Step 2: Autofocus enabled by OpenCV
As the biggest open-source computer vision library, OpenCV can help us make the Pi smart enough to tell whether the camera is in focus – by contrast detection.
sudo apt-get install python-opencv
The intensity difference between adjacent pixels of the sensor naturally increases with correct image focus. Then the Pi can adjust the motor until the maximal contrast is detected.
Arducam provides an OpenCV-powered autofocus example in Python. Here is what the image looks like on Raspbian when it runs.
If you are interested in how we’ve done that, here is the python code for autofocus.
Autofocus.py
import cv2 #sudo apt-get install python-opencv
import numpy as py
import os
import time
import smbus
bus = smbus.SMBus(0)
try:
import picamera
from picamera.array import PiRGBArray
except:
sys.exit(0)
def focusing(val):
value = (val << 4) & 0x3ff0
data1 = (value >> 8) & 0x3f
data2 = value & 0xf0
# time.sleep(0.5)
print("focus value: {}".format(val))
# bus.write_byte_data(0x0c,data1,data2)
os.system("i2cset -y 0 0x0c %d %d" % (data1,data2))
def sobel(img):
img_gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
img_sobel = cv2.Sobel(img_gray,cv2.CV_16U,1,1)
return cv2.mean(img_sobel)[0]
def laplacian(img):
img_gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
img_sobel = cv2.Laplacian(img_gray,cv2.CV_16U)
return cv2.mean(img_sobel)[0]
def calculation(camera):
rawCapture = PiRGBArray(camera)
camera.capture(rawCapture,format="bgr", use_video_port=True)
image = rawCapture.array
rawCapture.truncate(0)
return laplacian(image)
if __name__ == "__main__":
#open camera
camera = picamera.PiCamera()
#camera.awb_gains=4
#camera.exposure_mode='off'
#camera.awb_mode='fluorescent'
#open camera preview
camera.start_preview()
#set camera resolution to 640x480(Small resolution for faster speeds.)
camera.resolution = (640, 480)
time.sleep(0.1)
print("Start focusing")
max_index = 10
max_value = 0.0
last_value = 0.0
dec_count = 0
focal_distance = 10
while True:
#Adjust focus
focusing(focal_distance)
#Take image and calculate image clarity
val = calculation(camera)
#Find the maximum image clarity
if val > max_value:
max_index = focal_distance
max_value = val
#If the image clarity starts to decrease
if val < last_value:
dec_count += 1
else:
dec_count = 0
#Image clarity is reduced by six consecutive frames
if dec_count > 6:
break
last_value = val
#Increase the focal distance
focal_distance += 15
if focal_distance > 1000:
break
#Adjust focus to the best
focusing(max_index)
time.sleep(1)
#set camera resolution to 2592x1944
camera.resolution = (1920,1080)
#save image to file.
camera.capture("test.jpg")
print("max index = %d,max value = %lf" % (max_index,max_value))
#while True:
# time.sleep(1)
camera.stop_preview()
camera.close()
Next Level: Raspberry Pi Camera Autofocus with PTZ (Pan-tilt-zoom) cameras
Now that we’ve understood the camera I2C can be used as a control signal to move the lens, we can take it even further.
If to focus is to move the lens, then to zoom is to move the elements inside the lens.
We want to control not only the lens but also the elements inside the lens: we can have an autofocus zoom lens. Together with pan and tilt servos, we build a PTZ camera for the Raspberry Pi with autofocus possibilities.
Pivariety: Using Raspberry Pi’s Own ISP Tuning Algorithms with Autofocus Cameras
The Pivariety Project brings Pi’s hardware ISP tuning and camera control algorithms to more camera modules.
With better support (AE, AWB, and AF), our autofocus cameras can not only focus faster but also can produce higher quality images/videos than those native camera modules.
Suggestions and Recommendations
That’s everything about how we’ve made autofocus possible on Raspberry Pi cameras. However, here are some of our suggestions:
- Autofocus is possible but don’t expect it to be as smooth or accurate as a smartphone camera. Arducam’s main goal is to prove the feasibility and offer you more possibilities. It’s OpenCV-based software focus, and it is incomparable to those fancy PD or laser autofocus.
- An Autofocus example is provided, but we would still recommend that you use the manual control in the software way. We provide another example that allows you to focus the camera in a more intuitive way – by tapping the keyboard arrow keys. It’s more accurate to help you focus on your region of interest (ROI).
- We’ve only tested our examples on Raspberry Pi OS (Raspbian), so not sure about the other operating systems. However, moof and jneilliii have provided an Octoprint plugin that allows you to control the focus motor, called ArduCamFocus.
That being said, here are V1,V2 and HQ Arducam camera modules that support autofocus features.
The 5MP V1 and 12MP HQ cameras are a full camera module, and that means you can directly plug its camera ribbon cable into the Raspberry Pi’s CSI slot. The 8MP V2 version is a drop-in CCM replacement, and you need to detach the one on your V2 camera PCB and then attach this one to it.
Standard autofocus camera module for Raspberry Pi
5MP OV5647 Cameras , Cameras for Raspberry Pi
Arducam 5MP OV5647 1080p Autofocus Camera Module for Raspberry Pi, Compatible with Pi 4/3B+/3
Buy Now- SEE CLOSER: Software-controllable moveable Lens. Shoot objects in millimeter level and in the distance on the same camera, remotely controlled without lens adjustment tool
- SEE SMARTER: You can adjust the focus freely by the Motorized lens and …
The white balance adjusts automatically (in contrast to the official V2, which has pinkish tint in many environments). There is focus control, but it requires some software (simple code that works over I2C). This is more convenient than mechanical control of the V2, which is not always possible to do if the camera is in a case.
And finally, it makes much more sense for the price.
8MP IMX219 Cameras , 8MP IMX219 for Jetson
Arducam IMX219 Auto Focus Camera Module, drop-in replacement for Raspberry Pi V2 and NVIDIA Jetson Nano Camera
Buy Now- Native to Raspberry Pi: You don’t need to install additional driver for the camera
- Programmable Autofocus: Software controll, focus closer. See Arducam Github for more details
- Control Precisely: You can use “UP” and “Down” on your keyboard to adjust the …
Sharpest focus I’ve seen out of my Raspi cameras to date
There was a little bit of work to setup the hardware and software, but nothing too challenging if you have done stuff with Raspberry Pis in the past.
12MP IMX477 Cameras , Cameras for Raspberry Pi
Arducam 12MP 477P Motorized Focus High Quality Camera for Raspberry Pi
Buy Now- Motorized Focus: Programmable autofocus, software to control
- Simpliy Control: Python- OpenCV sofrware, also support using “up” and “down” to adjust the focus
- Native to Raspberry Pi: No need to install additional driver, just make some configuration
- Check Jetson Nano version SKU: …
Pivariety autofocus camera module for Raspberry Pi
Cameras for Raspberry Pi , Pivariety Camera Modules
Arducam Pivariety 16MP IMX298 Color Camera Module for RPi 4B, 3B+, 3A+, CM3/CM4 and Jetson Nano/Xavier NX
Buy Now- High Resolution: 16MP Sony IMX298 Exmor RS™ color sensor, up to 4640×3472.
- ISP Support: Auto Exposure, Auto White Balance.
- Gstreamer support.
- Autofocus: Motor Driver. Programmable focus …
Cameras for Raspberry Pi , Pivariety Camera Modules
Arducam Pivariety 21MP IMX230 Color Camera Module for RPi 4B, 3B+, 3A+, CM3/CM4 and Jetson Nano/Xavier NX
Buy Now- High Resolution: 21MP Sony IMX230 Exmor RS™ color sensor, up to 5344×[email protected] fps.
- Gstreamer support.
- ISP Support: Auto Exposure, Auto White Balance.
- Autofocus: Motor …
PTZ(Pan-tilt-zoom) Pi camera module
5MP OV5647 Cameras , Cameras for Raspberry Pi
Arducam 5MP 1080p Pan Tilt Zoom PTZ Camera for Raspberry Pi 4/3B+/3
Buy Now- Real PTZ with servos for directional control and varifocal lens for optical zoom now comes to the Raspberry Pi
- Switchable IR Cut: Through software for your day/night vision
- Fully use CSI connector: Now that a single camera can be used to …
8MP IMX219 Cameras , 8MP IMX219 for Jetson
8MP Pan Tilt Zoom PTZ Camera for Raspberry Pi 4/3B+/3 and NVIDIA Jetson Nano/NX and NVIDIA Orin NX/AGX Orin
Buy Now- Real PTZ with servos for directional control and varifocal lens for optical zoom now comes to the Raspberry Pi and Jetson Nano / Xavier NX
- Switchable IR Cut: Through software to achieve your day/night vision
- Make full use of the CSI …
Arducam 16MP-AF & 64MP-AF
Well, that brings us to the end of this overview.
To conclude: The official Raspberry Pi camera modules do not support autofocus, but Arducam has made it possible to achieve autofocus by controlling a focus motor in our customized module via I2C.
Why do you need the camera module to do autofocus on Raspberry Pi?
Leave your comments below!
11 Comments
Paul · December 4, 2020 at 2:08 pm
Helpful overview, thank you.
Can you please provide a list of which products have autofocus capabilities?
Thanks
[email protected] · December 5, 2020 at 6:52 pm
The products listed at the end of this overview are the recommended camera modules to support I2C focus motor control and OpenCV autofocus python codes.
You can also see the full list of Arducams that come with a focus motor.
Lars · January 5, 2021 at 9:55 am
I received my motorized focus version of the V2 camera yesterday.
With this guide I succeeded to reproduce the motorized focus and autofocus.
I just have one doubt: Is there a way to fix the focus after exiting the python program? My V2 camera resets the focus as I quit the python program. It could be useful to have the focus fixed eternally.
Otherwise I’d have to call the raspistill/raspivid/raspiraw from within the python script, is this the intended use?
[email protected] · January 5, 2021 at 4:54 pm
With the motorized focus version, we cannot fix the focus unless you use a script to set the parameters of the motor before opening the camera, because it uses a VCM (Voice Coil Motor).
It’s actually the same used in your phone cameras: I guess we can’t fix the focus of the phone camera when we quit the camera app?
Here is a brief explanation of this issue:
The voice coil motor is not rotating the lens – it lifts the lens up and down when it’s powered on and when it’s powered off, it resets. So that’s to some extent an electrical fix. You can’t hold an electrical fix after disconnecting the circuit, instead, you set the same parameter to retain the same position each time before you shoot. To do that, modify the python code to let it set the motor parameters before calling the camera.
When we use a manual threaded lens, it’s a physical fix because the lens stays in the thread.
Our PTZ camera, on the other hand, uses a stepper motor instead of a voice coil motor, so it does not require extra scripts to fix the focus. The stepper motors work like your hands to spinning the lens, but you just don’t actually have to do that with your bare hands to stay in a certain “step”. However, the PTZ cameras using a stepper motor are bulky, slower, and more power-consuming than a voice coil, so there are trade-offs.
Lars · January 6, 2021 at 8:25 am
Thanks for your detailed reply!
From your explanation I deduce that the sound I hear when the focus resets is normal and I shouldn’t worry about it.
I ended up using a python script in order to trigger the entire recording process. Works fine.
In the process of doing so, I think that I discovered that the focus doesn’t reset if I use “i2cset” one last time after “camera.close()”. However, that is just a working hypothesis.
[email protected] · January 6, 2021 at 4:47 pm
Great to hear that! By the way, if you are willing to share your current working python script, I can actually add it to a section of this article so that everyone else looking for a similar solution can see it and benefit from your code(of course I will mention the script is to Lars’ credit!).
Amit · January 16, 2021 at 11:17 pm
Is there any camera model with autofocus & microscopic lens?
[email protected] · January 17, 2021 at 6:17 am
There should be some fancy ones with USB connectors on the market, but it could be difficult to bring both autofocus and microscopic lens to RPi MIPI camera.
Since the Raspberry Pi ecosystem is not technically a standalone industry yet, it’s been “borrowing” things from other industries for quick growth. The autofocus module and its voice coil motors mentioned in this article are borrowed from the mobile industry, where autofocus has been a must-have for a long time and the cost has been brought down to the minimum because of huge mass production.
The microscope is another story. It’s not easy to directly purchase components and borrow things from this field, and there’s not been a huge market demand for autofocus microscopic lens on RPi, so what you’ve mentioned would usually be resolved with customization instead of off-the-shelf solutions.
Mark Goldberg · January 23, 2021 at 10:12 am
For the IMX477 with motorized focus, is the M12 lens replaceable? I have the Low-Distortion M12 Lens Kit & other lenses.
[email protected] · January 26, 2021 at 6:22 pm
We don’t recommend replacing the M12 lens on the IMX477 with motorized focus. The default lens is selected as the optimal choice, and usually, there is extra evaluation and calibration work for another lens, so a customization request is recommended.
However, if you are a camera-savvy user and already have both this camera and M12 lenses on hand, and do not require technical support in fitting and calibration to mess with them, you can surely try it at your own risk.
abo · July 13, 2021 at 4:18 pm
Hello
I am thinking about buying the IMX477 camera and mounting it in a housing. Can you tell me if the front part of the camera (the lens?) must be movable or can be mounted on the housing? If not, how could I mount the camera in a mailbox, for example?