CHDK Wiki
No edit summary
(updated to use set_aflock() instead of manual focus button)
Line 2: Line 2:
   
 
:'''Written for/on:''' G9
 
:'''Written for/on:''' G9
:'''Also works on:''' should work on any, but see note about pre-focus
+
:'''Also works on:''' should work on any
 
:'''Required CHDK build:''' any
 
:'''Required CHDK build:''' any
   
Line 10: Line 10:
   
 
* During the inter-frame delays you can use the Display button (to turn it off to save power).
 
* During the inter-frame delays you can use the Display button (to turn it off to save power).
* The script can "pre-focus" then switch to manual-focus mode; this slightly speeds up shooting time, and avoids annoying focus changes during shooting. You need to have a manual focus button for this to work. On the G9 this is the "up" button, which is preset below. On the S3 and others there is a dedicated manual-focus button, see the comments in the script for what to change. If you don't have a manual-focus button then you can't use pre-focus. To enable pre-focus, set the "Focus" option to "Start" (1). To disable, set it to "Every" (0).
+
* The script can "pre-focus" then lock the focus; this slightly speeds up shooting time, and avoids annoying focus changes during shooting. If you interrupt the script before it exits normally, you'll need to turn the camera off and on to restore autofocus. (I'll try to fix this.) To enable pre-focus, set the "Focus" option to "Start" (1). To disable, set it to "Every" (0).
 
* The script can optionally turn the display off after a set number of frames, to save power; as above you can turn the screen on again temporarily to see progress, and the script will turn it off again. For example, setting "Display off frame" to 3, the camera will turn the display off after the third frame. (Possibly the fourth, depending on how many display modes it has to cycle through). Set "Display off frame" to 0 to disable turning off the display.
 
* The script can optionally turn the display off after a set number of frames, to save power; as above you can turn the screen on again temporarily to see progress, and the script will turn it off again. For example, setting "Display off frame" to 3, the camera will turn the display off after the third frame. (Possibly the fourth, depending on how many display modes it has to cycle through). Set "Display off frame" to 0 to disable turning off the display.
   
Line 18: Line 18:
 
--[[
 
--[[
 
Author: Fraser McCrossan
 
Author: Fraser McCrossan
Tested on G9, should work on most cameras. Pre-focus requires a manual-focus
+
Tested on G9, should work on most cameras.
button. You may need to change this, look for "mf_button" below.
 
   
 
An accurate intervalometer script, with pre-focus and screen power off options.
 
An accurate intervalometer script, with pre-focus and screen power off options.
Line 35: Line 34:
 
See bottom of script for main loop.
 
See bottom of script for main loop.
 
]]
 
]]
 
-- for the G9, manual focus button is the "up" button; many cameras
 
-- (e.g. S3) have a dedicated manual focus button, in which case you
 
-- should change this to "mf"
 
mf_button = "up"
 
   
 
--[[
 
--[[
Line 126: Line 120:
 
-- switch to autofocus mode, pre-focus, then go to manual focus mode
 
-- switch to autofocus mode, pre-focus, then go to manual focus mode
 
function pre_focus()
 
function pre_focus()
if get_prop(props.FOCUS_MODE) ~= 0 then
 
click(mf_button)
 
end
 
 
local focused = false
 
local focused = false
 
local try = 1
 
local try = 1
Line 137: Line 128:
 
if get_prop(18) > 0 then
 
if get_prop(18) > 0 then
 
focused = true
 
focused = true
  +
set_aflock(1)
 
end
 
end
 
release("shoot_half")
 
release("shoot_half")
Line 142: Line 134:
 
try = try + 1
 
try = try + 1
 
end
 
end
release("shoot_half")
 
sleep(500)
 
click(mf_button)
 
sleep(500)
 
 
return focused
 
return focused
 
end
 
end
Line 182: Line 170:
   
 
--restore focus mode
 
--restore focus mode
  +
set_aflock(0)
if get_prop(props.FOCUS_MODE) ~= original_focus_mode then
 
click(mf_button)
 
sleep(500)
 
end
 
   
 
</pre>
 
</pre>

Revision as of 01:55, 14 June 2009

Accurate Intervalometer with power-saving and pre-focus

Written for/on: G9
Also works on: should work on any
Required CHDK build: any

This is yet another "accurate" intervalometer (that is, it uses get_tick_count to takes frames at exact intervals rather than after specific delays, so small variances in shooting time don't affect the frame rate). Takes the frame delay (e.g. 5 seconds) and the shooting time (e.g. 1 hour 30 minutes), or "endless" to ignore the delay, the script will run until you press the shutter button to stop it.

Extra features:

  • During the inter-frame delays you can use the Display button (to turn it off to save power).
  • The script can "pre-focus" then lock the focus; this slightly speeds up shooting time, and avoids annoying focus changes during shooting. If you interrupt the script before it exits normally, you'll need to turn the camera off and on to restore autofocus. (I'll try to fix this.) To enable pre-focus, set the "Focus" option to "Start" (1). To disable, set it to "Every" (0).
  • The script can optionally turn the display off after a set number of frames, to save power; as above you can turn the screen on again temporarily to see progress, and the script will turn it off again. For example, setting "Display off frame" to 3, the camera will turn the display off after the third frame. (Possibly the fourth, depending on how many display modes it has to cycle through). Set "Display off frame" to 0 to disable turning off the display.

Script Code (save as "lapse.lua" to your /CHDK/SCRIPTS/ folder - note the .lua - this is a Lua script, not a uBasic script.)

--[[
Author: Fraser McCrossan
Tested on G9, should work on most cameras.

An accurate intervalometer script, with pre-focus and screen power off options.

Features:
 - input is frame interval plus total desired run-time (or "endless")
 - displays frame count, frame total and remaining time after each frame
   (in endless mode, displays frame count and elapsed time)
 - honours the "Display" button during frame delays (so you can
   get it running then turn off the display to save power)
 - can turn off the display a given number of frames after starting
   (might take a couple of frames longer to cycle to correct mode)
 - can pre-focus before starting then go to manual focus mode

 See bottom of script for main loop.
]]

--[[
@title Time-lapse
@param s Secs/frame
@default s 5
@param h Sequence hours
@default h 0
@param m Sequence minutes
@default m 5
@param e Endless? 0=No 1=Yes
@default e 0
@param f Focus: 0=Every 1=Start
@default f 0
@param d Display off frame 0=never
@default d 0
--]]

-- convert parameters into readable variable names
secs_frame, hours, minutes, endless, focus_at_start, display_off_frame = s, h, m, (e > 0), (f > 0), d

props = require "propcase"

-- derive actual running parameters from the more human-friendly input
-- parameters
function calculate_parameters (seconds_per_frame, hours, minutes, start_ticks)
   local ticks_per_frame = 1000 * secs_frame -- ticks per frame
   local total_frames = (hours * 3600 + minutes * 60) / secs_frame -- total frames
   local end_ticks = start_ticks + total_frames * ticks_per_frame -- ticks at end of sequence
   return ticks_per_frame, total_frames, end_ticks
end

function print_status (frame, total_frames, ticks_per_frame, end_ticks, endless)
   if endless then
      local h, m, s = ticks_to_hms(frame * ticks_per_frame)
      print("#" .. frame .. ", " .. h .. "h " .. m .. "m " .. s .. "s")
   else
      local h, m, s = ticks_to_hms(end_ticks - get_tick_count())
      print(frame .. "/" .. total_frames .. ", " .. h .. "h" .. m .. "m" .. s .. "s left")
   end
end

function ticks_to_hms (ticks)
   local secs = (ticks + 500) / 1000 -- round to nearest seconds
   local s = secs % 60
   secs = secs / 60
   local m = secs % 60
   local h = secs / 60
   return h, m, s
end

-- sleep, but using wait_click(); return true if a key was pressed, else false
function next_frame_sleep (frame, start_ticks, ticks_per_frame)
   -- this calculates the number of ticks between now and the time of
   -- the next frame
   local sleep_time = (start_ticks + frame * ticks_per_frame) - get_tick_count()
   wait_click(sleep_time)
   return not is_key("no_key")
end

-- delay for the appropriate amount of time, but respond to
-- the display key (allows turning off display to save power)
function frame_delay (frame, start_ticks, ticks_per_frame)
   -- this returns true while a key has been pressed, and false if
   -- none
   while next_frame_sleep (frame, start_ticks, ticks_per_frame) do
      -- honour the display button
      if is_key("display") then
	 click("display")
      end
      -- respond to other keys here
   end
end

-- if the display mode is not the passed mode, click display and return true
-- otherwise return false
function seek_display_mode(mode)
   if get_prop(props.DISPLAY_MODE) == mode then
      return false
   else
      click "display"
      return true
   end
end

-- switch to autofocus mode, pre-focus, then go to manual focus mode
function pre_focus()
   local focused = false
   local try = 1
   while not focused and try <= 5 do
      print("Pre-focus attempt " .. try)
      press("shoot_half")
      sleep(2000)
      if get_prop(18) > 0 then
	 focused = true
	 set_aflock(1)
      end
      release("shoot_half")
      sleep(500)
      try = try + 1
   end
   return focused
end

if focus_at_start then
   if not pre_focus() then
      print "Unable to reach pre-focus"
   end
end

start_ticks = get_tick_count()

ticks_per_frame, total_frames, end_ticks = calculate_parameters(secs_frame, hours, minutes, start_ticks)

frame = 1
original_focus_mode = get_prop(props.FOCUS_MODE)
original_display_mode = get_prop(props.DISPLAY_MODE)
target_display_mode = 2 -- off

while endless or frame <= total_frames do
   print_status(frame, total_frames, ticks_per_frame, end_ticks, endless)
   if display_off_frame > 0 and frame >= display_off_frame then
      seek_display_mode(target_display_mode)
   end
   shoot()
   frame_delay(frame, start_ticks, ticks_per_frame)
   frame = frame + 1
end

-- restore display mode
if display_off_frame > 0 then
   while seek_display_mode(original_display_mode) do
      sleep(1000)
   end
end

--restore focus mode
set_aflock(0)

--Joatca