Sonntag, 27. Januar 2013

Nikon iTTL protocol: Who Master, who Slave?


Цель этих исследований -  создать эмулятор системной вспышки SB-900. Эмулятор мне нужен для работы со студийным светом в режиме HSS без участия системной вспышки. Пока все в рабочих тезисах. У меня есть предположение, что для корректной работы камеры с системной вспышкой в режиме HSS, вспышка сообщает камере о своих физических возможностях, камера учитывает их и подстраивает работу затвора. В прошлой статье я немного затронул особенности работы, но только для сигнала данных. Написал тест программу для Arduino. Но после первых проб выяснилось, что SPI контроллер Arduino очень часто сбивается. Заветное число х85 в начале пакета Arduino не ловит. У процессора Atmel нет аппаратного контроля выборки. Так что я расширил схему, добавил ещё два датчика тока на линии CLK и Direction и пересел с Arduino на Stellaris. Пару подарочных плат у меня с прошлой выставки валяется. В конечном устройстве планирую использовать MSP430.
Для начала надо было определить распределение ролей в обмене: кто в протоколе Master, а кто Slave. Для простоты понимания кто и куда, свёл все в таблицу истинности.

Стрелочкой показано направление тока. Pin3, Pin4 выводы INA193. Зная уровень сигнала на линиях CLK или DATA или SS и Direction, можно определить кто Master, а кто Slave. Для примера: на линии “1” и направлении “1” Master подключён в выводу “pin 3”.
И так, по порядку, что происходит.
Я пока не буду рассматривать момент включения камеры и вспышки. Считаем, что камера и вспышка уже включены. Я пока не планирую изучать весь протокол, поэтому не буду изменять параметры вспышки. Эмулятор будет без кнопок. Все что мне нужно -  записать кодограмму потока и потом проиграть её.  Так выглядят сигналы когда нет обмена.

800х480

800х480
На линии CLK виден цикличный сигнал с периодом 128мс и длительностью в 8мс. Интересно, что сигнал не просаживается до «0», а всего до 1,4V. Думаю так, вспышка определяет, что камера подключена.  Сигнал CKL всегда идет от вспышки.
Flash - MASTER.

800х480

800х480

800х480
Сигнал Handshake (SS).
С сигналом SS я пока полностью не определился. По логике работы этот сигнал должен генерировать Мастер. Но, если учесть направление тока в линии, то получается, что сигналом управляет камера. В состоянии сканирования сигнал установлен в “0”, после нажатия на спуск сигнал поднимается в “1”.
Датчик тока в сигнале CLK.

800х480
Датчик тока в сигнале SS. 
 
800х480
Датчик тока в сигнале SS.

