Блог / Собираем устройство для проверки длительности выдержек затворов аналоговых фотоаппаратов
14 февраля 2024

Мне давно было интересно замерить фактическую длительность выдержек которые отрабатывают затворы имеющихся у меня аналоговых фотокамер, чтобы оценить насколько эти значения отличаются от номинальных. Тем интереснее, что я располагаю камерами самых разных систем, годов выпуска и стран производителей. При поиске решения, меня заинтересовала заметка, в которой описана конструкция гаджета для измерения скорости затвора, собранного на базе Arduino. Отлично! Хорошая возможность и свою задачу решить, и познакомиться с Arduino, сделав на нём свой первый, хоть и не очень сложный, но интересный проект. Ну что, народ, погнали?!!
Arduino
Arduino — это по сути электронный конструктор (см. подробнее тут). В основе устройств собранных на Arduino лежит программируемый микроконтроллер, что в сочетании с широчайшим спектром совместимых модулей расширения, датчиков и прочих компонентов, даёт практически неограниченные возможности по созданию самых разнообразных электронных и электро-механических устройств.
Идея
Да, идея устройства не моя, более того, и схему я, по сути, взял из оригинальной статьи (хоть я её и немного модифицировал добавив кнопку «сброса»). А вот прошивку для данного гаджета мне пришлось переписать почти полностью, т.к. прошивка из оригинальной статьи «не взлетела», и, надо сказать, «взлететь» не могла.
Схема, принцип работы и компоненты
На схеме указаны именно те компоненты которые использовал я.

Моя версия схемы устройства
По схеме принцип работы устройства понять совсем не сложно (мне-то точно, т.к. по первой специальности я радиотехник 😄): между выводами +5V и A3 (один из аналоговых входов/выходов) микроконтроллера установлен фототранзистор. Чем больше интенсивность света попадающего на этот фототранзистор, тем больше он «открывается», и подаёт на вход A3 большее напряжение (максимум 5 вольт). Соответственно, чем меньше света попадает на фототранзистор, тем на вход A3 попадает меньшее напряжение. В темноте фототранзистор как бы «закрывается», и фактически «разрывает» указанную цепь. Чтобы при «разрыве» цепи контакт A3 не «висел в воздухе» и не ловил как антенна наводки, он через резистор с номиналом 10 кОм выведен на «землю» (контакт «GND» на микроконтроллере). Микроконтроллер же измеряет продолжительность входного импульса (выше некоторого порогового значения указанного в прошивке) поданного на аналоговый вход A3 и, после обработки в соответствии с программой заложенной в его прошивке, выводит результат измерения на дисплей. Всё до гениальности просто.
Ну и список элементов которые использовал я:
-
Микроконтроллер Arduino Nano 3.0 CH340 Type-C

Arduino Nano я специально покупал с разъёмом Type-C — как-то он мне милее прочих «мелкоUSB».
-
Дисплей NFP1315-61A (SSD1306)

Разрешение: 128×32 пикс., диагональ: 0.96", цвет: голубой. -
Фототранзистор Kingbright L-53P3C

NPN, длина волны: 940 нм.Данный фототранзистор имеет немного большие время нарастания и время спада (15 мкс. против 10 мкс. у фототранзистора из оригинальной статьи), но даже для выдержки 1/500 сек. (2 мс.) это всё равно весьма незначительная величина (разница — два порядка).
-
Резистор 10 кОм.

В нашем случае достаточно двух резисторов -
Кнопка

Я купил относительно модную кнопу, но на самом деле подойдёт практически любая.
-
Беспаечная макетная плата

400 отверстий (клеммная колодка на 300 отверстий + две планки по 50 отверстий), 82×55×8.5 мм. -
Набор соединительных проводов

«Папа-папа», «папа-мама», «мама-мама». Длина: 10 см.Вообще, для этой схемы мне понадобились только провода «папа-папа» и три провода «папа-мама» для кнопки (для неё не хватило места на плате), но на всякий случай я прикупил все комбинации проводов.
Вот и все детали что нам понадобятся. Все элементы покупал под беспаечную установку (паяльника у меня нет, а покупать его не хочу).

Вот такой получился испытательный стендик 😊 (на фото с батарейным отсеком, т.е. с автономным питанием ☝️).
Я запитал схему от 6-ти вольт (4 батарейки «АА») через пин «VIN», но наверное и 9-вольтовая «Крона» потянула бы (через тот же пин). А вообще, можно и просто через USB 5-тью вольтами запитаться.
Прошивка (скетч)
Повторюсь, прошивку из оригинальной статьи я переписал почти полностью, оставив более менее нетронутыми только методы displayDuration() и displaySpeed(), хотя в последнем и добавил округление дробной части значения для выдержек меньше одной секунды (возможно это округление и лишнее, так что при желании можете его убрать в коде — это не сложно).
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define WIRE Wire
#define RECEIVER_PIN A3
#define RESET_PIN 2
#define THRESHOLD_LEVEL 500
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &WIRE);
void displayDuration(unsigned long duration) {
double msecs = duration / 1000.0;
String text = String("Time: ") + msecs + String(" msecs");
display.println(text);
Serial.println(text);
}
void displaySpeed(unsigned long duration) {
String text;
if (duration >= 1000000.0) {
double secs = duration / 1000000.0;
text = String("Speed: ") + secs + String(" secs");
}
else {
double speed = 1000000.0 / duration;
text = String("Speed: 1/") + round(speed) + String(" secs");
}
display.println(text);
Serial.println(text);
}
void durationMeter() {
display.clearDisplay();
display.setCursor(0,0);
display.println("\nWaiting for shoot...");
display.display();
unsigned long start_time = 0;
while (true) {
unsigned long value = analogRead(RECEIVER_PIN);
if (start_time == 0 && value > THRESHOLD_LEVEL) {
start_time = micros();
}
if (start_time > 0 && value < THRESHOLD_LEVEL) {
break;
}
}
unsigned long duration = (micros() - start_time);
display.clearDisplay();
display.setCursor(0,0);
displayDuration(duration);
displaySpeed(duration);
display.println("Press Reset for continue.");
display.display();
while (start_time > 0) {
if (digitalRead(RESET_PIN) == HIGH) {
start_time = 0;
}
}
display.clearDisplay();
}
void setup() {
pinMode(RECEIVER_PIN, INPUT);
pinMode(RESET_PIN, INPUT);
Serial.begin(9600);
Serial.println("OLED FeatherWing test");
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
// Address 0x3C for 128x32
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306 allocation failed");
for (;;);
}
Serial.println("OLED begun");
}
void loop() {
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
durationMeter();
}
Прошивку компилил и закатывал в контроллер посредством своего смартфона (Samsung Galaxy M30s | SM-M307FN/DS + прога ArduinoDroid), т.к. ардуиновская идэешка не захотела работать на моей 7-ой Винде (при запуске программы вылезает ошибка: «Точка входа в процедуру GetPackegeFamilyName не найдена в библиотеке DLL KERNEL32.dll.»), а разбираться с причинами этого отлупа у меня не было никакого желания. Правда пришлось прикупить OTG-переходник под USB Type-C.

Кстати, если решите также заморочиться со смартфоном, то сначала убедитесь что ваш аппарат поддерживает OTG.
Как пользоваться устройством
Кроме подопытного фотоаппарата и данного измерительного ардуино-девайса нам понадобится обыкновенный фонарик. Идея такая: фототранзистор нашего измерительного гаджета «смотрит» на затвор фотоаппарата с одной стороны, а фонарик светит на затвор с другой, и как только затвор отработает некоторую выдержку, наш ардуино-агрегат отобразит её фактическую продолжительность на дисплее — всё очень просто.

Всё приготовили для замера, нажимаем кнопку спуска на камере...

