APM to CHDK Camera Link Tutorial

[Edit 12/31/2015: Note for Pixhawk users that Canon cameras require a 5V pulse to trigger so a voltage step-up from Pixhawk's 3.3V output is required. See compatible cable and link to more instructions here.]

ArduPilot Camera Tie-In Tutorial

This tutorial will show you how to get your CHDK-enabled camera connected to your ArduPilot Mega (APM) without buying any extra hardware or decoding PWM outputs. You might want to make this connection to take advantage of the camera trigger function based on distance covered, to ensure a certain overlap and to avoid excessively high overlap. This modification is not necessary, if you have a CHDK camera and want to keep it simple, you won’t gain much by switching to this method right away.

For this tutorial, I’ll use an SX260 HS but this should work equally well on any CHDK-supported Canon Powershot camera. You’ll need just the supplies below to make the cable. The SX260 uses a USB Mini-B connector. Most Powershot cameras come with a USB cable, you can just use that one to be safe.

APM CHDK Connection

If you don’t have a crimp tool to attach the servo connector, just take a spare servo wire and solder the wires together instead.

We’ll only be using the Mini-B side of this cable, so measure whatever length you need from that end depending on how your camera and autopilot mount in your airframe. I’ve measured out about 14″ and cut the cable completely through. Inside are four wires, we only need the red and black wire so cut away the green and white wires. Strip the ends of the red and black wires.


If you have the crimp tool, crimp and insert the wires into the first and third positions of a 3-position header. If you don’t have the crimp tool, solder these two wires to the ground and signal wires of a spare servo wire. Insert the ground wire into the side with an arrow so you can tell which wire is which later on.


Cover the connector with heatshrink. Be careful with the hot air near the connector as it can cause the locking plastic pieces in the receptacle to deform.

CHDK Cable

Now plug this cable into pin A9 on the side row of APM. The text doesn’t line up exactly so be sure to count rows. SPI takes two rows, then A11 and A10 are two more so there should be 4 rows of free pins, then our new connector.

APM Relay Pin A9

If you already have CHDK installed, just install the script file (right click, save link as) into the scripts directory on your SD card. If not, follow instructions for installing CHDK from the page corresponding to your camera atthe CHDK wiki. Load up CHDK and go into the menu then navigate to Miscellaneous Stuff -> Remote Parameters and make sure the Enable Remote setting is checked.


Now connect to your APM and open the Full Parameters List in the Config/Tuning tab. Set the parameters as following:

  • CAM_TRIGG_DIST: Depending on overlap required.. be sure to keep in mind the normal downwind speed of your plane as well as the maximum rate at which the camera can take pictures. For the SX260 and the E382 that’s once every 2.7 seconds and about 18m/s. I plan to operate below those condition in most cases but I do like to get as many pictures as possible, so I set my distance to 49 (meters).
  • RELAY_PIN: 13



All that’s left is to test it out. Load the E38_APM.bas script file like any normal CHDK script and start running it. If you can get a 3d fix inside, you can test it on your lab bench just using USB power. Just set the CAM_TRIGG_DIST to 1 or 2 meters and let your plane sit on the desk. Small movements between GPS readings will cause the distance value to count up slowly and it should trigger the shutter every few seconds.

If your camera lens closes and opens instead of taking a picture, make sure the CHDK remote enable setting saved properly. If nothing happens at all, take your APM outside and walk around to make sure you are getting some distance covered.

Original Post

E-mail me when people leave their comments –

You need to be a member of diydrones to add comments!

Join diydrones


  • It is working fine for me. I would read through the instructions again and make sure you have everything setup as described. I use the script E38_APM.bas provided by the link.

  • Also if I want it triggering just from the mission waypoints should I have cam trigger distance set to 0 in the parameters or manually set the distance every new mission?

    Thanks for the write up by the way really helped me get this going, very pleased with it so far.

  • Hi I got this working on apm 2.6 but when I plug it in and power it the plane it just starts taking photos regardless of what I have cam trigger distance set to.

    Any ideas anyone?


  • Hi,

    i am trying to get this to work - without success. 

    I am able to trigger the camera via cable + 5v.

    I set up everything according to the great tutorial, but it will just not trigger...

    i am using an APM 2.6, with arducopter 3.2.1 Firmware.

    Is there any logging why the copter will not trigger? 

    Thanks a lot,

  • Hi all, the method is great, tried and working fine as described.

    But.... i wa not able to fined any trace of relay status in the logs, I have tried to play back the mission from log and realized that the relay is not traced....any hints? I need to have it traced in order to extract the correct coordinates, imu etc...

    Your suggestion please.



  • Attached is the script which works for me (can shoot every second). Hope that helps other facing the same issue.

    @title E38_fast
    @default picture0 = 0
    print "Script Started, Listening"
    sleep 1000
    press "shoot_full"
    sleep 50
    release "shoot_full"
    sleep 2000

    press "shoot_half"
    sleep 2000

    goto "interval"

    p = get_usb_power
    if p > 0 then goto "picture_n"
    goto "interval"

    if picture0 = 0 then goto "picture_0"
    if picture0 = 1 then goto "picture_n"
    goto "picture_n"

    press "shoot_half"
    sleep 2000
    @default picture0 = 1
    goto "interval"

    press "shoot_full_only"
    sleep 50
    release "shoot_full_only"
    goto "interval"

    print "Shut-Down Command Received"
    sleep 1000
    release "shoot_half"
    sleep 1000

  • Your comment is much appreciated. It tells me this is quite tricky, and I am afraid to sidetrack. It is indeed somewhat in contradiction with reyalp's post in the chdk forum I linked just above (SD card speed doesn't matter). I tested the intervallometer script with the shoot_full_only command (as opposed to the shoot command), and the shooting rate dropped from roughly 4.3 seconds to 1.1 seconds. That is good enough for me because I want to take a picture every 2 seconds (my CAM_TRIGG_DIST is 30 meters and my X5 flies at about 14 m/s).

  • Hi

    My tests on an SX260 showed, that the biggest performance impact came from my SD card. Once I switched to a 30 or 40MB/s SD card, I could shave off about 1 sec on the interval. What the exact transfer rate on the SD Card bus is probably depends on the camera, but on the SX260 it is above 20MB/s.

    Then I have looked into the script's performance. The uBASIC interpreter is really slow. Even REM statements take up a significant amount of time (I think it was up to 1/10 sec on that camera, it's a long time ago, I don't remember exactly). The best option is to switch to LUA which is really recommended by the CHDK guys if you want your script to performa better. The startup time of LUA is slower but once it runs it is significantly faster than uBASIC. So if you start your script once, the LUA is the way to go. If you keep calling scripts, the uBASIC might be faster depending on your implementation.

    Just my 2 cents


  • My cannon camera (A2200 and SX120) are not fast enough to get me one shoot every 2 seconds. That's what I am aiming for because my X5 likes to fly at 15m/s and I would like to take a picture every 30m. I tried every 50, but pictures don't overlap, stiching don't work. Too bad.

    Google led me to this chdk trick to get chdk shooting as fast as continuous mode : about a picture every second.


    Did anyone play with such a script, or the shoot_full_only command ? Any pointer toward a robust script that I could use ?

  • Yep remote is enabled (via the CHDK menu), I'm definitely using A9 (four empty rows of pins to the side) and I've got GPS lock with movement much greater than my current CAM_TRIGG_DIST parameter (I've tried several different settings of this, but non will trigger).

This reply was deleted.