800х480
С сигналами пока все.
Если с сигналами и ролями в протоколе что-то проясняется, то с содержанием сплошные вопросы. Какая очередность битов в байте, LSB or MSB? Какая кодировка информации.
Пример протокола общения между D700 и SB-900 данные в формате LSB.
(Camera)a1,
(Flash)1,1,5,2,8,7,81,78,b4,64,a,4e,ff,3e,90,3e,90,1d,
(Camera)b1,1,1,12,5,3,1,9,1c,0,f4,b0,5,0,40,24,30,24,50,0,3,53,11,24,24,24,91,a0,
(Flash)6,6,b6,6,0,2a,88,54,30,23,0,ff,ff,0,ff,0,0,0,0,0,0,1f,
(Camera)a2,
(Flash)3,6d,9b,90,86,80,7a,72,6a,65,5e,6,75,9e,8a,80,77,6f,66,60,58,6,74,9e,95,8b,80,76,66,60,59,4,5f,96,8a,82,80,7e,71,6e,6a,fc,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,b6,4,0,2a,88,54,30,23,0,ff,ff,0,6,0,0,0,0,0,0,25,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,b6,4,0,2a,88,54,30,23,0,ff,ff,0,6,0,0,0,0,0,0,25,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,b6,4,0,2a,88,54,30,23,0,ff,ff,0,6,0,0,0,0,0,0,25,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,b6,4,0,2a,88,54,30,23,0,ff,ff,0,6,0,0,0,0,0,0,25,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,b6,4,0,2a,88,54,30,23,0,ff,ff,0,6,0,0,0,0,0,0,25,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,b6,4,0,2a,88,54,30,23,0,ff,ff,0,6,0,0,0,0,0,0,25,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,b6,4,0,2a,88,54,30,23,0,ff,ff,0,6,0,0,0,0,0,0,25,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,b6,4,0,2a,88,54,30,23,0,ff,ff,0,6,0,0,0,0,0,0,25,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,b6,4,0,2a,88,54,30,23,0,ff,ff,0,6,0,0,0,0,0,0,25,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,b6,4,0,2a,88,54,30,23,0,ff,ff,0,6,0,0,0,0,0,0,25,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,b6,4,0,2a,88,54,30,23,0,ff,ff,0,6,0,0,0,0,0,0,25,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,b6,4,0,2a,88,54,30,23,0,ff,ff,0,6,0,0,0,0,0,0,25,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,b6,4,0,2a,88,54,30,23,0,ff,ff,0,6,0,0,0,0,0,0,25,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,b6,4,0,2a,88,54,30,23,0,ff,ff,0,6,0,0,0,0,0,0,25,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,b6,4,0,2a,88,54,30,23,0,ff,ff,0,6,0,0,0,0,0,0,25,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,c7,4,0,2a,99,65,30,c8,0,ff,ff,0,6,0,0,0,0,0,0,fd,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,c7,4,0,2a,99,65,30,c3,0,ff,ff,0,6,0,0,0,0,0,0,f8,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,c6,4,0,2a,98,64,30,b4,0,ff,ff,0,6,0,0,0,0,0,0,e6,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,c5,4,0,2a,97,63,30,9b,0,ff,ff,0,6,0,0,0,0,0,0,ca,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,c4,4,0,2a,96,62,30,82,0,ff,ff,0,6,0,0,0,0,0,0,ae,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,c3,4,0,2a,95,61,30,6e,0,ff,ff,0,6,0,0,0,0,0,0,97,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,c2,4,0,2a,94,60,30,5c,0,ff,ff,0,6,0,0,0,0,0,0,82,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,c0,4,0,2a,92,5e,30,50,0,ff,ff,0,6,0,0,0,0,0,0,70,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bf,4,0,2a,91,5d,30,46,0,ff,ff,0,6,0,0,0,0,0,0,63,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bd,4,0,2a,8f,5b,30,3e,0,ff,ff,0,6,0,0,0,0,0,0,55,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bc,4,0,2a,8e,5a,30,38,0,ff,ff,0,6,0,0,0,0,0,0,4c,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,34,0,ff,ff,0,6,0,0,0,0,0,0,45,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,6,0,0,0,0,0,0,43,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,6,0,0,0,0,0,0,43,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,5,0,0,0,0,0,0,42,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,4,0,0,0,0,0,0,41,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,3,0,0,0,0,0,0,40,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)b0,5,24,40,24,2f,24,50,0,3,53,11,24,24,24,b4,a0,
(Flash)7,6,bb,4,0,2a,8d,59,30,32,0,ff,ff,0,2,0,0,0,0,0,0,3f,
(Camera)e0,0,


Требуется помощь клуба.
Понять какую кодировку использует Никон.
Начать можно с фрейма “B0”.
1/250 F8
(Camera 50mm) b0,5,20,40,24,2f,24,50,0,3,43,11,24,24,24,a0,a0,
(Camera 85mm) b0,5,24,40,24,2f,24,62,0,3,7a,03,24,24,24,df,a0,
(Camera105mm) b0,5,24,40,24,2f,24,6a,0,3,41,11,24,24,24,bc,a0,


1/250 F8 2m
(Camera 50mm) b0,5,20,40,24,2f,24,50,0,3,47,11,24,24,24,a4,a0,
(Camera 85mm) b0,5,20,40,24,2f,24,62,0,3,5e,11,24,24,24,cd,a0,
(Camera105mm) b0,5,20,40,24,2f,24,6a,0,3,40,11,24,24,24,b7,a0,


