10/22/2007

Экспозиция более 30 секунд на цифровой камере: Long-time remote shooting

Задача: требуется фотографировать с выдержками более 30 секунд ("от руки") и есть необходимость этот процесс автоматизировать.
Решение: при помощи паяльника, доступных электрических компонентов и скрипта на bash можно снимать с длительными выдержками без необходимости стоять с камерой и держать кнопку.


Исходные данные
Имеется цифровая фотокамера Canon EOS 400D, Debian-powered ноутбук и необходимость снимать фотографии с выдержкой более 30 секунд. Если немного погуглить, то можно найти замечательную схему, которую предлагает Michael A. Covington здесь. На всякий случай дублирую её тут:



Схема прекрасная, но она подходит для Canon EOS 300D, а для 400D нет - если её спаять и попробовать управлять 400D, то затвор будет только подниматься, но не опускаться. То есть нет возможности остановить экспозицию в нужный момент, кроме как выключить камеру.


Схема для Canon EOS 400D
Долго ли, коротко, однако я с коллегой, Алексеем Ропяным, экспериментальным путём выяснили, что закрывает затвор фотоаппарат по сигналу с другого контакта, и Алексей предложил схему изменить вот так:



И это сработало: наш лабораторный Canon EOS 400D стал открывать и закрывать затвор по команде с компьютера!


Необходимые компоненты
Для того, чтобы спаять шнурок управления камерой, требуется некоторое количество четырёхжильного кабеля (от аудиоаппаратуры или простой телефонный провод), jack на 2.5мм (он же 3/32 inch), указанные на схеме радиоэлементы (можно купить в Chip&Dip), 9-контактный COM-порт и соответственно переходник USB-COM (чтобы можно было использовать и на современных компьютерах, и на старых), а так же паяльник и немного терпения.

Переходник USB-COM лучше всего брать на чипе Profilic 2303 - это самый распространённый чип и в Линукс работает "из коробки".


Программное обеспечение
Для управления камерой требуется одна маленькая утилита, которую мне подсказали на Астрофоруме (обсуждение велось в теме "Выдержка более 30 сек. через комп?" тут и "Чем Linux полезен ЛА?" здесь).

Программа называется setSerialSignal и её исходник находится здесь. Скомпилировать её GCC, который входит в любой дистрибутив *nix-систем:
gcc -o setSerialSignal setSerialSignal.c
Проверялось на системе Debian GNU/Linux v4.0 r.0 "Etch", gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21).

На всякий случай дублирую исходный код программы:

/*
* setSerialSignal v0.1 9/13/01
* www.embeddedlinuxinterfacing.com
*
*
* The original location of this source is
* http://www.embeddedlinuxinterfacing.com/chapters/06/setSerialSignal.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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
*/
/* setSerialSignal
* setSerialSignal sets the DTR and RTS serial port control signals.
* This program queries the serial port status then sets or clears
* the DTR or RTS bits based on user supplied command line setting.
*
* setSerialSignal clears the HUPCL bit. With the HUPCL bit set,
* when you close the serial port, the Linux serial port driver
* will drop DTR (assertion level 1, negative RS-232 voltage). By
* clearing the HUPCL bit, the serial port driver leaves the
* assertion level of DTR alone when the port is closed.
*/

/*
gcc -o setSerialSignal setSerialSignal.c
*/


#include
#include
#include

/* we need a termios structure to clear the HUPCL bit */
struct termios tio;

int main(int argc, char *argv[])
{
int fd;
int status;

if (argc != 4)
{
printf("Usage: setSerialSignal port DTR RTS\n");
printf("Usage: setSerialSignal /dev/ttyS0|/dev/ttyS1 0|1 0|1\n");
exit( 1 );
}

if ((fd = open(argv[1],O_RDWR)) < 0)
{
printf("Couldn't open %s\n",argv[1]);
exit(1);
}
tcgetattr(fd, &tio); /* get the termio information */
tio.c_cflag &= ~HUPCL; /* clear the HUPCL bit */
tcsetattr(fd, TCSANOW, &tio); /* set the termio information */

ioctl(fd, TIOCMGET, &status); /* get the serial port status */

if ( argv[2][0] == '1' ) /* set the DTR line */
status &= ~TIOCM_DTR;
else
status |= TIOCM_DTR;

if ( argv[3][0] == '1' ) /* set the RTS line */
status &= ~TIOCM_RTS;
else
status |= TIOCM_RTS;

ioctl(fd, TIOCMSET, &status); /* set the serial port status */

close(fd); /* close the device file */
}



