Magic Lantern Firmware Wiki
Advertisement

Preamble[]

With ML is possible to program the time of exposure in BULB mode.

This allows us, among other things, extend the range of exposure available, based on the longer exposure times achieved thanks on BULB mode.

Come here to discuss how to integrate new shutter speeds in the 550D measurement system (we suposse it's the same in the 5D, 60D or 7D).

First, we explain some background, about how the cam stores the shutter, aperture and ISO settings:

(1) log2(1 / Tv) = ( raw_shutter - 56 ) / 8

Tv measured in seconds. This means that to shutter speed slower (Tv greater and 1/Tv lower), the CAM assigns raw values lower. So if we need to underexpose based on shutter (less brigther image), we need to increase the raw_shutter value. Then we got a negative exposure compensation.

For more information, see APEX system

(2) log2(A*A) = ( raw_aperture - 8 ) / 8

A is measured in f stops. For apertures wider (number f lower), the cam assigns raw values lower. So if we need to underexpose based on aperture (less bright image), we need to increase the raw_aperture value. Then we got a negative exposure compensation.

(3) log2(ISO / 100) = ( raw_iso - 72 ) / 8

ISO has no units. For ISO higher, the cam assigns raw values higher. So if we need to underexpose based on ISO (less bright image), we need to decrease the raw_iso value. Then we got a negative exposure compensation.

The three numbers are aditive so I can use together to change exposure.

Also, one stop of exposure change (doubling or halving the light that reach the sensor) arises every 8 unit variation of raw values.

So, we can define:

(4) raw_global = raw_shutter + raw_aperture - raw_iso

it means that we obtain the same exposure (equaly bright image):

  • increasing raw_iso by n
  • decreasing raw_shutter by n
  • decreasing raw_aperture by n
  • decreasing raw_aperture by n/2 and decreasing shutter by n/2
  • decreasing raw_aperture by n/2 and increasing iso by n/2

and so on.

In stops (ev):

(5) ev_global = raw_global / 8

What can be do with all this?

1) Implement new algorithms for auto exposure, different of CANON ones.

2) Include in such algorithms the HI ISOs (12800 and 25600). (ISO auto now limited to 6400).

3) Include new Tv exposures based on BULB mode.

4) Include these new exposures with a 64 units / stop, that let to a better exposure control (NOTE: it's no more than a codification, it's possible that the precission of the timers on BULB mode cannot reach such refinement).

We are going to focus on points (3) and (4)

Include new Tv exposures based on BULB mode[]

First we need to create a table that maps exposure raw values to miliseconds, the parameter that we send to bulb shots.

We will employ an additive formula like (1):

log2(1 / Tv) = ( ml_raw_shutter - DISP ) / STEPS

where DISP is the displacement of maping (value of ml_raw_shutter for Tv = 1") and

STEPS is the number of units assigned to every doubling or halving exposure.

We deal also for EXTENDED_STOPS, number of stops to cover on table.

With the following ruby program we can generate the C table and play with several values of DISP and STEPS.

STEP = 64   
DISP = 1000.0

EXTENDED_STOPS = 12	#number of stops to calculate

#generate table for shutters between disp seconds (= 1 second)  and nstops away 
# if nstops = 12, we got exposure times to 4096 seconds
def generate_table_extended(step, disp, nstops)
	ml_raw_shutter = disp
	puts "//ml_raw_shutter, milliseconds\n"
	puts "uint32_t mlshutter[] = {\n";
	n=0;
	while (ml_raw_shutter >= disp - nstops * step)
		puts "[#{ml_raw_shutter.round}] = #{ (1000.0/ (  2 ** ( (ml_raw_shutter - disp) / step)  )).round()  },\n"
		ml_raw_shutter-=1
		n+=1
	end
	puts "};\n";
	puts "//table values #{n}\n"
end

And the linear mapings to convert between raw_shutter and ml_raw_shutter:

A = STEP/8   		#conversion factor between cam raw_shutter and ml_raw_shutter 
B =  DISP - 56*A  	#displacement parameter between cam raw_shutter and ml_raw_shutter 

def  get_ml_raw(raw_shutter)
	A*raw_shutter + B
end

def  get_raw(ml_raw_shutter)
	(ml_raw_shutter - B) / A
end

And the generated table to include in C core of ML:

//ml_raw_shutter, milliseconds
uint32_t mlshutter[] = {
[1000] = 1000,
[999] = 1011,
[998] = 1022,
[997] = 1033,
[996] = 1044,
[995] = 1056,
...
[784.0] = 10375,
...
[720.0] = 20749,
...
[236] = 3922343,
[235] = 3965055,
[234] = 4008231,
[233] = 4051878,
[232] = 4096000,
};
//table values 769

NOTE: we choose STEP = 64 and DISP = 1000 for convenience.

Extending the shutter bracketing[]

To extend the HDR shutter bracketing to the new values, we need:

1) Decide wich is the raw_shutter of rupture and calculate the nl_raw_shutter equivalent. Example, if we want to use BULB mode for exposures longer than 10", raw_shutter = 29 and ml_raw_shutter = get_ml_raw(29) = 784.

2) Do all the exposure arithmetic beyond raw_shutter over ml_raw_shutter equivalent and in ml_steps, say 64.

Example, if we need to overexpose 1 EV more over 10" (to obtain 20") we do:

784 - 64 = 720.

3) Obtain the miliseconds necessary to trigger the bulb.

From generated table we obtain 20749 miliseconds. Yes, we now it in advance and we have some rounding errors, but think on increments < 64, and we have more subttle increments than in raw_shutter, because of 64 steps.

4) Trigger the bulb with this value of milliseconds.

To be continued ...

Advertisement