Авторизация
Зарегистрироваться

Еще один люксметр на BH1750


Здоровья всем читателям Муськи!
Неоднократно делал для дома и аквариумов разные светильники на галогенках, ЛЛ и светодиодах. И в какой-то момент понял, что не помешало бы иметь хотя бы простейший приборчик для количественного сравнения светильников, ибо человеческий глаз ну очень не стабильный измеритель. Если светильники включать не одновременно, то глаз адаптируется и освещенность отличающаяся даже не в разы, а на порядки, кажется одинаковой. Но потом оказывается, что под этим светом не получается различить мелкие детали, цвета, а в аквариуме трава не растет.

Но тратиться на нормальный прибор для домашнего применения пару раз в год казалось излишеством. И тут как нельзя кстати оказались обзоры самодельных люксметров на дешевом датчике BH1750FVI (datasheet), который выдает уровень освещенности прямо в люксах, да еще с приличной точностью. Замечательно — прибор делаем сами, заодно изучив новые технологии.
В обзоре помимо конструкции люксметра расскажу об отличиях двух модулей датчиков и будет некоторый ликбез по шине I2C.
Аналогичные люксметры на таком же датчике собирались вот в этих обзорах, которыми я и вдохновлялся:
Приборный корпус с ТАОБАО и самодельный люксметр в нем.
Люксометр за 80 рублей. Часть 1
Люксометр за 80 рублей. Часть 2. Сравнение с Extech 407026

Однако, по-моему, осталась некоторая недосказанность по вопросам:
— в продаже присутствуют почти одинаковые модули CY-30 и CY-302 на одном том же датчике BH1750FVI. Чем они отличаются и который лучше купить?
— датчик работает от 3.3В, микроконтроллер как правило от 5В, для их связи на модулях применены разные схемы преобразования уровней сигналов. В чем их отличия и какие могут быть проблемы?
Я купил оба модуля (благо стоят недорого) для изучения и возможности сравнить показания хотя бы между собой.
Покупка

Модуль CY-302

Применялся в приведенных выше обзорах, габариты платы вдвое меньше у CY-30, деталей напаяно меньше.

Схема модуля

Входное напряжение 5В понижается линейным стабилизатором с маркировкой 662К (datasheet) до 3.3В для питания датчика.
Линии данных SDA и SCL просто подтянуты к 3.3В резисторами 4.7К. Преобразователь уровня по сути отсутствует. Безопасно ли подключать к ним выводы 5В микроконтроллера рассмотрим ниже.

Модуль CY-30

Больше габаритами, больше радиодеталей.

Схема модуля

Все то же самое, плюс преобразование уровней сигналов SDA и SCL. Для линии SDA преобразование двунаправленное, на полевом транзисторе и двух резисторах, для линии SCL — однонаправленное, на диоде и резисторе. А нужен ли этот дополнительный обвес? Вон же работает у людей и без него!

Шина I2C

Про стандарт шины можно почитать:
robocraft.ru/blog/communication/780.html
easyelectronics.ru/interface-bus-iic-i2c.html
ru.wikipedia.org/wiki/I%C2%B2C
www.gaw.ru/html.cgi/txt/interface/iic/index.htm

Протокола обмена касаться не будем (для этого есть библиотеки), а рассмотрим более простой и важный для здоровья железок уровень физического подключения.

Основы:
— к шине подключаются устройства с выходом в режиме «с открытым коллектором» с образованием схемы «монтажное И», т.е. устройства могут:
— слушать шину в режиме входа с высоким входным сопротивлением,
— в режиме выхода притягивать шину к «земле», выдавая логический «0».
— в уровень логической «1» шина возвращается сама при помощи подтягивающих резисторов, когда ни одно устройство не выдает «0»;
— данные передаются в обе стороны по линии SDA;
— синхроимпульсы по линии SCL выдаются только Мастером, а Slave-устройства эту линию только слушают. Это стандартно, а реально некоторые устройства (пример — датчик влажности SHT21) и эту линию используют как двунаправленную, для информирования другой стороны о своем состоянии.

