Arducam Motorized Focus Camera Control

Despite the company name name, the Arducam 5 MP Motorized Focus camera plugs into a Raspberry Pi’s camera connector and lives on a PCB the same size as ordinary RPi cameras:

Arducam Motorized Focus RPi Camera - test overview
Arducam Motorized Focus RPi Camera – test overview

That’s a focus test setup to get some idea of how the control values match up against actual distances.

It powers up focused at infinity (or maybe a bit beyond):

Arducam Motorized Focus RPi Camera - default focus
Arducam Motorized Focus RPi Camera – default focus

In practice, it’s a usable, if a bit soft, at any distance beyond a couple of meters.

The closest focus is around 40 mm, depending on where you set the ruler’s zero point:

Arducam Motorized Focus RPi Camera - near focus
Arducam Motorized Focus RPi Camera – near focus

That’s the back side of the RPi V1 camera PCB most recently seen atop the mystery microscope objective illuminator.

Pondering the sample code shows the camera focus setting involves writing two bytes to an I²C address through the video controller’s I²C bus. Enable that bus with a line in /boot/config.txt:

dtparam=i2c_vc=on

If you’re planning to capture 1280×720 or larger still images, reserve enough memory in the GPU:

gpu_mem=512

I don’t know how to determine the correct value.

And, if user pi isn’t in group i2c, make it so, then reboot.

The camera must be running before you can focus it, so run raspivid and watch the picture. I think you must do that in order to focus a (higher-res) still picture, perhaps starting a video preroll (not that kind) in a different thread while you fire off a (predetermined?) focus value, allow time for the lens to settle, then acquire a still picture with the video still running.

The focus value is number between 0 and 1023, in two bytes divided, written in big-endian order to address 0x0c on bus 0:

i2cset -y 0 0x0c 0x3f 0xff

You can, of course, use decimal numbers:

i2cset -y 0 0x0c 63 255

I think hex values are easier to tweak by hand.

Some tinkering gives this rough correlation:

Focus value (hex)Focus distance (mm)
3FFF45 (-ish)
300055
200095
1000530
0800850
Arducam Motorized Focus Camera – numeric value vs mm

Beyond a meter, the somewhat gritty camera resolution gets in the way of precise focusing, particularly in low indoor lighting.

A successful write produces a return code of 0. Sometimes the write will inexplicably fail with an Error: Write failed message, a return code of 1, and no focus change, so it’s Good Practice to retry until it works.

This obviously calls for a knob and a persistent value!