Экспонируй это

9bjg_lstaia8eejjtz3syzilh-g.jpeg


Несколько лет назад я открыл для себя DigitalRev TV. В одном из выпусков в руки Кая и Лока попадает отечественный фотоаппарат «Любитель-166», но моё внимание привлёк совсем не он. Из кожаного футлярчика Кай достаёт маленькое устройство, которое включается в разъём гарнитуры телефона — экспонометр. С тех пор эта белая полусфера не даёт мне покоя. В статье хочу поделиться опытом создания подобного устройства своими руками.

Вместо введения


Как известно, каждый сходит с ума по-своему. Есть люди, которые собирают марки, не выпускают из рук паяльник, или ходят в походы. Мне же стукнуло в голову поснимать на плёнку — запрыгнуть в последний вагон поезда уходящей эпохи.

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

Экспозиция — это величина засветки светочувствительного материала или матрицы фотоаппарата. От неё прямо зависит качество снимка. Слишком большая экспозиция (или передержка) приведёт к потере деталей в светлых участках, недостаточная (или недодержка) — к потере деталей в тенях. Номинальная экспозиция (т.е. необходимое количество освещения) называется чувствительностью фотоматериала. Идея замера экспозиции заключается в том, чтобы подобрать параметры съёмки (время выдержки и диафрагменное число — экспопару), дающие номинальную экспозицию вне зависимости от условий освещения.
Современные фотоаппараты и камеры мобильных телефонов могут делать это автоматически (или полуавтоматически, оставляя выбор части параметров за вами), но так было не всегда, и на многих старых фотоаппаратах всё делается вручную. Некоторые камеры комплектовались встроенным экспонометром, однако:

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


Одним словом, отдельный прибор — полезная в хозяйстве вещь.

Троллейбус из буханки


frmstvazlw4gmge7umi4rmraujo.jpeg

Мой экземпляр, май 1978

Вообще, можно было не заморачиваться и найти на какой-нибудь барахолке старенький «Ленинград-4» по цене от 100 до 1000 рублей в зависимости от жадности продавца. Его должно хватить с головой, но мы не ищем лёгких путей:

  • Во-первых, меня очень привлекло устройство из ролика и я люблю изобретать велосипеды. Интересно как повторить подобную конструкцию, так и разобраться в общих принципах.
  • Во-вторых, пользоваться старой отечественной шкалой чувствительности не очень удобно, когда в качестве международного стандарта давно приняты единицы ASA и DIN.
  • В третьих, селеновые фотоэлементы со временем теряют чувствительность. Тут уж как повезёт.

▍ Что и как измерять


Производить измерения можно двумя способами — по падающему и по отражённому свету. В первом случае экспонометр направляется приёмником от объекта съёмки к камере, измеряется освещённость. Во втором — наоборот, измеряется интегральная яркость сцены. Обе величины могут изменяться в очень большом диапазоне — до 120000 лк (под прямым солнечным светом) или примерно до 30000 кд/м2 (освещённый солнцем снег). Т.к. требуются конкретные величины, а не просто наличие/отсутствие света, то нужен соответствующий фотодатчик. Фоторезисторы можно сразу отбросить из-за малого динамического диапазона. Фототранзисторы выглядят интереснее, но они чувствительны преимущественно к красной и инфракрасной части спектра. Лучшим выбором мог бы стать фотодиод. При подаче обратного напряжения ток через диод растёт вместе с освещённостью, причём эта зависимость линейна. В зависимости от величины обратного напряжения фототок может достигать миллиампера (прямой солнечный свет).

▍ Без внятного ТЗ…


По закону жанра в процессе неоднократно будут внесены правки, первоначальный же вариант требований был сформулирован так:

▍ Общие требования


Устройство предназначено для измерения освещённости. Измеренная освещённость используется для вычисления экспопары.
Питание от разъёма гарнитуры, максимальный ток потребления определяется результатами измерений.
Выход — меандр, частота которого пропорциональна освещённости

▍ Частные требования


  • Диапазон: 1–120000 лк.
  • Точность: до ½ ступени.
  • Напряжение питания: 5,0±0,1 В.

▍ Как дела с усилением


image-loader.svg«Классическое» включение фотодиода

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

image-loader.svgЛогарифмический усилитель

В теории логарифмический усилитель можно получить, используя характеристику биполярного транзистора. Согласно модели Эберса-Молла

$I_к = I_{нас}\cdot e^{\frac{U_{БЭ}}{U_T}-1}$


где Iк — ток в коллекторной цепи, Iнас — ток насыщения. Тогда напряжение база-эмиттер можно выразить как

$U_{БЭ}=U_T \cdot ln\frac{I_к}{I_{нас}}$


Тогда

$U_{вых}=U_T(ln\frac{I_{вх}}{I_{нас}}-ln\frac{I_{оп}}{I_{нас}})=U_T\cdot ln\frac{I_{вх}}{I_{оп}}$


Проблема в том, что в реальности произвести два абсолютно одинаковых транзистора с одинаковыми характеристиками невозможно. Для этих целей применяются специальные согласованные пары на одном кристалле, которые почти все сняты с производства и их поиск превращается в довольно непростой квест. Более того, коэффициент UT раскрывается как

$U_T = \frac{kT}{q}$


где k — постоянная Больцмана, q — элементарный заряд, а T — абсолютная температура в Кельвинах. Нужно как-то скомпенсировать зависимость от температуры, в противном случае логарифм будет гулять. Я чувствую себя лишним на этом празднике отладки, поэтому выбор пал на LOG104 от Burr-Brown простите, Texas Instruments. Микросхема дорогая, но её хотя бы можно купить. Главное неудобство связано с требованием двухполярного питания и наличием опорного источника тока.

Питание


Кстати о питании — именно с него всё началось, и именно из-за него я очень долго не мог решить, стоит ли вообще браться за эту затею.

▍ Цифры


Разъём гарнитуры имеет 4 контакта: левый канал, правый канал, общий и микрофонный вход. Согласно спецификации, телефон может подавать на вход вплоть до 2,9 В постоянного напряжения — фантомное питание микрофона. Запитать устройство от него не выйдет, но сама возможность в дальнейшем окажется полезной.

Единственный вариант — повышать и выпрямлять переменное напряжение с какого-либо из каналов. Здесь же становится понятно, почему использование выхода гарнитуры совсем не универсальный вариант, как могло показаться. В теории стандартный уровень сигнала для потребительской техники составляет -10 дБВ (примерно 0,3В действующего), но чего ожидать на практике от конкретного устройства могут сказать только результаты измерений. Как назло, в тот момент мой телефон был в ремонте. В поисках ответа на вопрос «а на что же примерно можно рассчитывать?», я наткнулся на эту статью. Разброс неприятно удивил: от 256 мВ до 672 мВ действующего на канал. Тут же вспоминаем, что кроме напряжения, было бы неплохо прикинуть максимально допустимую нагрузку по току, ибо мощность тоже скачет (3–80 мВт на канал).

▍ Повышаем и выпрямляем


Первым в голову приходит трансформаторное питание — собственно авторы вышеупомянутой статьи и других подобных проектов, как один используют миниатюрные трансформаторы от Coilcraft. В момент написания в наших краях это чудо если и продавалось, то от 12 штук при цене около 5300 рублей за партию. Найти сердечник и мотать самому? Сомнительное удовольствие.

▍ Паяем, пишем и измеряем


rqjuhyz71ubnow1vwbab66mkdvc.jpegNXP Quickjack

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

image-loader.svg

Импровизированный тестовый стенд состоит из мультиметра, осциллографа и горсти выводных сопротивлений. К этому моменту телефон вернулся из ремонта, а я купил переходник с 3,5-мм на клеммы, вытравил плату и набросал программу для теста.

Генерация синусоиды
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 только в планах. По нажатию кнопки телефон генерирует синусоидальный сигнал в обоих каналах. Сигнал в правом канале — инвертированный левый.

v_dfiysxykv4j6sbrv-dcjalw7g.jpegProof of concept

t6xbiohpioty2zhzfvg2arcosy4.jpegВожделенный синус, 10 кГц. 400 мВ амплитудного или примерно 283 мВ действующего на канал. Немного меньше того, на что рассчитывал, но тоже неплохо

На холостом ходу, когда задействованы оба канала, напряжение на входе стабилизатора подбирается к 12В, однако при подключении нагрузки оно резко падает:


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);
    }
}


xyxjh8cvbfupkwtktgvjkjv3dy8.jpeg600 мВ на канал после применения эффекта. Итого 40,5 мВт на моём Xperia 10 plus. Практически магия

Грандиозный облом


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

image-loader.svg

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

Кажется, самое время начать с чистого листа. Первым под нож пойдёт двуполярное питание. Далее необходимо снизить напряжение с 5 хотя бы до 3,3В. В третьих — нужно более интегрированное решение.

Вариант с датчиками, с частотным выходом, как в упомянутой выше статье на hackaday отпал сам собой, т.к. всё, что я нашёл, снято с производства. Альтернативы же все как на подбор цифровые, так что от использования микроконтроллера похоже не отвертеться.

image-loader.svg
Попытка №2. На этот раз удачная

Подходящим решением стал датчик освещённости VEML7700 — вполне реально найти и купить, а спектральная характеристика приближена к человеческому глазу. В свою очередь, микроконтроллер занят тем, что опрашивает датчик по I2C и отправляет показания; для этих целей более чем достаточно ATtiny 13A, 85-й откровенно избыточен, однако у меня под рукой был именно он. Несмотря на простоту, тупил я над второй версией знатно — начиная всеми любимыми fuse-битами и заканчивая обращением к датчику не по тому адресу.

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

Модулируем и демодулируем


Датчик отдаёт значение в готовом виде, эти два байта данных нужно как-то передать. Идею подсказали китайские передатчики 433-МГц диапазона. Таймеры в микроконтроллерах AVR имеют режим генерации импульсов на отведённой для этого линии; подключение/отключение таймера к ноге осуществляется записью всего в один регистр, что позволяет реализовать что-то вроде амплитудной модуляции, где »1» — наличие сигнала, а »0» — его отсутствие.

image-loader.svg
Сверху вниз: необработанный сигнал, ФВЧ, выпрямленный сигнал, ФНЧ

Для демодуляции на стороне телефона в теории достаточно пропустить записанный сигнал через выпрямитель и фильтр нижних частот. На практике (см. верхнюю осциллограмму) сигнал перед выпрямлением придётся дополнительно пропустить через ФВЧ.

Калибровка и расчёты


Выдержка, диафрагма, чувствительность и освещённость связаны соотношением

$\frac{A^2}{T}=\frac{IS}{C}$


где A — диафрагменное число, T — выдержка в секундах, I — освещённость, S — чувствительность в единицах ASA, C — калибровочная константа.
В таком виде оно не очень удобно, поэтому в 1954 году компания Friedrich Deckel AG предлагает концепцию экспозиционных чисел:

$E_V = log_2\frac{A^2}{T}=log_2\frac{IS}{NC}$


где произведение NC — экспонометрическая постоянная. Пусть
$A_V = 2log_2A$ — эффективная диафрагма,
$T_V = -log_2T$ — эффективная выдержка,
$S_V = log_2\frac{ASA}{N}$ — эффективная чувствительность (N принята равной 3,125),
$I_V = log_2\frac{I}{C}$ — эффективная освещённость.
Тогда

$E_V = A_V + T_V = I_V + S_V$


Загадочные письмена на фотоаппаратах Canon становятся чуть понятнее.

Итоги


Лучшим итогом проделанной работы станет испытание в полевых условиях. По иронии судьбы я не успел обзавестись плёночным аппаратом, но ничто не мешает снимать в ручном режиме и использовать экспонометр камеры в качестве эталона. В большинстве случаев ошибка не превышала ⅓ ступени.

Тестовые фотографии


Демонстрация работы


Получившееся устройство скорее не инструмент, а забавная демонстрация концепции использования привычных вещей не по назначению. Аппаратная и в особенности программная часть далеки от совершенства — некоторые вопросы пока остались нерешёнными:

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


P.S. Возможно бывалые электронщики лишь усмехнутся — буду очень рад любой конструктивной критике, однако попрошу проявить чуть-чуть снисхождения к самоучке.

image-loader.svg

© Habrahabr.ru