Any CS-mount camera deserves autofocus!

windowI have been working on open-sourced motorized zoom lens for a while. Probably there is no need to mention benefits of having motorized zoom/focus lens on a regular CS type camera. Even greater value comes by having auto-focus capability. This feature is being calculated on host computer and does not consume lot of resources. Many other features can be added to suit particular needs (like automated object fitting into frame, barcode scanning, etc.).

I have also been interested in computer vision algorithms and frameworks for a quite a long time. Naturally I have chosen OpenCV (which is kind of De Facto for most research applications).

As I later found out it is not so difficult to calculate useful analytical data by yourself. Contrast (or inverted blur) ratio can be found by calculating Laplacian transformation. Which is pretty fast to work in real-time.


For a while I could not decide which microcontroller to use, there are so many families to chose from. Benefits of attracting Arduino community made me taking the a risk and I chose Atmega328p. So motorized lens controller is based on popular Arduino platform. While redesigning to another base is not as hard as making project from scratch, probably I will stay with current design for a while.


Controller and motorized lens

While lens can be used with any CS or C-mount camera, I used Kurokesu C1 camera (another good option is reworked Logitech C920).


C1 camera and motorized lens mounted on tripod


At the beginning had intentions to use grbl but as I found out it was not quite suitable for this application. While being perfect for 3D printers, cheap laser engravers and small cnc Routers, it is difficult to make necessary adjustments (uses one port for all STEP pins, it is difficult to split. Due to PCB routing decisions I placed STEP1 and STEP2 on PORTB and PORTD. Uses GPIO pins to control motor direction, my controller has to send special SPI command to change direction. Also lot of functionality needed to be stripped and necessary to be added).

Full source code (Python and Arduino) of working code is located on Github. Feel free to use and modify according to your needs.

Current firmware version provides these features:

  • G-code like commands
  • Simultaneous movement of both axis
  • Possibility to stop motion at any time (M0 code)
  • Set current coordinate as (G92 X.. Y..)
  • Set timer register (in general motor speed)
  • Set coil power
  • Coil power is automatically lowered after motor is stopped moving
  • Real-time position (and some other parameters) reporting to host
  • Basic auto-focus functionality


Single package solution makes lens controller move, captures frames from USB camera and analyzes frames to detect best global focus. All tools under one hood.


Auto-focus demonstration

Notes and thoughts

  • Time to shift from focus 0 to focus infinity takes ~4 seconds. It might be boosted to ~3seconds by increasing stepping frequency and motor coil current.
  • It takes ~15seconds to fully focus from unknown state without any optimizations. This is dumb method of finding best focus. Normally there should be smarter adjustments without moving lens full range.
  • To speed up operation various additional components can be used:
    • Controller has ADC in pin located on unpopulated header it is possible to add infrared distance meter. Distance would be reported to software and it will be much faster to lock focus.
    • Laser pointer also can be used to triangulate distance to visible object. Drawback – there would be some lost frames due to visible red spot, but in photo mode this could be perfectly suitable.
  • Focusing algorithm can be written to measure if blur rate is getting increasing or decreasing. If going wrong direction seek focus would be reversed to save time.
  • Adding presets might be nice touch to demo program.
  • ROI (Region Of Interest) can be added to focus on  subject of interest.
  • Notes about lens:
    • Lens can focus from 0mm to infinity.
    • Focal length can be changed from 2.8mm to 12mm.
  • Try on Raspberry Pi headless mode. It should be enough of power to handle control and focus algorithms.

Comments ( 21 )

  1. Project XXX
    Have you had time to try it on a Raspberry Pi yet? Would really like to buy it if it work for it, and how about the software for it?
    • saulius
      Hi, what functionality do you need to be running on Raspberry Pi?
  2. roo
    I too am trying to get the lens working on a Raspi3 using Python. I have had success from my Ubuntu PC, however I am struggling to get it working on the Pi. Do you have any example Python code for basic manual zoom to get me out of the starting gate :-) Many thanks Roo (UK)
    • saulius
      Hi, you can use plain commands to serial port to control it from raspberry. For example [G0 X1000\n] or [G0 Y1000\n] for zoom and focus control. In general you can strip down on PC and then use this code on Raspberry.
  3. Roo
    I am just unsure which device it is?? It looks like /dev/TTYAMA0 but when I connect to that nothing happens?
  4. roo
    The problem is I am not sure which device it is? I tried /dev/ttyAMA0 but it doesn't work, either from a serial terminal (built-in to Rasbian) or from python. Both work ok on a PC using /dev/USB0. When you connect the board to your Pi which device does it show up as? I think I may be trying to conenct to the wrong thing.
    • saulius
      Serial port is /dev/ttyUSB0. Here is a simple command to check if controller is alive: [picocom -b 115200 /dev/ttyUSB0]. My Raspberry is running Raspbian GNU/Linux 8 (jessie)
  5. roo
    Thank you. I now have it connected - as you say /dev/ttyUSB0 Not sure why it didn't come up the first time. Anyhow I think there is more wrong.... I reconnected to my PC (Ubuntu) and now, although I can connect a terminal, I am not getting anything from the port....nor is the lens responding to the commands. I am going to try it on another PC to make certain, but not sure it may be a bit poorly?! Is this the best place to talk to you about this? or do you prefer PM?
    • saulius
      We can keep discussion here. Unless it get's too long. Let me know if it is still alive (should be printing status report constantly on the serial port)
  6. roo
    Yes, it used to fine, but since trying to get it working on the Pi that has now stopped. Can running the board without the lens connected damage the board? The USB chip is certainly communicating it's ID when I use lsusb, so I assume this is ok.
  7. saulius
    I'd try connecting to another computer and running original software to confirm. If it fails, there is a chance that board needs to be re-flashed. Uploaded firmware here: Can be flashed with [avrdude.exe -p m328p -P COM86 -c arduino -b 57600 -F -u -U flash:w:firmware.hex]. Running controller with lens detached will not damage it. There is one more thing to confirm - when you run original demo software and set different position is position being updated and numbers are changing?
  8. roo
    I am using just a terminal-serial program on a windows PC and on an Ubuntu PC. Both have worked with the board before. As you say you see a stream of position data on the RX (normally). Now I see nothing. When I type G0 X1000\r nothing happens.... I tried to upload the firmware using avrdude but all I get is: C:\RUPERT\REMAP\VIDSEE>avrdude.exe -p m328p -P COM9 -c arduino -b 57600 -F -u - U flash:w:firmware.hex avrdude.exe: stk500_recv(): programmer is not responding avrdude.exe: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00 I think it may be dead?!
    • saulius
      Can you send it back for RMA? Will write you an PM email soon.
  9. Bogi
    Hi. So good idea! Any progress with your project? I'd love to have the ability of zooming RB Pi camera with old still camera optical lens attched to it!
    • saulius
      Hi Bogi, unfortunately stacking lenses is not an option. And to be honest RPI camera as it is not quite suitable for additional lenses as it is attached with double sided tape to PCB. Also it has CRI compensation adapted for cr*ppy lens in firmware so by mounting any other lens gives you weird results.
  10. Bogi
    Thank you for reply. I've read this: And now i understand what you are talking about color corrections. I have rb pi 2 with c and some old minolta dimage on hand so i'll try to get rid of stock rb cam lens and put on minolta one as i'm so curious about the result:) apart from colors correction is your software able to control stepper (or different motor) that is responsible for focusing based on captured or streamed image analyses? The second thing is zooming but i think this can be made using free radio channel and some arduino. What i plan to do is radio (like from RC wolrd) controlled gimbal with zooming capability and auto focus on RC plane. Am i looking at too high mountain?;)
    • saulius
      If you are good at Arduino programming, sure your desired functionality can be achieved
  11. nntona
    I played a lot to get my 2.8/12mm lens to work. It is just focusing on 1m and lower, I can't achieve more. The process of calibration is not clear. I am trying to follow the zero button instruction where you said: Use thic button to calibrate lens. 1. Move dials to maximal position 2. Click "0" button. (It will make controller think it is in 0 position) 3. Move dials to maximal position again. (Lens will try to go beyond limits) 4. Your lens is calibrated. Can you please clarify this, please? Or if it is possible upload an instruction video or more detailed post.
    • saulius
      These lenses do not have "home" sensor, thus relies on initial calibration. Idea is to drive lens to it's max position until it reaches mechanical limits and set it as max position.
  12. Andrew
    Hi! Will it appear in stock any soon?
    • saulius
      Hi Andrew. ON Semi deprecated main driver chipset and new board is in heavy development now. New controller with lenses

Leave a reply

Your email address will not be published.