Отсюда следуют два важных следствия:
1. В схеме обязательно должны быть резисторы подтягивающие линии данных к "+" питания.
2. ЗАПРЕЩЕНА установка выхода в «1» (pinMode(OUTPUT), digitalWrite(HIGH) в Arduino; DDR=1, PORT=1 в AVR). Если другое устройство в это время «прижмет» линию к «земле», то будет КЗ и оба устройства выгорят!

В случае питания устройств от одного напряжения местоположение подтягивающих резисторов значения не имеет — могут быть например на плате Arduino, на модуле датчика, или вообще — встроенные в микроконтроллер подтягивающие резисторы порта.
А вот когда одно устройство питается от 5В, а другое от 3.3В, то без соответствующей развязки подтягивать шину к +5В уже нельзя — может выжечь ногу датчика, а то и 3.3В стабилизатор. Но если подтянуть шину на низкой стороне, к +3.3В, то запрет выдачи «1» идет нам на пользу — более высокое напряжение на нее уже никто не выдаст, а 3.3В даже 5В устройство воспримет как логическую «1» и все заработает и без преобразования уровней. Так сделано на «мелком» модуле CY-302.

Однако, дополнительные схемы преобразования уровней дают преимущества:
— повышается скорость и надежность передачи данных;
— некоторые схемы попутно защищают от последствий ошибок при монтаже и программировании: не пропускают высокое напряжение на низкую сторону. А ведь на некоторых платах Arduino напаяны резисторы подтяжки SDA и SCL к +5В, а в некоторых версиях библиотеки Wire.h включаются встроенные в МК подтяжки на те же +5В. Не проследили этот момент — и прощай датчик!

Про схемы преобразования уровней можно почитать:
we.easyelectronics.ru/Shematech/soglasovanie-logicheskih-urovney-5v-i-33v-ustroystv.html
playground.arduino.cc/Main/I2CBi-directionalLevelShifter
learn.sparkfun.com/tutorials/using-the-logic-level-converter

Таким образом, «мелкий» модуль CY-302 лучше применять в готовом устройстве, где гарантируется, что:
— нет резисторов подтяжки на +5В;
— в МК заранее загружена программа, в которой (а) не включаются встроенные подтяжки и (б) на выходы не подается «1».

«Крупный» модуль CY-30 лучше применять с ардуинкой и при отладке на макетке:
— в МК может запущена программа предыдущего проекта, где на эти выводы подключается подтяжка, а то и выдается логическая «1»;
— резисторы подтяжки на +5В могли остаться на макетной плате от другого проекта;
— разработчик (например ребенок) не в курсе, как устроена его плата Arduino и библиотека работы с I2C.
В этих случаях встроенные преобразователи уровня спасут датчик. И хотя преобразователь на одном полевике не способен защитить от КЗ, но и в этом случает выручит то, что датчик выставляет «0» и передает данные только получив свой адрес. А подключение с выводу со статическими +5В для этого модуля безопасно.

Люксметр

Разобравшись с матчастью, приступаем к конструированию устройства.

Требования к нему:
1. В качестве корпуса — небольшая распаечная коробка 75*75*20мм с «пеньком» самореза посередине.
2. Питание от литиевого аккумулятора BL-4C старого телефона Nokia.
3. Встроенная зарядка от micro-USB.
4. Кнопка включения и переключения режимов.
5. Отсутствие выключателя питания — коммутация питания транзисторами и использование Sleep режима микроконтроллера.
6. Два режима работы с разной настройкой датчика:
a) медленные замеры с высоким разрешением и отображение только освещенности;
б) замеры с максимальной частотой и расчет Min/Max/Avg значений и величины пульсации.

Ставить целый дисплей в устройство, отображающее только 1 число показалось излишним и решил применить лежащую в загашнике матрицу семисегментных индикаторов FYQ-2541AS-11 (datasheet) с красным свечением и общими катодами. Индикатор оказался странным (отдельный знак "-" оказался справа, да еще электрически соединен с точкой над ним, у старшего разряда нет десятичной точки, а точки наверху не светятся), но нам подойдет.

Выбираем микроконтроллер. У имеющихся ATtiny85 слишком мало ног, а добавлять отдельный драйвер для индикатора не хотелось. Arduino Pro Mini надо дорабатывать — удалить стабилизатор питания и светодиод, чтобы не разряжали аккумулятор при спящем МК. Отдельный чип ATmega328P — подходит идеально. Тактировать его будем на 1МГц от встроенной RC цепочки — высокая скорость не нужна (только лишний расход энергии), стабильность времени не важна.

Схема получается весьма простая:

Библиотечный элемент индикатора для Eagle нарисовал сам. Также сделал элемент для ATmega328P с ардуинскими обозначениями ног, вдруг решу в Arduino IDE программировать.

Схема (кроме датчика) питается напрямую от литиевого акумулятора. Стабилизировать напряжение нет никакой нужды, лишний расход деталей и энергии. В процессе разряда 4.2-3.0В только слегка меняется яркость индикатора. Можно было запитать всю схему от 3.3В, но стабилизатор на модуле датчика не потянет по току, а дополнительный нафиг не нужен.
Кстати, проводил эксперименты — ATmega328P стабильно работал и при 1.5В, светодиоды гасли, а МК молотил как ни в чем ни бывало.
Для зарядки аккумулятора взят «народный» модуль на TP4056.

Датчик подключается через двунаправленные преобразователи уровня на транзисторах Q6, Q7. Можно было не делать, но пусть будут — вдруг решу поменять датчик и они понадобятся. Для работы преобразователей нужно питание 3.3В, оно добыто на выводах резисторов 472 модуля (со стороны датчика) и проводом сквозь дырку Addr прокинуто на плату устройства.
Транзистор Q8 вырубает питание датчика.

Матрица анодами через токоограничивающие резисторы подключается к порту D микроконтроллера (D0-D7 ардуины). Сегменты A-G всех разрядов уже соединены внутри с расчетом на динамическую индикацию, к ним же подключаем точки, как пятый «разряд».
Общие катоды (разряды) через транзисторы Q1-Q5 замыкаются на землю по сигналу с порта B (D8-D12 ардуины). Подключать напрямую к МК (как делают некоторые ардуинщики) не рискнул — 175мА даже импульсного тока для одной ноги МК многовато.

Кнопка подключена также к порту D (D2 ардуины), поскольку это одна из двух ног, которая может генерировать прерывание и будить МК из спячки.

Ток и ограничивающие резисторы рассчитывал так:
Подходящая яркость на 4.2В достигается при 5мА с резистором 500 Ом. При динамической индикации на 5 разрядов (ШИМ 1:5) для сохранения той же яркости ток надо увеличить в 5 раз — значит резисторы 100 Ом. Однако, при импульсном питании свечение светодиодов кажется ярче, чем при постоянном и берем резисторы на 130 Ом.

Программирование производится через гребенку ICSP программатором USBasp (можно использовать Arduino как программатор).

Мучиться с макеткой и клубком проводков при удобстве ЛУТа неохота. Разводим в Eagle плату под размер корпуса. Используем выводные резисторы для возможности провести дороги между ног. Но из-за навороченного подключения индикатора сделать одностороннюю плату без десятка перемычек все равно не вышло.

Плата
Верх:


Низ:


Для ЛУТ (600dpi):
yadi.sk/i/ErKI8iW9zNxgE
Напаиваем детали. Датчик решил разместить под 90 градусов к основной плате, чтобы можно было его направлять на источник как фонарик и не засвечивать индикатор.


Низ

Программировать решил в AVR Studio 4.19. Во-первых, было лениво изучать чего ардуинщики наворочали в библиотеках, а во-вторых, тормозной ардуинский digitalWrite мало пригоден для организации быстрой динамической индикации.

Чтение кнопки и динамическая индикация на экране повешены на прерывания INT0 и 1мс таймера, чтение датчика и выбор чего показывать — в основном цикле.

Удивило, что в стандартных библиотеках AVR не оказалось либы для I2C (в МК есть аппаратная поддержка, но ее изучим в другой раз) и использовал первую попавшуюся, с софтовым ногодрыгом. Ну и пусть себе дрыгает и delay'ит, больше то в главном цикле ничего и не делается, все остальное работает на прерываниях.

