supplierdeeply

shooting script using Canon basic ?

  • 32 Replies
  • 1607 Views
shooting script using Canon basic ?
« on: 29 / August / 2018, 04:36:47 »
Advertisements
Hi,
I'm just wondering if it's possible to use a default Canon Basic script to shoot bracketing shots?   I've got a M6 and tend to use only CHDK on my previous cameras for ETTR AEB; so I was thinking instead of porting CHDK to the M6 why not using the Canon script...
Here is my pain in the butt workflow to do my ETTR bracketings with my manual lenses:
  • enable AEB -2/+2 EV
  • use spot metering
  • measure the most highlighted part of the scene
  • lock the exposure with the * button
  • dial the exposure compensation to +3EV (there is no way of dialing the AEB to 0/+2/+4EV in the Canon menu)
  • frame the shot / focus / etc.
  • press the shutter button
Then I need to reset the AEB and the metering mode to the default settings... and dial the EV to 0!

With this technique:
  • the -2EV bracket (with compensation of +3EV) become the shot for highlight
  • the +2EV bracket (with compensation of +3EV) become the shot for the shadow
  • the 0EV bracket become the shot for the mid-tone (might be optional/ redundant)
  • then I process the bracket shots with http://jcelaya.github.io/hdrmerge/
Based on what I've quickly read from the wiki; the Canon Basic script is fired from the play mode and with the func/set button.

Cheers,
« Last Edit: 29 / August / 2018, 04:41:15 by cedricb »

*

Offline srsa_4c

  • ******
  • 3689
Re: shooting script using Canon basic ?
« Reply #1 on: 29 / August / 2018, 13:52:30 »
I'm just wondering if it's possible to use a default Canon Basic script to shoot bracketing shots?
Sadly, the answer is either 'no' or 'not with our current knowledge'. Here's why:
The following script switches to rec mode, using the method used by CHDK
Code: [Select]
private sub Initialize()
        System.Create()
        UI.CreatePublic()
        Wait(100)
        ExecuteEventProcedure("PostLogicalEventToUI",0x1001,0) 'PressRecButton
        Wait(10)
        ExecuteEventProcedure("PostLogicalEventToUI",0x1002,0) 'UnpressRecButton
        Wait(100)
end sub
It works on my newer cameras, including the M10.
If I add a few more keypress events to it like this
Code: [Select]
private sub Initialize()
        System.Create()
        UI.CreatePublic()
        Wait(100)
        ExecuteEventProcedure("PostLogicalEventToUI",0x1001,0) 'PressRecButton
        Wait(10)
        ExecuteEventProcedure("PostLogicalEventToUI",0x1002,0) 'UnpressRecButton
        Wait(2000)
        ExecuteEventProcedure("PostLogicalEventToUI",0x9a1,0)  'PressSwOne
        Wait(2000)
        ExecuteEventProcedure("PostLogicalEventToUI",0x9a3,0)  'PressSwTwo
        Wait(10)
        ExecuteEventProcedure("PostLogicalEventToUI",0x9a4,0)  'UnpressSwTwo
        ExecuteEventProcedure("PostLogicalEventToUI",0x9a2,0)  'UnpressSwOne
end sub
all I get is the camera switching to rec mode after all the Wait() delay that is in the script (~4 seconds).
My impression is that, from a CBasic script, no more than one (keypress) event can be scheduled, and that event only gets executed after the script has finished.
While it might be possible to do shooting some other way, I have no idea how.

Re: shooting script using Canon basic ?
« Reply #2 on: 29 / August / 2018, 16:14:40 »
Thanks for the reply!
...about using the Canon basic loader to load a little ARM binary to do the sequence?

*

Offline srsa_4c

  • ******
  • 3689
Re: shooting script using Canon basic ?
« Reply #3 on: 29 / August / 2018, 16:38:52 »
...about using the Canon basic loader to load a little ARM binary to do the sequence?
In theory, that method could work, but it would have severe usability issues: a piece of code could run alongside the Canon firmware, but finding a way to control it is not trivial (no CHDK - no input from keyboard).

However, when using the method in the M5 blind experiment, things did not quite work as anticipated - camera crashed for unknown reason.


*

Offline reyalp

  • ******
  • 11496
Re: shooting script using Canon basic ?
« Reply #4 on: 01 / September / 2018, 17:27:02 »
Sadly, the answer is either 'no' or 'not with our current knowledge'.
I spent a bit of time on this back when @aortega posted the original Canon Basic breakthrough  (in 2010 :o) with no success.

It always bugged me, because the function available strongly suggest Canon use have scripts that shoot. My guess has been that there is some other way of running than the set + extend.m path. Maybe starting with set means it runs in the same task that processes logical events, so the whole script runs while handling the "set" press?

The string "A/autotest.m" suggests another way to run scripts, but I've never figured out how it would be loaded.

A minimal canon-basic loaded mod that just uses easily identifiable eventprocs is an interesting idea. It's possible one could hook into the event handling code somehow to get key presses.
Don't forget what the H stands for.

*

Offline srsa_4c

  • ******
  • 3689
Re: shooting script using Canon basic ?
« Reply #5 on: 02 / September / 2018, 06:01:38 »
The string "A/autotest.m" suggests another way to run scripts
After taking a look at the related code, I found it.
SET + RIGHT at the same time (press and hold SET then press RIGHT), in rec mode (!). It blocks the UI just like launching extend.m . Only tested on a490 and ixus115 so far. Script can be executed multiple times.

edit:
On a490, following script does seem to work completely (shutter button states appear to return to 'unpressed' at the end), and a picture is taken. The events are queued and are executed after the script finishes. Adding more button events does not work.
Code: [Select]
private sub Initialize()
        System.Create()
        UI.CreatePublic()
        Wait(1000)
        ExecuteEventProcedure("PostLogicalEventForNotPowerType",0x9a1,0)  'PressSwOne
        ExecuteEventProcedure("PostLogicalEventForNotPowerType",0x9a3,0)  'PressSwTwo
        ExecuteEventProcedure("PostLogicalEventForNotPowerType",0x9a4,0)  'UnpressSwTwo
        ExecuteEventProcedure("PostLogicalEventForNotPowerType",0x9a2,0)  'UnpressSwOne
end sub
There are a few event procedures that can shoot. The most promising one, UIFS_Capture, seems to use keypress events and may suffer from the same issue as the above test script (its parameters are not trivial, so I did not try executing it).

Maybe starting with set means it runs in the same task that processes logical events, so the whole script runs while handling the "set" press?
That would be my guess too. The Canon UI code runs in context of the CtrlSrv task, which happens to process the keypress events - when the script finished.
« Last Edit: 02 / September / 2018, 16:44:02 by srsa_4c »

*

Offline reyalp

  • ******
  • 11496
Re: shooting script using Canon basic ?
« Reply #6 on: 02 / September / 2018, 17:17:06 »
After taking a look at the related code, I found it.
SET + RIGHT at the same time (press and hold SET then press RIGHT), in rec mode (!). It blocks the UI just like launching extend.m . Only tested on a490 and ixus115 so far. Script can be executed multiple times.
Nice :)
Quote
That would be my guess too. The Canon UI code runs in context of the CtrlSrv task, which happens to process the keypress events - when the script finished.
If that's the case, maybe a tiny arm binary that just started a task and called the canon run script function would be enough.

Or maybe this can even be done entirely from Canon basic
System.Create / SystemEventInit register LoadScript and UnloadScript as well as CreateTask. You would still need a real pointer to pass to createtask somehow, so some ARM code still seems to be required.

On A540, RegisterShootSeqEvent also registers ExecuteScript, but this doesn't seem to be present on newer cameras. edit: It just calls LoadScript('A/autotest.m')

Other possible areas to investigate:
The"SetScriptMode" function is somehow related to event handling.
There are also references to "A/Factory.m"
« Last Edit: 03 / September / 2018, 02:25:48 by reyalp »
Don't forget what the H stands for.

*

Offline srsa_4c

  • ******
  • 3689
Re: shooting script using Canon basic ?
« Reply #7 on: 05 / September / 2018, 15:44:41 »
Or maybe this can even be done entirely from Canon basic
System.Create / SystemEventInit register LoadScript and UnloadScript as well as CreateTask. You would still need a real pointer to pass to createtask somehow, so some ARM code still seems to be required.
That was a useful hint.
I found that the code that starts the A/autotest.m script is inside a simple function - why not start it as a task.
From a490 100f (asm syntax is not proper)
Code: [Select]
loc_FFC28348: <load_autotest_script>
    FFC28348 10 40 2D E9   push      {r4, lr}
    FFC2834C 74 10 8F E2   adr       r1, 0xFFC283C8 ; *"Script"
    FFC28350 12 0E A0 E3   mov       r0, #0x120
    FFC28354 05 F9 00 EB   bl        0xffc66770 ; <LogCameraEvent>
    FFC28358 38 00 00 EB   bl        0xffc28440
    FFC2835C 00 00 50 E3   cmp       r0, #0
    FFC28360 03 00 00 1A   bne       0xffc28374
    FFC28364 64 00 8F E2   adr       r0, 0xFFC283D0 ; *"A/autotest.m"
    FFC28368 39 EA 00 EB   bl        0xffc62c54 ; <LoadScript_FW>
    FFC2836C 00 00 50 E3   cmp       r0, #0
    FFC28370 10 80 BD 08   popeq     {r4, pc}
loc_FFC28374:
    FFC28374 01 00 A0 E3   mov       r0, #1
    FFC28378 10 80 BD E8   pop       {r4, pc}

So, here's a proof-of-concept script set (not fine-tuned), running on a490 100f.
extend.m
Code: [Select]
private sub Initialize()
System.Create()
CreateTask("cbasic1", 0x19, 0x2000, 0xFFC28348, 0) ' routine that starts A/autotest.m
end sub
autotest.m
Code: [Select]
' script runs in its own task when started by the extend.m script

private sub shoot(delay)
        ExecuteEventProcedure("PostLogicalEventForNotPowerType",0x9a1,0)  'PressSwOne
        Wait(delay)
        ExecuteEventProcedure("PostLogicalEventForNotPowerType",0x9a3,0)  'PressSwTwo
        ExecuteEventProcedure("PostLogicalEventForNotPowerType",0x9a4,0)  'UnpressSwTwo
        ExecuteEventProcedure("PostLogicalEventForNotPowerType",0x9a2,0)  'UnpressSwOne
end sub

private sub Initialize()
        System.Create()
        UI.CreatePublic()
        ExecuteEventProcedure("PostLogicalEventForNotPowerType",0x9a1,0)  'PressSwOne
        ExecuteEventProcedure("PostLogicalEventForNotPowerType",0x9a2,0)  'UnpressSwOne
        Wait(3000)
        for n1 = 0 to 2
            shoot(1000)
            Wait(3000)
        next
end sub
The two scripts go in the root dir of the card. Script needs to be started in playback mode.

If anyone wants to try: the address in the CreateTask call needs to be adapted to each camera and firmware version. Post here (your camera model and its fw version) if you're unsure.


Re: shooting script using Canon basic ?
« Reply #8 on: 06 / September / 2018, 11:01:51 »
Quote from: srsa_4c
If anyone wants to try: the address in the CreateTask call needs to be adapted to each camera and firmware version. Post here (your camera model and its fw version) if you're unsure.
Well done!  ...so is it a "no" or a "yes" ?  :P

I'll be happy to test; I've a got a M6 (that's why I've originally asked) and from the fw dump thread the version is GM1.00B.

*

Offline srsa_4c

  • ******
  • 3689
Re: shooting script using Canon basic ?
« Reply #9 on: 06 / September / 2018, 12:03:30 »
I'll be happy to test; I've a got a M6 (that's why I've originally asked) and from the fw dump thread the version is GM1.00B.
For this cam, use the following extend.m script:
Code: [Select]
private sub Initialize()
System.Create()
CreateTask("cbasic1", 0x19, 0x2000, 0xE027B7A9, 0)
end sub
autotest.m is:
Code: [Select]
' script runs in its own task when started by the extend.m script

dim disp0, msgstr

private sub shoot(delay)
        PostLogicalEventForNotPowerType(0x9a1,0)  'PressSwOne
        Wait(delay)
        PostLogicalEventForNotPowerType(0x9a3,0)  'PressSwTwo
        PostLogicalEventForNotPowerType(0x9a4,0)  'UnpressSwTwo
        PostLogicalEventForNotPowerType(0x9a2,0)  'UnpressSwOne
end sub

private sub myinit()
        System.Create() ' already done by the first script
        UI.CreatePublic()
        msgstr = AllocateMemory(80)
        disp0 = LCDMsg_Create(10,10,"Init",2)
end sub

private sub myuninit()
        LCDMsg_Delete(disp0)
        FreeMemory(msgstr)
end sub

private sub Initialize()
        myinit()
        PostLogicalEventForNotPowerType(0x9a1,0)  'PressSwOne
        PostLogicalEventForNotPowerType(0x9a2,0)  'UnpressSwOne
        Wait(3000)
        for n1 = 0 to 2
            sprintf(msgstr,"shot %d",n1)
            LCDMsg_SetStr(disp0,msgstr)
            shoot(1000)
            Wait(3000)
        next
        LCDMsg_SetStr(disp0,"Script finished")
        Wait(1000)
        myuninit()
end sub
Start the cam in playback mode and press SET.
The cam should do the following:
- display Init at the top of the screen - this text will change later
- switch to rec mode
- take 3 shots (this will only succeed if there is nothing preventing the cam from shooting)

If the text isn't visible, try adding the following line after LCDMsg_Create:
LCDMsg_ChangeColor(disp0, 1)
where you can change '1' to other integers between 0 and 65535.

If the cam crashes, try to get a romlog.

 

Related Topics