1/250 F8 4m
(Camera 50mm) b0,5,20,40,24,2f,24,50,0,3,53,11,24,24,24,b0,a0,
1/500 F8 4m
(Camera 50mm) b0,5,30,40,24,36,24,50,0,3,53,11,24,24,24,c7,a0,
1/250 F11 4m
(Camera 50mm) b0,5,24,40,24,2f,2a,50,0,3,53,11,2a,24,24,c0,a0,
1/250 F1.4 4m
(Camera 50mm) b0,5,24,40,24,2f,06,50,0,3,53,11,06,24,24,78,a0,


Восьмой байт в фрейме явно определяет фокусное объектива.

Но перевести х50 в 50мм, х62 в 85мм, х6а в 105мм однозначно не получается. Я не думаю, что это табличные значения. Вспышка должна иметь таблицу на все фокусные от 8 до 600 с шагом в 1 мм. Не верю. Smiley 

Буду признателен за любые бредовые и небредовые идеи.

Успешных вам Кадров.

© Andrew Buckin.

Sonntag, 13. Januar 2013

Nikon iTTL protocol Analysis: Hardware.



В этой статье хочу изложить рабочие тезисы для взлома протокола iTTL. Перед тем как начать изучение, я посмотрел что есть в сети. В сети не очень много достоверной информации по протоколу iTTL. Любители уже многого достигли. Я хочу добавить немного своих знаний. И так.

На горячем башмаке находятся 5 контактов DATA, CLK, Query , HOT, GND.
Интерфейс похож на SPI. Частота работы ~ 62,5КГц. Сигнал DATA двунаправленный. Сигнал Query очень похож на сигнал выбора, активный уровень «0», но, по всей видимости, тоже двунаправленный, так как переходит в активное состоянии при изменении на камере и на вспышке. Для анализа я планирую использовать Arduino. Чтобы различать направление данных пришлось модернизировать кабель SC-17. Выбросил ненужные мне подключения и добавил датчик тока в разрыв линии данных.


 Думаю, что эта маленькая особенность (датчик тока) поможет мне больше.  Smiley

1024 x 442 
Жаль, что датчик тока можно поставить только в одну сторону. Я пробовал два усилителя, но увы. Падение напряжения можно измерить только в одну сторону. Если увеличить шунт до 100 ом, связь между камерой и вспышкой прекращается.  Trauriges Smiley

Ch 1 — CLK, Ch 2 – DATA, Ch 3 – Current, Ch 4 - Query.
800 x 480 
Видно что SPI работает в MODE3. Какой порядок битов (LSB or MSB ) пока определить трудно.
Пока все.
Fotostream
© Andrew Buckin.












Time machine: Price.

С момента выхода первого релиза я получил немало вопросов. Спасибо.
Одни из них связаны с ценой на прибор, могу ли я помочь платами или продать готовое устройство. Дело обстоит так. Я не обладаю сейчас производственными мощностями и не готов поставить «Машину времени.» Но это не означает, что вы сами не можете повторить устройство. Схемы и платы распространяются по General Public License. Стоимость я свёл в таблицу. В этой таблице не учтена стоимость работы и печатные платы. От страны к стране цены могут изменяться.   
Price
Успехов в сборке.
© Andrew Buckin.

Samstag, 5. Januar 2013

Time machine: Release One.



Camera Control with Arduino.
Myths and realities Х-sync with studio light.
Time machine: Display.
Time machine: Power.
Time machine: Microphone.
Time machine: Analog.
Time machine: Encoder.

Шаг за шагом я добрался до готового устройства. Схема закончена, платы заказаны, базовый код написан, ошибки найдены и исправлены. Вспоминая закон «Мерфи» в это поверить трудно. Но пока так и останется. Если ошибки и есть, то это будут не ошибки, а скрытые возможности.

Подведём итоги:

Питается всё от батарейки 9В. Аккумулятора 200мАч должно хватить на 7 часов работы, щелочной батарейки на 23 часа работы, с литий-тионил батарейкой можно работать 44 часа непрерывно. Максимальное входное напряжение 40В. Это на тот случай, если нет под рукой подходящей батарейки. Из  органов управления есть всего один энкодер, пока неудобства не испытывал. Вся информация отображается на OLED дисплее. В устройстве есть два входа: логический и для микрофона. Все входы разведены на стандартный аудио штекер 3,5мм. К логическому входу кроме камеры можно подключить фототранзистор или фотодиод. Есть три гальванически развязанных выхода. Выходы «1» и «2» совмещены и разведены на штекер 2,5мм, сюда можно подсоединить дистанционный кабель камеры. Выход «3» разведён на штекер 3,5мм и «горячий башмак», можно установить вспышку или радио - триггер непосредственно на «МВ». К выходу «3» можно подключать высоковольтные устройства до 300В. Из железа пока ничего больше не планируется. Есть пару идей в будущем добавить bluetooth и организовать сеть между приборами и управлять всем через смарт телефон.
 
 