Для общения с самим BH1750 с нужными 2 режимами никаких библиотек (а они есть, и с поддержкой всех режимов датчика) решил не использовать, чего уж там — 2 функции по 3 строки.

Прошивка (исходники и hex):
yadi.sk/d/2pWcDk2VzNzGf
Фьюзы используются дефолтные для ATmega328P: 62 D9

В работе:

Короткое нажатие кнопки переключает режим (только освещенность или Max/Avg/Min/Pulse).
Что именно сейчас отображается говорят точки слева и точки/минус справа (похоже на %).
Если люксов больше 9999 — вместо младшего разряда отображается тоже точки/минус справа.

В основном режиме точность 1лк, время замера 120мс, период опроса 200мс.

В режиме Max/Avg/Min/Pulse точность 4лк, время замера 16мс, период опроса 20мс. Но режим достаточно бестолковый — пульсации с частотой выше 50Гц (а по науке даже 25Гц) датчик заметить не в состоянии. Рекомендуемые на замену TSL2561 (12мс) и MAX44009 (6,5мс) не сильно то ушли от BH1750FVI и смысла менять датчик не вижу.

Подсмотрел работу I2C шины:
Момент перехода на 20мс опрос + реально читает разные значения:
149.7310ms, I2C-0, [S] 47 Read 14 7E [P]
356.5130ms, I2C-0, [S] 47 Read 14 61 [P]
563.3060ms, I2C-0, [S] 47 Read 14 AE [P]
770.1460ms, I2C-0, [S] 47 Read 14 C7 [P]
976.9560ms, I2C-0, [S] 47 Read 14 EA [P]
1.1837920s, I2C-0, [S] 47 Read 15 1B [P]
1.3845370s, I2C-0, [S] 46 Write 13 [P]
1.4017910s, I2C-0, [S] 47 Read 14 E2 [P]
1.4209930s, I2C-0, [S] 47 Read 14 84 [P]
1.4403100s, I2C-0, [S] 47 Read 14 90 [P]
1.4595000s, I2C-0, [S] 47 Read 14 90 [P]
1.4788090s, I2C-0, [S] 47 Read 14 94 [P]
1.4980120s, I2C-0, [S] 47 Read 14 9C [P]
1.5173130s, I2C-0, [S] 47 Read 14 A0 [P]

При долгом (>3c) нажатие кнопки, разряде аккумулятора ниже 3В, после 5 минут работы устройство обесточивает датчик, гасит экран и засыпает. Перед засыпанием и в течение нескольких секунд после пробуждения отображает напряжение аккумулятора.

В состоянии сна МК мультиметр в режиме 2000мкА показывает потребление тока 0 мкА. За месяц напряжение на аккумуляторе не изменилось.

Второй имеющийся модуль, GY-30, подключил к ардуине и загрузил простейший скетч для BH1750FVI. Расположенные рядом датчики показывали различающиеся в пределах 5% значения.

Приборчиком доволен, теперь можно сравнивать лампочки.
Планирую купить +24 Добавить в избранное +42 +68
свернуть развернуть
Комментарии (30)
RSS
+
avatar
  • sav13
  • 24 ноября 2016, 19:16
+5
Очень рекомендую присмотреться в сторону MAX44009
aliexpress.com/item/MAX44009-Ambient-Light-Sensor-Module-with-4P-Pin-Header/32761901963.html
По цене практически то же самое, а по характеристикам на голову превосходит B1705 и TSL2561

У него в первую очередь больше измеряемый диапазон как в меньшую сторону почти на два порядка, так и в большую
+
avatar
0
2.17 и 0.93 это практически одно и тоже?
aliexpress.com/item/1pcs-lot-GY-302-BH1750-Chip-Light-Intensity-Light-Module/32673799136.html
хотя мне в моих поделках хватает датчика TEMT6000 вполне хорошо определяет освещённость в квартире в вечернее время
+
avatar
  • loole
  • 24 ноября 2016, 23:04
