Created
April 19, 2014 16:24
-
-
Save mtrl/11089414 to your computer and use it in GitHub Desktop.
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
--[[ | |
KAP UAV Exposure Control Script v1.5 | |
-- Released under GPL by waterwingz and wayback/peabody | |
http://chdk.wikia.com/wiki/KAP_%26_UAV_Exposure_Control_Script | |
@title KAP UAV 1.5 | |
@param i Shot Interval (sec) | |
@default i 15 | |
@range i 2 120 | |
@param s Total Shots (0=infinite) | |
@default s 0 | |
@range s 0 10000 | |
@param j Power off when done? | |
@default j 0 | |
@range j 0 1 | |
@param e Exposure Comp (stops) | |
@default e 6 | |
@values e -2.0 -1.66 -1.33 -1.0 -0.66 0.33 0.0 0.33 0.66 1.00 1.33 1.66 2.00 | |
@param d Start Delay Time (sec) | |
@default d 0 | |
@range d 0 10000 | |
@param n Av Mode | |
@default n 0 | |
@values n None Iris NdFlter Both | |
@param t Target Tv (sec) | |
@default t 5 | |
@values t 1/100 1/200 1/400 1/640 1/800 1/1000 1/1250 1/1600 1/2000 | |
@param x Tv Max (sec) | |
@default x 3 | |
@values x 1/1000 1/1250 1/1600 1/2000 1/5000 1/10000 | |
@param y Tv Min (sec) | |
@default y 2 | |
@values y 1/60 1/100 1/200 1/400 1/640 | |
@param f Lowest Av (f-stop) | |
@default f 4 | |
@values f 1.8 2.0 2.2 2.6 2.8 3.2 3.5 4.0 4.5 5.0 5.6 6.3 7.1 8.0 | |
@param a Target Av (f-stop) | |
@default a 7 | |
@values a 1.8 2.0 2.2 2.6 2.8 3.2 3.5 4.0 4.5 5.0 5.6 6.3 7.1 8.0 | |
@param m Highest Av (f-stop) | |
@default m 13 | |
@values m 1.8 2.0 2.2 2.6 2.8 3.2 3.5 4.0 4.5 5.0 5.6 6.3 7.1 8.0 | |
@param p ISO Min | |
@default p 1 | |
@values p 80 100 200 400 800 1250 1600 | |
@param q ISO Max1 | |
@default q 2 | |
@values q 100 200 400 800 1250 1600 | |
@param r ISO Max2 | |
@default r 3 | |
@values r 100 200 400 800 1250 1600 | |
@param z Zoom position | |
@default z 0 | |
@values z Off 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% | |
@param c Focus @ Infinity Mode | |
@default c 0 | |
@values c None aflock AFL MF1 MF2 MF3 | |
@param u USB Shot Control? | |
@default u 0 | |
@range u 0 1 | |
@param b Backlight Off? | |
@default b 0 | |
@range b 0 1 | |
@param l Logging | |
@default l 3 | |
@values l Off Screen SDCard Both | |
@param m Power off when USB turned off? | |
@default m 0 | |
@values m 0 1 | |
--]] | |
props=require("propcase") | |
-- convert user parameter to usable variable names and values | |
tv_table = { 576, 640, 736, 832, 896, 928, 960, 992, 1024, 1056, 1180, 1276} | |
tv96target = tv_table[t+2] | |
tv96max = tv_table[x+7] | |
tv96min = tv_table[y+1] | |
sv_table = { 381, 411, 507, 603, 699, 761, 795 } | |
sv96min = sv_table[p+1] | |
sv96max1 = sv_table[q+2] | |
sv96max2 = sv_table[r+2] | |
av_table = { 171, 192, 218, 265, 285, 322, 347, 384, 417, 446, 477, 510, 543, 576 } | |
av96target = av_table[a+1] | |
av96minimum = av_table[f+1] | |
av96max = av_table[m+1] | |
ec96adjust = (e - 6)*32 | |
Av_mode = n | |
interval = i | |
max_shots = s | |
poff_if_done = j | |
start_delay = d | |
backlight = b | |
log_mode= l | |
poff_on_usb_off = m | |
if( u==0) then usb_mode = false else usb_mode = true end | |
focus_mode = c | |
if ( z==0 ) then zoom_setpoint = nil else zoom_setpoint = (z-1)*10 end | |
-- initial configuration | |
shot_count = 0 -- shot counter | |
blite_timer = 300 -- backlight off delay in 100mSec increments | |
nd96offset=3*96 -- ND filter's number of equivalent f-stops (f * 96) | |
function printf(...) | |
if ( log_mode == 0) then return end | |
local str=string.format(...) | |
if (( log_mode == 1) or (log_mode == 3)) then print(str) end | |
if ( log_mode > 1 ) then | |
local logname="A/KAP.log" | |
log=io.open(logname,"a") | |
log:write(os.date("%Y%b%d %X ")..string.format(...),"\n") | |
log:close() | |
end | |
end | |
tv_ref = { -- note : tv_ref values set 1/2 way between shutter speed values | |
-608, -560, -528, -496, -464, -432, -400, -368, -336, -304, | |
-272, -240, -208, -176, -144, -112, -80, -48, -16, 16, | |
48, 80, 112, 144, 176, 208, 240, 272, 304, 336, | |
368, 400, 432, 464, 496, 528, 560, 592, 624, 656, | |
688, 720, 752, 784, 816, 848, 880, 912, 944, 976, | |
1008, 1040, 1072, 1096, 1129, 1169, 1192, 1225, 1265, 1376 } | |
tv_str = { | |
">64", | |
"64", "50", "40", "32", "25", "20", "16", "12", "10", "8.0", | |
"6.0", "5.0", "4.0", "3.2", "2.5", "2.0", "1.6", "1.3", "1.0", "0.8", | |
"0.6", "0.5", "0.4", "0.3", "1/4", "1/5", "1/6", "1/8", "1/10", "1/13", | |
"1/15", "1/20", "1/25", "1/30", "1/40", "1/50", "1/60", "1/80", "1/100", "1/125", | |
"1/160", "1/200", "1/250", "1/320", "1/400", "1/500", "1/640", "1/800", "1/1000","1/1250", | |
"1/1600","1/2000","1/2500","1/3200","1/4000","1/5000","1/6400","1/8000","1/10000","hi" } | |
function print_tv(val) | |
if ( val == nil ) then return("-") end | |
local i = 1 | |
while (i <= #tv_ref) and (val > tv_ref[i]) do i=i+1 end | |
return tv_str[i] | |
end | |
av_ref = { 160, 176, 208, 243, 275, 304, 336, 368, 400, 432, 464, 480, 496, 512, 544, 592, 624, 656, 688, 720, 752, 784 } | |
av_str = {"n/a","1.8", "2.0","2.2","2.6","2.8","3.2","3.5","4.0","4.5","5.0","5.6","5.9","6.3","7.1","8.0","9.0","10.0","11.0","13.0","14.0","16.0","hi"} | |
function print_av(val) | |
if ( val == nil ) then return("-") end | |
local i = 1 | |
while (i <= #av_ref) and (val > av_ref[i]) do i=i+1 end | |
return av_str[i] | |
end | |
sv_ref = { 370, 397, 424, 456, 492, 523, 555, 588, 619, 651, 684, 731, 779, 843, 907 } | |
sv_str = {"n/a","80","100","120","160","200","250","320","400","500","640","800","1250","1600","3200","hi"} | |
function print_sv(val) | |
if ( val == nil ) then return("-") end | |
local i = 1 | |
while (i <= #sv_ref) and (val > sv_ref[i]) do i=i+1 end | |
return sv_str[i] | |
end | |
function switch_mode( m ) -- change between shooting and playback mode | |
if ( m == 1 ) then | |
if ( get_mode() == false ) then | |
set_record(1) -- switch to shooting mode | |
while ( get_mode() == false ) do | |
sleep(100) | |
end | |
sleep(1000) | |
end | |
else | |
if ( get_mode() == true ) then | |
set_record(0) -- switch to playback mode | |
while ( get_mode() == true ) do | |
sleep(100) | |
end | |
sleep(1000) | |
end | |
end | |
end | |
function lock_focus() | |
if ((get_focus_mode()==0) and (focus_mode >0)) then -- check if not already in MF mode | |
if ( focus_mode == 1 ) then -- method 1 : set_aflock() command enables MF | |
set_aflock(1) | |
elseif ( focus_mode == 2 ) then -- method 2 : use camera buttons to force AFL | |
local count = 0 -- NOTE : replace with camera specific key sequence | |
local timeout = false | |
press("shoot_half") | |
repeat | |
sleep(50) | |
count = count + 1 | |
if (count > 100 ) then timeout = true end | |
until (get_focus_ok() == 1 ) or (timeout == true) | |
if (timeout == true) then printf("Warning : focus attempt timed out") | |
else click("left") end | |
sleep(100) | |
release("shoot_half") | |
elseif ( focus_mode == 3 ) then -- method 3 : MF1 use camera buttons to select MF | |
click("up") -- NOTE : replace with camera specific key sequence | |
elseif ( focus_mode == 4 ) then -- method 4 : MF2: post a logical even to simulate manual button presses | |
post_levent_for_npt("PressSw1AndMF") | |
elseif ( focus_mode == 5 ) then -- method 5 : MF3: call event proc to enable MF mode | |
call_event_proc("SS.Create") | |
call_event_proc("SS.MFOn") | |
end | |
sleep(500) | |
set_focus(60000) | |
sleep(3000) | |
end | |
end | |
function unlock_focus() | |
if (focus_mode == 2 ) then -- method 2 : AFK use camera buttons to deselect | |
click("left") -- NOTE : replace with camera specific key sequence | |
elseif (focus_mode == 3 ) then -- method 3 : MF1 use camera buttons to select MF | |
click("up") -- NOTE : replace with camera specific key sequence | |
elseif (focus_mode == 4 ) then -- method 4 : MF2: post a logical even to simulate manual button presses | |
post_levent_for_npt("PressSw1AndMF") | |
elseif (focus_mode == 5 ) then -- method 5 : MF3: call event proc to enable MF mode | |
call_event_proc("SS.Create") | |
call_event_proc("SS.MFOff") | |
end | |
sleep(100) | |
set_aflock(0) | |
end | |
function update_zoom(zpos) | |
if(zpos ~= nil) then | |
zstep=((get_zoom_steps()-1)*zpos)/100 | |
printf("setting zoom to "..zpos.." percent step="..zstep) | |
sleep(200) | |
set_zoom(zstep) | |
sleep(2000) | |
end | |
end | |
function restore() | |
print("entered restore function") | |
sleep(500) | |
--set_config_value(121,0) -- USB remote disable | |
if (backlight==1) then set_lcd_display(1) end -- display on | |
unlock_focus() | |
if( zoom_setpoint ~= nil ) then update_zoom(0) end | |
if( shot_count >= max_shots) and ( max_shots > 1) then | |
if ( poff_if_done == 1 ) then -- did script ending because # of shots done | |
printf("power off - shot count at limit") -- power down | |
sleep(1000) | |
post_levent_to_ui('PressPowerButton') | |
else | |
printf("Retracting lens. LOL") | |
set_record(0) -- retract lens | |
end | |
end | |
if(poff_on_usb_off == 1) then | |
print("Attempting to turn off") | |
sleep(500) | |
shut_down() | |
sleep(500) | |
end | |
end | |
-- Basic exposure calculation using shutter speed and ISO only | |
-- called for Tv-only and ND-only cameras (cameras without an iris) | |
function basic_tv_calc() | |
tv96setpoint = tv96target | |
av96setpoint = nil | |
local min_av = get_prop(props.MIN_AV) | |
-- calculate required ISO setting | |
sv96setpoint = tv96setpoint + min_av - bv96meter | |
-- low ambient light ? | |
if (sv96setpoint > sv96max2 ) then -- check if required ISO setting is too high | |
sv96setpoint = sv96max2 -- clamp at max2 ISO if so | |
tv96setpoint = math.max(bv96meter+sv96setpoint-min_av,tv96min) -- recalculate required shutter speed down to Tv min | |
-- high ambient light ? | |
elseif (sv96setpoint < sv96min ) then -- check if required ISO setting is too low | |
sv96setpoint = sv96min -- clamp at minimum ISO setting if so | |
tv96setpoint = bv96meter + sv96setpoint - min_av -- recalculate required shutter speed and hope for the best | |
end | |
end | |
-- Basic exposure calculation using shutter speed, iris and ISO | |
-- Called for iris-only and "both" cameras (cameras with an iris & ND filter) | |
function basic_iris_calc() | |
tv96setpoint = tv96target | |
av96setpoint = av96target | |
-- calculate required ISO setting | |
sv96setpoint = tv96setpoint + av96setpoint - bv96meter | |
-- low ambient light ? | |
if (sv96setpoint > sv96max1 ) then -- check if required ISO setting is too high | |
sv96setpoint = sv96max1 -- clamp at first ISO limit | |
av96setpoint = bv96meter + sv96setpoint - tv96setpoint -- calculate new aperture setting | |
if ( av96setpoint < av96min ) then -- check if new setting is goes below lowest f-stop | |
av96setpoint = av96min -- clamp at lowest f-stop | |
sv96setpoint = tv96setpoint + av96setpoint - bv96meter -- recalculate ISO setting | |
if (sv96setpoint > sv96max2 ) then -- check if the result is above max2 ISO | |
sv96setpoint = sv96max2 -- clamp at highest ISO setting if so | |
tv96setpoint = math.max(bv96meter+sv96setpoint-av96setpoint,tv96min) -- recalculate required shutter speed down to tv minimum | |
end | |
end | |
-- high ambient light ? | |
elseif (sv96setpoint < sv96min ) then -- check if required ISO setting is too low | |
sv96setpoint = sv96min -- clamp at minimum ISO setting if so | |
tv96setpoint = bv96meter + sv96setpoint - av96setpoint -- recalculate required shutter speed | |
if (tv96setpoint > tv96max ) then -- check if shutter speed now too fast | |
tv96setpoint = tv96max -- clamp at maximum shutter speed if so | |
av96setpoint = bv96meter + sv96setpoint - tv96setpoint -- calculate new aperture setting | |
if ( av96setpoint > av96max ) then -- check if new setting is goes above highest f-stop | |
av96setpoint = av96max -- clamp at highest f-stop | |
tv96setpoint = bv96meter + sv96setpoint - av96setpoint -- recalculate shutter speed needed and hope for the best | |
end | |
end | |
end | |
end | |
-- calculate exposure for cams without adjustable iris or ND filter | |
function exposure_Tv_only() | |
insert_ND_filter = nil | |
basic_tv_calc() | |
end | |
-- calculate exposure for cams with ND filter only | |
function exposure_NDfilter() | |
insert_ND_filter = false | |
basic_tv_calc() | |
if (tv96setpoint > tv96max ) then -- check if shutter speed now too fast | |
insert_ND_filter = true -- flag the ND filter to be inserted | |
bv96meter = bv96meter - nd96offset -- adjust meter for ND offset | |
basic_tv_calc() -- start over, but with new meter value | |
bv96meter = bv96meter + nd96offset -- restore meter for later logging | |
end | |
end | |
-- calculate exposure for cams with adjustable iris only | |
function exposure_iris() | |
insert_ND_filter = nil | |
basic_iris_calc() | |
end | |
-- calculate exposure for cams with both adjustable iris and ND filter | |
function exposure_both() | |
insert_ND_filter = false -- NOTE : assume ND filter never used automatically by Canon firmware | |
basic_iris_calc() | |
if (tv96setpoint > tv96max ) then -- check if shutter speed now too fast | |
insert_ND_filter = true -- flag the ND filter to be inserted | |
bv96meter = bv96meter - nd96offset -- adjust meter for ND offset | |
basic_iris_calc() -- start over, but with new meter value | |
bv96meter = bv96meter + nd96offset -- restore meter for later logging | |
end | |
end | |
-- ========================== Main Program ================================= | |
set_console_layout(1 ,1, 45, 14 ) | |
printf("KAP 1.5 started - press MENU to exit") | |
bi=get_buildinfo() | |
printf("%s %s-%s %s %s %s", bi.version, bi.build_number, bi.build_revision, bi.platform, bi.platsub, bi.build_date) | |
version= tonumber(string.sub(bi.build_number,1,1))*100 + tonumber(string.sub(bi.build_number,3,3))*10 + tonumber(string.sub(bi.build_number,5,5)) | |
if ( tonumber(bi.build_revision) > 0 ) then | |
build = tonumber(bi.build_revision) | |
else | |
build = tonumber(string.match(bi.build_number,'-(%d+)$')) | |
end | |
if ((version<120) or ((version==120)and(build<3276)) or ((version==130)and(build<3149))) then | |
printf("CHDK 1.2.0 build 3276 or higher required") | |
else | |
printf(" Tv:"..print_tv(tv96target).." maxTV:"..print_tv(tv96max).." exp comp:"..(ec96adjust/96).."."..(math.abs(ec96adjust*10/96)%10) ) | |
printf(" Av:"..print_av(av96target).." minAv:"..print_av(av96minimum).." maxAv:"..print_av(av96max) ) | |
printf(" ISOmin:"..print_sv(sv96min).." ISO1:"..print_sv(sv96max1).." ISO2:"..print_sv(sv96max2) ) | |
printf(" AvM:"..Av_mode.." int:"..interval.." Shts:"..max_shots.." Dly:"..start_delay.." B/L:"..backlight.." USB:"..tostring(usb_mode)) | |
sleep(500) | |
if (start_delay > 0 ) then | |
printf("entering start delay of ".. start_delay.." seconds") | |
sleep( start_delay*1000 ) | |
end | |
-- check if USB remote enabled | |
if (usb_mode == true) then | |
set_config_value(121,1) -- make sure USB remote is enabled | |
if (get_usb_power(1) == 0) then -- can we start ? | |
printf("waiting on USB signal") | |
repeat wait_click(500) until ((get_usb_power(1) == 1) or ( is_key("menu"))) | |
else sleep(1000) end | |
printf("USB signal received") | |
end | |
-- switch to shooting mode | |
switch_mode(1) | |
-- set zoom position | |
update_zoom(zoom_setpoint) | |
-- lock focus at infinity | |
lock_focus() | |
-- disable flash and AF assist lamp | |
set_prop(props.FLASH_MODE, 2) -- flash off | |
set_prop(props.AF_ASSIST_BEAM,0) -- AF assist off if supported for this camera | |
next_shot_time = get_day_seconds() | |
script_exit = false | |
set_console_layout(2 ,0, 45, 4 ) | |
repeat | |
if( get_day_seconds() > next_shot_time ) then | |
-- intervalometer timing | |
next_shot_time = next_shot_time + interval | |
-- check exposure | |
local count = 0 | |
local timeout = false | |
press("shoot_half") | |
repeat | |
sleep(50) | |
count = count + 1 | |
if (count > 40 ) then timeout = true end | |
until (get_shooting() == true ) or (timeout == true) | |
-- shoot in auto mode if meter reading invalid, else calculate new desired exposure | |
if ( timeout == true ) then | |
release("shoot_half") | |
repeat sleep(50) until get_shooting() == false | |
shoot() -- shoot in Canon auto mode if we don't have a valid meter reading | |
shot_count = shot_count + 1 | |
printf(string.format('IMG_%04d.JPG',get_exp_count()).." : shot in auto mode, meter reading invalid") | |
else | |
-- get meter reading values (and add in exposure compensation) | |
bv96raw=get_bv96() | |
bv96meter=bv96raw-ec96adjust | |
tv96meter=get_tv96() | |
av96meter=get_av96() | |
sv96meter=get_sv96() | |
-- set minimum Av to larger of user input or current min for zoom setting | |
av96min= math.max(av96minimum,get_prop(props.MIN_AV)) | |
if (av96target < av96min) then av96target = av96min end | |
-- calculate required setting for current ambient light conditions | |
if (Av_mode == 1) then exposure_iris() | |
elseif (Av_mode == 2) then exposure_NDfilter() | |
elseif (Av_mode == 3) then exposure_both() | |
else exposure_Tv_only() | |
end | |
-- set up all exposure overrides | |
set_tv96_direct(tv96setpoint) | |
set_sv96(sv96setpoint) | |
if( av96setpoint ~= nil) then set_av96_direct(av96setpoint) end | |
nd_string="none" | |
if(Av_mode > 1) then -- ND filter available ? | |
if ( insert_ND_filter == true ) then | |
set_nd_filter(1) -- activate the ND filter | |
nd_string="NDin" | |
else | |
set_nd_filter(2) -- make sure the ND filter does not activate | |
nd_string="NDout" | |
end | |
end | |
-- and finally shoot the image | |
press("shoot_full_only") | |
sleep(100) | |
release("shoot_full") | |
repeat sleep(50) until get_shooting() == false | |
-- update shooting statistic and log as required | |
shot_count = shot_count + 1 | |
if ((max_shots>0) and (shot_count >= max_shots)) then script_exit = true end | |
shot_focus=get_focus() | |
if ((shot_focus > 40000 ) or (shot_focus<0)) then focus_string=" foc:infinity" else focus_string=" foc:"..(shot_focus/1000).."."..(shot_focus%1000).." m" end | |
printf(string.format('%d) IMG_%04d.JPG',shot_count,get_exp_count())) | |
printf(" meter : Tv:".. print_tv(tv96meter) .." Av:".. print_av(av96meter) .." Sv:"..print_sv(sv96meter).." "..bv96raw ..":"..bv96meter) | |
printf(" actual: Tv:".. print_tv(tv96setpoint).." Av:".. print_av(av96setpoint).." Sv:"..print_sv(sv96setpoint)) | |
printf(" AvMin:".. print_av(av96min).." NDF:"..nd_string..focus_string ) | |
end | |
collectgarbage() | |
end | |
-- check if USB remote enabled and USB power is off -> pause if so | |
if ((usb_mode == true) and (get_usb_power(1) == 0)) then | |
-- Added this | |
script_exit = true | |
print("script exit true") | |
sleep(100) | |
end | |
if (blite_timer > 0) then | |
blite_timer = blite_timer-1 | |
if ((blite_timer==0) and (backlight==1)) then set_lcd_display(0) end | |
end | |
wait_click(100) | |
if( not( is_key("no_key"))) then | |
if ((blite_timer==0) and (backlight==1)) then set_lcd_display(1) end | |
blite_timer=300 | |
if ( is_key("menu") ) then script_exit = true end | |
end | |
until (script_exit==true) | |
print("Script ended") | |
restore() | |
end | |
--[[ end of file ]]-- | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment