ARDUINO Универсальный ИК ИНТЕРВАЛОМЕТЕР (для всех фотокамер с ИК портом)

necton

✩✩✩✩✩✩✩
21 Янв 2019
2
1
Товарищи, ищу братьев по разуму в DSLR фотокамерами - вы меня точно поймете. Решил я собрать ИНТЕРВАЛОМЕТР для интервальной фотосъемки (устройство выдает команду на спуск затвора через выставляемый интервал).

Перекопал массу проектов на эту тему, но увы.. 90% их них проводные (т.е с разъемом вставляемым в камеру, что не есть хорошо), а хотелось бы использовать "не инвазивный" метод фактический повторение ИК команды с пульта ДУ на спуск затвора через ИК диод, размещенный вблизи ИК порта фотокамеры.

ВНИМАНИЕ! Эта схема авторская, не финальная (финальную см.ниже)

Для сборки понадобится: Дисплей 16x2 с i2c, Ардуинка Nano, модуль джойстика, ИК диод, резистор на 200ом, кнопка (сброса). И всё!!!

Покопался, нашел один древний и очень простенький проект ВОТ ЭТОТ, собрал его - а он увы (сразу) не заработал как надо и судя по комментариям на которые автор не отвечает - не заработал ни у кого.
Итак о проблемах:
A)
- собранное устройство запускается, дисплей работает, даже пытается работать, переходя в соответствующий режим но... странно ведет себя мини-джойстик управления (дурачится, срывает выбор и т.д). Такое впечатление что проблема или в кнопке "выбора" она должна быть инвертирована или нет, не понятно. А так же в том что в момент исполнения через несколько секунд поступает команда с джойстика будто его кто-то тронул и исполнение прекращается. P.S. - РЕШЕНО (см. ниже)

Б
) и главное - вшитый код команды "спуск затвора" не для моей камеры, а хотелось бы что бы или был выбор производителя с меню, или хотя бы выбор камеры путем правки в коде. Метод PulseOn/OFF (код в конце поста) как мне кажется тут перечеркивает все замашки на универсальность. P.S. - НЕ РЕШЕНО

Задача:

1) - Разобраться с управлением или поменять его на другой метод.
2) - В общем, вычитал я что есть библиотека multi-Camera-IR-Control (от Sebastian Setz) в которой автор предусмотрительно подсобрал ИК коды для разных производителей фотокамер, но проектов где можно подсмотреть скетч для этой библиотеки - для нее я так и не нашел (может у вас получится). С другой стороны, можно использовать любой метод засылки СЧИТАННОГО с оригинального пульта ИК кода, но уж точно не PulseOn/OFF.
3) - если кто-то проявит материализованный энтузиазм и доведет до ума затею, лично проставлю ему стакан коньяка. А вообще, устройство любому фотографу реально нужное и было бы неплохо продумать вариант с OLED дисплеем и дополнительными функциями, вроде автоматического вычисления сколько нужно снимков, что бы сделать ролик заданной длинны с заданной частотой кадров.

В общем, буду благодарен за любые советы и помощь как скрестить одно с другим и сделать очень полезную штуку для увлеченных астрофотографией.

ВНИМАНИЕ! Код исходный, авторский со всеми косяками - исправленный см. ниже.
C++:
// Article http://english.cxem.net/arduino/arduino6.php
// Version 1.0

#include "Wire.h"
#include "LiquidCrystal_I2C.h"

#define axis_X 1    // axis Х of Joystic connected to Analog 0
#define axis_Y 0    // axis Y of Joystic connected to Analog 1
#define axis_Z 3    // axis-button Z of Joystic connected to Digital 3
#define pinIRLED 10 // IR LED
#define LEDgreen 13 // onboard LED

#define autoOFF 10  // autoOFF backlight LCD

LiquidCrystal_I2C lcd(0x27,16,2);    // set the LCD address to 0x27 for a 16 chars and 2 line display

int value_X, value_Y, value_Z = 0;   // axis values
int pos = 0;                         // current position (0 - delay, 1 - work)
int interval = 1;                    // pause between shots (sec)
int cntPict = 0;                     // shots count
boolean working = false;

unsigned long currentTime;
unsigned long TimeShot, TimeLCDOff;

void setup()
{
  pinMode(axis_Z, INPUT);         // Joystic button
  pinMode(pinIRLED, OUTPUT);      // IR LED

  lcd.init();                     // init LCD
  lcd.backlight();                // turn LCD backlight ON
  lcd.clear();                    // clear LCD
  show_menu();                    // function show menu

  currentTime = millis();
  TimeShot = currentTime;         // shots timer
  TimeLCDOff = currentTime;       // backlight timer
  Serial.begin(115200);
}

void loop()
{
  value_X = analogRead(axis_X);    // read the analog value of the X axis
  value_Y = analogRead(axis_Y);    // read the analog value of the Y axis
  value_Z = digitalRead(axis_Z);   // read the digital value of the Z axis (button)
  value_Z = value_Z ^ 1;           // invert the value

  if(working == false){
    if(value_Y > 550){              // joystick up
      pos = 0;
      lcd.backlight();              // LCD backlight ON
      TimeLCDOff = currentTime;     // new value of TimeLCDOff
      show_menu();
    }
    else if(value_Y < 390){         // joystick down (middle postition data from joystick is Y= 516)
      pos = 1;
      lcd.backlight();              // LCD backlight ON
      TimeLCDOff = currentTime;     // new value of TimeLCDOff
      show_menu();
    }
    if(value_X > 530){              // joystick left (middle postition data from joystick is X= 511)
      lcd.backlight();              // LCD backlight ON
      TimeLCDOff = currentTime;     // new value of TimeLCDOff
      if(pos == 0){
          --interval;
          if(value_X > 800) interval = interval-10;  // joystick full left
          if(interval < 1) interval = 1;
      }
      show_menu();
    }
    else if(value_X < 500){         // joystick right
      lcd.backlight();              // LCD backlight ON
      TimeLCDOff = currentTime;     // new value of TimeLCDOff
      if(pos == 0) {
          ++interval;
          if(value_X < 100) interval = interval+5;  // joystick full right
      }
      show_menu();
    }
  }

  if(value_Z == 1){               // joystick button press
    lcd.backlight();              // LCD backlight ON
    TimeLCDOff = currentTime;
    if(working == true){
      working = false;
      pos = 0;
      show_menu();
    }
    if(pos == 1) show_working();  // turn on work mode
  }

  delay(200);

  currentTime = millis();
  if(working == true){
    if(currentTime >= (TimeShot + (interval*1000))){
      digitalWrite(LEDgreen, HIGH);                   // blink onboard LED
      delay(100);
      digitalWrite(LEDgreen, LOW);                
      takePicture();                                  // send IR
      TimeShot = currentTime;
      ++cntPict;                                      // increase the counter shots
      show_working();                                 // refresh LCD
    }
  }

  if(currentTime >= (TimeLCDOff + (autoOFF*1000))){          
      lcd.noBacklight();                              // LCD backlight OFF
  }

}

void show_menu()
{
  cntPict = 0;        // zero out counter shots

  lcd.clear();
  lcd.setCursor(0, pos);
  lcd.print("*");     // current position

  lcd.setCursor(1, 0);
  lcd.print("delay:");

  lcd.setCursor(8, 0);
  lcd.print(interval);

  lcd.setCursor(1, 1);
  lcd.print("go work");
}

void show_working()
{
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("working...");
  lcd.setCursor(2, 1);
  lcd.print("shots:");
  lcd.setCursor(9, 1);
  lcd.print(cntPict);
  working = true;
}

// pulse the infrared emitter for a specified duration (in microseconds)
void pulseON(int pulseTime) {
  unsigned long endPulse = micros() + pulseTime;        // create the microseconds to pulse for
  while( micros() < endPulse) {
    digitalWrite(pinIRLED, HIGH);                       // turn IR on
    delayMicroseconds(13);                              // half the clock cycle for 38Khz - e.g. the 'on' part of our wave
    digitalWrite(pinIRLED, LOW);                        // turn IR off
    delayMicroseconds(13);                              // half a clock cycle for a 38 Khz (26.32 microseconds period)
  }
}
void pulseOFF(unsigned long startDelay) {
  unsigned long endDelay = micros() + startDelay;       // create the microseconds to delay for
  while(micros() < endDelay);
}
void takePicture() {
  for (int i=0; i < 2; i++) {    // impulse send twice
    pulseON(2336);
    pulseOFF(646);
    pulseON(1168);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(646);
    pulseON(572);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(646);
    pulseON(572);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(11008);
    pulseON(2336);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(646);
    pulseON(572);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(646);
    pulseON(572);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(11008);
    pulseON(2336);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(646);
    pulseON(572);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(1168);
    pulseOFF(621);
    pulseON(1093);
    pulseOFF(696);
    pulseON(572);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(621);
    pulseON(572);
    pulseOFF(1218);
    pulseON(497);
    pulseOFF(1292);
    pulseON(422);
    pulseOFF(1367);
    pulseON(373);
    pulseOFF(11803);
    pulseON(298);
    pulseOFF(2659);
    pulseON(199);
    pulseOFF(1590);
    pulseON(174);
    pulseOFF(1019);
    pulseON(174);
    pulseOFF(1615);
    pulseON(174);
    pulseOFF(1615);
    pulseON(149);
    pulseOFF(1044);
    pulseON(149);
    pulseOFF(1640);
    pulseON(124);
    pulseOFF(1093);
    pulseON(149);
    pulseOFF(1044);
    pulseON(124);
    pulseOFF(1665);
    pulseON(124);
    pulseOFF(1068);
    pulseON(124);
    pulseOFF(1665);
    pulseON(99);
    pulseOFF(1690);
    pulseON(99);
    pulseOFF(1690);
    pulseON(99);
    pulseOFF(1093);
    pulseON(99);
    pulseOFF(1118);
    pulseON(99);
    pulseOFF(1093);
    pulseON(99);
    pulseOFF(1690);
    pulseON(99);
    pulseOFF(1690);
    pulseON(75);
    pulseOFF(1715);
    pulseON(75);
    pulseOFF(12101);
    pulseON(149);
    pulseOFF(2833);
    pulseON(75);
    pulseOFF(1715);
    pulseON(75);
    pulseOFF(1118);
    pulseON(75);
    pulseOFF(1715);
    pulseON(75);
    pulseOFF(1715);
    pulseON(75);
    pulseOFF(1118);
    pulseON(75);
    pulseOFF(1715);
    pulseON(75);
    pulseOFF(1118);
    pulseON(99);
    pulseOFF(1093);
    pulseON(99);
    pulseOFF(1690);
    pulseON(99);
    pulseOFF(1093);
    pulseON(99);
    pulseOFF(1690);
    pulseON(99);
    pulseOFF(1690);
    pulseON(99);
    pulseOFF(1690);
    pulseON(99);
    pulseOFF(1093);
    pulseON(99);
    pulseOFF(1118);
    pulseON(99);
    pulseOFF(1093);
    pulseON(99);
    pulseOFF(1690);
    pulseON(99);
    pulseOFF(1690);
    pulseON(99);
    pulseOFF(1690);
    pulseON(99);
    pulseOFF(646);
  }
}
 
Изменено:

kalobyte

★★★✩✩✩✩
1 Янв 2020
726
146
странно ведет себя мини-джойстик управления (дурачится, срывает выбор и т.д).
потому что выводы джойстика резисторами не подтянуты к питани
+ нет транзистора на ик диоде, свет тупо может не доходить при малом токе

алгоритм управления затвором я не знаю
так что непонятно как оно должно работать
просто затвор что ли спускать или открывать диафрагму на какое-то время заданное с этого пульта?

если коды пульта передаются как в теликах, то эта херня изначально нерабочая
 

necton

✩✩✩✩✩✩✩
21 Янв 2019
2
1
Хорошо, внял совету и чутка пересобрал схему. На "капризный" выключатель джойстика повесил подтягивающий резистор на 10К (R2), на ИК светодиод (U3) прицепил усилитель в виде транзистора 2N2222 (Q1) и резистора на 1K (R1).

Итог опыта: ИК-диод заменил пока на обычный и при исполнении тот горит отлично, ярко и явно дает в эфир какие-то цифровые пачки. А вот с управлением просто беда.. Что-то явно не то с кнопкой, поскольку стоит закомментировать строку 47: value_Z = value_Z ^ 1; // invert the value
инвертирующую кнопку, как начинает работать меню "вниз" без старта процесса. Такое впечатление что кнопка "нажимается"с бешенной скоростью запуская и тут же прерывая процесс исполнения ИК команды и возвращая меню в исходную позицию установки задержки. Один раз правда цикл успевает отработать и я вижу что диод что-то явно излучает. P.S. - подтягивающий резистор кнопка-земля на 10К совершенно ничего не дал.
Коллеги, посмотрите пожалуйста что там не так с типом или способом подключения кнопки джойстика?

ВНИМАНИЕ! Схема с ошибкой - подтягивающий резистор R2 надо закинуть на VCC а не на массу.

Schematic_Intervalometer V1.1_2020-06-19_00-59-30.png
 
Изменено:

kalobyte

★★★✩✩✩✩
1 Янв 2020
726
146
Такое впечатление что кнопка "нажимается"с бешенной скоростью запуская и тут же прерывая процесс исполнения ИК команды

резистор к плюсу подтягивают обычно

сейчас понял, что этот джойстик аналоговый!!11 🤦‍♂️
это надо быть особо альтернативно одаренным, чтобы для управлению меню в индикаторе использовать переменные резисторы

у кнопки еще нет защиты от дребезга
припаяй между землей и кнопкой конденсатора 0.01мкф


вот решил не полениться и загуглил команды камер
там реально какие-то импульсы надо п одавать
так что возьми логический анализатор или оциллограф цифровой и запиши сигнал с пульта для своей камеры

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