О программе.

В первую очередь в этом релизе делался упор на совместную работу «МВ» и студийного света.
/*
 * @name        Time machine.
 * @version     1.0
 * @web         http://karu2003.blogspot.de/
 * @author      Andrew Buckin, Eugene Glushko.
 *
 *
 * "Time machine" 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 3 of the License, or
 * (at your option) any later version.
 *
 * "Time machine" 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 "Time machine".  If not, see <http://www.gnu.org/licenses/>.
 * Questions?  Send mail to ka_ru2003@msn.com
 */

#include <Wire.h>
#include <math.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define NO_PORTD_PINCHANGES
#define NO_PORTB_PINCHANGES

#include <PinChangeInt.h>
#include <SPI.h>

#include <EEPROM.h>

#define OLED_RESET_PIN 10

struct delay_entry_t {
    uint16_t exposure;
    uint16_t delay;
    uint8_t  dirty;
};

enum ui_mode_e {
    BROWSING,
    EDITING
};

enum gen_mode_e {
    IDLE,
    DELAY,
    PULSE
};

struct status_t {
    ui_mode_e  ui_mode;
    gen_mode_e gen_mode;
    int8_t     index;
    int8_t     digit;
};

delay_entry_t entries[] = {
//    { 60,   1001, 0 },
//    { 80,   1002, 0 },
//    { 100,  1003, 0 },
//    { 125,  1004, 0 },
//    { 160,  1005, 0 },
//    { 200,  1006, 0 },
    { 250,  1007, 0 },
//    { 320,  1008, 0 },
//    { 400,  1009, 0 },
    { 500,  1010, 0 },
//    { 640,  1011, 0 },
//    { 800,  1012, 0 },
    { 1000, 1013, 0 },
//    { 1250, 1014, 0 },
//    { 1600, 1015, 0 },
    { 2000, 1016, 0 },
//    { 2500, 1017, 0 },
//    { 3200, 1018, 0 },
    { 4000, 1019, 0 },
//    { 5000, 1020, 0 },
//    { 6400, 1021, 0 },
    { 8000, 1022, 0 }
};

#define SAVE_EVENT 1
#define SHDN_EVENT 2

#define DEBOUNCING_INTERVAL 20
#define SAVE_INTERVAL       2000
#define SHDN_INTERVAL       5000

#define DEFAULT_INVERSE_MASK 0

#define PULSE_DELAY 500

#define A_EN_PIN A3
#define B_EN_PIN A2
#define INT_PIN  A1
#define KILL_PIN A0

#define FLASH_IN 2

#define OUT1_PIN 4
#define OUT2_PIN 5
#define OUT3_PIN 8

#define VREF 6

#define TPL0501_CS1 7  // Vref
#define TPL0501_CS2 9  // Gain

#define AIN_PIN  A6

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

#define TEXT_SIZE 2

Adafruit_SSD1306 display(OLED_RESET_PIN);

volatile status_t status = { BROWSING, IDLE, 0, 0 };

char screen_buf[9] = { 0 };
uint8_t inverse_mask = DEFAULT_INVERSE_MASK;

static volatile uint8_t button_clicks = 0;
static volatile uint8_t events = 0;

static volatile uint8_t need_reinit_display = 0;
static volatile uint8_t need_redraw = 0;

// interrupt service routine vars
volatile boolean ABc = false;
volatile boolean BBc = false;
volatile boolean AAc = false;
volatile boolean BAc = false;
volatile int8_t clicks = 0;      // Counter to indicate cumulative clicks in either direction
volatile int8_t direction = NULL;   // indicator
volatile int8_t enc = NULL;   // indicator

