Created
September 9, 2012 02:17
-
-
Save nickrsan/3682108 to your computer and use it in GitHub Desktop.
Synchronizes two cameras without communication between them or a third party (remote). Designed for A495 and adapted from previous code - Works so long as the interval time is set to a number that divides evenly into 60 and that is longer than the time it
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
Author: Fraser McCrossan | |
Tested on G9, should work on most cameras. | |
Modified by Nick Santos for use in synchronizing two cameras. | |
Designed for A495 and adapted from previous code - Works so long as the interval time is set to a number that divides evenly into 60 and that is longer than the time it. Creative Commons Attribution licensed - please cite both authors above. | |
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 | |
- use SET button to exit | |
See bottom of script for main loop. | |
]] | |
--[[ | |
@title Time-lapse | |
@param s Secs/frame | |
@default s 20 | |
@param h Sequence hours | |
@default h 0 | |
@param m Sequence minutes | |
@default m 5 | |
@param b Synchronize time 0=No 1=Yes | |
@default b 1 | |
@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) | |
local free = get_jpg_count() | |
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/" .. free .. " 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() | |
if sleep_time < 1 then | |
sleep_time = 1 | |
end | |
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) | |
-- return true if we should exit, else false | |
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 | |
-- if set key is pressed, indicate that we should stop | |
if is_key("set") then | |
return true | |
end | |
end | |
return false | |
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 -- This line should be changed to get_prop(67) for non Digic III processors | |
focused = true | |
set_aflock(1) | |
end | |
release("shoot_half") | |
sleep(500) | |
try = try + 1 | |
end | |
return focused | |
end | |
function start_sync() | |
l_cont = false | |
print "Synchronizing" | |
repeat | |
t_time = get_time('s') | |
--time_small = t_time /1000 | |
--time_round = tonumber(string.format("%.0d", time_small)) -- effectively rounds for us - a bit of a hack | |
t_val = t_time % s -- are we on a number evenly divisible by s? | |
if t_val == 0 then | |
l_cont = true | |
print "Beginning" | |
else | |
timeleft = s-t_val | |
if timeleft % 5 == 0 or timeleft == 2 or timeleft == 1 then | |
print(string.format("waiting %d seconds to start - t_time = %d", timeleft, t_time)) | |
end | |
sleep(250) | |
end | |
until (l_cont == true) | |
end | |
if focus_at_start then | |
if not pre_focus() then | |
print "Unable to reach pre-focus" | |
end | |
end | |
if b == 1 then | |
start_sync() -- Nick's function to delay start until a specific time | |
end | |
start_ticks = get_tick_count() | |
ticks_per_frame, total_frames, end_ticks = calculate_parameters(secs_frame, hours, minutes, start_ticks) | |
frame = 1 | |
original_display_mode = get_prop(props.DISPLAY_MODE) | |
target_display_mode = 2 -- off | |
print "Press SET to exit" | |
while endless or frame <= total_frames do | |
print_status(frame, total_frames, ticks_per_frame, end_ticks, endless) | |
-- commented out following because A495 doesn't support it | |
--if display_off_frame > 0 and frame >= display_off_frame then | |
-- seek_display_mode(target_display_mode) | |
--end | |
shoot() | |
if frame_delay(frame, start_ticks, ticks_per_frame) then | |
print "User quit" | |
break | |
end | |
frame = frame + 1 | |
end | |
-- commented out because A495 doesn't support that | |
-- 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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment