Мое фото: Canon EOS 650D: f/4, 18 мм, 949 сек, ISO-200 (10 км от города и небо сильно засвечено).
Захотелось мне пофотографировать звезды на длинных выдержках. Так, чтобы оставить фотоаппарат неподвижным хотя бы минут на 10-15 и увидеть, как поворачиваются звезды вокруг Полярной звезды. Опыта у меня особо никакого нет, что я точно знаю - хорошо бы фотоаппарат во время съемки не трогать руками, чтобы он не дрожал во время нажатия кнопки. Поэтому нужен штатив для фотоаппарата и пульт дистанционного управления.
На нашем сайте уже было несколько статей про пульты дистанционного управления. Ну вот еще одна. Можно было бы просто купить пульт ДУ к Кэнону, но это не интересно. Сделаю его сам из платы Марсоход.
С длинными выдержками интересно фотографировать не только треки звезд, но и всякие события вроде пролета искусственных спутников Iridium. Конструкция спутника такая, что его блестящая антенна может давать на Землю блик от Солнца буквально на 10-20 секунд. При наблюдении неба пролет Iridium выглядит как появление слабой звездочки яркость которой быстро растет, а потом спадает. Поскольку затвор фотоаппарата при съемке с длинной выдержкой все время открыт, то на фото получается интересный след:
Вот что получилось у меня. Canon EOS 650D: f/4, 24 мм, 104.5 сек, ISO-400.
Вот если сделать зум той же фотографии:
Расписание "вспышек Иридиумов" (Iridium Flares) конкретно для вашего местоположения можно посмотреть на сайте http://www.heavens-above.com/. Само ожидание пролета спутника и его наблюдение - довольно захватывающее мероприятие. Я, примерно зная время появления спутника и его местоположение, заранее направляю фотоаппарат со штатива и включаю его, открываю затвор в режиме BULB. После пролета спутника с пульта ДУ фотоаппарата выключаю съемку, закрываю затвор и смотрю, что получилось.
Теперь о том, как я делал пульт дистанционного управления.
Оригинальный пульт Canon типа RC-6 вроде бы имеет всего две кнопки: "сделать снимок" и "сделать снимок с задержкой 2 секунды".
Прежде всего нужно порыться в интернете и посмотреть, может кто-то что-то уже делал такое. Желательно найти описание или документацию на протокол передачи инфракрасных сигналов к фотоаппарату. Я надеялся, что тут есть какой-то стандарт, но я ошибался. Похоже каждый производитель изобретает свой велосипед.
Наиболее полная информация по пультам и протоколам собрана на странице http://www.numericana.com/answer/ir.htm#camera
Здесь я хотя бы узнал, что несущая частота передачи для пульта Кэнон должна быть 32768Hz.
Вторая интересная ссылка, которую я нашел http://sebastian.setz.name/arduino/my-libraries/multi-camera-ir-control/ - это библиотека на C/C++ для Ардуино в которой реализованы функции ShutterNow() и ShutterDelayed() - как раз они вызываются при нажатии первой и второй кнопки пульта соответственно. Функции простые они управляют всего одним выходным сигналом, который идет на инфракрасный излучающий диод.
Тут в сишной ардуиновской библиотеке конечно все сделано на задержках, но мне главное понять суть, какой пакет данных передается.
void Canon::shutterNow()
{
for(int i=0; i<16; i++) {
digitalWrite(_pin, HIGH);
delayMicroseconds(11);
digitalWrite(_pin, LOW);
delayMicroseconds(11);
}
delayMicroseconds(7330);
for(int i=0; i<16; i++) {
digitalWrite(_pin, HIGH);
delayMicroseconds(11);
digitalWrite(_pin, LOW);
delayMicroseconds(11);
}
}
void Canon::shutterDelayed()
{
for(int i=0; i<16; i++) {
digitalWrite(_pin, HIGH);
delayMicroseconds(11);
digitalWrite(_pin, LOW);
delayMicroseconds(11);
}
delayMicroseconds(5360);
for(int i=0; i<16; i++) {
digitalWrite(_pin, HIGH);
delayMicroseconds(11);
digitalWrite(_pin, LOW);
delayMicroseconds(11);
}
}
Похоже передается пачка из 16-ти импульсов, потом пауза-задержка и еще пачка из 16-ти импульсов. По интервалу между пачками импульсов видимо фотоаппарат отпределяет какая кнопка нажата на пульте, первая или вторая.
К сожалению, библиотеки для Ардуино используют программную задержку, поэтому особенно доверять этим исходным текстам не приходится... Вот если предположить, что пачка 16 импульсов - это модулированный бит=1, то его длина получается (11+11)*16=352 микросекунды. Пауза между пачками - это несколько битов нулей. Посмотрим сколько: 7330 / 352 = 20,8238..
Видимо точно выдержать паузы программным способом на Ардуино очень непросто, раз число бит получилось не круглым.. Ну наверное пауза 21 бит? Или нет?
Опять же возникают вопросы по несущей частоте. Судя по коду программы период несущей частоты будет 11+11=22 микросекунды.
То есть частота: 45.45 КГц и это не соответствует 32768Hz, которые я вычитал с другого сайта. С другой стороны, я видел комментарии разных людей в интернете по этим задержкам, так некоторые говорят, что на Ардуино сам вызов процедуры установки бита в порту занимает какое-то время.
В общем, похоже четкой документации мне не найти, придется пробовать разные варианты пока не заработает.
Я написал модуль на Verilog HDL, ну и tesbench в придачу, чтоб быть уверенным, что все сделано правильно. Вот модуль Verilog:
module canon_rc6(
input wire clk,
input wire button0,
input wire button1,
output reg ir_line
);
localparam CMD_INSTANT_SHOT = 20'b01000000000000000100;
localparam CMD_DELAYED_SHOT = 20'b01000000000001000000;
//Canon RC-6 has modulation frequency 32768 Hz
//divide input 100MHz clock to get period
reg [15:0]div_cnt = 0;
reg mod_clk = 0;
always @(posedge clk)
if(div_cnt<1526)
begin
div_cnt <= div_cnt +1'b1;
mod_clk <= mod_clk;
end
else
begin
div_cnt <= 0;
mod_clk <= mod_clk ^ 1;
end
reg [2:0]button_fixed0 = 0;
always @(posedge mod_clk)
button_fixed0 <= { button_fixed0[1:0] , button0 };
wire button_pressed0; assign button_pressed0 = (button_fixed0[2:1]==2'b10);
reg [2:0]button_fixed1 = 0;
always @(posedge mod_clk)
button_fixed1 <= { button_fixed1[1:0] , button1 };
wire button_pressed1; assign button_pressed1 = (button_fixed1[2:1]==2'b10);
reg state = 0; //0 mean waiting, 1 mean sending
reg [3:0]cnt16 = 0;
always @(posedge mod_clk)
cnt16 <= (state==0) ? 0 : cnt16+1;
reg [19:0]shift_reg = 0;
always @(posedge mod_clk)
if( state==0 )
begin
if( button_pressed0 )
shift_reg <= CMD_INSTANT_SHOT;
else
if( button_pressed1 )
shift_reg <= CMD_DELAYED_SHOT;
end
else
if(cnt16==15)
shift_reg <= { shift_reg[19:0],1'b0 }; //shift out CMD to right
always @(posedge mod_clk)
case( state )
0: begin
//waiting for button press
if(button_pressed0 || button_pressed1)
state <= 1'b1;
end
1: begin
//sending
if( shift_reg== 0)
state <= 1'b0;
end
endcase
always @(posedge clk)
ir_line <= shift_reg[19] & mod_clk;
endmodule
Надеюсь, что тут все более или менее понятно.
Из входной частоты 100 МГц (на плате Марсоход стоит такой кварцевый генератор) делаю mod_clk = 32768Hz путем деления частоты. Дальше все происходит на этой низкой частоте. Во-первых, происходит опрос нажатия кнопок. Ловлю только момент нажатия кнопки, получаю сигналы button_fixed0 и button_fixed1. Если схема находится в режиме ожидания, если state==0, и если при этом обнаружено нажатие кнопки, то в сдвиговый регистр загружается одно из двух возможных значений CMD_INSTANT_SHOT или CMD_DELAYED_SHOT. Каждые 16 импульсов модулирующей частоты mod_clk содержимое регистра shift_reg сдвигается влево. Самый старший бит сдвигового регистра идет прямо на ИК светодиод, правда модулированный частотой mod_clk, вот так: ir_line <= shift_reg[19] & mod_clk; Возврат в состояние ожидания происходит, когда передающий сдвиговый регистр полностью опустошен: if( shift_reg== 0) state <= 1'b0;
Простейший тестбенч к модулю имитирует нажатие кнопки:
`timescale 1ns / 1ns
module testbench();
//assume basic clock is 100Mhz
reg clk;
initial clk=0;
always
#5 clk = ~clk;
wire led;
reg but0;
reg but1;
canon_rc6 canon_rc6_inst(
.clk( clk),
.button0( but0 ),
.button1( but1 ),
.ir_line ( led )
);
initial
begin
but0 = 1'b0;
but1 = 1'b0;
$dumpfile("out.vcd");
$dumpvars(0,testbench);
#5000;
but0=1'b1;
#80000;
but0=1'b0;
#10000000;
$finish;
end
endmodule
С помощью этого тестбенча я могу хотя бы посмотреть временные диаграммы сигналов, убедиться, что длительности импульсов и паузы между пачками сигналов именно такие, как я хочу.
Я использую простой симулятор Icarus Verilog. Из командной строки вызываю команду компиляции:
>iverilog -o myout canon_rc6.v testbench.v
Теперь симуляции:
>vvp myout
Получаю файлы временных диаграмм *.vcd и смотрю их в GtkWave:
>gtkwave out.vcd
Вот что я вижу во временных диаграммах, пауза между пачками импульсов 7330 микросекунд:
Сама пачка импульсов выглядит вот так:
Период модулирующей частоты примерно правильный, соответствует частоте 32768 Гц.
Теперь модуль canon_rc6 можно вставить в проект в среде Altera Quartus II.
Весь проект можно скачать здесь:
Проект совсем простой: три входа: вход от генератора, два кнопки, один выход на ИК диод. Диод подключается через резистор к контакту F5 платы Марсоход:
Выглядит это вот так:
Небольшая видео демонстрация моего пульта дистанционного управления для фотоаппарата:
И да, не забудьте, что для управления фотоаппаратом с пульта в его настройках нужно выбрать режим управления "с пульта". А то я по началу не понимал, почему фотоаппарат не принимает мой сигнал.
PS: все фото звезд вверху выполнены с большими выдержками с применением этого IR "пульта".
Подробнее...