
Несколько лет назад я открыл для себя DigitalRev TV. В одном из выпусков в руки Кая и Лока попадает отечественный фотоаппарат «Любитель-166», но моё внимание привлёк совсем не он. Из кожаного футлярчика Кай достаёт маленькое устройство, которое включается в разъём гарнитуры телефона — экспонометр. С тех пор эта белая полусфера не даёт мне покоя. В статье хочу поделиться опытом создания подобного устройства своими руками.
Вместо введения
Как известно, каждый сходит с ума по-своему. Есть люди, которые собирают марки, не выпускают из рук паяльник, или ходят в походы. Мне же стукнуло в голову поснимать на плёнку — запрыгнуть в последний вагон поезда уходящей эпохи.
На Хабре есть как минимум одна хорошая статья, рассказывающая об азах фотографии, с которой стоит ознакомиться. Тем не менее кратко пройдусь по основным моментам.
Экспозиция — это величина засветки светочувствительного материала или матрицы фотоаппарата. От неё прямо зависит качество снимка. Слишком большая экспозиция (или передержка) приведёт к потере деталей в светлых участках, недостаточная (или недодержка) — к потере деталей в тенях. Номинальная экспозиция (т.е. необходимое количество освещения) называется чувствительностью фотоматериала. Идея замера экспозиции заключается в том, чтобы подобрать параметры съёмки (время выдержки и диафрагменное число — экспопару), дающие номинальную экспозицию вне зависимости от условий освещения.
Современные фотоаппараты и камеры мобильных телефонов могут делать это автоматически (или полуавтоматически, оставляя выбор части параметров за вами), но так было не всегда, и на многих старых фотоаппаратах всё делается вручную. Некоторые камеры комплектовались встроенным экспонометром, однако:
- Где-то он был опционален, найти его сейчас может быть слишком сложно и дорого.
- Его использование может быть связано с определёнными трудностями. Например, экспонометры некоторых фотоаппаратов требовали для работы ртутно-цинковые батареи, которые давно не производятся.
Одним словом, отдельный прибор – полезная в хозяйстве вещь.
Троллейбус из буханки

Вообще, можно было не заморачиваться и найти на какой-нибудь барахолке старенький «Ленинград-4» по цене от 100 до 1000 рублей в зависимости от жадности продавца. Его должно хватить с головой, но мы не ищем лёгких путей:
- Во-первых, меня очень привлекло устройство из ролика и я люблю изобретать велосипеды. Интересно как повторить подобную конструкцию, так и разобраться в общих принципах.
- Во-вторых, пользоваться старой отечественной шкалой чувствительности не очень удобно, когда в качестве международного стандарта давно приняты единицы ASA и DIN.
- В третьих, селеновые фотоэлементы со временем теряют чувствительность. Тут уж как повезёт.
▍ Что и как измерять
Производить измерения можно двумя способами — по падающему и по отражённому свету. В первом случае экспонометр направляется приёмником от объекта съёмки к камере, измеряется освещённость. Во втором — наоборот, измеряется интегральная яркость сцены. Обе величины могут изменяться в очень большом диапазоне – до 120000 лк (под прямым солнечным светом) или примерно до 30000 кд/м2 (освещённый солнцем снег). Т.к. требуются конкретные величины, а не просто наличие/отсутствие света, то нужен соответствующий фотодатчик. Фоторезисторы можно сразу отбросить из-за малого динамического диапазона. Фототранзисторы выглядят интереснее, но они чувствительны преимущественно к красной и инфракрасной части спектра. Лучшим выбором мог бы стать фотодиод. При подаче обратного напряжения ток через диод растёт вместе с освещённостью, причём эта зависимость линейна. В зависимости от величины обратного напряжения фототок может достигать миллиампера (прямой солнечный свет).
▍ Без внятного ТЗ...
По закону жанра в процессе неоднократно будут внесены правки, первоначальный же вариант требований был сформулирован так:
▍ Общие требования
Устройство предназначено для измерения освещённости. Измеренная освещённость используется для вычисления экспопары.
Питание от разъёма гарнитуры, максимальный ток потребления определяется результатами измерений.
Выход — меандр, частота которого пропорциональна освещённости
▍ Частные требования
- Диапазон: 1-120000 лк.
- Точность: до ½ ступени.
- Напряжение питания: 5,0±0,1 В.
▍ Как дела с усилением