void setup()
{
    display.begin(SSD1306_SWITCHCAPVCC);
    display.setTextSize(TEXT_SIZE);

    displayPrint("READING", DEFAULT_INVERSE_MASK);
    readDelays();
    delay(500);

    renderScreen();
    displayPrint(screen_buf, inverse_mask);

    pinMode(INT_PIN, INPUT);
    pinMode(A_EN_PIN, INPUT);
    pinMode(B_EN_PIN, INPUT);
    pinMode(FLASH_IN, INPUT);

    digitalWrite(FLASH_IN, HIGH);

    pinMode(OUT1_PIN, OUTPUT);
    pinMode(OUT2_PIN, OUTPUT);
    pinMode(OUT3_PIN, OUTPUT);

    TCCR1A = 0x00;
    TCCR1C = 0x00;
    TIMSK1 &= ~_BV(TOIE1);

    attachInterrupt(0, int0_isr, FALLING);
    
    PCintPort::attachInterrupt(A_EN_PIN, &doEncoderA, CHANGE);
    PCintPort::attachInterrupt(B_EN_PIN, &doEncoderB, CHANGE);
//----------SPI init    
    pinMode (TPL0501_CS1, OUTPUT);
    pinMode (TPL0501_CS2, OUTPUT);
    digitalWrite(TPL0501_CS1,HIGH);
    digitalWrite(TPL0501_CS2,HIGH);
    SPI.begin();
    Serial.begin(9600);
}

void loop()
{
    int8_t clicks = 0;

    for (;;) {
        handle_button();
        handle_events();
        
        if (direction != NULL){
         enc = !NULL;
          if (direction > 0) clicks=+1;
          else clicks=-1;
         direction = NULL;
        }
        if (enc != NULL) {
            
            need_redraw = 1;
            if (status.ui_mode == BROWSING) {
                status.index =
                        wrap(status.index + clicks, ARRAY_SIZE(entries));
            } else {
                edit_digit(clicks);
            }
            enc = NULL;
        }

        if (get_button_clicks()) {
            need_redraw = 1;
            if (status.ui_mode == BROWSING) {
                status.ui_mode = EDITING;
                status.digit = 0;
            } else {
                status.digit++;
                if (status.digit == 4) {
                    status.ui_mode = BROWSING;
                }
            }
        }

        if (need_redraw || need_reinit_display) {
            need_redraw = 0;
            renderScreen();
            displayPrint(screen_buf, inverse_mask);
        }
    }
}

void edit_digit(int8_t delta)
{
    uint8_t digits[4];
    uint16_t number = entries[status.index].delay;
    switch (status.digit) {
    case 0:
      number = number + (delta *1000);
      if (number >= 10000){number = number - (delta *1000);}
      break;
    case 1:
      number = number + (delta *100);
      if (number >= 10000) {number = number - (delta *100);}
      break;
    case 2:
      number = number + (delta *10);
      if (number >= 10000) {number = number - (delta *10);}
      break;
    case 3:
      number = number + (delta *1);
      if (number >= 10000) {number = number - (delta *1);}
      break;      
    }
    Serial.println(number, DEC);
    entries[status.index].delay = number;
    entries[status.index].dirty = 1;
}

uint8_t handle_events()
{
    if (events & _BV(SAVE_EVENT)) {
        displayPrint("SAVING", 0);
        writeDelays();
        delay(500);
        events &= ~(_BV(SAVE_EVENT));
        status.ui_mode = BROWSING;
        need_redraw = 1;
        return 1;
    } else if (events & _BV(SHDN_EVENT)) {
        displayPrint("SHUTDOWN", 0);
        delay(500);
        digitalWrite(KILL_PIN, 0);

        for (;;)
            ;

        return 0;
    }
}

int8_t wrap(int8_t value, int8_t limit)
{
    return (value >= 0) ? value % limit
                        : limit - (-value % limit);
}

void readDelays()
{
    for (uint16_t i = 0; i < ARRAY_SIZE(entries); i++) {
        uint8_t lo = EEPROM.read(i * 2);
        uint8_t hi = EEPROM.read(i * 2 + 1);

        uint16_t dly = (hi << 8) + lo;

        entries[i].delay = dly >= 10000 ? 9999 : dly;
    }
}

void writeDelays()
{
    for (uint16_t i = 0; i < ARRAY_SIZE(entries); i++) {
        if (entries[i].dirty) {
            EEPROM.write(i * 2, entries[i].delay & 0xFF);
            EEPROM.write(i * 2 + 1, entries[i].delay >> 8);
        }
    }
}

void renderScreen()
{
    if (status.ui_mode == BROWSING) {
        inverse_mask = 0x00;
    } else {
        inverse_mask = _BV(4 + status.digit);
    }

    strcpy(screen_buf, format_exposure(entries[status.index].exposure));
    if (status.ui_mode == BROWSING){
    strcat(screen_buf, ">");
    }
    if (status.ui_mode == EDITING){
    strcat(screen_buf, "<");
    }
    
    strcat(screen_buf, i2a(entries[status.index].delay, DEC, 4));
}

void displayPrint(char *s, uint8_t inverse_mask)
{
    uint16_t len = strlen(s);

    if (len > 8) {
        len = 8;
    }

    if (need_reinit_display) {
        display.begin(SSD1306_SWITCHCAPVCC);
        display.setTextSize(TEXT_SIZE);
        need_reinit_display = 0;
    }

    display.setCursor(0, 1);
    display.clearDisplay();
    display.fillRect(0, 0, display.width(), display.height(), BLACK);

    for (uint8_t i = 0; i < len; i++) {
        if (((inverse_mask >> i) & 0x01) == 1) {
             display.setTextColor(BLACK, WHITE);
        } else {
            display.setTextColor(WHITE, BLACK);
        }
        display.print(s[i]);
    }

    display.setTextColor(WHITE, BLACK);
    display.display();
}

char *format_exposure(uint16_t exposure)
{

#define MAX_EXPOSURE_STRING_LENGTH 4
#define THOUSANDS_POS              0
#define HUNDREDS_POS               2

    static char exposure_str[MAX_EXPOSURE_STRING_LENGTH] = "0K0";

#define DEC 10

    if (exposure < 1000) {
        return i2a(exposure, DEC, 3);
    }

#define ERROR_STR "???"

    if (exposure >= 10000) {
        return ERROR_STR;
    }

    uint8_t thousands = (exposure / 1000);
    uint8_t hundreds = (exposure - thousands * 1000) / 100;

    exposure_str[THOUSANDS_POS] = thousands + '0';
    exposure_str[HUNDREDS_POS] = hundreds + '0';

    return exposure_str;
}

char *i2a(int32_t i, uint8_t base, int8_t positions)
{
    enum { PLUS, MINUS };

#define I2A_BUF_LEN 12

    static char buf[I2A_BUF_LEN] = { 0 };
    uint8_t j = I2A_BUF_LEN - 2;
    uint8_t sign = PLUS;

    int8_t positions_left = 0;

    if (i == 0) {
        if (positions == 0) {
            buf[j--] = '0';
        } else {
            while (j && positions--) {
                buf[j--] = '0';
            }
        }
        return &buf[j + 1];
    } else if (i < 0) {
        i = -i;
        sign = MINUS;
    }

    base = base < BIN ? BIN : base;
    base = base > HEX ? HEX : base;

    for(; i && j; j--, i /= base) {
        buf[j] = "0123456789ABCDEF"[i % base];
    }

    if (sign == MINUS) {
        buf[j--] = '-';
    } else {
        positions_left = positions - (I2A_BUF_LEN - (int8_t) j) + 2;
        while (j && positions_left > 0) {
            buf[j--] = '0';
            positions_left--;
        }
    }

    return &buf[j + 1];
}

uint8_t get_button_clicks()
{
    uint8_t i = button_clicks;

    button_clicks = 0;

    return i;
}

void handle_button()
{
    static uint32_t timestamp = 0;
    static uint8_t debouncing = 0;
    static uint8_t holding = 0;
    static uint8_t saved = 0;

    uint8_t button_state;

    button_state = digitalRead(INT_PIN);

    if (debouncing) {
        if (millis() - timestamp > DEBOUNCING_INTERVAL) {
            debouncing = 0;
            if (button_state == LOW) {
                holding = 1;
                button_clicks++;
            } else {
                timestamp = 0;
            }
        }
        return;
    }

    if (button_state == HIGH) {
        timestamp = 0;
        holding = 0;
        saved = 0;
        return;
    }

    if (!holding) {
        timestamp = millis();
        debouncing = 1;
        return;
    }

    if (millis() - timestamp > SAVE_INTERVAL && !saved) {
        events |= _BV(SAVE_EVENT);
        saved = 1;
        return;
    }

    if (millis() - timestamp > SHDN_INTERVAL) {
        events |= _BV(SHDN_EVENT);
        return;
    }
}