... получаем результат замера
Конечно же, перед замерами нужно открыть диафрагму объектива на максимум или вообще снять объектив с камеры (если это возможно). Если относительное отверстие объектива около f/4.5 или меньше (темнее), а снять его с камеры не представляется возможным, то просто придётся воспользоваться более ярким фонариком.
Измерения можно проводить при нормальном (не слишком ярком ☝️) освещении.
О точности измерений
(касательно повышения точности измерений см. обновление от 29 февраля 2024 г.)
Конечно, в таком деле важно понимать с какой точностью измерения мы имеем дело. Особенно это критично для выдержек 1/500 сек. и короче. Что же, давайте проанализируем факторы, которые могут влиять на точность рассмотренного прибора.
- Инерционность фототранзистора. Как я указал выше, у фототранзистора который использовал я, и время нарастания, и время спада равны 15 мкс. Если я всё правильно понял, эти параметры характеризуют инерционность реакции фототранзистора при попадании на него света и при его снятии. Т.е., о том что на него начал попадать свет, фототранзистор в полной мере «поймёт» в худшем случае с задержкой на 15 мкс, и с такой же задержкой «узнает» о том, что свет на него попадать перестал. Таким образом, получается взаимная компенсация и выходит что эти параметры не оказывают влияния на точность прибора. Если мои рассуждения неверны, поправьте меня в комментариях.
- Частота дискретизации. Немного поколдовав над скриптом, я замерил время которое уходит на одну итерацию в цикле запущенном на моём контроллере, и у меня получилось значение 112 мкс. Т.е., контроллер чекает сигнал от фототранзистора каждые 112 мкс (без малого 9 кГц). Таким образом, можно прикинуть что от выдержки 1/500 это время составляет 5.6%, а от выдержки 1/1000 — 11.2%. Собственно, исходя из этого можно оценить и возможную погрешность измерения столь коротких выдержек — если прибор показывает значение 1/500 сек, то надо понимать что реальное значение лежит в пределах от 1/473 сек. до 1/530 сек. (вы там за мной проверяйте, ничего ли я не напутал 😜). На более долгих выдержках эта погрешность будет, по сути, вообще нивелирована за счёт округления дробной части значения выдержки.
Таким образом, получается что, в принципе, точность измерения данным гаджетом выдержек длиннее 1/500 сек. весьма недурная, ну а при измерении более коротких выдержек конечно нужно держать погрешность в голове. Тем не менее, если вы выставили на затворе выдержку 1/1000 сек., а прибор показывает 1/200 сек., то тут уже точно можно говорить о том, что затвор данную выдержку отрабатывает некорректно. Так что, в любом случае, прибором имеет смысл прочекать и выдержки короче 1/500 сек.
И ещё...
Вы наверное обратили внимание на то, что на иллюстрациях к данной статье гаджет руссифицирован, а приведённый мной код прошивки нет. Так вот, если тоже захотите озадачиться кириллицей, то тут сможете узнать как это можно сделать (обратите внимание на то, какая у вас версия библиотеки «Adafruit-GFX» — «новая» или «старая»). Удачи!
Повышаем точность измерения коротких выдержек (обновление от 29 февраля 2024 г.)
Когда я узнал что микроконтроллеры Ардуино поддерживают аппаратные прерывания, у меня появилась идея как можно усовершенствовать свой гаджет, повысив скорость его реакции, а, следовательно, его точность. Конечно же, в первую очередь это критично для коротких выдержек (1/500 сек. и короче). Аппаратные прерывания часто используют именно для детектирования коротких событий — импульсов.
У Arduino Nano (ATmega 328/168) аппаратные прерывания поддерживают только два пина — «D2» и «D3», так что пришлось немного изменить схему устройства, а именно, перекинуть провод с аналогового пина «A3» на цифровой пин «D3» («D2» у меня уже занят кнопкой сброса).