«Классическое» включение фотодиода представлено на схеме выше, но конкретно к этой задаче оно вряд ли подходит — поведение реальных фотоплёнок отличается от линейной зависимости. При увеличении яркости в два раза (на одну ступень) имеем равный прирост оптической плотности негатива. Кроме того, динамический диапазон играет с нами злую шутку: 90-100 дБ требуется как-нибудь запихнуть в 60 (16-20000 Гц), или, например, в 10 разрядов АЦП. Нужна компрессия сигнала.

В теории логарифмический усилитель можно получить, используя характеристику биполярного транзистора. Согласно модели Эберса-Молла
где Iк — ток в коллекторной цепи, Iнас — ток насыщения. Тогда напряжение база-эмиттер можно выразить как
Тогда
Проблема в том, что в реальности произвести два абсолютно одинаковых транзистора с одинаковыми характеристиками невозможно. Для этих целей применяются специальные согласованные пары на одном кристалле, которые почти все сняты с производства и их поиск превращается в довольно непростой квест. Более того, коэффициент UT раскрывается как
где k — постоянная Больцмана, q — элементарный заряд, а T — абсолютная температура в Кельвинах. Нужно как-то скомпенсировать зависимость от температуры, в противном случае логарифм будет гулять. Я чувствую себя лишним на этом празднике отладки, поэтому выбор пал на LOG104 от
Питание
Кстати о питании — именно с него всё началось, и именно из-за него я очень долго не мог решить, стоит ли вообще браться за эту затею.
▍ Цифры
Разъём гарнитуры имеет 4 контакта: левый канал, правый канал, общий и микрофонный вход. Согласно спецификации, телефон может подавать на вход вплоть до 2,9 В постоянного напряжения — фантомное питание микрофона. Запитать устройство от него не выйдет, но сама возможность в дальнейшем окажется полезной.
Единственный вариант — повышать и выпрямлять переменное напряжение с какого-либо из каналов. Здесь же становится понятно, почему использование выхода гарнитуры совсем не универсальный вариант, как могло показаться. В теории стандартный уровень сигнала для потребительской техники составляет -10 дБВ (примерно 0,3В действующего), но чего ожидать на практике от конкретного устройства могут сказать только результаты измерений. Как назло, в тот момент мой телефон был в ремонте. В поисках ответа на вопрос «а на что же примерно можно рассчитывать?», я наткнулся на эту статью. Разброс неприятно удивил: от 256 мВ до 672 мВ действующего на канал. Тут же вспоминаем, что кроме напряжения, было бы неплохо прикинуть максимально допустимую нагрузку по току, ибо мощность тоже скачет (3-80 мВт на канал).
▍ Повышаем и выпрямляем
Первым в голову приходит трансформаторное питание — собственно авторы вышеупомянутой статьи и других подобных проектов, как один используют миниатюрные трансформаторы от Coilcraft. В момент написания в наших краях это чудо если и продавалось, то от 12 штук при цене около 5300 рублей за партию. Найти сердечник и мотать самому? Сомнительное удовольствие.
▍ Паяем, пишем и измеряем

Решение всё-таки нашлось. В своё время NXP выпускала отладочную плату, которая питалась и передавала данные как раз через разъём гарнитуры. Оттуда была нагло позаимствована идея со схемой умножителя напряжения. Ключевое отличие в том, что устройство не принимает никаких данных, поэтому для питания можно задействовать оба канала и соответственно удвоить амплитуду и мощность.

Импровизированный тестовый стенд состоит из мультиметра, осциллографа и горсти выводных сопротивлений. К этому моменту телефон вернулся из ремонта, а я купил переходник с 3,5-мм на клеммы, вытравил плату и набросал программу для теста.
Генерация синусоиды
В свою очередь в MainActivity:
public class Oscillator {
private static final int SAMPLE_RATE = 44100;
private boolean isPlaying;
private int bufferSize;
private int frequency;
private int phase;
private AudioTrack track;
private short[] LUT, buffer;
public Oscillator() {
frequency = 10000;
isPlaying = false;
bufferSize = AudioTrack.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
generateLUT();
buffer = new short[bufferSize];
track = init();
}
private AudioTrack init() {
return new AudioTrack(
new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
.build(),
new AudioFormat.Builder()
.setSampleRate(SAMPLE_RATE)
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
.build(), bufferSize, AudioTrack.MODE_STREAM, AudioManager.AUDIO_SESSION_ID_GENERATE);
}
private void generateLUT() {
LUT = new short[SAMPLE_RATE];
for (int i = 0; i < SAMPLE_RATE; i++) {
LUT[i] = (short) ((double) Short.MIN_VALUE * (Math.sin((2.0 * Math.PI * ((double) i)) / ((double) SAMPLE_RATE))));
}
}
public void fillBuffer() {
for (int i = 0; i < bufferSize - 1; i += 2) {
phase %= SAMPLE_RATE;
buffer[i] = LUT[phase];
buffer[i + 1] = (short) -LUT[phase];
phase += frequency;
}
track.write(buffer, 0, bufferSize);
}
public void play() {
if (track.getState() != AudioTrack.STATE_INITIALIZED) track = init();
isPlaying = true;
fillBuffer();
track.play();
}
public void pause() {
if (track.getState() == AudioTrack.STATE_INITIALIZED) {
isPlaying = false;
track.pause();
track.flush();
}
}
//...
}
В свою очередь в MainActivity:
@Override
protected void onStart() {
super.onStart();
sine.play();
new Thread(() -> {
while (sine.isPlaying()) sine.fillBuffer();
}).start();
}
@Override
protected void onPause() {
super.onPause();
sine.stop();
}
Последний раз я притрагивался к Android SDK всерьёз ещё до появления Android Studio, поэтому Java, знакомство с Kotlin только в планах. По нажатию кнопки телефон генерирует синусоидальный сигнал в обоих каналах. Сигнал в правом канале — инвертированный левый.


На холостом ходу, когда задействованы оба канала, напряжение на входе стабилизатора подбирается к 12В, однако при подключении нагрузки оно резко падает:
Сопротивление нагрузки, Ом | Напряжение на выходе, В |
---|---|
Холостой ход | 4,96 |
1540 | 4,96 |
1320 | 4,09 |
990 | 3,73 |
660 | 2,85 |
16 мВт/3 мА… Маловато будет. Я думал сворачиваться на этом этапе, но на глаза попалась программа с говорящим названием Volume Booster. В одном из отзывов было написано, что это чудо не работает и ругается на некий LoudnessEnhancer… Быстрый поиск показал, что это один из классов Android API, и вскоре в код генератора добавились строки:
try {
amplifier = new LoudnessEnhancer(track.getAudioSessionId());
} catch (Exception e) {
Log.e(TAG, "Failed to create enhancer: ", e);
}
//...
public void gainSetEnabled(boolean enabled) {
try {
amplifier.setEnabled(enabled);
} catch (Exception e) {
Log.e(TAG, "Failed to toggle enhancer: ", e);
}
}
public void setGain(int gain) {
try {
amplifier.setTargetGain(gain);
} catch (Exception e) {
Log.e(TAG, "Failed to set gain: ", e);
}
}

Грандиозный облом
Первоначальный вариант схемы представлен на иллюстрации ниже. Выход логарифмического усилителя через аттенюатор подаётся на вход ГУН.
Не могу сказать, что я параноил, однако на всякий случай всё-таки решил проверить работоспособность идеи в Tina. Результаты симуляции немного успокаивали, но меня по-прежнему беспокоил вопрос энергопотребления.

Всё это добро еле укладывалось в 40 мВт при типовых токах потребления согласно документации, а это уже предел возможностей выхода, о запасе для максимальных говорить не приходится. Плата уже была разведена и заказана, но мои опасения подтвердились. В таком виде устройство кушало слишком много, а на выходе гарнитуры начинало твориться что-то странное вроде появления постоянной составляющей.
Первое, что приходит в голову — избавиться от аттенюатора, вот только усилитель, на котором он сделан, никуда не денется. Использовать один счетверённый усилитель? Выбранные ОУ уже не отличаются аппетитом, многие сдвоенные и счетверённые усилители потребляют значительно больше. Выкидывать отсюда что-то кроме аттенюатора особо нечего.
Кажется, самое время начать с чистого листа. Первым под нож пойдёт двуполярное питание. Далее необходимо снизить напряжение с 5 хотя бы до 3,3В. В третьих — нужно более интегрированное решение.
Вариант с датчиками, с частотным выходом, как в упомянутой выше статье на hackaday отпал сам собой, т.к. всё, что я нашёл, снято с производства. Альтернативы же все как на подбор цифровые, так что от использования микроконтроллера похоже не отвертеться.

Попытка №2. На этот раз удачная
Подходящим решением стал датчик освещённости VEML7700 — вполне реально найти и купить, а спектральная характеристика приближена к человеческому глазу. В свою очередь, микроконтроллер занят тем, что опрашивает датчик по I2C и отправляет показания; для этих целей более чем достаточно ATtiny 13A, 85-й откровенно избыточен, однако у меня под рукой был именно он. Несмотря на простоту, тупил я над второй версией знатно – начиная всеми любимыми fuse-битами и заканчивая обращением к датчику не по тому адресу.
Из старой схемы в новую без изменений перекочевали умножитель напряжения и оптопара, на которую хочу обратить отдельное внимание. Трансформаторное питание даёт такое преимущество, как гальваническая развязка. Т.к. в качестве общего используется один из каналов, соединить земли просто так не получится. Оптопара призвана решить этот вопрос, и упомянутое ранее фантомное питание здесь придётся как никогда кстати.
Модулируем и демодулируем
Датчик отдаёт значение в готовом виде, эти два байта данных нужно как-то передать. Идею подсказали китайские передатчики 433-МГц диапазона. Таймеры в микроконтроллерах AVR имеют режим генерации импульсов на отведённой для этого линии; подключение/отключение таймера к ноге осуществляется записью всего в один регистр, что позволяет реализовать что-то вроде амплитудной модуляции, где «1» — наличие сигнала, а «0» — его отсутствие.

Сверху вниз: необработанный сигнал, ФВЧ, выпрямленный сигнал, ФНЧ
Для демодуляции на стороне телефона в теории достаточно пропустить записанный сигнал через выпрямитель и фильтр нижних частот. На практике (см. верхнюю осциллограмму) сигнал перед выпрямлением придётся дополнительно пропустить через ФВЧ.
Калибровка и расчёты
Выдержка, диафрагма, чувствительность и освещённость связаны соотношением
где A — диафрагменное число, T — выдержка в секундах, I — освещённость, S — чувствительность в единицах ASA, C — калибровочная константа.
В таком виде оно не очень удобно, поэтому в 1954 году компания Friedrich Deckel AG предлагает концепцию экспозиционных чисел:
где произведение NC — экспонометрическая постоянная. Пусть
Тогда
Загадочные письмена на фотоаппаратах Canon становятся чуть понятнее.
Итоги
Лучшим итогом проделанной работы станет испытание в полевых условиях. По иронии судьбы я не успел обзавестись плёночным аппаратом, но ничто не мешает снимать в ручном режиме и использовать экспонометр камеры в качестве эталона. В большинстве случаев ошибка не превышала 1/3 ступени.
Тестовые фотографии








Демонстрация работы
Получившееся устройство скорее не инструмент, а забавная демонстрация концепции использования привычных вещей не по назначению. Аппаратная и в особенности программная часть далеки от совершенства – некоторые вопросы пока остались нерешёнными:
- В текущем виде устройство втыкается в беспаечную макетную плату. Подключение происходит через переходник с 3,5мм на клеммы. Очень хотелось бы найти штекер для монтажа на плату.
- Согласно спецификации, телефон считает, что к нему подключена гарнитура, если сопротивление контактом микрофона и землёй больше 100 Ом (типичное сопротивление микрофона — около 2 кОм). Проблема в том, что оптопара ведёт себя как разрыв цепи, что не даёт устройству быть автоматически обнаруженным, хотя иногда это срабатывало.
- Нет возможности проводить измерения по отражённому свету. Я честно пытался измерить яркость с помощью цифрового фотоаппарата и полученные значения вместе с освещённостью датчика загонять в Octave. Зависимость явно линейная, но получить похожие на правду результаты так и не получилось.
P.S. Возможно бывалые электронщики лишь усмехнутся — буду очень рад любой конструктивной критике, однако попрошу проявить чуть-чуть снисхождения к самоучке.
