This wiki page presents a script written to provide manual control of exposure settings during the video recording. It should work with all CHDK enabled Canon P&S cameras. Please check if your model has been tested (below) and if not, please report any testing results.
Forum Thread : Video Manual Control
Download Link : videxp3.lua
Operation
Edit
To use this script, place the camera into video recording mode. When the script is activated, a GUI input box will open on the bottom of the camera LCD screen. Use the camera keyboard keys to control the GUI. The right & left keys change fields. The up & down keys to change the exposure values in each field. Use the DISP/SET button to start and stop video recording. The MENU key or a shutter button full press will end script execution.
!!! Note !!! : using this script requires that Lua Native Calls be enabled in the CHDK Miscellaneous menu. See the warning below about the use of native calls.
Configuration
Edit
Configuration Options are :
- Starting Tv (sec) : set the default shutter speed to be used when the script starts
- Starting Av (f-stop) : set the default lens aperture opening to be used when the script starts
- Starting ISO : set the default ISO sensitivity setting to be use used when the script starts
- ISO Max : set the maximum value the script will allow for ISO adjustment. One some cameras, too high a value will cause the script to shut down
- Show start message : enables a startup help screen
- Debug mode : enable the script console - useful if the script does not seem to be working.
Warning
Edit
Use this script at you own risk. This script makes native calls to the Canon firmware in order to manipulate exposure settings during video recording. While it is generally believed safe to do so, and this code has been tested on many camera models, it is potentially more risky than standard CHDK activities.
Results may also vary between different camera models so if you test this script and find it works for your camera please report it here.
Tested Cameras
Edit
(please add any additional cameras tested here - please note any failures too)
- A Series:
- A570 (ISO 3200 works)
- A720
- A1200
- A2000 (ISO 3200 works)
- A2500 (*)
- G series:
- G10
- G1X (Fails)
- G12 ( Failed with script versions prior to 3.3)
- G15
- IXUS series:
- IXUS 115HS/ELPH 100HS (worked until video record is pressed. Then manual shutter speed fails. Iso works.)
- IXUS120_SD940
- Elph 300/Ixus 220 HS (worked until video record is pressed. Then auto expose happens.)
- S series:
- S100
- S110
- SX series:
- SX100i0
- SX130is
- SX150is
- SX160is
- SX220HS
- SX260HS
- SX40 is working
- SX50HS (Hangs when ISO 3200 selected, works fine otherwise if mode dial set to Video)
- SX230HS: (Works great! Thanks - stop/start record with func set. Script may cause issues issues with live view in manual mode; turn camera off then back on if that happens, Functioning ISO range is 80-1250.)
- SX510HS: (Hangs when ISO 3200 is selected, makes camera slighly unestable, even when the script isn't running, I recommend to turn off the camera and turning it back on without chdk after using it, if you restart it with chdk on, it will crash after a few minutes. However, you can follow this pattern to keep your camera stable when running chdk [CRASH / TURN OFF - NO CHDK - TURN OFF - TURN ON W/ PLAY MODE - ACTIVATE CHDK])
- SX530HS: Works great and ISO goes up to 3200. Great job coders!
(*) There is no video recording mode on the A2500, only a red button to start/stop video recording. But you can use still the script as follows :
- press shutter in ALT mode to start the script running
- an error message will says "Camera not in video mode" - ignore it
- use the arrow keys to show/modify Tv, Av and Sv parameters
- press the FUNC/SET button to start & stop video recording
- press the shutter or MENU button to stop the script
- repeat these steps as desired
WARNING: don't activate Debug mode in the script, it freezes the recording.
Failures :
- Inability to manually set shutter speed.
- Inability to manually set the aperture.
- Inability to manually set the ISO.
Lua Script
Edit
videxp3.lua : for CHDK v1.3.0 or greater
hint : you can download the most recent version of the script from the link posted at the top of this page
--[[ @title Video Exp Ctrl v3.1 original script by fudgey 2010/08/23 http://chdk.setepontos.com/index.php?topic=5295.msg68622#msg68622 modified 2013/11/29 by waterwingz & msl @param t Starting Tv (sec) @default t 3 @values t 1/30 1/60 1/100 1/200 1/400 1/640 1/800 1/1000 1/1250 1/1600 1/2000 @param a Starting 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 p Starting ISO @default p 1 @values p 80 100 200 400 800 1250 1600 @param q ISO Max @default q 4 @values q 100 200 400 800 1250 1600 3200 @param s Show Start Message ? @default s 1 @range s 0 1 @param d Debug Mode ? @default d 0 @range d 0 1 --]] require("drawings") props=require("propcase") -- ========================== Functions ================================= function restore() if ( get_movie_status() == 4 ) then if ( vbutton == 1 ) then press("video") sleep(500) release("video") else press("shoot_full") sleep(250) release("shoot_full") end end set_aelock(0) set_console_autoredraw(0) end tv_ref = { -- note : tv_ref values set 1/2 way between shutter speed values 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_val = { 400, 471, 511, 542, 567, 607, 638, 669, 703, 734, 765, 799, 830, 861, 895, 926, 957, 988, 1022, 1053, 1084, 1118, 1149, 1180, 1214, 1245, 1276 } tv_str = { "err", "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_table = {163, 192, 218, 254, 285, 322, 347, 384, 417, 446, 477, 510, 543, 576, 609, 638, 664, 710, 731, 768} function print_av(val) if ( val == nil ) then return("-") end local fstop=av96_to_aperture(val) return((fstop/1000).."."..(fstop%1000)/100) end sv_table = { 380, 411, 507, 603, 699, 795, 891 } function print_sv(val) if ( val == nil ) then return("-") end return( ((iso_real_to_market(sv96_to_iso(val))+5)/10)*10 ) end function screen_w() -- lookup table for 480 px screen local cams = "ixus110_sd960|ixus200_sd980|ixus240_elph320hs|ixus300_sd4000|ixus310_elph500hs|ixus1000_sd4500|sx1|sx210is|sx220hs|sx230hs" return string.find(cams, get_buildinfo().platform) and 480 or 360 end function help_screen() local x = screen_w()/2 - 132 local help_msg = { "HELP SCREEN","FUNC/SET : start/stop video","\017 \016 : change field", "\030 \031 : change value", "MENU : exit", "FULLPRESS : exit", "Press any key to start", " "} local i=1 while (i < #help_msg) do msg = " "..(help_msg[i]).." " inx = string.find(msg,":") if (inx ~= nil) then draw.add( "string", x, i*16+64, string.sub(msg, inx-12, inx+18), "red","white") else draw.add( "string", x, i*16+64, string.sub(msg, (#msg/2)-12, (#msg/2)+18),"white", "blue") end i=i+1 end rec,vid,mode=get_mode() if (vid ~= true) then msg =" ".."**Camera not in video mode**".." " draw.add( "string", x, i*16+64, string.sub(msg, (#msg/2)-12, (#msg/2)+18), "yellow","red") end repeat draw.overdraw() wait_click(100) until not(is_key("no_key")) draw.clear() end function draw_box() local fg, bg = "blue" , "black" local w = box_width local h = box_height --if (gb ~= "trans") then draw.add("rectf", xpos-1, ypos-6, xpos+w+1, ypos+h+1, bg, bg) --end draw.add("string", xpos, ypos-6, " Tv Av Sv", fg, bg) draw.add("line", xpos, ypos, xpos+20, ypos, fg) draw.add("line", xpos+45, ypos, xpos+70, ypos, fg) draw.add("line", xpos+100, ypos, xpos+120, ypos, fg) draw.add("line", xpos+150, ypos, xpos+w, ypos, fg) draw.add("line", xpos, ypos, xpos, ypos+h, fg) draw.add("line", xpos+w, ypos, xpos+w, ypos+h, fg) draw.add("line", xpos, ypos+h, xpos+w, ypos+h, fg) end function init_values() local fg, bg = "blue" , "black" val1=draw.add("string", xpos+6, ypos+12, " -", fg, bg) val2=draw.add("string", xpos+76, ypos+12, " -" , fg, bg) val3=draw.add("string", xpos+120, ypos+12, " -" , fg, bg) end function show_values(Tv, Av, Sv) local fg, bg = "white" , "black" local fg1, fg2, fg3, fg4, bg1, bg2, bg2 , bg3, bg4 if(gui_index==0) then fg1 = bg bg1=fg else fg1 = fg bg1=bg end if(gui_index==1) then fg2 = bg bg2=fg else fg2 = fg bg2=bg end if(gui_index==2) then fg3 = bg bg3=fg else fg3 = fg bg3=bg end draw.replace(val1, "string", xpos+6, ypos+12, string.sub(" "..print_tv(Tv).." ",0,8), fg1, bg1) draw.replace(val2, "string", xpos+76, ypos+12, string.sub(" "..print_av(Av).." ",0,5), fg2, bg2) draw.replace(val3, "string", xpos+120, ypos+12, string.sub(" "..print_sv(Sv).." ",0,5), fg3, bg3) end function adjust_value(inx, offset) local i=1 if (inx==0 ) then -- adjust Tv value while (i <= #tv_ref) and ( tv96 > tv_ref[i]) do i=i+1 end if ( offset > 0 ) then tv96=tv_val[math.min(#tv_val,i+1)] else tv96=tv_val[math.max(2,i-1)] end while (i <= #tv_ref) and ( tv96 > tv_val[i]) do i=i+1 end tv96ret=call_event_proc("SetAE_ShutterSpeed",tv96) if ((tv96ret < tv96-96) or (tv96ret > tv96+96))then -- clamp values beyond cameras range print("clamp", tv96ret) tv96=tv96ret end print("new Tv96=",tv96) elseif (inx==1) then -- adjust Av value av96old = av96 while (i <= #av_table) and ( av96 > av_table[i]) do i=i+1 end if ( offset > 0) then repeat -- find next f-stop value the camera will accept av96=av_table[math.min(#av_table,i)] av96ret=call_event_proc("MoveIrisToAv",av96) i=i+1 until (i > #av_table) or (av96ret>av96old) av96=av96ret else repeat i=i-1 av96=av_table[math.max(1,i)] av96ret=call_event_proc("MoveIrisToAv",av96) until (i==1) or (av96ret<av96old) av96=av96ret end print("new Av96=",av96) elseif (inx==2) then -- adjust Sv value while (i <= #sv_table) and ( sv96 > sv_table[i]) do i=i+1 end if ( offset > 0) then sv96=sv_table[math.min(#sv_table,i+1)] else sv96=sv_table[math.max(1,i-1)] end call_event_proc("SetCDSGain",sv96) print("new Sv96=",sv96) end end -- ========================== Main Program ================================= tv_table = { 471, 567, 640, 736, 832, 896, 928, 960, 992, 1024, 1056, 1180, 1276} tv96target = tv_table[t+1] av_table = { 171, 192, 218, 265, 285, 322, 347, 384, 417, 446, 477, 510, 543, 576 } av96target = av_table[a+1] sv_table = { 381, 411, 507, 603, 699, 761, 795, 891 } sv96target = sv_table[p+1] sv96max = sv_table[p+2] xpos = screen_w()/2 -110 -- msl: 360 or 480 px for default screen position & size (upper left hand corner) ypos = 175 -- msl: above the warning text of the unlimited video recording time box_width = 170 box_height = 32 set_console_layout(1 ,4, 45, 16 ) bi=get_buildinfo() print(string.format("%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(string.gsub(get_buildinfo().build_number, "%p", ""), 0, 3)) if ( tonumber(bi.build_revision) > 0 ) then build = tonumber(bi.build_revision) else build = tonumber(string.match(bi.build_number,'-(%d+)$')) end if ( version < 130) or ( build < 3250) then error("CHDK 1.3.0 or higher, build 3250 or higher, required") end if (type(call_event_proc) ~= "function" ) then -- need native calls turned on error("Lua native calls not enabled") end if (call_event_proc("FA.Create") == -1) then -- required for event procedures SetAE_ShutterSpeed, MoveIrisToAv, SetCDSGain error("FA CREATE failed") end if (call_event_proc("InitializeAdjustmentSystem") == -1) then error("InitializeAdjustmentSystem failed") end -- switch to shooting mode & make sure we are in a video mode if ( get_mode() == false ) then sleep(1000) set_record(1) while ( get_mode() == false) do sleep(100) end end sleep(500) -- setup splash screen & console set_console_autoredraw(d -1) cls() if (s==1) then help_screen() end set_exit_key("no_key") -- use "menu" key to exit so that recording gets stopped if running set_draw_title_line(0) vbutton = get_video_button() -- startup values set_aelock(1) -- go to manual exposure mode tv96=call_event_proc("SetAE_ShutterSpeed",tv96target) av96=call_event_proc("MoveIrisToAv",av96target) call_event_proc("SetCDSGain",sv96target) sv96=sv96target draw_box() init_values() gui_index=0 while true do show_values(tv96, av96, sv96) repeat draw.overdraw() wait_click(200) until not(is_key("no_key")) if is_pressed("set") then if ( vbutton == 1 ) then press("video") sleep(1000) release("video") sleep(1000) else press("shoot_full") sleep(1000) release("shoot_full") sleep(1000) end elseif is_pressed("left") then if gui_index > 0 then gui_index = gui_index - 1 end elseif is_pressed("right") then if gui_index < 2 then gui_index = gui_index + 1 end elseif ( is_key("up")) then adjust_value(gui_index, 1) elseif ( is_key("down")) then adjust_value(gui_index, -1) elseif ( is_key("zoom_in")) then press("zoom_in") while(is_pressed("zoom_in")) do sleep(20) end release("zoom_in") elseif ( is_key("zoom_out")) then press("zoom_out") while(is_pressed("zoom_out")) do sleep(20) end release("zoom_out") elseif (is_pressed("menu") or is_pressed("shoot_full")) then break end end restore()