Уроки

Измеритель экспозиции для фотосъемки с использованием Arduino и BH1750

Нет комментариев

В этом небольшом уроке мы научимся делать экспонометр с использованием Arduino UNO и сенсорного модуля BH150.

Что такое экспонометр?

В этом уроке я покажу вам, как сделать экспонометр, используя Arduino UNO, SSD1306 SPI OLED-дисплей, сенсорный модуль BH1750.

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

Типичный экспонометр
Типичный экспонометр

Результаты датчика BH1750 могут быть неточными на 100%, но оно того стоит. В аналоговой фотографии люди все время использовали экспонометры для измерения света, соответствующего ISO их пленки.

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

Цифровой датчик света BH1750

Цифровой датчик освещенности BH1750 работает через интерфейс шины I2C. В основном он используется в мобильных телефонах для автоматической регулировки подсветки ЖК-дисплея и клавиатуры. Этот датчик имеет диапазон чувствительности от 1 до 65535 лк.

Технические характеристики

  • Низкое потребление тока
  • Функция подавления шума 50 Гц - 60 Гц
  • I2C связь
  • Преобразователь освещенности в цифровые значения
  • Широкий диапазон и высокое разрешение (1-65535 лк)

Возможности экспонометра

Цифровые экспонометры действительно дорогие, а аналоговые измерители не очень точны и неудобны в использовании. Но своими руками мы можем собрать устройство за менее чем 7 долларов и оно будет работать от обычной батареи.

Счетчик способен выполнять следующие действия:

  • Считывать окружающий свет;
  • Коррекция фильтра ND;
  • Приоритет диафрагмы;
  • Диапазон ISO от 8 до 4 000 000;
  • Легкое чтение в Люкс;
  • Отображение значения экспозиции, EV;
  • Диапазон диафрагмы от 1,0 до 3251;
  • Диапазон выдержек от 1/10000 до 133 сек;
  • Приоритет выдержки;
  • ND диапазон фильтров ND2 - ND8192.

Комплектующие

Для сборки нашего экспонометра на Ардуино нам понадобятся следующие комплектующие:

  • Arduino Uno
  • Кнопки
  • Макетная плата
  • SSD1306 SPI OLED дисплей
  • BH1750 модуль

Схема соединения

Подключите все комплектующие так, как показано ниже. Также ниже описаны все необходимые соединения.

Кнопки:

Pushbutton Arduino UNO
1 - Metering 2
2 - Plus 3
3 - Minus 4
4 - Metering Mode 5
5 - Menu 6
6 - Priotity 7

Дисплей:

OLED SPI Arduino UNO
GND GND
VCC 5V
D0 8
D1 9
RST 10
DC 11
CS 12

BH1750:

BH1750 Arduino UNO
VCC 3.3V
GND GND
SDA A4
SCL A5

Программное обеспечение

Загрузите Arduino IDE и все необходимые библиотеки по ссылкам выше. Если вы новичок, тогда рекомендую посмотреть мой материал по Arduino IDE, который поможет вам настроить среду разработки на вашем компьютере.

Чтобы добавить загруженные библиотеки в Arduino, перейдите в:

Эскиз/Скетч -> Включить библиотеку -> Добавить Zip библиотеку (Sketch —> Include Library —> Add Zip Library)

Повторите этот шаг для всех библиотек.

После добавления библиотек подключите плату Arduino к компьютеру. Затем перейдите в:

Инструменты -> Плата -> Выбрать плату Arduino UNO (Tools —> Board —> Arduino UNO)

Теперь перейдите в:

Инструменты -> Порт -> Выберите COM порт (Tools —> Port —> Select COM PORT)

В моем случае это COM3.

Код Ардуино

Скопируйте и вставьте код проекта, который ниже, в Arduino IDE и нажмите кнопку загрузки (Upload).

Все нужные файлы программы для BH1750 можно скачать в архиве ниже (.ino + .h):

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <BH1750.h>
#include <EEPROM.h>
#include <avr/sleep.h>

#define OLED_DC                 11
#define OLED_CS                 12
#define OLED_CLK                8 //10
#define OLED_MOSI               9 //9
#define OLED_RESET              10 //13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

BH1750 lightMeter;

#define DomeMultiplier          2.17                    // Multiplier when using a white translucid Dome covering the lightmeter
#define MeteringButtonPin       2                       // Metering button pin
#define PlusButtonPin           3                       // Plus button pin
#define MinusButtonPin          4                       // Minus button pin
#define ModeButtonPin           5                       // Mode button pin
#define MenuButtonPin           6                       // ISO button pin
#define MeteringModeButtonPin   7                       // Metering Mode (Ambient / Flash)
//#define PowerButtonPin          2

#define MaxISOIndex             57
#define MaxApertureIndex        70
#define MaxTimeIndex            80
#define MaxNDIndex              13
#define MaxFlashMeteringTime    5000                    // ms

float   lux;
boolean Overflow = 0;                                   // Sensor got Saturated and Display "Overflow"
float   ISOND;
boolean ISOmode = 0;
boolean NDmode = 0;

