Index: ptp/PtpUsbTransport.py =================================================================== --- ptp/PtpUsbTransport.py (revision 12) +++ ptp/PtpUsbTransport.py (working copy) @@ -2,8 +2,8 @@ import PtpAbstractTransport import usb import struct +import sys - class PtpUsbTransport(PtpAbstractTransport.PtpAbstractTransport): """Class defining a PTP USB transport.""" @@ -26,6 +26,8 @@ if (device.deviceClass == usb.CLASS_HUB): raise UsbException("Supplied USB device is not a PTP device") + self.idVendor = device.idVendor + # Find the endpoints we need self.__bulkin = None self.__bulkout = None @@ -64,9 +66,11 @@ def send_ptp_request(self, request): length = 12 + (len(request.params) * 4) buffer = struct.pack(">sys.stderr, ">", " ".join(c.encode("hex") for c in buffer) if self.__usb_handle.bulkWrite(self.__bulkout, buffer, self.usb_write_timeout) != length: raise UsbException(usb.USBError) @@ -74,7 +78,9 @@ def send_ptp_data(self, request, data): buffer = struct.pack(">sys.stderr, ">", " ".join(c.encode("hex") for c in buffer) # NOTE: UNTESTED CODE while len(buffer) > 0: tmp = self.__usb_handle.bulkWrite(self.__bulkout, buffer, self.usb_write_timeout) @@ -112,6 +118,7 @@ if toread > data_size: toread = data_size + print >>sys.stderr, "<", " ".join(c.encode("hex") for c in pkt) buffer = None if (stream == None): buffer = pkt[12:12+toread] @@ -122,6 +129,7 @@ # Read the rest of the data while done != data_size: pkt = self.__usb_bulkread() + print >>sys.stderr, "<", " ".join(c.encode("hex") for c in pkt) toread = len(pkt) if toread > (data_size - done): @@ -133,11 +141,14 @@ stream.write(pkt[0:toread]) done += toread + print >>sys.stderr, "<", " ".join(c.encode("hex") for c in buffer) return (data_size, buffer) def get_ptp_response(self, request): - return self.__decode_ptp_response(request, self.__usb_bulkread()) + buffer = self.__usb_bulkread() + print >>sys.stderr, "<", " ".join(c.encode("hex") for c in buffer) + return self.__decode_ptp_response(request, buffer) def check_ptp_event(self, sessionid, timeout=None): if timeout == None: Index: ptp/CanonSupport.py =================================================================== --- ptp/CanonSupport.py (revision 0) +++ ptp/CanonSupport.py (revision 0) @@ -0,0 +1,49 @@ +import PtpSession +import PtpValues +from PtpValues import CanonOperations + +def MoveFocus(session, step): + ptp_request = PtpSession.PtpRequest(CanonOperations.MOVE_FOCUS, + session.sessionid, session.NewTransaction(), (step,)) + ptp_response, rx = session.transport.ptp_simple_transaction(ptp_request) + if ptp_response.respcode != PtpValues.StandardResponses.OK: + raise PtpSession.PtpException(ptp_response.respcode) + +def SetProp(session, prop, value): + packer = PtpSession.PtpPacker() + packer.pack("" % PtpValues.ResponseNameById(e.responsecode, 0) + def __str__(self): + return PtpValues.ResponseNameById(self.responsecode, 0) Index: Capture.py =================================================================== --- Capture.py (revision 12) +++ Capture.py (working copy) @@ -38,6 +38,7 @@ except PtpException, e: print "PTP Exception: %s" % PtpValues.ResponseNameById(e.responsecode, vendorId) + traceback.print_exc() except Exception, e: print "An exception occurred: %s" % e traceback.print_exc() Index: stack.py =================================================================== --- stack.py (revision 0) +++ stack.py (revision 0) @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Focus Stacker for Canon EOS cameras +# Copyright © 2011 Jeff Epler +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import sys +import time +from ptp.PtpUsbTransport import PtpUsbTransport +from ptp.PtpSession import PtpSession, PtpException +from ptp import PtpValues +from ptp.CanonSupport import * +from optparse import OptionParser + +nsteps = 10 +stepsize = 10 +capturedelay = .5 +focusdelay = .5 + +parser = OptionParser(version="0.0") +parser.add_option("-c", "--count", help="Number of photos to capture", + metavar="N", action="store", type="int", dest="count") +parser.add_option("-s", "--stepsize", help="Size of focus step", + metavar="N", action="store", type="int", dest="stepsize") +parser.add_option("-d", "--capture-delay", help="Delay after capture", + metavar="SECONDS", action="store", type="float", + dest="capturedelay") +parser.add_option("-f", "--focus-delay", help="Delay after focus", + metavar="SECONDS", action="store", type="float", + dest="focusdelay") +parser.set_defaults(count=10, stepsize=1, capturedelay=.1, focusdelay=.1) + +options, args = parser.parse_args() +if args: + raise SystemExit, ("Unexpected positional arguments: %s" + % " ".join(repr(a) for a in args)) + +devices = PtpUsbTransport.findptps() +if not devices: + raise SystemExit, "No PTP devices found" +if len(devices) > 1: + print >>sys.stderr, "Warning: Multple devices; who knows which one we'll use" +print devices + +transport = PtpUsbTransport(devices[0]) +session = PtpSession.PtpSession(transport) +session.OpenSession() + +vendorId = session.GetDeviceInfo().VendorExtensionID +print vendorId, PtpValues.Vendors.CANON +if vendorId != PtpValues.Vendors.CANON: + raise SystemExit, "The stacking assistant only works with Canon cameras" + +EOS_DPC_LiveView = 0xD1B0 +SetLiveView(session, 0) +SetLiveView(session, 2) + +def Operation_busywait(fn, *args, **kw): + while 1: + try: + return fn(*args, **kw) + except PtpException, detail: + if detail.responsecode == PtpValues.StandardResponses.DEVICE_BUSY: + print "busy!" + time.sleep(capturedelay) + continue + else: + raise + +try: + for i in range(options.count): + if 1: + time.sleep(options.capturedelay) + print "MoveFocus" + Operation_busywait(MoveFocus, session, options.stepsize) + print "MoveFocus done" + time.sleep(options.focusdelay) + print "Capture" + Operation_busywait(Capture, session) + print "Capture done" +finally: + pass + #SetLiveView(session, 0) Property changes on: stack.py ___________________________________________________________________ Added: svn:executable + *