0
это практически одно и тоже?
При изготовлении одного девайса — да. А учитывая, что у макса 22 разрядный ацп (упрощенно) против 16 у BH, так он получается с лучшим Разрешение/Цена. Аналоговый 6000 здесь вообще использовать бессмысленно — АЦП у Меги 10 разрядов…
+
avatar
0
MAX44009 дапазон измерения 0.045 — 188 000 lx
BH1750 диапазон измерения 1 — 65 535 lx а если реализовать в прошивке auto range то спокойно можно и 0.11 — 100 000 lx выжать.

для бытовых нужд вполне хватет 1 — 65 535 lx. Вобщем когда цена на MAX44009 опустится до $0.93 то можно переходить на него.
+
avatar
  • sav13
  • 25 ноября 2016, 05:16
+2
Для хорошего прибора, который послужит долго — два бакса за сенсор это копейки.
Свой труд в изготовлении платы лично я цегю намного дороже, поэтому экономить на самых ключевых деталях можно либо на коммерческих партиях, которые нужно слепить как можно дешевле, либо на коленках разово что-то померить.

А так дешевле фоторезистора ничего не найдете — тоже вполне мерит освещенность если есть чем откалибровать
+
avatar
0
ну про плату вы немножно преувеличиваете. MAX44009 и BH1750 общаються по i2c шине. так что на крайняк (если ноги на шилдах не совпадают) можно небольшую адаптер сдалать к основной плате.

про остальное с вами согласен. если есть деньги берите MAX44009, если нет, то BH1750 вполне еще неплохой вариант.
+
avatar
  • demonk
  • 25 ноября 2016, 10:44
0
Если еще никакого датчика нет, то лучше конечно брать именно такой.
А менять BH1750FVI никакого смысла не вижу — измерять в темноте или на улице в солнечный день мало кому надо, а выше разрешение и частота 100Гц вместо 50 не принципиальны.
Вот если бы был встроенный режим замера пульсаций с приличной частотой…
+
avatar
  • dys
  • 24 ноября 2016, 19:23
+8
Какое хорошее начало обзора… Зашёл с мыслями почитать инструкцию и смастерить себе такую же штучку. И каково было моё разочарование, когда я понял что люди только с узкими и глубокими знаниями смогут понять и повторить ваш результат..!
+
avatar
  • sav13
  • 24 ноября 2016, 19:29
+6
Соберите тоже самое на Ардуине. Ничем от обозреваемого кроме внешнего вида отличаться не будет
+
avatar
  • dys
  • 24 ноября 2016, 19:59
0
А Вы считаете что Ардуина проще и доступна любому?? Вы так говорите буд-то Ардуину в школе каждому на уроках физики преподают…
+
avatar
+4
Дело не в школьной программе.
В ардуину залил скетч, простенькая платка…
И вместо матриц можно поюзать LCD.
Хотя каждому ближе то, с чем он знаком: ардуина, пик, атмел…
+
avatar
  • sav13
  • 24 ноября 2016, 20:22
+8
Однозначно проще, чем плату разводить.
Скачать инструкцию в интернете и по ней проводки соединить — знание физики вообще не нужны )))
+
avatar
+2
Посмотрите, в моём обзоре я рассказал как подключить к дуине, даже код есть)
+
avatar
+1
есть такая штука flprog и по ней есть уроки
хорошо на ней клепать конечные автоматы
+
avatar
  • demonk
  • 25 ноября 2016, 10:52
0
Не знаю чего сейчас преподают в школах, но я на школьных уроках информатики уже писал программы посложнее чем этот люксметр, но в начале 90x микроконтроллеры не были доступны. Но добавить чуть знаний электроники и можно было мастерить.
И, кстати, у друзей дети-первоклашки в кружок ходят, так они там на ардуине роботов ваяют и сражения устраивают.
+
avatar
  • Aostspb
  • 25 ноября 2016, 14:13
0
Берите не самую дешевую ProMini, а нормальную Uno R3. На ней, для начала работы, Вам потребуется найти в своем компьютере USB разъем, дальше дело будет только в программном обеспечении.

Подключение i2c устройства к шине одно из самых простых: два подтягивающих резистора на линии данных и питание с землей (4 провода).
+
avatar
  • manatu
  • 24 ноября 2016, 22:17
+1
Спасибо за мануал по изготовлению Люксометра! В Карму плюс!
+
avatar
  • koto18
  • 24 ноября 2016, 23:23