#define TCNT1_PULSE (65536 - (50 << 1))
ISR(TIMER1_OVF_vect)
{
    noInterrupts();
    TIMSK1 &= ~(_BV(TOIE1));
    
    if (status.gen_mode == DELAY) {
        status.gen_mode = PULSE;    

        TCNT1H = (TCNT1_PULSE >> 8);
        TCNT1L = (TCNT1_PULSE & 0xFF);

        digitalWrite(OUT1_PIN, HIGH);
        digitalWrite(OUT2_PIN, HIGH);
        digitalWrite(OUT3_PIN, HIGH);
        
        TIMSK1 |= (1 << TOIE1);   // enable timer overflow interrupt
        //interrupts();
    } //else {
    if (status.gen_mode == PULSE) {
        status.gen_mode = IDLE; 
        digitalWrite(OUT1_PIN, LOW);
        digitalWrite(OUT2_PIN, LOW);
        digitalWrite(OUT3_PIN, LOW);
        
        TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
        
        need_reinit_display = 1;
        //interrupts();
    }
    interrupts();
}

void int0_isr()
{
    noInterrupts();
    if (status.gen_mode == IDLE) {
        status.gen_mode = DELAY;

        uint16_t counter = entries[status.index].delay << 1;
        if (counter == 0) counter = 1;
        counter = 65536-counter;
        TCNT1H = (counter >> 8);
        TCNT1L = (counter & 0xFF);

        // 16MHz / 8 -> 0.5 us / tick
        TCCR1B |= (1 << CS11);    // 8 prescaler 
        TIMSK1 |= (1 << TOIE1);   // enable timer overflow interrupt
        
    }
    interrupts();
}

int Pot_value_SET(int Chip, int value) {
  // take the SS pin low to select the chip:
  digitalWrite(Chip,LOW);
  //  send in the value via SPI:
  SPI.transfer(value);
  // take the SS pin high to de-select the chip:
  digitalWrite(Chip,HIGH);
}

// Interrupt on A changing state
void doEncoderA(){
  AAc = digitalRead(A_EN_PIN);
  BAc = digitalRead(B_EN_PIN);
  if (!ABc && AAc && !BBc && !BAc){direction=1 ;}
  if (ABc && !AAc && BBc && BAc){direction=1;}
  if (!ABc && AAc && BBc && BAc){direction=-1;}
  if (ABc && !AAc && !BBc && !BAc){direction=-1;}
}

// Interrupt on B changing state
void doEncoderB(){
  ABc = digitalRead(A_EN_PIN);
  BBc = digitalRead(B_EN_PIN);
}


В одной из своих ранних статей я описывал  возможность работы студийного света на выдержках до 1/8000. Этот релиз заточен под скоростную съёмку в студии.  Всё управление осуществляется энкодером и кнопкой.



Кнопкой меняются режимы работы, а вращая энкодер можно изменить значения задержек.

Навигация.

Коротким нажатием прибор включается. После включения, на дисплее появиться сообщение «READING». Инициализируется прибор, читаются данные из постоянной памяти в оперативную, и прибор переходит в рабочей режим - BROWSING. Дисплей разбит на три области, первые три цифры показывают выдержку, символ «>» указывает что прибор в режиме «BROWSING», символ «<» указывает что прибор находиться в режиме «EDITING». Оставшиеся четыре знака показывают значение задержи в микросекундах, минимальная задержка 1мкС, максимальная задержка 9999мкС. В режиме «BROWSING» вращая энкодер можно выбрать выдержки. Я остановился на целых значения выдержек 1/250,1/500,1/1000,1/2000,1/4000,1/8000. Для любителей дробных величин «EV» можно убрать комментарии в программе. На дисплее выдержки показываются как 250,500,1К0,2К0,4К0,8К0 соответственно. :) Коротким нажатием на кнопку прибор переходит в режим EDITING. Редактируемый разряд показывается с инверсией. Вращая энкодер изменяем значения разряда +/-1000, +/-100, +/-10, +/-1. Перейти к следующему разряду можно коротким нажатием на кнопку. После редактирования последнего разряда прибор переходит в режим BROWSING. Всю последовательность я постарался показать в схеме. :)



