Magic Lantern Forum

Developing Magic Lantern => Scripting Corner => Topic started by: GamerGuppy on December 21, 2019, 01:56:31 PM

Title: Script for AE-lock/autoISO-lock in manual mode
Post by: GamerGuppy on December 21, 2019, 01:56:31 PM
I am a Canon 7D shooter, and would really love to have the feature to "exposure lock" my auto-iso in manual mode with the click of a button. Besides sending in a request for this feature, I thought it would be simple enough for me to code as a Lua script.

The idea is as follows. I put my camera in manual, with spot metering and auto-ISO. I set the shutterspeed and aperture I think is suitable for the scene. I point the camera at my subject, such that my spot metering finds the correct ISO value for my exposure. This is where the script comes in: I then press a dedicated button (ideally the (*) button, but could be the info or set button too) and now the ISO is frozen. Now I can recompose and take my picture. I can than press the dedicated button again to get back in auto-ISO. The process can now be repeated. Maybe it can even be optimized one step further such that the camera is only very briefly in auto-ISO and then almost instantly freezes the ISO value. This way only one press of a button is required. (Basically AE lock hold as found on newer camera's).

So far I have the following script. However I can't seem to manage to get the current value of the ISO as set by the auto-ISO. I already looked at the "copy2m.lua" file as an example, however as a Lua noob, I have a hard time understanding how that script works.

Questions:
1) Is there a simple way to get the ISO value as determined by the auto-ISO
2) I couldn't find the button event for the (*) button in the documentation. Is it possible to use this (*) button for this purpose?

Thank you for your reading!

isostate = 1

function freezeautoiso(key)
if key == KEY.INFO and camera.mode == MODE.M then
if isostate == 1
isostate = 0
[b]camera.iso.raw = ???[/b]
else
isostate = 1
camera.iso.raw = 0
end
return false
else
return true
end
end

event.keypress = freezeautoiso
Title: Re: Script for AE-lock/autoISO-lock in manual mode
Post by: a1ex on December 22, 2019, 04:00:53 PM
1) The auto-ISO value is not currently exposed to Lua (the API should be extended somehow). In ML core, this is available as lens_info.iso_auto (decimal units) or lens_info.raw_iso_auto (internal value, in 1/8 EV steps). It's only updated when you press the shutter halfway, IIRC.

I'd suggest the following change to the Lua API, to make it somewhat consistent with Tv and Av (where you can get the metered value as usual):
- iso.auto as a boolean field, to be added (get/set whether the ISO is auto or manual, read-only in certain shooting modes)
- iso.value, iso.apex, iso.raw etc should report either the manual or the auto-metered value

2) No, this button shares the same internal codes with the half-shutter. It might be possible to figure it out eventually, as Canon code is able to tell them apart somehow, just not with the "usual" button codes. The AF-ON and DOF buttons share the same issue.
Title: Re: Script for AE-lock/autoISO-lock in manual mode
Post by: GamerGuppy on December 22, 2019, 10:40:13 PM
Thank you for your message A1ex!

So that means I am out of luck as of right now to get this feature by Lua scripting.  :(

When you say: "The auto-ISO value is not currently exposed to Lua", do you mean that only for Manual mode? Because otherwise I am at loss how "copy2m.lua" is able to do just that, albeit the auto-iso values in the P, Av & Tv modes.

When you say "It's only updated when you press the shutter halfway". That could actually be neat, since I am quite used already to controlling focus with backbutton AF and exposure lock through depressing the shutter half-way. I believe Lua scripting would allow to capture that event (half press) and fix auto-iso accordingly. That is, once the API allows for that.
Title: Re: Script for AE-lock/autoISO-lock in manual mode
Post by: a1ex on December 23, 2019, 07:02:21 AM
Ah, right - the copy2m script uses the low-level property interface, so it's able to get pretty much everything Canon firmware provides (i.e. their internal values). Cool!

Still, "basic" functionality should probably be available in the "basic" API :)
Title: Re: Script for AE-lock/autoISO-lock in manual mode
Post by: GamerGuppy on December 23, 2019, 07:40:51 PM

I might try and clean the code up a little further later on. Hope it is useful to others!

require("config")

prop_value = {}
prop_value.__index = prop_value

local isostate = 1
local isovalue = 0

local ISO_step_up={75,77,80,83,85,88,91,93,96,99,101,104,107,109,112,115,117,120,120} -- RAW ISO values used when increasing
local ISO_current={72,75,77,80,83,85,88,91,93,96,99,101,104,107,109,112,115,117,120}
local ISO_step_dn={72,72,75,77,80,83,85,88,91,93,96,99,101,104,107,109,112,115,117} -- RAW ISO values used when decreasing

