Gerroa by Ian Mills


One of the nicest features of CHDK is its ability to add motion detection to a Canon "Point & Shoot" camera. This functionality is provided through special scripting commands which enable flexible implementation of many clever motion detection programs. Two particularly popular uses of motion detection include lightning and fireworks photography.

Scripting Functions[]


To use the CHDK motion detection functions, a suitable script has to be loaded on the camera. Two simple scripts written in uBASIC and LUA are posted below and links to more complicated scripts can be found at the end of this page. A little searching of the CHDK wikia and forum will turn up many other useful scripts. Information about loading and running scripts can be found here: Scripts

Note: The uBASIC and LUA motion detection commands each take as many as 16 input parameters. For convenience, these are usually represented as the sequential variables a to p so that convention will be used here.

Key Concepts[]

CHDK motion detection scripting commands is based on the following concepts :

Zones : The camera field of view is broken into a grid of zones. These zones are used to control how motion is detected. Parameters a & b define the zone setup.
Exclusion Zone: The motion detection zones defined above can be set up so that part of the field of view is ignored. This is useful when there may be motion in parts of your field of view that you do not want to cause a photograph to be taken. There is a good description of how to use exclusion zones posted on this Forum thread. Parameters i,j,k,l & m define the exclusion zone.
Detection Modes: CHDK can be configured to trigger on different parts of the image. Motion can be detected based on changes of luminance (Y), blue/green chrominance (U), yellow/red chrominance (V) or individual R, G or B values. Parameter c determines which parts will be used to decide that motion has been detected.
Sensitivity: Sensitivity settings determine how much of a change in the camera's image will be detected as motion. There is a threshold adjustment (parameter f) and a pixel step adjustment (parameter o).
Other: several other parameters are available to tune how the motion detection function works. The following parameters can be set: How long the function waits for motion to occur, how long the function waits before attempting to detect motion, how often the function checks for motion and how many actual pixels are tested each time the function tests for motion.

Function : md_detect_motion[]

The md_detect_motion command carries the main brunt of setting all feature parameters for motion detection. Both the Lua and uBASIC scripting functions in CHDK support this command although there are subtle differences in the implementation.


md_detect_motion a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p


zones = md_detect_motion( a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)

Note : Parameters i through p are optional. However, an optional parameter can only be specified if all the parameters before it in the function call are also specified. Also, the returned value in Lua (zones) is the same as the "h" parameter in the uBASIC function (see below).

a: the number of columns to split the screen into.

b: the number of rows to split the screen into.

Note: If a or b are less than 1, they are set to 3.  If total number of cells is greater than 1024, a and b are reduced as necessary.

c: pixel_measure_mode - YUV model: 0 for U, 1 for Y, 2 for V; RGB model: 3 for R, 4 for G, 5 for B. You may detect motion based on changes of luminance (Y), green/blue chrominance (U), yellow/red chrominance (V) or individual R, G or B chrominance values. For non-specialized use, luminance (c = 1) can be used.

d: time in milliseconds for which md_detect_motion will wait for motion to occur. This parameter is useful if some other ubasic commands need to be periodically executed after MD has run. If no motion detected, the script can continue to execute some other code and then if required can resume motion detection by calling md_detect_motion again. Practically, this timeout value (parameter d) has to be greater than the trigger delay (parameter p), or else the return variable (parameter h) will always equal 0.

e: measure_interval. The time delay in milliseconds in which to check for a change in a cell's values. If small changes made frequently by faster moving objects need to be filtered out (leaves in the wind, or flying insects, for example) this value would be increased so that timed samples are further apart. Very useful when trying to detect changes in very slow moving subjects, i.e. snails, slime-molds, a slow-moving criminal trying to avoid motion detection devices :-), etc.

f: threshold for the desired mode that will not result in triggering in normal operation. Higher equates to less sensitive. Typical values might be: 10=Lightning, 12=Sunshine, 24=Cloudy, 36=Dawn/Dusk

g: determines whether a grid showing cells is displayed on the camera's LCD display. Recent versions of CHDK (trunk 1.2.0 or later) will also show changes in the measure value of each grid - useful for tuning sensitivity.  (0=no, 1=grid, 2=sensitivity readout, 3=sensitivity readout & grid)

h: in uBASIC, the variable specified here will be used to hold the detected cells count passed back from the function. This variable is ignored in the LUA version of the function - the detected cell count is passed back as the return value of the function.

i: determines if the exclusion zone is inclusive or exclusive: 0=no regions, 1=include, 2=exclude

j: first column (counting from 1) of the exclusion zone

k: first row of the exclusion zone

l: last column that is part of the exclusion zone

m: last row that is part of the exclusion zone

n: miscellaneous flags - each bit has a different meaning.

  • bit 1 = immediate shoot on motion detection. Function issues a key PRESS_FULL on detection of motion for fastest possible response to motion. Assumes a key PRESS_HALF was issued prior to the md_detect_motion function being called.
  • bit 2 = log debug information into file (*see note below)
  • bit 4 = dump liveview image from RAM to a file (*see note below)
  • bit 8 = on immediate shoot, don't release key PRESS_FULL - useful when Canon continuous (or multiple shot) mode is enabled.
OR-ed values are accepted, e.g. use 9 for immediate shoot & don't release shutter.

* Note: use of bit 2 and bit 4 requires a custom CHDK version built with OPT_MD_DEBUG=1 in Support was removed from standard CHDK versions to save memory.

o: determines the fraction of pixels read. With o = 1, all pixels are read, o = 2, every second pixel, etc. The greatest accuracy of motion detection results when every pixel is sampled but a faster response suitable for some applications may be obtained with a larger pixel-step.

p: allows a delay of "p" milliseconds before the function starts looking for motion. Useful to allow any camera vibration to settle and maybe for the photographer to get out of the picture area.