boolean PlusButtonState;                // "+" button state
boolean MinusButtonState;               // "-" button state
boolean MeteringButtonState;            // Metering button state
boolean ModeButtonState;                // Mode button state
boolean MenuButtonState;                // ISO button state
boolean MeteringModeButtonState;        // Metering mode button state (Ambient / Flash)

boolean ISOMenu = false;
boolean NDMenu = false;
boolean mainScreen = false;

// EEPROM for memory recording
#define ISOIndexAddr        1
#define apertureIndexAddr   2
#define modeIndexAddr       3
#define T_expIndexAddr      4
#define meteringModeAddr    5
#define ndIndexAddr         6

#define defaultApertureIndex 12
#define defaultISOIndex      11
#define defaultModeIndex     0
#define defaultT_expIndex    19

uint8_t ISOIndex =          EEPROM.read(ISOIndexAddr);
uint8_t apertureIndex =     EEPROM.read(apertureIndexAddr);
uint8_t T_expIndex =        EEPROM.read(T_expIndexAddr);
uint8_t modeIndex =         EEPROM.read(modeIndexAddr);
uint8_t meteringMode =      EEPROM.read(meteringModeAddr);
uint8_t ndIndex =           EEPROM.read(ndIndexAddr);

int battVolts;
#define batteryInterval 10000
double lastBatteryTime = 0;

#include "lightmeter.h"

void setup() {  
  pinMode(PlusButtonPin, INPUT_PULLUP);
  pinMode(MinusButtonPin, INPUT_PULLUP);
  pinMode(MeteringButtonPin, INPUT_PULLUP);
  pinMode(ModeButtonPin, INPUT_PULLUP);
  pinMode(MenuButtonPin, INPUT_PULLUP);
  pinMode(MeteringModeButtonPin, INPUT_PULLUP);

  //Serial.begin(115200);

  battVolts = getBandgap();  //Determins what actual Vcc is, (X 100), based on known bandgap voltage

  Wire.begin();
  lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE_2);
  //lightMeter.begin(BH1750::ONE_TIME_LOW_RES_MODE); // for low resolution but 16ms light measurement time.

  display.begin(SSD1306_SWITCHCAPVCC, 0x3D);
  display.setTextColor(WHITE);
  display.clearDisplay();

  // IF NO MEMORY WAS RECORDED BEFORE, START WITH THIS VALUES otherwise it will read "255"
  if (apertureIndex > MaxApertureIndex) {
    apertureIndex = defaultApertureIndex;
  }

  if (ISOIndex > MaxISOIndex) {
    ISOIndex = defaultISOIndex;
  }

  if (T_expIndex > MaxTimeIndex) {
    T_expIndex = defaultT_expIndex;
  }

  if (modeIndex < 0 || modeIndex > 1) {
    // Aperture priority. Calculating shutter speed.
    modeIndex = 0;
  }

  if (meteringMode > 1) {
    meteringMode = 0;
  }

  if (ndIndex > MaxNDIndex) {
    ndIndex = 0;
  }

  lux = getLux();
  refresh();
}

void loop() {  
  if (millis() >= lastBatteryTime + batteryInterval) {
    lastBatteryTime = millis();
    battVolts = getBandgap();
  }
  
  readButtons();

  menu();

  if (MeteringButtonState == 0) {
    // Save setting if Metering button pressed.
    SaveSettings();

    lux = 0;
    refresh();
    
    if (meteringMode == 0) {
      // Ambient light meter mode.
      lightMeter.configure(BH1750::ONE_TIME_HIGH_RES_MODE_2);

      lux = getLux();

      if (Overflow == 1) {
        delay(10);
        getLux();
      }

      refresh();
      delay(200);
    } else if (meteringMode == 1) {
      // Flash light metering
      lightMeter.configure(BH1750::CONTINUOUS_LOW_RES_MODE);

      unsigned long startTime = millis();
      uint16_t currentLux = 0;
      lux = 0;

      while (true) {
        // check max flash metering time
        if (startTime + MaxFlashMeteringTime < millis()) {
          break;
        }

        currentLux = getLux();
        delay(16);
        
        if (currentLux > lux) {
          lux = currentLux;
        }
      }

      refresh();
    }
  }
}

После загрузки кода включите Arduino. Вы должны увидеть информацию на OLED дисплее. В пользовательском интерфейсе есть шесть кнопок, которые выполняют следующие действия:

  1. Кнопка 1 - Измерение
  2. Кнопка 2 - + значение
  3. Кнопка 3 - - значение
  4. Кнопка 4 - Режим измерения
  5. Кнопка 5 - Меню
  6. Кнопка 6 - Приоритет (ISO / без фильтра)

За этот урок спасибо Реджинальду Уотсону с проекта maker.pro.

26 января 2020 в 16:17
Опубликовано:
Уроки, ,

Добавить комментарий

Ваш E-mail не будет никому виден. Обязательные поля отмечены *