function prop_value.create(...)
    local pv =
    {
        value = 0,
        previous = 0,
        time = dryos.ms_clock,
        props = {...}
    }
    setmetatable(pv,prop_value)
    return pv
end

function prop_value:enable()
    for i,v in ipairs(self.props) do
        function v.handler(prop,value) self:set(value) end
    end
end

function prop_value:set(value)
    if value ~= 0 then
        self.previous = self.value
        self.value = value
    end
end

function prop_value:get()
    return self.value
end

local iso_value = prop_value.create(property.ISO,property.ISO_AUTO)

copy2m_menu = menu.new
{
    parent  = "Prefs",
    name    = "AUTO ISO LOCK",
    help    = "Lock auto-iso in M",
    choices = {"OFF","ON"},
    value   = "OFF"
}

function lockisoinmanual(key,value)
isovalue = camera.iso.raw
if camera.mode == MODE.M then
-- Toggle between fixed and auto ISO
if key == KEY.JOY_CENTER then
if isostate == 0 then
isostate = 1
iso_value:enable()
local i = iso_value:get()
if i ~= 0 then camera.iso.raw = i end
else
isostate = 0
camera.iso.raw = 0
end
beep(1, 100, 330)
end
-- Control ISO with joystick once locked
if isostate == 1 then
if key == KEY.UP or key == KEY.UP_RIGHT or key == KEY.UP_LEFT or key == KEY.RIGHT then
for j,v in ipairs(ISO_current) do
if isovalue == v then
camera.iso.raw = ISO_step_up[j] -- ISO increasing
break -- exit "for" statement
end
end
elseif key == KEY.DOWN or key == KEY.DOWN_RIGHT or key == KEY.DOWN_LEFT or key == KEY.LEFT then
for j,v in ipairs(ISO_current) do
if isovalue == v then
camera.iso.raw = ISO_step_dn[j] -- ISO increasing
break -- exit "for" statement
end
end
end
end
end
end

event.keypress = lockisoinmanual
Title: Re: Script for AE-lock/autoISO-lock in manual mode
Post by: Audionut on December 24, 2019, 07:40:05 AM
It's nice when someone sees my blunt nature as a reflection of myself, doesn't take it personally, and even finds some humor.

As I mentioned in my PM, this is a feature that has a long history on this board, and with a little tickle in the right direction you have found a solution in less then a week.
Title: Re: Script for AE-lock/autoISO-lock in manual mode
Post by: GamerGuppy on December 27, 2019, 09:59:22 PM
Hope you all had a great Christmas! So there are 2 things I am looking to improve my script upon.


If you have any suggestions or solutions I would be very grateful! Thanks.
Title: Re: Script for AE-lock/autoISO-lock in manual mode
Post by: garry23 on December 27, 2019, 11:28:01 PM
One thought, and a technique I use, is to hyjack a button and use time.

For instance, press twice quickly = normal use, press twice with a delay between = do something else.

Have a look at a few of my scripts.
Title: Re: Script for AE-lock/autoISO-lock in manual mode
Post by: GamerGuppy on January 06, 2020, 07:15:43 PM
Thank you garry23, I have looked through some of your work and will definitely use it for inspiration for future projects!

Having used my script for some time now, I found there to be one major issue with the script in it's current state. For the auto-ISO value to be read out succesfully, the camera's metering needs to detect a change in light intensity (1) or the metering must be restarted (2). If neither of these events have taken place, attempting to read out the auto-ISO value will instead return 0.

E.g. a typical use-case of this script is described below. However the script will frequently choose a faulty ISO value when the scene you photograph is uniformly lit.


The reason the camera went back to ISO 800, was because it simply could not read out the ISO 640 value as determined by auto-ISO. Instead the script found the auto-ISO value to be 0.
Note that this only happens when the new scene you photograph is evenly or uniformly lit. If I would briefly place my hand in front of the lens and remove it again, then the metering of the camera would detect this change of light intensity and suddenly I would be able to read out the auto ISO value of 640. Also if I would wait about 5 seconds for my metering to stop, and then restart it again, would give me the correct value of 640.

I tried all sorts of things to fix this problem. But I am unable to do so. Tips or tricks are very much welcome! I wish I could write my own auto-ISO script, but that would require me to read out the camera's metering somehow. Which I think is impossible through Lua scripting as of now.