Programmed file transfers... is it possible?

  • 18 Replies
  • 3306 Views
  • Publish
    Programmed file transfers... is it possible?
    « on: 22 / October / 2011, 23:10:49 »
    Advertisements
    I've been looking into buying a Canon S95 for a project I'm working on. I'd like to control the camera over USB with an embedded microprocessor. It basically needs to do two things: remotely activate the shutter (from what I understand, fairly easy to do) and transfer the picture off of the camera on to some external memory so that it can later be transmitted to something else.

    I assume that the microprocessor is going to have to act as the USB host device, at least that's what would seem to make sense to me. Is there a way to have the host request the newest picture file from the camera programmatically?

    I'm also guessing that there's going to need to be some sort of handshaking that needs to happen when the camera/microprocessor start up for the first time. Is there some documentation on what needs to happen for that? Or am I off base there?

    Any other sort of advice for making this work would be welcome. I'm new here and I'm just trying to figure out if what I want to do is possible before I go out and buy a camera.

    *

    Offline reyalp

    • ******
    • 9878
  • Publish
    Re: Programmed file transfers... is it possible?
    « Reply #1 on: 22 / October / 2011, 23:15:12 »
    You can use the CHDK PTP extension for this: http://chdk.wikia.com/wiki/PTP_Extension

    There isn't a direct way to request the most recent photo, but you can figure this from the files.

    If your controller runs linux or windows, there's client code you can easily adapt. If it's running through something else, you may have to implement a large part of the PTP stack by yourself.

    edit:
    FWIW http://www.raspberrypi.org/ looks to be a promising Linux capable controller for this sort of application.
    Don't forget what the H stands for.

  • Publish
    Re: Programmed file transfers... is it possible?
    « Reply #2 on: 23 / October / 2011, 00:27:06 »
    Ok, I was sort of guessing that I would need to look at file creation times or w/e to determine what the newest file was. That shouldn't be too difficult, I think.

    I'm not real enthusiastic about running Linux on my microcontroller, though. I was hoping the implementation would be simpler than that. The Raspberry Pi does look promising and maybe that's worth looking into.

    How difficult do you think would it be to implement as much of the PTP stack on a microproc that I would need to get done what I need done?

    *

    Offline reyalp

    • ******
    • 9878
  • Publish
    Re: Programmed file transfers... is it possible?
    « Reply #3 on: 23 / October / 2011, 22:50:11 »
    Ok, I was sort of guessing that I would need to look at file creation times or w/e to determine what the newest file was. That shouldn't be too difficult, I think.
    The CHDK PTP extension mostly operates by sending lua scripts to the camera. The lua API includes functions to list and stat files. There are also functions to access the exposure counter.
    Quote
    How difficult do you think would it be to implement as much of the PTP stack on a microproc that I would need to get done what I need done?
    It's going to depend a lot on what you are starting with and you're familiarity with the subject. If your system comes with some kind of USB stack that you are already familiar with I wouldn't expect it to be a huge deal (but then again, I've never done it). The spec for the "still image" device class  (PTP) can be found at http://www.usb.org/developers/devclass_docs#approved
    Don't forget what the H stands for.


  • Publish
    Re: Programmed file transfers... is it possible?
    « Reply #4 on: 05 / November / 2011, 17:30:11 »
    I think I've got it figured out now. I found an implementation of PTP on Arduino boards.

    http://www.circuitsathome.com/camera-control/ptp-support-for-usb-host-shield-library-2-0-released

    He even sells USB host shields that will interface with the specific board I had already picked out:

    http://www.circuitsathome.com/products-page/arduino-shields/usb-host-shield-for-arduino-pro-mini/

    Even if this implementation doesn't work with CHDK out of the box, it's definitely going to be a huge step in the right direction. I've got parts on order now and i have a camera that I can test with.

  • Publish
    Re: Programmed file transfers... is it possible?
    « Reply #5 on: 06 / November / 2011, 10:46:07 »
    Keep us posted on that, I am very interested in seeing if it can work.


    David

  • Publish
    Re: Programmed file transfers... is it possible?
    « Reply #6 on: 11 / February / 2012, 19:10:16 »
    I am doing something pretty similar too. Please let us know how it goes.

  • Publish
    Re: Programmed file transfers... is it possible?
    « Reply #7 on: 11 / February / 2012, 20:12:23 »
    As you are online Mr.nightmare75, how about a progress update ?


  • Publish
    Re: Programmed file transfers... is it possible?
    « Reply #8 on: 11 / February / 2012, 20:17:22 »
    I've made some good progress and I think it's time to share some of what I've learned. I went ahead and purchased the Arduino board and USB host shield that I posted in my last post. The first thing I found out is that my test camera (an SD870) won't acknowledge a USB host unless it senses 5v on the VBUS line. That required a modification to the USB host shield, detailed here in the hardware manual for the USB host shield:

    http://www.circuitsathome.com/usb-host-shield-hardware-manual

    From there, it doesn't take much modification at all to get the PTP code provided with the host shield to get the Arduino talking to CHDK. The only functionality I've added so far is the ability to send Lua to the camera to be executed. This will provide all of the functionality that I need for my project, but adding support for the other CHDK-specific PTP commands should be pretty trivial. I've now got functions written that put the camera into record mode and capture a photo by sending Lua instead of using PTP operations.

    I started with canonps.cpp from the USB host shield PTP library and am modifying the CanonPS class. CHDK's ptp.h needs to be included (and probably renamed first so that it isn't named the same thing as the ptp lib's ptp.h) for any of this to work. A couple of functions were added:

    Code: [Select]
    //Captures an image
    uint16_t CanonPSCHDK::Capture()
    {
    uint16_t ptp_error;
    char script[] = "shoot();";
    OperFlags flags = { 2, 2, 1, 1, 3, 0};
    uint32_t params[2];

    params[0] = PTP_CHDK_ExecuteScript;
    params[1] = PTP_CHDK_SL_LUA;

    flags.dataSize = 9;//script.length()+1;

    ptp_error = Transaction(PTP_OC_CHDK, &flags, params, &script);

    return ptp_error;
    }

    I intend to have this function set record or play mode based on the number passed to it. It's still a work in progress

    Code: [Select]
    //Puts the camera into record or play mode
    uint16_t CanonPSCHDK::SetRecordMode(int mode)
    {
            uint16_t ptp_error;
            char script[] = "switch_mode_usb(1);";
            OperFlags flags = { 2, 2, 1, 1, 3, 0};
            uint32_t params[2];
           
            params[0] = PTP_CHDK_ExecuteScript;
    params[1] = PTP_CHDK_SL_LUA;

    flags.dataSize = 20;//script.length()+1;

    ptp_error = Transaction(PTP_OC_CHDK, &flags, params, &script);

            return ptp_error;
    }

    I also changed the Initialize function so that it uses Lua instead of straight PTP:

    Code: [Select]
    uint16_t CanonPSCHDK::Initialize(bool binit)
    {
    uint16_t ptp_error;

    if (binit)
    {
    if ((ptp_error = SetRecordMode(1)) != PTP_RC_OK)
    PTPTRACE2("StartShootingMode failed: ", ptp_error);
    }
    else
    {
    if ((ptp_error = SetRecordMode(0)) != PTP_RC_OK)
    PTPTRACE2("EndShootingMode failed: ", ptp_error);
    }
    return ptp_error;
    }

    The meat-and-potatoes of this is the Transaction function, which is defined in ptp.cpp and ptp.h. The hard part of this was basically deciding how to call it and with what parameters. I'll break it down a little bit here.

    Code: [Select]
    uint16_t PTP::Transaction(uint16_t opcode, OperFlags *flags, uint32_t *params = NULL, void *pVoid = NULL)
    opcode: The opcode of the function that you want to call. The supported ptp and CHDK ptp operations are defined in their respective ptp.h files.

    OperFlags is a data type that contains a number of parameters for the operation you're running. Its submembers are:

    • opParams: the number of parameters to involved in the operation
    • rsParams: the number of parameters that are returned from the operation
    • txOperation: defines whether you're the host or receiver is sending data
    • typeOfVoid: defines the type of the operation's data. 3 means the data is a buffer
    • dataSize: The number of bytes in your data buffer

    params: This should be an array which contains the parameters of the operation. What these are depends on the operation. Operation parameters are defined in the PTP specification or in CHDK's ptp.h

    pVoid: This should be a pointer to the first element of your data buffer. I've found that trying to pass an actual string type doesn't work. Use a character array instead. The operations on strings and char arrays are similar.

    Some of this might require some knowledge of the PTP specification in order to make sense of it. I recommend finding a copy of PIMA15740-2000 on Google. This has the formal definition of all of the canonical PTP operations and should give you some idea of what's expected in a PTP transaction. I also found it very useful to look at the source code for chdkptp (http://trac.assembla.com/chdkptp) for examples.

    Sorry it's been so long between replies. I'm pretty busy with other stuff, this is just one of the projects on my plate right now. I need to figure out file transfers now. I intend to release the full source of everything once I'm finished adding new functionality, as well as some more formal documentation.

    The timing of your post was almost uncanny, DavidBowman. I had actually just sat down to start writing this post when you replied.

    Whew, I think that's everything. I'd be happy to attempt to answer questions about what I've learned so far if you're trying to do something similar.

  • Publish
    Re: Programmed file transfers... is it possible?
    « Reply #9 on: 13 / February / 2012, 11:51:38 »
    Hi,
    very cool!  :D

    Would it be possible to post the project file, which I can upload to my arduino?
    I read your post several times and copied the code provided to the arduino-editor, though obviously my programming skills are too limited to make it work  :(

    Is it also possible to receive results from the cam with this implementation?

    Thanks for your help!

    A newbie ...

     

    Related Topics