Использование светодиода как датчика освещенности без применения усилителей и АЦП

10.01.2019

Некоторое время назад наткнулся на на статью "Старые друзья шиворот-навыворот, или как светодиод может быть фотодатчиком" из далекого 2009 года. Стало интересно и я решил немного поглубже изучить этот метод. Оказалось, эта тема не очень широко, но все таки обсуждалась в том году среди поклонников Ardiuno (большей частью). Сам же описанный на Хабре метод просто взят из "Using LEDs as photodiodes (light sensors)", только добавлен рисунок и переведено на русский язык. Там же нашлась и ссылка на первоисточник "Very Low-Cost Sensing and Communication Using Bidirectional LEDs" опубликованный MITSUBISHI ELECTRIC RESEARCH LABORATORIES еще в 2003 году.

Обычно, для измерения освещенности используются фоторезисторы, фотодиоды и фототранзисторы, фотоэлементы и фотоэлектронные умножители, и другие фоточувствительные компоненты. Но использование нестандартных компонентов, особенно в любительской практике, имеет давнюю историю. Так в 70-х годах прошлого века в качестве датчиков света любители не редко использовали транзисторы МП39-МП42, и им подобные, с прорезанным в корпусе окном (рекомендовалось со стороны коллекторного вывода, но часто просто срезали шляпку). Чувствительностью к свету обладали и высокочастотные диоды, вроде Д2 и Д9, имевшие большой кристалл и прозрачный корпус. Однако и обычные фотодиоды, и самодельные из транзисторов, чаще всего включают по классическим схемам (фотогальваническое или фотодиодное включение). При этом приходится использовать усилители и компараторы, а для цифровой техники и микроконтроллеров и АЦП. Предлагавшийся же, по ссылкам выше, метод позволяет напрямую подключать светодиоды (и фотодиоды, конечно) к цифровым выводам микроконтроллеров. Переводя измерение аналоговых величин, тока или напряжения, в измерение временных интервалов и работу с логическими уровнями.

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

Теория. Суть метода

Обратимся к первоисточнику и возьмем оттуда рисунок с моделью обратно-смещенного фотодиода.

То есть, в фотодиодном включении фотодиод можно представить как конденсатор с параллельно подключенным источником тока. Конденсатор представляет емкость обратно-смещенного p-n перехода, она есть у всех диодов. Обычно, она вредна, но может иметь и полезное применение, например, в варикапах. Источник тока это ток (утечки) через обратно-смещенный p-n переход. Этот ток зависит от освещенности перехода, что нам и нужно. Стоит отметить, что в реальности емкость диода зависит от приложенного напряжения, а обратный ток от температуры и напряжения. То есть, полная модель должна содержать и эти источники погрешности. Но нам пока это не важно, так что обойдемся без них. Фактически, для еще большего упрощения можно заменить источник тока резистором, сопротивление которого зависит от освещенности.

Измерение освещенности производится в два этапа. На первом этапе мы заряжаем емкость диода током существенно выше обратного тока диода до заданного напряжения. Например, до напряжения питания схемы. На втором этапе мы измеряем время, за которое емкость диода разрядится обратным током до заданного напряжения. Например, до уровня логического нуля. Это можно представить в виде схемы:

Резистор R1 ограничивает зарядный ток емкости диода. В данной схеме он может показаться лишним, но при реальном использовании он нужен для ограничения тока через выводы, например, микроконтроллера. Кроме того, как станет видно дальше, он позволяет использовать светодиод и по прямому назначению, для индикации. Под схемой измерения подразумевается, например, цифровой вход микроконтроллера или логической схемы. Нужно отметить, что схема измерения должна быть высокоомной! Причем очень высокоомной. Обратные токи светодиодов, даже освещенных, составляют единицы-десятки нА.

Теперь посмотрим, как можно использовать микроконтроллер. Напомню, что микроконтроллеры, обычно, имеют многофункциональные выводы. Так вывод может быть цифровым входом, цифровым выходом, аналоговым входом, специальной функцией. Чем в данный момент является каждый вывод определяется программой. Итак:

Пунктирной линией обозначена внутренняя схема микроконтроллера. Первый этап изображен на рисунке слева. Вывод микроконтроллера задан как цифровой выход и переведен в состояние логической 1. Через резистор R емкость диода заряжается практически до напряжения питания (Vdd). Сопротивление резистора выбирается исходя из безопасного значения тока через вывод микроконтроллера. Например, сопротивления в 1кОм будет вполне достаточно. Емкости светодиодов, обычно, менее 100пФ. Что бы емкость диода гарантированно зарядилась достаточно 1-2мкс. Второй этап изображен на рисунке справа. Вывод микроконтроллера задается как цифровой вход. С этого момента программа в микроконтроллере начинает счет времени. Емкость диода начинает разряжаться обратным током p-n перехода диода, на который падает свет, и током утечки цифрового входа микроконтроллера. При условии, что ток утечки входа существенно меньше обратного тока через диод, можно считать, что вход не влияет на процесс разряда емкости. Когда напряжение на емкости снизится ниже уровня логического нуля программа, зафиксировав этот факт, останавливает счет времени. Полученное значение временного интервала обратно пропорционально освещенности светодиода. То есть, чем больше освещен диод, тем выше его обратный ток и тем быстрее разрядится емкость диода. Сопротивление резистора при этом ничтожно мало по сравнению с сопротивлением цифрового входа и не оказывает влияния на работу схемы.

Практика

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

  • Подключение к микроконтроллеру PIC12F629
  • Подключение к триггеру Шмитта SN74LVC2G14
  • Подключение к затвору транзистора 2N7002L

С микроконтроллером все понятно, это именно то, что рассматривалось в первоисточнике (правда для применения в пультах дистанционного управления) и на форумах про Arduino. О причине выбора именно этого контроллера расскажу позже. Две оставшихся схемы покажут применимость метода для устройств без микроконтроллеров, например, на жесткой логике, или в цифро-аналоговых схемах.

Подопытные диоды

Осталось выбрать светодиоды, которые будут участвовать в тестах. Я выбрал 4 диода АЛ307Б (красные), 2 диода АЛ307Е (желтые), 2 диода АЛ307В (зеленые) и три современных импортных желтых светодиода. Большое количество старых (90-е годы прошлого века), но не использовавшихся, светодиодов обусловлено тем, что они имеют значительный разброс параметров, что позволяет лучше оценить применимость такого метода измерения освещенности. Современные диоды гораздо более стабильны, поэтому их взято меньшее количество, а желтый цвет выбран из соображения спектральной характеристики. Параметры светодиодов измерены доступным и популярным "транзистортестером". Он не очень подходит, в данном случае, но есть у многих и позволяет примерно оценить применимость светодиодов. Результаты сведены в таблицу:

N Тип Прямое падение напряжения, В Обратный ток при освещении, нА Емкость, пФ
1 АЛ307Б 1.61 68 114
2 АЛ307Б 1.65 6 31
3 АЛ307Б 1.67 10 48
4 АЛ307Б 1.63 3300 63
5 АЛ307E 1.86 0 44
6 АЛ307E 2.00 10 31
7 АЛ307B 1.88 10 37
8 АЛ307B 1.88 12 27
9 BL-L543UYC 1.93 27 3
10 BL-L524UYC 1.90 48 8
11 BL-L2506UYC 1.92 14 7

Обратите внимание, насколько большой разброс параметров. В темное обратный ток утечки был близок к 0. Исключение диод номер 4, у него обратный ток не зависел от освещенности и составлял примерно 3.3мкА! При этом он нормально работал как собственно светодиод, но не совершенно годился для измерения освещенности. У диода номер 5 обратный ток и в темноте, и на свету был близок к 0. Так же видно, что современные светодиоды имеют гораздо меньший разброс параметров. Нужно отметить, что при отборе светодиодов для тестирования попадались и такие, которые в принципе не реагировали на освещение. Они не попали в таблицу и не участвовали в тестах.

Нужно сказать несколько слов о столбце "Обратный ток". Этот ток очень сильно зависит от освещенности, а значит, и от ориентации диода на источник света (почти все светодиоды имеют корпус в виде линзы). Я старался измерять ток в том же положении, в котором проводились тесты, но особо точным этот столбец считать не стоит.

Условия тестирования

Светодиоды освещались двумя светодиодными лампами (пульсации светового потока отсутствуют) с цветовой температурой около 6000К и световым потоком, примерно, соответствующим 100Вт лампе накаливания (именно по потоку, не по мощности). Расстояние между лампами около метра, а высота над столом около 70см. Освещенность светодиодов составляла около 800лк для условия "свет" и около 400лк для условия "тень". Более подробно условия освещения описывать нет смысла, так как результаты сильно зависят от собственно светодиода и от схемы включения, как станет видно в дальнейшем. Осциллограммы снимались цифровым осциллографом Owon SDS7102V.

Подключение в микроконтроллеру

В качестве микроконтроллера был выбран PIC12F629. Это довольно простой микроконтроллер и подходит для демонстрации практического применения метода. При этом он выдерживает 100000 циклов перезаписи памяти программ, что удобно для разных экспериментов. Кроме того, он позволит мне рассказать о нескольких подводных камнях, которые могут испортить результат. При этом нужно сказать, что сам подход применим и к Arduino, и к другим микроконтроллерам имеющим высокоомные цифровые входы.

Я подключил светодиод так же, как в обсуждениях схем на Arduino именно для того, что бы показать общность подхода. Если выводы GP4 и GP5 определить как цифровые выходы и задать GP4=1, а GP=0, то светодиод будет светиться, как и обычно. То есть, в данном включении светодиод может быть и элементом индикации, и датчиком освещенности. Вот только экономии выводов при этом все равно не получится. Если индикации от светодиода не требуется, то его анод (вместе с конденсатором, конечно) можно подключить не к GP4, а к общему проводу. При этом не потребуется и управление выводом GP4, то есть, программа упростится. Конденсатор 82пФ подключен параллельно светодиоду для уменьшения влияния разброса емкостей диодов. И для того, что бы получить более длительные временные интервалы для светодиодов с малой емкостью. Этот конденсатор, кроме того, позволяет получить большую чувствительность временного интервала к малым изменения освещенности. Выходы "Заряд" и "Задержка" подключаются к двум каналам осциллографа. Первый из них имеет высокий уровень во время первого этапа, то есть во время заряда емкости диода и конденсатора. Второй отражает состояние вывода GP5 во время второго этапа, то есть во время разряда емкости диода и конденсатора обратным током диода. Подключить осциллограф напрямую на вывод GP5 нельзя, так как даже его вполне высокое сопротивление (10МОм) и небольшая емкость (7пФ) существенным образом влияют на результат измерений. Да и нам важнее не значение напряжения на этом выводе, а тот факт, что микроконтроллер посчитает его логическим нулем. Напряжение питания (Vdd) равно 5В. Интересующее нас время разряда емкости диода измеряется между задним фронтом (спадом) импульса на GP0 и задним фронтом (спадом) импульса на GP2.

Пожалуй, стоит упомянуть о параметрах входов микроконтроллера. Ток утечки входов 0.1мкА типовой (1мкА максимальный) во всем диапазоне питающих напряжений и температур. Максимальная емкость входа 50пФ. Это будет важно в дальнейшем.

Текст программы тестирования приведен ниже. Надо учитывать, что программа лишь для целей тестирования, она никак не оптимизировалась а прямо в тексте встречаются "магические константы". Да и приводится программа лишь в целях иллюстрации практической реализации метода. Хотя именно эта программа использовалась в тестах. Фактически, это программная реализация релаксационного генератора.

            #include "p12f629.inc"

                __config  0xF1C4         ; внутренний тактовый генератор

                udata_shr
            cnt res       1              ; счетчик задержки

            rst_vec  code 0x0000
                goto      Start

            int_vec  code 0x0004
                goto      Start

            main_proc     code
            Start:
                banksel   CMCON
                movlw     b'00000111'
                movwf     CMCON          ; выключаем компаратор

                movlw     b'00101010'    ; задаем направление для выводов порта
                movwf     TRISIO
                
            ; заряжаем емкость диода

            Loop:
                banksel   GPIO
                movlw     b'00100101'    ; GP4=0 GP5=1 GP0=1 GP2=1
                movwf     GPIO
                banksel   TRISIO
                bcf       TRISIO,GP5     ; GP5 на выход, заряд емкости
                banksel   GPIO
                movlw     .250           ; ожидаем
                movwf     cnt
            L1:
                decfsz    cnt
                goto      L1

            ; замер времени разряда

                movlw     b'00100100'    ; GP0=0
                movwf     GPIO
                banksel   TRISIO
                bsf       TRISIO,GP5     ; GP5 на вход, начинаем измерение
                banksel   GPIO
            L2: 
                btfsc     GPIO,GP5
                goto      L2             ; еще не разрядился
                movlw     b'00100000'    ; GP2=0, разряд закончен
                movwf     GPIO
                movlw     .250           ; ожидаем
                movwf     cnt
            L3:
                decfsz    cnt
                goto      L3
                goto      Loop

                end

Не ставлю целью данной статьи описывать систему команд и архитектуру Mid Range PIC, поэтому остановлюсь только на основных моментах. В данном случае используется внутренний тактовый генератор микроконтроллера дающий время выполнения одной команды 1мкс. В микроконтроллере есть внутренний компаратор, который необходимо отключить, что бы выводы стали цифровыми, а не аналоговыми. Псевдокоманда banksel нужна для переключения банков памяти данных, где находятся и управляющие регистры контроллера. Направление работы выводов (вход/выход) порта осуществляется регистром TRISIO. Нулевое значение соответствующего бита переключает вывод в режим выхода, а единичное входа. Собственно состояние (логические уровни) выводов порта определяется соответствующими битами регистра GPIO. Пожалуй, этого достаточно в данном случае.

Заряд емкости диода сводится к переключению выводов GP4 и GP5 в режим цифровых выходов. Причем, так как нам не нужна индикация, вывод GP4 всегда 0, а вывод GP5 всегда 1. Время заряда выбрано большим лишь для лучшей видимости на осциллограммах, так времена разряда лежат в миллисекундном диапазоне. Выводы GP0 и GP2 устанавливаются в 1, так как идет заряд емкости, и состояние вывода GP5 так же 1.

Цикл измерения начинается с переключения вывода GP5 в состояние входа. При этом соответствующий бит в регистре GPIO начинает соответствовать фактическому уровню вывода, а не установленному программой значению. Кроме того, цифровой вход имеет очень высокое сопротивление. Вывод GP4 по прежнему 0. Вывод GP0 сбрасываем в 0 для индикации окончания заряда емкости. Далее начинается циклический опрос вывода GP5 до тех пор, пока он не станет логическим нулем, что соответствует окончанию разряда емкости. Теперь можно сбросить вывод GP2 в 0 для индикации окончания разряда. После небольшой задержки снова начинаем заряд емкости. И так до бесконечности.

Для каждого подопытного светодиода привожу по две осциллограммы. Вертикальное разрешение всегда 1В/деление. Красный луч первый канал (заряд), желтый луч второй канал (задержка). Слева будет состояние "Свет", а справа "Тень".

   
Светодиод номер 1. Горизонтальное разрешение 10мс/деление. Как видно, время разряда емкости на свету 12мс, а в тени 35мс. Увеличение времени разряда на 23мс.

   
Светодиод номер 2. Горизонтальное разрешение 20мс/деление для левой осциллограммы и 50мс/деление для правой. Как видно, время разряда емкости на свету 70мс, а в тени почти 300мс. Увеличение времени разряда на 230мс.

   
Светодиод номер 3. Горизонтальное разрешение 10мс/деление. Как видно, время разряда емкости на свету 18мс, а в тени 63мс. Увеличение времени разряда на 45мс.

   
Светодиод номер 4. Горизонтальное разрешение 1мс/деление. Как видно, время разряда емкости на свету 1.5мс, а в тени 2.6мс. Увеличение времени разряда на 1.1мс. Как вы помните, это диод с большим током утечки. И это единственная схема включения где он показал хоть какой то вменяемый результат.

   
Светодиод номер 5. Горизонтальное разрешение 20мс/деление для левой осциллограммы и 50мс/деление для правой. Как видно, время разряда емкости на свету 38мс, а в тени почти 150мс. Увеличение времени разряда на 112мс.

   
Светодиод номер 6. Горизонтальное разрешение 20мс/деление. Как видно, время разряда емкости на свету 21мс, а в тени 100мс. Увеличение времени разряда на 79мс.

   
Светодиод номер 7. Горизонтальное разрешение 50мс/деление. Как видно, время разряда емкости на свету 75мс, а в тени 190мс. Увеличение времени разряда на 115мс.

   
Светодиод номер 8. Горизонтальное разрешение 20мс/деление для левой осциллограммы и 50мс/деление для правой. Как видно, время разряда емкости на свету 48мс, а в тени 155мс. Увеличение времени разряда на 107мс.

   
Светодиод номер 9. Горизонтальное разрешение 10мс/деление. Как видно, время разряда емкости на свету 15мс, а в тени 37мс. Увеличение времени разряда на 22мс.

   
Светодиод номер 10. Горизонтальное разрешение 5мс/деление. Как видно, время разряда емкости на свету 6.8мс, а в тени 29,5мс. Увеличение времени разряда на 22.7мс.

   
Светодиод номер 11. Горизонтальное разрешение 10мс/деление. Как видно, время разряда емкости на свету 24мс, а в тени 48мс. Увеличение времени разряда на 24мс.

Сведу результаты в таблицу. При этом добавлю столбец процентов изменения времени разряда, который будет содержать отношение разницы времен к времени разряда в тени.

N Тип Tтень, мс Tсвет, мс Разница, мс Процент
1 АЛ307Б 35 12 23 66
2 АЛ307Б 300 70 230 76
3 АЛ307Б 63 18 45 71
4 АЛ307Б 2.6 1.5 1.1 42
5 АЛ307E 150 38 112 75
6 АЛ307E 100 21 79 79
7 АЛ307B 190 75 115 61
8 АЛ307B 155 48 107 69
9 BL-L543UYC 37 15 22 59
10 BL-L524UYC 29.5 6.8 22.7 77
11 BL-L2506UYC 48 24 24 50

Погрешность замеров не так мала, как хотелось бы, но общий итог виден. Не смотря на разброс параметров, большинство светодиодов, в среднем, показывают разницу времен разряда в районе 66%. Да, есть и аутсайдеры (диод номер 4 с большой утечкой) и лидеры (диоды номер 2, 5 и 10), но понятно, что такой метод использования светодиодов для из измерения освещенности вполне рабочий применимо к микроконтроллерам. Так же понятно, что каждый отдельно взятый светодиод требует калибровки для определения значения констант отвечающих за пороговые значения освещенности в программе. Так что метод применим в любительской практике, но не пригоден для серийного применения.

Нужно отметить еще одну тонкость. Схема весьма чувствительна к наводкам в силу своей высокоомности, особенно в темноте. Поэтому светодиод нужно размещать как можно ближе к входу микроконтроллера. Сделать выносной датчик освещенности не получится. По этой же причине последовательные измерения времени разряда могут давать несколько результаты, из-за наводок. Так что стоит делать несколько замеров и усреднять получившееся время. Кроме того, не лишним будет введение гистерезиса в пороговые значения измерений.

Кривая зависимости времени разряда от освещенности не снималась, все равно метод не предназначен для точных измерений, так что нелинейность (а она, скорее всего, не маленькая) большого влияния не имеет.

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

Подводные камни

Теперь нужно пояснить, почему же не у всех получается использовать этот метод? Приведу несколько причин, которые могут привести к неудаче. Начну с довольно простых и, в некотором смысле, очевидных.

Выбран не подходящий светодиод
Это первое, с чего нужно начинать поиск причины неудачи. Как я уже писал, может попасться диод в принципе не реагирующий на свет или реагирующий очень слабо. Так же, следует избегать использования диодов с большими токами утечки (вроде диода номер 4 из данного теста). Попробуйте взять другой диод, желательно другого типа.
Выбраны неверные параметры способа измерения времени
Как видно из результатов тестирования, время разряда емкости может измеряться и единицами миллисекунд, и сотнями. А в темноте и секундами. Это зависит от многих факторов, но основное значение имеет обратный ток светодиода и емкость дополнительного конденсатора, а при его отсутствии емкость самого светодиода. Ваш счетчик, не важно, программный или аппаратный (счетчик таймера, например), может переполняться при выборе слишком долгого времени счета или высокой частоты импульсов на входе таймера. При слишком малом времени счета, или низкой частоте, счетчик может изменяться недостаточно, для уверенной фиксации факта изменения освещенности. Напишите простую тестовую программу, вроде использованной здесь, и измерьте времена осциллографом.
Слепое копирование чужой схемы/программы
Довольно распространенная ошибка. Один участник обсуждения приводит свою схему с указанием использованных деталей и текст программы. Второй ее в точности повторяет. При этом у первого все работает, а у второго нет. Кажется, мистика, но на самом деле такое вполне возможно. Даже применение того же самого светодиода и микроконтроллера, включая схему подключения (то же самый порт и те же самые разряды порта), не гарантирует, что время разряда будет соответствовать времени счета. Причина в разбросе параметров диодов и порта контроллера. Например, первый может получить время разряда 20мс, а ваш светодиод даст время 150мс, что приведет к переполнению счетчика времени разряда. Кроме того, не известно при какой интенсивности освещения работала схема, а это существенно влияет на результаты.
К диоду подключен измерительный прибор
Я уже говорил, что схема измерения должна быть очень высокоомной. Поэтому подключение к диоду измерительного прибора, например, осциллографа, вносит существенные искажения и даже может привести к полной неработоспособности схемы (емкость просто мгновенно, или очень быстро, разряжается и на это не влияет освещенность диода). Даже мой осциллограф с входными параметрами 10МОм и 7пФ (это щуп с делителем 1:10) оказывает существенно влияние. Что уж говорить об использовании щупа с делителем 1:1 (это даст входное сопротивление 1МОм, в большинстве случаев). А ведь встречаются и осциллографы с более низким сопротивлением входа.
Недостаточно высокое входное сопротивление схемы измерения (вывода микроконтроллера)
Возможно, не отключена одна из специальных функций вывода микроконтроллера. Например, может остаться подключенным резистор подтяжки. Это может быть если вы сами проектируете схему и пишете программу (забыли, с кем не бывает), или переносите подключение светодиода на другой вывод при повторении готовой схемы не внеся всех необходимых изменений в программу. Возможна и неисправность микроконтроллера и просто не подходящий тип.

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

Вы не знаете используемый микроконтроллер!

Вот тут мне все таки придется немного углубиться в особенности PIC12F629, да и всей линейки Base Line, Mid Range и Extended Mid Range микроконтроллеров Microchip (PIC10, PIC12, PIC16). Сразу замечу, что подобные тонкости, которые можно не знать, или просто упустить из виду, есть у всех микроконтроллеров. Поэтому просто необходимо внимательно изучать документацию производителя!

Начну с простого. Повторюсь, в большинстве случаев каждый вывод микроконтроллера может выполнять несколько функций и иметь несколько настраиваемых параметров. Так, если вы вернетесь к приведенной выше программе, то заметите, что я отключил встроенный компаратор. Для данного микроконтроллера он использует выводы GP0, GP1 и GP2. Освободить нужные нам GP0 и GP2 можно либо полностью отключив компаратор, что я и сделал, либо переведя его в режим отключенного выхода (тогда его выход доступен только программно) и использования внутреннего источника опорного напряжения. Если же этого не сделать, то выводы будут не цифровыми, а аналоговыми, что нам совершенно не подходит. Да, я не использовал эти выводы для подключения светодиода, но мог бы это сделать.

Не все выводы портов микроконтроллеров могут быть равнозначными. Так в данном микроконтроллере вывод GP3 может использоваться только как цифровой вход или вход сброса. Разумеется, его не получится использовать для подключения светодиода. В некоторых микроконтроллерах (не в PIC12F629) вывод в режиме выхода может быть выполнен не двухтактным, а с открытым стоком. Такой вывод не получится использовать для подключения светодиода, так как неизбежный внешний подтягивающий резистор заставит забыть о высоком входном сопротивлении.

Выводы портов цифровых входов могут иметь встроенные подтягивающие резисторы, которые необходимо отключить для вывода с подключенным светодиодом (нам нужно высокое входное сопротивление). Эти резисторы могут управляться через биты конфигурации и/или через специальные регистры управления портом. Для данного микроконтроллера это только специальный управляющий регистр.

Теперь о самом не очевидном на котором подаются многие, не исключая и меня. Обратите внимание, что я не использовал инструкции сброса/установки отдельных бит (bcf/bsf) при работе с GPIO, но использовал при работе с TRISIO. Дело в том, что эти инструкции работают по принципу чтение-модификация-запись. То есть, в АЛУ считывается весь байт из регистра, выполняется сброс или установка указанного бита, измененный байт записывается обратно в регистр. Вроде бы обычное поведение. Но тут нужно учитывать то, как работают порты ввода-вывода. В данном микроконтроллере есть регистр данных порта (GPIO). Записанное в него значение выводится на выводах микроконтроллера находящихся в режиме выхода. Но записать в этот регистр можно и значения разрядов находящихся в состоянии входа. Просто от таких разрядов будут отключены выходные буферные каскады и на состояние выводов это не повлияет. Но вот чтение данных из порта считывает не информацию из этого регистра, а напрямую с выводов микроконтроллера! То есть, можно записать в соответствующий разряд регистра, например, 1, а затем считать 0. При этом записанная 1 никуда не денется и окажется на выводе микроконтроллера при переводе соответствующего разряда порта в состояние выхода. В более поздних разработках микроконтроллеров к внутренней схеме портов ввода-вывода были добавлены регистры LAT, которые позволяют раздельно считывать и текущее состояние входа порта, и записанное для вывода значение.

И в документации производителя, и в многочисленных учебниках, указывается, что такая архитектура портов может привести к ошибкам при использовании инструкций манипуляции отдельными битами. Но в качестве примера приводятся довольно однотипные и не очень возможные на практике примеры, что вывод порта может быть перегружен, что и даст неверный результат. Но проблема гораздо шире. Давайте еще раз посмотрим на нашу программу. GP4 у нас всегда 0, а GP5 или 1 или вход. С учетом написанного выше можно еще до цикла начинающегося с метки Loop задать значения этих разрядов и далее переключать только GP0 и GP2. И направление передачи для GP5. Но это приведет к неработоспособности программы! Почему? Вот одно из критических мест, когда зафиксировав низкий уровень на GP5 мы сбрасываем GP2. Если для этого использовать инструкцию сброса бита, то будет прочитано фактическое состояние выводов, где GP5=0 (емкость разряжена). После сброса GP2 обратно в регистр порта будет записан байт, где записанная в GP5 до цикла 1 пропадет, там теперь будет 0. Все, емкость больше никогда не будет заряжаться и мы потерпим неудачу. И это лишь один из примеров. Поэтому в сложных программах, если регистры LAT не предусмотрены производителем, приходится применять их программную эмуляцию в памяти данных.

Извиняюсь за столь длинное повествование об архитектуре PIC. Я старался показать, как много факторов могут привести к неудаче. Это актуально для практически любых микроконтроллеров, кроме самых простых. И чем сложнее контроллер, тем больше тонкостей в его настройке и программировании. Не делайте преждевременных выводов о неработоспособности.

Теперь перейду к двум оставшимся схемам подключения. Кроме полноты картины они помогут понять некоторые уже упомянутые мной особенности и тонкости. Да и понимания описанных подводных камней прибавится.

Подключение к триггеру Шмитта SN74LVC2G14

Использование триггера Шмитта необходимо по причине весьма медленно изменяющихся сигналов на входе, напряжение на емкости светодиода и дополнительной емкости изменяется медленно. А современные цифровые микросхемы обычно выпускают буферизованными, что накладывает серьезные ограничения на длительности фронтов (скорости нарастания напряжения) входного напряжения. Так для NC7WZ04P6X (сдвоенный инвертор) требуемая скорость нарастания входного напряжения должна быть не ниже 5нс/В для питающего напряжения 5В. Причина в мощном выходном каскаде, который не предназначен для работы в линейном режиме. Разумеется, старые серии вроде CD4000 или К176/К561 могут работать в линейном режиме. Выпускаются и специальные вариации современных микросхем допускающие линейный режим, но они редки, а цены на них не радуют. Поэтому триггер Шмитта самый разумный выбор. Я использовал половинку микросхемы сдвоенного инвертора с триггером Шмитта, вход второго инвертора заземлен.

В данной схеме пришлось использовать внешний генератор импульсов, а для имитации разомкнутого состояния ключа использован диод 1N4148, ток утечки которого при комнатной температуре и напряжении менее 20В не превышает 25нА. Так как обратный ток 1N4148 сравним с обратными токами светодиодов, он будет оказывать заметное влияние на результаты измерений. Все остальные детали те же самые, что и для подключения к микроконтроллеру. Параметры входов использованного инвертора: ток утечки не более 5мкА и емкость не более 4пФ. Уже видно, что ток утечки выше, чем у входов микроконтроллера.

Это осциллограмма без подключения светодиода. Поскольку у нас инвертор, то необходимое нам время разряда емкости измеряется между задним фронтом (спадом) импульса "Заряд" и передним фронтом (нарастанием) импульса "Задержка". Разрешение по горизонтали 10мс/деление. Видно, что даже без светодиода емкость отлично разряжается примерно за 70.5мс. Напомню, что для микроконтроллера время разряда без светодиода или с полностью затемненным светодиодом составляло секунды и десятки секунд. Это наглядно демонстрирует мои слова о влиянии входного сопротивления на работу схемы. Фактически, уже понятно, что полученные при такой схеме включения результаты будут хуже, чем в схеме с микроконтроллером.

Для каждого подопытного светодиода привожу по две осциллограммы. Вертикальное разрешение всегда 1В/деление. Красный луч первый канал (заряд), желтый луч второй канал (задержка). Слева будет состояние "Свет", а справа "Тень".

   
Светодиод номер 1. Горизонтальное разрешение 5мс/деление. Как видно, время разряда емкости на свету 7.2мс, а в тени 16.1мс. Увеличение времени разряда на 8.9мс.

   
Светодиод номер 2. Горизонтальное разрешение 10мс/деление. Как видно, время разряда емкости на свету 36.5мс, а в тени 58мс. Увеличение времени разряда на 21.5мс.

   
Светодиод номер 3. Горизонтальное разрешение 5мс/деление. Как видно, время разряда емкости на свету 8.9мс, а в тени 22мс. Увеличение времени разряда на 13.1мс.

   
Светодиод номер 4. Горизонтальное разрешение 200мкс/деление. Как видно, время разряда емкости на свету 120мкс (по уровню 4В), а в тени 121мкс. Увеличение времени разряда на 1мкс. Как вы помните, это диод с большим током утечки. В отличии от схемы с микроконтроллером тут он потерпел полное фиаско.

   
Светодиод номер 5. Горизонтальное разрешение 10мс/деление. Как видно, время разряда емкости на свету 15.5мс, а в тени 41.5мс. Увеличение времени разряда на 26мс.

   
Светодиод номер 6. Горизонтальное разрешение 10мс/деление. Как видно, время разряда емкости на свету 17мс, а в тени 34.5мс. Увеличение времени разряда на 17.5мс.

   
Светодиод номер 7. Горизонтальное разрешение 10мс/деление. Как видно, время разряда емкости на свету 31.5мс, а в тени 41.5мс. Увеличение времени разряда на 10мс.

   
Светодиод номер 8. Горизонтальное разрешение 10мс/деление. Как видно, время разряда емкости на свету 19.5мс, а в тени 39мс. Увеличение времени разряда на 19.5мс.

   
Светодиод номер 9. Горизонтальное разрешение 5мс/деление. Как видно, время разряда емкости на свету 7.2мс, а в тени 14.1мс. Увеличение времени разряда на 6.9мс. Обратите внимание, как и для диода номер 4, для некоторых новых импортных диодов наблюдается генерация на переднем фронте (нарастании) сигнала "Задержка". Затрудняюсь сказать, с чем это связано.

   
Светодиод номер 10. Горизонтальное разрешение 5мс/деление. Как видно, время разряда емкости на свету 4мс, а в тени 11мс. Увеличение времени разряда на 7мс.

   
Светодиод номер 11. Горизонтальное разрешение 5мс/деление. Как видно, время разряда емкости на свету 10мс, а в тени 19мс. Увеличение времени разряда на 9мс.

Сведу результаты в таблицу. При этом добавлю столбец процентов изменения времени разряда, который будет содержать отношение разницы времен к времени разряда в тени.

N Тип Tтень, мс Tсвет, мс Разница, мс Процент
1 АЛ307Б 16.1 7.2 8.9 55
2 АЛ307Б 58 36.5 21.5 37
3 АЛ307Б 22 8.9 13.1 60
4 АЛ307Б 0.121 0.12 0.01 5
5 АЛ307E 41.5 15.5 26 63
6 АЛ307E 34.5 17 17.5 51
7 АЛ307B 41.5 31.5 10 24
8 АЛ307B 39 19.5 19.5 50
9 BL-L543UYC 14.1 7.2 6.9 49
10 BL-L524UYC 11 4 7 63
11 BL-L2506UYC 19 10 9 47

Результаты действительно хуже. Причем лидер теста с микроконтроллером, диод номер 2, неожиданно показал неважный результат. Возможно, это артефакт связанный с неточным расположением диода по направлению источников света. Возможно, результат того, что малый обратный ток диода оказался мало значимым на фоне суммарного тока утечки схемы. Тем не менее, средняя разница времен составляет 50%, если не считать провала диода номер 4. То есть, такая схема включения вполне работоспособна и имеет право на жизнь. Но хорошо показывает влияние параметров схемы измерения на результат.

Подключение к затвору транзистора 2N7002L

А что если ставить дополнительную микросхему не хочется, зато под рукой есть полевой транзистор, пусть и самый дешевый, 2N7002L?

Отличие от схемы с триггером Шмитта заключается в полевом транзисторе и стоковом резисторе. Все остальное точно такое же. Ток утечки затвора до 0.1мкА, как и у микроконтроллера. Емкость до 50пФ (фактическая 46пф у использованного транзистора). Пороговое напряжение от 1В до 2.5В (для тока стока 250мкА). Напряжение питания схемы 5В. В отличии от схемы с триггером Шмитта, схема с полевым транзистором не разряжает емкость без подключенного светодиода за сколько нибудь разумное время. В остальном посмотрим.

Для каждого подопытного светодиода привожу по две осциллограммы. Вертикальное разрешение всегда 1В/деление. Красный луч первый канал (заряд), желтый луч второй канал (задержка). Слева будет состояние "Свет", а справа "Тень".

   
Светодиод номер 1. Горизонтальное разрешение 5мс/деление. Как видно, время разряда емкости на свету 12мс (по уровню 4В), а в тени 26мс. Увеличение времени разряда на 14мс. В глаза сразу бросается большое время переднего фронта (нарастание) сигнала задержка. Это из-за довольно малой крутизны данного транзистора и малого коэффициента усиления каскада в целом.

   
Светодиод номер 2. Горизонтальное разрешение 20мс/деление. Как видно, время разряда емкости на свету 76мс, а в тени 108мс. Увеличение времени разряда на 32мс.

   
Светодиод номер 3. Горизонтальное разрешение 20мс/деление. Как видно, время разряда емкости на свету 18мс, а в тени 43мс. Увеличение времени разряда на 25мс.

   
Светодиод номер 4. Горизонтальное разрешение 200мкс/деление. Как видно, время разряда емкости на свету 470мкс, а в тени 500мкс. Увеличение времени разряда на 30мкс. Как вы помните, это диод с большим током утечки. Тут он так же потерпел полное фиаско.

   
Светодиод номер 5. Горизонтальное разрешение 20мс/деление. Как видно, время разряда емкости на свету 27мс, а в тени 73мс. Увеличение времени разряда на 46мс.

   
Светодиод номер 6. Горизонтальное разрешение 10мс/деление. Как видно, время разряда емкости на свету 34мс, а в тени 63мс. Увеличение времени разряда на 29мс.

   
Светодиод номер 7. Горизонтальное разрешение 20мс/деление. Как видно, время разряда емкости на свету 55мс, а в тени 82мс. Увеличение времени разряда на 27мс.

   
Светодиод номер 8. Горизонтальное разрешение 20мс/деление. Как видно, время разряда емкости на свету 36мс, а в тени 71мс. Увеличение времени разряда на 35мс.

   
Светодиод номер 9. Горизонтальное разрешение 5мс/деление. Как видно, время разряда емкости на свету 14.5мс, а в тени 29мс. Увеличение времени разряда на 14.5мс.

   
Светодиод номер 10. Горизонтальное разрешение 5мс/деление. Как видно, время разряда емкости на свету 7.5мс, а в тени 24мс. Увеличение времени разряда на 16.5мс.

   
Светодиод номер 11. Горизонтальное разрешение 10мс/деление. Как видно, время разряда емкости на свету 23мс, а в тени 40мс. Увеличение времени разряда на 17мс.

Сведу результаты в таблицу. При этом добавлю столбец процентов изменения времени разряда, который будет содержать отношение разницы времен к времени разряда в тени.

N Тип Tтень, мс Tсвет, мс Разница, мс Процент
1 АЛ307Б 26 12 14 54
2 АЛ307Б 108 76 32 30
3 АЛ307Б 43 18 25 58
4 АЛ307Б 0.5 0.47 0.03 6
5 АЛ307E 73 27 46 63
6 АЛ307E 63 34 29 46
7 АЛ307B 82 55 27 33
8 АЛ307B 71 36 35 49
9 BL-L543UYC 29 14.5 14.5 50
10 BL-L524UYC 24 7.5 16.5 69
11 BL-L2506UYC 40 23 17 43

Результат примерно соответствует схеме с триггером Шмитта. Средняя разница времен так же составляет 50%, если не считать провала диода номер 4. То есть, такая схема включения вполне работоспособна и имеет право на жизнь.

Заключение

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

Все ли уже сказано? Да, почти все. Осталось лишь сказать, что в тестах не было учтено влияние порогового напряжения схем измерения. Для PIC12F629 максимальное входное напряжение низкого уровня составляет примерно 0.8В. То есть, емкость разряжается от 5В до 0.8В. Для использованного триггера Шмитта порог переключения при спадающем напряжении на входе составляет от 1.4 до 2.5В. То есть, емкость разряжается до более высокого напряжения, разумеется, для этого требуется меньше времени. Для транзистора пороговое напряжение составляет от 1 до 2.5В (и зависит от тока стока), что, в нашем случае, оказалось ниже, чем у использованного триггера Шмитта. Это и привело к большим временам (вместе с меньшим паразитным током утечки). При этом все схемы имеют сравнимую чувствительность, хотя чувствительность микроконтроллера немного выше.

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