0
Для простых нужд вполне подойдёт обычный смарт на андроид+прога например Sensors Multitool
+
avatar
+1
Оно показывает погоду на марсе.
+
avatar
  • demonk
  • 25 ноября 2016, 10:56
0
Видел такой совет и сравнивал для интереса. Может в каком девайсе и стоит нормальный датчик, но в моем разве что свет от темноты отличить может. Штук 5 градаций всего, ниже 500лк показывает 0, выше 2000лк зашкаливает. И цифры с потолка.
+
avatar
  • koto18
  • 25 ноября 2016, 11:49
0
х.з, обычный китайский планшет, градации:10,50,100,150,200,250,280,1600,6000…
Вот фонарик приближал для интереса
+
avatar
  • tklim
  • 25 ноября 2016, 01:45
+1
2. ЗАПРЕЩЕНА установка выхода в «1» (pinMode(OUTPUT), digitalWrite(HIGH) в Arduino; DDR=1, PORT=1 в AVR). Если другое устройство в это время «прижмет» линию к «земле», то будет КЗ и оба устройства выгорят!
Зачем людей пугаете? Никто не выгорит. Все останется в пределах «absolute maximum rates»
А ведь на некоторых платах Arduino напаяны резисторы подтяжки SDA и SCL к +5В, а в некоторых версиях библиотеки Wire.h включаются встроенные в МК подтяжки на те же +5В. Не проследили этот момент — и прощай датчик!
Туда же…
+
avatar
  • demonk
  • 25 ноября 2016, 11:07
0
Если в одном устройстве открытый полевик с сопротивлением канала доли ома на +5В, а в другом открытый полевик на GND — каков через них будет ток и где о нем упоминание в absolute maximum rates?

Порты защищают от перенапряжения диодами, рассчитанными на микроамперные токи. Ток от встроенной подтяжки 50КОм наверняка выдержит, а вот если подтяжка внешняя да на пару килоом? А если вместо нее открытый полевик?
+
avatar
  • tklim
  • 25 ноября 2016, 14:05
0
полевик с сопротивлением канала доли ома
Где в AVR или в датчиках полевики с долями ома?

Я вижу тут ~45ом

Для датчика подобного не нашел, но думаю, там будет больше.
Подтяжка от 5В — тоже не сделает дела.

P.S. Я знаю, что так делать нельзя и всячески не приветствую вещи типа «заявлено 3В, но у меня и от 4 работает». Но тут — «не сгорит»
+
avatar
  • demonk
  • 25 ноября 2016, 16:41
0
Гм, получается полевички там не самые качественные. Хотя для 5В уже 25ом получается и ток КЗ 100мА.
Для меги максимальный ток 40мА, для датчика — SDA Sink Current Imax 7 mA.
И рассчитывать на выживание при КЗ благодаря тому «на проводах напряжение просядет» совсем не дело.
По поводу защитных от перенапряжения диодов не видел значений допустимого тока в документах, но везде упоминаются только микроамперы.
Оно конечно может повезти, железка окажется крепкая и волшебный дым не выйдет, но так делать — нельзя!
+
avatar
+1
подробности об библиотеке тут
+
avatar
0
А можно с помощью такого датчика определить частоту мерцания? Или с помощью какого-нибудь другого цифрового датчика?
+
avatar
  • demonk
  • 25 ноября 2016, 11:17
+1
Такой датчик может замерить частоту максимум 25Гц, MAX44009 — 50Гц. Слишком велико время замера. Может и существуют специализированные датчики, но я о таких не слышал.
Нормально измерить частоту (но в ущерб точности) смогут быстрый фотодиод+быстрый АЦП, как здесь
radiokot.ru/konkursCatDay2014/47/
Или, проще всего, фотодиод+осциллограф.
+
avatar
0
То, что надо! :)
+
avatar
0
BH1750 частоту 50 гц и выше не померяет. Слишком быстро для него.

50 герц — это 0.02 сек. Время измерения, на самом грубом режиме, у BH1750 равно 0.025 сек. Так что реально померять пульсации от 38 гц и ниже.

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.