Вторая версия схемы
Ну, а дальше дело за скетчем:
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define WIRE Wire
#define RECEIVER_PIN 3
#define RESET_PIN 2
volatile unsigned long start_time = 0;
volatile unsigned long end_time = 0;
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &WIRE);
void displayDuration(unsigned long duration) {
double msecs = duration / 1000.0;
String text = String("Time: ") + msecs + String(" msecs");
display.println(text);
Serial.println(text);
}
void displaySpeed(unsigned long duration) {
String text;
if (duration >= 1000000.0) {
double secs = duration / 1000000.0;
text = String("Speed: ") + secs + String(" secs");
}
else {
double speed = 1000000.0 / duration;
text = String("Speed: 1/") + round(speed) + String(" secs");
}
display.println(text);
Serial.println(text);
}
void durationMeter() {
display.clearDisplay();
display.setCursor(0,0);
display.println("\nWaiting for shoot...");
display.display();
while (true) {
if (start_time > 0 && end_time > 0) {
break;
}
}
unsigned long duration = (end_time - start_time);
display.clearDisplay();
display.setCursor(0,0);
displayDuration(duration);
displaySpeed(duration);
display.println("Press Reset for continue.");
display.display();
while (start_time > 0) {
if (digitalRead(RESET_PIN) == HIGH) {
start_time = 0;
end_time = 0;
}
}
display.clearDisplay();
}
void listener() {
byte value = digitalRead(RECEIVER_PIN);
if (value == HIGH && start_time == 0) {
start_time = micros();
}
if (value == LOW && start_time > 0 && end_time == 0) {
end_time = micros();
}
}
void setup() {
pinMode(RECEIVER_PIN, INPUT);
pinMode(RESET_PIN, INPUT);
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(RECEIVER_PIN), listener, CHANGE);
Serial.println("OLED FeatherWing test");
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
Serial.println("SSD1306 allocation failed");
for (;;);
}
Serial.println("OLED begun");
}
void loop() {
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
durationMeter();
}
Ума не приложу каким образом теперь оценить точность измерений, но по логике вещей она должна быть заметно выше чем у первой версии гаджета.
P.S. — В ближайшее время планирую посидеть со своими фотоаппаратиками и оценить точность работы затвора каждого из них. Результаты замеров опубликую отдельной заметкой. Интересно 😋! На днях прочекал данным гаджетом почти все свои фотокамеры, по итогам опубликовал заметку с результатами замеров — результаты получились весьма интересные.
P.P.S. — Ceterum censeo Washington esse delendam.
Читайте также:
Поддержать проект «Свинцовый Пепелац»:
Вы можете поддержать проект «Свинцовый Пепелац» финансово, переведя в его пользу любую сумму (от 1 руб.)
Комментарии посетителей (58):
По возможности сделайте скетч на русском. Я ведь вообще древний. Для меня вражеские буквы это проблема.
Сделаю, только мгновенно у меня это не получиться, т.к. я всё это дело крутил-вертел и компилил на старом своём смартфоне, который перед новым годом почил в бозе 😵, так что придётся немного вспомнить что я там как делал 😊. Но уверен, что всё получиться 💪.
P.S. — мне на родном языке тоже как-то приятнее 😊.
Знаменский23, маленькая поправка: скетч с русским языком сам по себе нормально не скомпилится (скорее всего крокозяблы вместо русских букв будут), т.к. у библиотеки Adafruit-GFX, нет поддержки кириллицы (ведь нет же ещё?). Так что я только могу HEX-файл скомпиленный приложить к статье (когда сделаю его). А если вы прямо сами хотите из скетча своего компилить с кириллицей, я в статье оставил ссылку на рецепт как это сделать (статья «Русификация библиотеки Adafruit-GFX и вывод русских букв на дисплей в кодировке UTF-8 из Arduino IDE»).
Я вот о чем чтобы как у вас слово "выдержка" было на русском.... Вообщем для древний и от этого могу говорить наивные преставления.
Короче, вы там пока тогда схемой занимайтесь (или уже собрали?), а там разберёмся 😊. Как залить прошивку в контроллер вы разобрались же? Если да, то дальше дело за малым 😊.
Купил на маркетплейсе всё за раз. Жду. Ну а пока, сидя на работе, подготавливаю теорию. У меня фотобарохла много. Тут на старости глядя на «Смена 8М» решил было я опять в плёнку вернуться. Купил средний формат: «Москва-5», «Искра», «Любитель-166У», «Киев-60» (вообще новым). И вот я тут понял, что затворы этих аппаратов давно щёлкают, так сказать, от балды. Взялся интернет шерстить, попал на ваш сайт. От радости запрыгал до потолка. Вот на днях приеду с вахты северной, открою сундук с аппаратами, соберу это устройство и... наверно, расстроюсь. Собрать эту машину я смогу, но вот мозги ей вставить может быть долгим и тернистым приключением. Заранее благодарю за спасибо за помощь. Я еще дам о себе знать.
Знаменский23, не переживайте, подскажем и поможем 😊. Если что, напишите мне с формы обратной связи ( https://lead-pepelats.ru/feedback/ ), перейдём в приватное общение чтобы тут не флудить 😊.
Итак, мои познания закрепились. Сейчас не без сомнений однако основываясь на собственной наивности а следовательно и поэтому уверенности могу утверждать, что данное устройство измеряет выдержку возможно точно, но только до 1/499 секунды. А дальше видимо ее характеристики не предназначены. По крайней мере у меня так получается. Я экспериментировал с двумя фотоаппаратами, Киев 60, Zenit KM-plus. Первый со шторным механизмом, второй фотоаппарат имеет электромеханический привод так сказать ламельный. Измерения показали относительно правильные числа, но как только выдержка составила больше 1/499 устройство от выдает ошибку измерения.
Знаменский23, приветствую! Не очень понял что значит "устройство выдает ошибку измерения" 🤔.
Возможно оно пишет, что-то другое, но я так понял. Вот что я увидел: скорость, точнее, болле короткую длительность чем 1/499 секунды оно измерить не способно технически. Это мое понимание. Не претендую на правильность моих представлений. Но это (!) не точно!
Знаменский23, короче так: для начала убедитесь что источник света (фонарик), который вы используете при измерениях, светит без пульсаций (диодные фонарики этим часто грешат). Прибор весьма чувствителен (в плане реакции) и в случае пульсирующего источника света может реагировать не на работу затвора, а на пульсации этого самого источника света ☝️.
Уточню: Вы таки смогли успешно залить скетч или HEX-файл в своего терминатора? Если да, то это очень круто 👍.
Далее: там вроде на экране всё достаточно просто-понятно пишется, но если Вы чего-то не понимаете из отображённого на экране девайса, то просто задайте вопрос в комментах приложив фото экрана тестера — подскажем и объясним 😊.
Спасибо, вам большое, действительно квест по установки скетч(а) я прошел, не первого раза. Спасибо вам. Действительно, я использовал диодный фонарь, я осознаю, что фонарь может работать с частотой. Однако я всё же пренебрег, рассчитывая на русское авось. И вот что мне удалось увидеть. На двух фотоаппаратах Киев60 89г.в. и Зенит КМ+ 2005 г.в. выдержки до 1/500 показывали красивые цифры. Например Киев60 показывал на 1/30 разброс 1/24-1/37, и такие разбросы были почти на всех установках. На 1/500 показывал 1/437-1/499 и иногда устройство матюкалось. И всегда матюкалось на выдержках 1/1000. Так же показал себя и Зенит КМ+, правда разброс сжался значительно. Но на выдержке 1/500 показывал либо меньше 1/500 либо выдавал нецензурную брань. И вот на выдержке 1/1000 перешел на простое ругательство, но цифр уже не показывал. Поэтому я сделал не сложный вывод, что ардуино наше с данным скетчем или фототранзистор не могут просчитать время всплеска которое меньше 1/500. Завтра если будет желание я проверю его еще на одном фотоаппарате.
Здравствуйте, решил собрать ваш девайс и не могу понять в чём причина неисправности. Не хочет выводить данные на экран пока не конснусь пальцами GND и D2 при чем касаясь диэлектриком ничего не происходит. Но стоит замкнуть пальцем или грифелем карандаша эти контакты как он выдаёт все данные.
ade, приветствую!
Так, конечно, сложно сказать, но, скорее всего, тут либо неконтакт где-то (если вы как и я на беспаечной плате собирали, то это легко может быть), либо что-то вы напутали в соединениях. Надо все соединения перепроверить ещё раз, проверить «землю». Вы пишите: «Но стоит замкнуть пальцем или грифелем карандаша эти контакты как он выдаёт все данные» — а данные хоть адекватные? Это же может быть просто сигнал наводки. Нет?
Можно проще же и без бабуино. На голом C с выводом на USART.
Tuzemak, ну если так как вы сказали проще, то подробнее опишите как сделать, обсудим при необходимости 🤷♂️.
Накидал примерно. Схема та же остаётся за исключением экранчика, вывод идёт через UART.
https://gitlab.com/tuzemak/shutter-speed/-/blob/main/main.c
Tuzemak, прикольно 😊!
Я лично на настоящем C не пишу (как собака — понимаю более-менее что написано, но не говорю 😂), ну и надо понимать, что тут подавляющая часть читателей это, по понятный причинам, глубоко «аналоговые» человеки 😊, так что если бы вы всё доходчиво пояснили: куда что как подключать,... и т.д. и т.п. было бы просто замечательно! Я сам пока не до конца вашу идею понял, но что-то явно интересное 😊👍.
Схема та же самая - фототранзистор к пину прерывания, дисплей из схемы исключен.
Вывод идёт в UART(в случае с бабуино этот UART распаян на USB переходнит FT232 на плате). Подключение через любую терминалку
- putty, minicom и.т.д. на скорости 9600 к порту, через который прошиватся бабуино. Если прошивается голый МК, то UART распаивается на тот же DB-9.
Прошивка заводит внутренний таймер микроконтроллера на счет интервалов и ведёт счет общего uptime работы.
Внешнее прерывание сконфигурировано на срабатывание по изменению уровня. Обработчик прерывания фиксирует время срабатывания относительно uptime, счетчик четности определяет фиксирует момент открытия/закрытия шторки.
На выход выдаётся выдержка в миллисекундах и в долях секунды(насколько гуляет ).
Прошивка с рядом косяков, но в общих чертах работает.
Tuzemak, 👏👏👏! Спасибо 🤝!