Посылаемые сигналы
Программу собираем и даём ей необходимые права на выполнение, а ниже - сигналы, посылаемые в порт программой, и их передача setSetialSignal:

Сигнал DTR
setSerialSignal /dev/ttyS0 1 0



Сброс сигнала DTR
setSerialSignal /dev/ttyS0 0 0


Сигнал RTS
setSerialSignal /dev/ttyS0 0 1


Сброс сигнала RTS
setSerialSignal /dev/ttyS0 1 1


Всё это обеспечивает вам возможность управления камерой: открытие происходит по сигналу DTR, закрытие - сигналу RTS.


Скрипт управления камерой
Дальше удобно воспользоваться простым скриптом, который написал Евгений Ромас aka BrainBug, но для случая с 400D я скрипт немного поправил, и теперь он выглядит так:

#!/bin/bash

for i in `seq $3`; do
{
setSerialSignal /dev/ttyUSB0 0 0 &&
sleep $1 && setSerialSignal /dev/ttyUSB0 0 1 &&
sleep 0.3 && setSerialSignal /dev/ttyUSB0 0 0 &&
sleep $2 && setSerialSignal /dev/ttyUSB0 1 1 && echo "One more image captured!" &&
sleep $4;

}
done

echo "Done!"

Параметры скрипта:
1: задержка поднятия зеркала
2: время выдержки в секундах
3: количество кадров
4: задержка между кадрами

Пример:
make_captures 4 60 30 2

Скрипт расчитан на работу с переходником USB-COM, и если у вас другой номер порта - естественно, скрипт нужно немного поправить.


Как это работает
Итак, шнурок спаян, переходник USB-COM включён в USB или сам шнурок вставлен в COM-порт, софт скомпилирован и наделён необходимыми правами. Изложение ориентировано на любую *nix-систему, в данном случае это Debian GNU/Linux.
  • Включаем камеру, переводим её в режим BULB, выставляем значение диафрагмы и ISO, а так же другие параметры при необходимости.
  • Вставляем jack в разъём фотокамеры, а противоположный конец в COM-порт или COM-USB переходник и далее в USB-порт компьютера.
  • Убеждаемся (в случае USB), что переходник опознан и работает: dmesg должен выдать что-то вроде:
usb 2-1: new full speed USB device using uhci_hcd and address 2
usb 2-1: configuration #1 chosen from 1 choice
drivers/usb/serial/usb-serial.c: USB Serial support registered for pl2303
pl2303 2-1:1.0: pl2303 converter detected
usb 2-1: pl2303 converter now attached to ttyUSB0
usbcore: registered new interface driver pl2303
drivers/usb/serial/pl2303.c: Prolific PL2303 USB to serial adaptor driver
  • Всё готово, теперь снимаем при помощи команды:
    make_capture 1 5 2 3
В этом примере будет сделано 2 кадра с экспозицией 5 секунд, задержка между кадрами 3 секунды, задержка поднятия зеркала 1 секунда.
Следует так же отметить, что таким способом можно отсекать выдержки от 1 секунды и больше по Exif. Физически передавать сигнал можно и быстрее, однако в Exif при этом пишутся неправильные данные. Точно так же, выдержки в данном случае отсекаются с точностью 1 секунда. Впрочем, для установки, которая должна отсекать длинные выдержки, это приемлемо.

Данное устройство с успехом применяется в оптическом эксперименте для снятия изображений с длинной выдержкой. Конкретно: применяется в оптико-цифровом корреляторе. Кроме того, может быть полезно астрономам-любителям для фотографирования астрономических объектов с длительной экспозицией.

Работает на камерах по крайней мере с firmware 1.0.4, имеются частные сообщения, что оригинальная схема должна работать с 400D. Выясняется в настоящее время.

Благодарности
Эта статья появилась в результате усилий многих людей, которых мне хотелось бы поблагодарить за помощь:
  • Michael A. Covington for his original article "Building a Cable Release and Serial-Port Cable for the Canon EOS 300D Digital Rebel".
  • Евгению Ромасу aka BrainBug за ссылку на оригинальную статью по управлению фотоаппаратом при помощи COM-порта, а так же за ценные мысли, высказанные в частных сообщениях.
  • Антону aka NTRNO за то, что выискал ключевые посты в недрах Астрофорума и выдал идеи по управлению камерой в Linux.
  • Всем участникам Астрофорума, так или иначе участвовавших в темах управления фотокамерой при помощи компьютера.
  • Алексею Ропяному, который экспериментально выяснил особенность фотокамеры, предложил изменить схему и использовать сигнал DTR для закрывания затвора.
  • Леониду Серёжкину за реализацию схемы в железе.
А так же огромная благодарность сотрудникам кафедры Физики твёрдого тела №25 МИФИ за поддержку и понимание.

12 комментариев:

  1. Вообще-то для работы с последовательным портов есть libdevice-serialport-perl, которая не требует компиляции.

    ОтветитьУдалить
  2. Лёхе Ропяному привет от бывших сокурсников :) М., бывш. каф. 60 :)

    ОтветитьУдалить
  3. А можно вопрос? Зачем это нужно, если есть стандартный софт от Canon?

    ОтветитьУдалить
  4. 2 Stanislav пишет...
    Вообще-то для работы с последовательным портов есть libdevice-serialport-perl, которая не требует компиляции.
    Спасибо, я не знал этого. Учту.

    2 Вээээ! пишет...
    Лёхе Ропяному привет от бывших сокурсников :) М., бывш. каф. 60 :)
    Обязательно передам. Собственно, Алексей нам и помог переделать схему.

    2 UncleSam пишет...
    А можно вопрос? Зачем это нужно, если есть стандартный софт от Canon?
    А что, по ссылкам ходить уже не модно? 1. Софт под мастдай и кривой. 2. Он не умеет отсекать выдержки больше 30секунд.

    ОтветитьУдалить
  5. Установи gphoto2 сотоварищи и
    добавь после << echo "Done!" >>

    (Флешка должна быть пустой)

    # Lets get all shots
    echo "Downloading files ..."
    gphoto2 --get-all-files
    echo "All shots saved!"

    # Lets clear flash
    echo "Clearing FLASH ..."
    gphoto2 --delete-all-files
    echo "FLASH card clear !"

    ОтветитьУдалить
  6. Я в технике не силен, но вы пытаетесь управлять затвором с компа? игде это может быть применимо? ведь не пойду я фотографировать горы со всем этим набором

    ОтветитьУдалить
  7. 2 Mef_Poter пишет...
    Установи gphoto2 сотоварищи и
    добавь после << echo "Done!" >>

    Спасибо, попробую.


    2 Анонимный пишет...
    Я в технике не силен, но вы пытаетесь управлять затвором с компа?
    Да, так и есть.

    игде это может быть применимо?
    Ну, если почитать пост повнимательней, особенно в конце - там написано про сотрудников кафедры моего ВУЗа. Логично предположить, что это не фотографы :-)

    Данное устройство с успехом применяется в оптическом эксперименте для снятия изображений с длинной выдержкой. Конкретно: применяется в оптико-цифровом корреляторе.

    ведь не пойду я фотографировать горы со всем этим набором
    Вы, может, и не пойдёте, а вот астрономы-любители пойдут - более того, уже ходили :-) На Астрофоруме есть замечательный человек, Евгений Ромас aka BrainBug. Он ходил. Лично :-)

    Но вопрос правильный, пост поправил.

    ОтветитьУдалить
  8. А кеноновский софт с компа не позволяет управлять длительной выжержкой?

    ОтветитьУдалить
  9. 2 Анонимный пишет...
    А кеноновский софт с компа не позволяет управлять длительной выжержкой?
    Так о том и песня поётся... кеноновский софт, писаный индусскими жрецами, время от времени не может с камерой соединиться, не то что выдержки длинные поставить.

    Сей способ есть единственное автоматизированное средство.

    ОтветитьУдалить
  10. а под usb не пробовали сразу ваять?

    ОтветитьУдалить
  11. Ghoul, можно и сразу под USB. Тогда в схему уже по дефолту вставится чип Profilic 2303. Схем много, можешь и сам додумать как, что и куда.

    ОтветитьУдалить
  12. Sorry, что пишу через столько времени -- только сейчас прочитал. Вы не павильно сделали вывод об управлении затвором. В Canon EOS у пульта дистанционного управления три провода -- "минус" (М), "автофокус" (АФ) и "затвор" (З). Замыкание М+АФ приводит к срабатыванию автофокуса, а М+З -- к спуску затвора. Они работают независимо -- замыкаем М+З и сколько держим, столько и длится экспозиция (если выставлен BULB). Так во всех Canon EOS -- проверено лично на 350D, 400D, 40D, 1000D... Затык, на который вы указали, скорее всего связан с тем, что в настройках был выставлен приподъём зеркала. Тогда первое замыкание М+З подымает зеркало, а второе -- спускает затвор.
    Сам спаял не один такой пульт.

    P.S. А вообще, спасибо за блог -- много полезного для себя нашёл.

    ОтветитьУдалить