I've been doing a lot of testing in continuous drive mode. I got all those buffers working, but I discovered I may not need them.
I have 2 hooks where I delay the shooting process. First is in capt_seq_hook_nr(), which I call pre_shot. It happens right before the shutter opens. Next is in raw_save_file(), after the exposure is finished and the raw picture buffer is valid. I call this post_shot.
pre_shot: This is where I delay to get the desired shot interval. As long as the new exposure values are set before the end of the delay, it applies to the shot. If not, it takes effect on the next shot, which means you're 2 shots behind.
post_shot: Here I call build_shot_histogram() which calculates the shot meters. After they are ready, the Lua routine, get_shot_ready() returns true (once). The script then calculates and stores the new exposure values and signals the post_shot routine, which is now waiting for the script, to go ahead.
To faciliate this, I added a new Lua function: set_exp96(tv,sv,av,nd). This sets all the possible exposure values at one time, and then signals the post_shot_routine. The next call to get_shot_ready() also signals the post shot routine to proceed, in case the script isn't setting exposure.
A major discovery is that the pre shot and post shot routines never execute at the same time (at least on the G1X). As long as the post shot routine is waiting for the script signal, the pre shot routine isn't called. This means that the next shot always gets the exposure from the last shot, without missing shots. The key is to delay post shot until the exposure is set. It actually works (on the G1X). I discovered this when I added a pre shot wait for script, and stored the delay time. It was always 0. That is, the script was always ready before the pre shot routine was called. I confirmed this by writing values to the screen at the beginning and end of the pre and post shot routines.
So this is good news. I don't have to buffer all the exposure values for the shot meters. I just need to store one value, I call bvbase=tv+av-sv. I then return this value with the next get_shot_meter(0), and add it to the value returned by a meter to get bv96 for that meter.
The buffers did work really well for printing the log file, though. The script sets the exposure first, as soon as possible, and the next pre shot starts immediately afterwards. But the script is still reading the values from the last shot out of the buffer. Without the buffer, they disappear as soon as the next pre shot starts. The script could print the exposure values it just calculated as well as the shot meter values from the last shot that it used for those calculations. That should be enough, as long as the pre shot and post shot routines are always executed in sequence. I'll have to test this on my other cameras, the sx260 and sx50 (when I get it working).
I think the new handshake timing, along with the busy flag in build_shot_histogram() has fixed the script error problem. The new timing prevents the script from calling get_shot_meter() during the histogram build, but it's also possible that the script won't follow the handshake, so the busy flag is the backup.
The handshake only occurs in continuous mode, since it's not needed in single shot. Activating the handshake also requires a call to set_shot_interval(interval, nshots). If nshots>0, then the handshake is activated. nshots is the number of shots per interval. 0 is the same as 1, except without the handshake. Everything is disabled when a script is not active.
I'll leave the buffers in for now, for testing, since they also contain a lot of shot timing data useful for debugging.
I also modified my script to adjust for Bv as it gets darker, to avoid overexposure. Here's the exposure portion of the script, for those who might be interested:
set_shot_interval(m,n)
if(not single)then press("shoot_full_only") end
repeat
if(single)then press("shoot_full_only") end
repeat
sleeper(10) -- sleeps at least once, so it will yield each loop
until get_shot_ready() or is_pressed("menu") -- waits for build_histogram --
if(is_pressed("menu"))then break end
if(single)then release("shoot_full_only") end
--find meter with lowest exposure (brightest)
tvd=-100000
for i=1,nmeters do
tx=get_shot_meter(i)
if(tvd<tx)then
tvd=tx
im=i
end
end
--adjust bv as it gets darker
bv=tvd+get_shot_meter(0) --bv96
if(bv>=bv1)then bvd=0
elseif(bv<=bv2)then bvd=bvdmax
else bvd=((bv-bv1)*bvdmax)/(bv2-bv1) end
tv=tv+tvd+bvd+svmin-sv
sv=svmin
if(tv<tvs)then
sv=sv+tvs-tv
tv=tvs
if(sv>svmax)then
tv=tv-(sv-svmax)
sv=svmax
end
end
if(tv<tvmin)then tv=tvmin
elseif(tv>tvmax)then tv=tvmax end
set_exp96(tv,sv) -- aborts script wait too
And finally, here's the time lapse from last night:
http://www.youtube.com/watch?v=eOtKYe11pIk#ws