Удерживая кнопку нажатой 2 секунды можно сохранить значения задержек в постоянную память. При включении не надо  настраивать «МВ» по новой. Если удерживать кнопку нажатой более 5 секунд, «МВ» выключиться. Это базовый набор команд. С дальнейшим развитием проекта функций будет больше.
   
Работа с «MB» на коротких выдержках.

В первую очередь хочу отметить, что работать можно с любым студийным светом. Сейчас выпускается свет по технологии с IGBT транзисторами, и без IGBT. Студийный свет с IGBT транзисторами более новая технология. Основное отличие между старой и новой технологией -  это длительность импульса и количество света при этом. У блоков на IGBT самая большая длительность импульса на максимальной мощности. У старых приборов все наоборот -  на максимальной мощности самая маленькая длительность. В добавок ко всему этому для генераторов существуют быстрые и медленные головы. Чтобы не запутывать вас больше, и не грузить вас электроникой, напишу коротко — для лучших результатов нужен длинный (широкий) импульс. Так сложилось что у меня самый широкий импульс с кольцевой вспышкой на максимальной мощности, и все особенности настройки я опишу для этого света. Можно порадоваться за владельцев старых систем, у них самый длинный импульс. :) Они могут снимать на меньшей мощности и на самых коротких выдержках.
 
Всё по порядку.

Нужна системная вспышка. В моём случае это SB-900. Вспышку нужно установить на камеру, переключить в режим M + FP на мощности 1/128. Подключить логический вход «Машины Времени» к PC разъёму камеры. Выход «3» подключить к моно-блоку.


На моно-блоке или генераторе нужно выключить светоловушку. Теперь нужно настроить задержки в «МВ» и повторить настройку для каждой выдержки. Выдержку на камере и «МВ» нужно синхронизовать самому. После настройки не забудьте сохранить значения в постоянную память. Для подбора задержек нужно сделать от 5 до 10 кадров. Я фотографирую белую стену.
Для примера: На камере выдержка 1/500. На «МВ» нужно установить 500, перейти в режим EDITING, установить 9000 и сделать пробный кард. Полученный кард нужно оценивать по наличию градиенты. Изменяя задержку в минус, нужно добиться, чтобы градиенты не было или она равномерно расходилась от центра кадра вверх и вниз. Для моего моно блока самая оптимальная задержка для выдержки 1/500 получилась 2000мкС. Такую процедуру нужно повторить для каждой выдержки.






После настройки у меня получились такие цифры.
1/500 — 2000uS.
1/1000 – 1500uS.
1/2000 – 1100uS.
1/8000 – 600uS.

С уменьшением выдержки нужно добавлять мощность на блоке. В моём генераторе на выдержке 1/8000 мне пришлось добавить 2 стопа относительно к 1/500, чтобы получить кадр с контролируемой градиентой. Увы электроника не всемогуща. Существуют блоки, с которыми нормально работать можно только до выдержки 1/2000.

Пару сравнительных примеров с «МВ» и без.

Это снимок работающего винчестера, скорость вращения 5400 оборотов в минуту. Виден смаз. 

С выдержкой 1/8000 всё замёрзло.


У меня есть старый серверный винчестер с 10000 rmp. Я сделал пару кадров и с ним. Тут видно, что камера уже не успевает. Смаз есть даже на 1/8000.




Пару кадров с водой.




В этих снимках я сделал маленькую ошибку установил фокус на душ, а надо было на воду. Но даже так хорошо видно, как, на выдержке 1/8000, вода разлетелась на отдельные капли, и кадр получился более эффектным и динамичным.

Удачных вам кадров.

© Andrew Buckin.

PS: Большое спасибо Жене в подготовке первого релиза. Все фотографии в большом разрешении есть у меня на Flickr.

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


Shutterstock Dreamstime
Fotostream http://www.flickr.com