Function : md_get_cell_diff[]

This function is designed for advanced analysis of scene changes or to implement more complicated exclusion zones. It is designed to be called immediately after an md_detect_motion has returned. It allows you to determine the actual level of change in any cell in the field of view.


x = md_get_cell_diff v w


x = md_get_cell_diff(v,w)

v : column of the cell to be checked ( 1st column = 1 )

w : row of the cell to be checked ( 1st row = 1 )

x : returned value equal to the luminance difference between two last two measurements in the selected cell  -  range of 0 to 255 representing the magnitude of the luminance change of the cell being checked.

Function : md_get_cell_val[]

This function is designed for advanced analysis of scene changes or to implement more complicated exclusion zones. It is designed to be called immediately after an md_detect_motion has returned. It allows you to determine the actual brightness level in any cell in the field of view for the Y,U,V, R, G, or B setting specified.


x= md_get_cell_val v w


x = md_get_cell_val(v,w)

v : column of the cell to be checked ( 1st column = 1 )

w : row of the cell to be checked ( 1st row = 1 )

x : returned value equal to the brightness level in the selected cell  -  range of 0 to 255 representing the brightness of the cell being checked.

Note : available only in CHDK release 1.2.0 or greater.

Function : md_af_on_time[]

This function is used during CHDK porting to test the response to motion using the camera's Auto Focus assist lamp to trigger the MD detection.


md_af_on_time d t



d : delay in 10mSec increments before AF lamp turns on

t : time in 10mSec increments that AF lamp remains illuminated

Use md_af_on_time(0,0) to disable the MD AF lamp test mode

Note : available only in CHDK release 1.2.0 or greater.   In the absence of better documentation, the forum thread where this was discussed is here :  Re: Motion Detection - time for a second look ?

Performance Tuning (Sensitivity)[]

The CHDK md_detect_motion() function allow for the setting of sixteen different parameters.   While this level of detailed control gives the function great flexability,  it can also make it difficult to use.  To that end,  there are some simpler things to keep in mind when adjusting those parameters for sensitivity.

Parameter Comment
Rows & Columns (a,b) Increasing rows & columns increases sensitivity to small changes.
Measure Mode (c) Use Y mode (1) for broadest coverage. The other modes (U,V,R,G,B) will seldom be too useful with normal scenes.
Timeout(d) No effect on sensitivity
Measure Interval (e) Shorter values will tend to ignore slow moving changes. Longer values ignore / miss some fast short changes.
Threshold Value (f) The most imporant sensitivity parameter. Small values will cause triggering on small changes, larger values require bigger changes. Use small values for low contrast situations like dim lighting,  large values for bright scenes.
Grid (g)  No effect on sensitivity.  NOTE : setting this to 2 or 3 is very useful for observing the actual readings in each cell and then tuning the f parameter
Variable (h) No effect of sensitivity  (and actually obsolete)
Zone (i,J,k,l.m) Useful for excluding sections of the image where you wish to ignore movement.
Misc (n) No effect on sensitivity
Pixel Step (o) Smaller values increase sensitivity somewhat. Larger values decrease processing times but does not really have a significant effect.
Delay (p) The second most important sensitivity parameter.  Used to allow the display to settle when the md_detect_motion() function is called as the Canon firmware tends to change the display brightness right after the function is first entered.

Note : n=2 (debug mode): The debug feature has been removed from standard CHDK builds to save RAM. To use it, a custom CHDK version must now be built (OPT_MD_DEBUG=1 in will enable motion detector debug).

Speed Testing[]


CHDK version 1.2.0 now contains built-in MD speed testing.  The MD_TUNE.BAS script in the SCRIPT/TEST directory combined with some CHDK enhancements allow convenient and accurate speed testing using the camera's focus assist lamp as the trigger.  See this forum thread for details : [Motion Detection MD_TEST.BAS

There has been much discussion on the proper ways to use the sometimes-confusing and highly adaptable user-configurable features of CHDK motion detection. Lengthy discussions on the CHDK Forum on how to get the fastest reaction times for lightning photography have shed some light on the subject (pun not intended). For further clarification on the best ways to implement some of the timing controls, see the "Motion Detection Too Slow?" forum discussion thread. There are scripts optimized to obtain the fastest detection speed possible by using 2 different methods (both available in the same script).

You can find software to allow testing the speed of motion detection on your camera here : Motion Detection Speed Tests

Note also that the MD routine has been reworked for some cameras so the internal "immediate shoot" option is now lightning-fast (literally). Actual speed of response is a function of the buffer arrangement in your camera and the skill of the person who made the camera port. Futher enhancements are always possible.

Sample Scripts[]


@title Motion Detect uBASIC Script



  md_detect_motion a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p

  if( h > 0 ) then

until (0)



@title Motion Detect Lua Script

a=6         -- columns to split picture into 
b=6         -- rows to split picture into 
c=1         -- measure mode (Y,U,V R,G,B) <96> U=0, Y=1, V=2, R=3, G=4, B=5
d=300000    -- timeout (mSec) 
e=200       -- comparison interval (msec) 
f=5         -- threshold (difference in cell to trigger detection)
g=1         -- draw grid (0=no, 1=yes)   
h=0         -- not used in LUA 
i=0         -- region masking mode: 0=no regions, 1=include, 2=exclude
j=0         --      first column
k=0         --      first row
l=0         --      last column
m=0         --      last row
n=0         -- optional parameters  (1=shoot immediate)
o=2         -- pixel step
p=500       -- triggering delay (msec) 


   zones = md_detect_motion( a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)

   if( zones > 0 ) then

until (false)


Wikia Pages[]


Sample Videos and Photos[]

Forum Threads[]