In this project, we will make a Arduino based LUX Meter Using BH1750 and OLED Gauge Display. Sometime we need to measure the exposure of light but a lux meter costs is high. Here to learn low cost and accurate ambient lighting sensor BH1750 interface with arduino with OLED Gauge display and enjoyed it. In this Project Push Button added for HOLD the Lux meter display value if pressed and Reading value displayed again push button pressed.
Circuit Diagram
Components Required
Arduino Uno - 1 no
OLED 0.96 SSD1306 - 4 PIN - 1no
BH1750 GY-302- 1no
Push button switch- 1 no
BH1750
Refer previous project for more detail : https://www.dofbot.com/post/iot-cloud-bh1750-lux-monitor
A digital Lux Meter is a device to measure the intensity of a source of light. A lux meter will be used in photography to estimate how bright the flash is and also the encircling ambient lighting.
BH1750 is a digital ambient light sensor that is used commonly used in mobile phones to manipulate the screen brightness based on the environment lighting. This sensor can accurately measure the LUX value of light up to 65535lx.
A digital Lux Meter is a device to measure the intensity of a source of light. A lux meter will be used in photography to estimate how bright the flash is and also the encircling ambient lighting.
working principle of lux meter
Most of the lux meter consists of a body, photocell or light sensor, and display. The light that falls on to the photocell or sensor contains energy that is transformed into electric current. Indeed, the measure of current depends on the light that strokes the photocell or light sensor. Lux meters read the electrical current calculate the appropriate value, and show this value on its display.
BH1750 Features
Power Supply: 2.4V-3.6V (typically 3.0V)
Less current consumption: 0.12mA
Measuring Rang: 1-65535lx
Communication: I2C bus
Accuracy: +/-20%
Built in A/D converter for converting analog illuminance in the digital data.
Very small effect of IR radiation
Highly responsive near to human eye.
This is a BH1750 light intensity sensor breakout board with a 16 bit AD converter built-in which can immediately output a digital signal, there is no need for complex calculations. This is more accurate and simpler to use the version of the simple LDR which only outputs a voltage that needs to be calculated to obtain meaningful data.
First, connect the VCC and GND of the BH1750 Light Sensor to 3V3 and GND of Arduino Then connect the SCL and SDA pins of the sensor to corresponding pins of Arduino A5 &A4 Pin using jumper wires.
Then, connect the SCL, SDA, GND, and VCC pin of the OLED display to the corresponding BH1750 sensor pins.
Let's talk about lux and Illuminance:
The lux (symbol: lx) is the SI derived unit of illuminance, measuring luminous flux per unit area. It is equal to one lumen per square meter. In photometry, this is used as a measure of the intensity, as perceived by the human eye, of light that hits or passes through a surface. It is analogous to the radiometric unit watt per square meter, but with the power at each wavelength weighted according to the luminosity function, a standardized model of human visual brightness perception. In English, "lux" is used as both the singular and plural form.
Illuminance: Illuminance is a measure of how much luminous flux is spread over a given area. One can think of luminous flux (measured in lumens) as a measure of the total "amount" of visible light present, and the illuminance as a measure of the intensity of illumination on a surface. A given amount of light will illuminate a surface more dimly if it is spread over a larger area, so illuminance is inversely proportional to the area when the luminous flux is held constant.
One lux is equal to one lumen per square meter:
1 lx = 1 lm/m2 = 1 cd·sr/m2.
A flux of 1000 lumens, concentrated into an area of 1 square meter, lights up that square meter with an illuminance of 1000 lux. However, the same 1000 lumens, spread out over 10 square meters produces a dimmer illuminance of only 100 lux.
OLED SSD1306-I2C 128X64 Display Module 0.96 inch
This is a 0.96 inch Blue OLED display module. The display module can be interfaced with any microcontroller using SPI/IIC protocols. It is having a resolution of 128x64. The package includes display board,display, 4 pin male header presoldered to board.
OLED (Organic Light-Emitting Diode) is a self light-emitting technology composed of a thin, multi-layered organic film placed between an anode and cathode. In contrast to LCD technology, OLED does not require a backlight. OLED possesses high application potential for virtually all types of displays and is regarded as the ultimate technology for the next generation of flat-panel displays.
Download Data sheet
Installing the Arduino Library
Installing SSD1306 OLED Library – Arduino
Download u8glib Library , we need to use this library for OLED
Download BH1750_Library , we need to use this library for Lux Sensor
Follow the next steps to install those libraries.
In your Arduino IDE, to install the libraries go to Sketch > Include Library > Add .ZIP library… and select the library you’ve just downloaded.
After installing the required libraries, copy the following code to your Arduino IDE.
Subscribe and Download code.
Arduino Code:
//----------------------------------------Include Library
#include <Wire.h>
#include "U8glib.h"
#include <ErriezBH1750.h>
//----------------------------------------
//----------------------------------------Initialize u8g
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C / TWI
//----------------------------------------
///----------------------------------------BH1750 I2C address
// ADDR line LOW/open: I2C address 0x23 (0x46 including R/W bit) [default]
// ADDR line HIGH: I2C address 0x5C (0xB8 including R/W bit)
BH1750 sensor(LOW);
//----------------------------------------
//----------------------------------------Variable and button pin declarations
#define Button_Pin 4
bool Button;
//----------------------------------------
//----------------------------------------Variable for LUX Value
uint16_t read_lux;
uint16_t result_lux;
byte lux_HR;
//----------------------------------------
int x_LUX_val; //--> X position to display LUX value
//----------------------------------------Variables for Gauge Chart
int xmax=128;
int ymax=62;
int xcenter=xmax/2;
int ycenter=ymax/2+10;
int arc=ymax/2;
int angle=0;
int p, w, m;
u8g_uint_t xx=0;
//----------------------------------------Variables for Gauge Chart
//----------------------------------------Variable for Mode
// Mode = 1 for realtime reading of sensor values (LUX).
// Mode = 2 to capture sensor value (LUX).
int Mode = 1;
//----------------------------------------
bool Blink_Cap; //--> Variables to make the sensor value flashes on the capture mode.
unsigned long previousMillis = 0; //--> will store last time was updated
const long interval = 250; //--> interval (milliseconds)
//========================================================================VOID ShowLux_With_GaugeChart(uint8_t angle)
void ShowLux_With_GaugeChart(uint8_t angle) {
//----------------------------------------draw border of the gauge
u8g.drawCircle(xcenter,ycenter,arc+6, U8G_DRAW_UPPER_RIGHT);
u8g.drawCircle(xcenter,ycenter,arc+4, U8G_DRAW_UPPER_RIGHT);
u8g.drawCircle(xcenter,ycenter,arc+6, U8G_DRAW_UPPER_LEFT);
u8g.drawCircle(xcenter,ycenter,arc+4, U8G_DRAW_UPPER_LEFT);
//----------------------------------------
//----------------------------------------draw the needle
float x1=sin(2*angle*2*3.14/360);
float y1=cos(2*angle*2*3.14/360);
u8g.drawLine(xcenter, ycenter, xcenter+arc*x1, ycenter-arc*y1);
u8g.drawDisc(xcenter, ycenter, 5, U8G_DRAW_UPPER_LEFT);
u8g.drawDisc(xcenter, ycenter, 5, U8G_DRAW_UPPER_RIGHT);
u8g.setFont(u8g_font_chikita);
//----------------------------------------
//----------------------------------------show MIN and MAX labels
u8g.drawStr(0, 5, "MIN");
u8g.drawStr(0, 13, "1");
u8g.drawStr(110, 5, "MAX");
u8g.drawStr(98, 13, "65535");
u8g.drawStr(9, 42, "MIN");
u8g.drawStr(105, 42, "MAX");
//----------------------------------------
//----------------------------------------show gauge label
u8g.setPrintPos(56,24);
u8g.print("LUX");
u8g.setPrintPos(50,32);
u8g.print("METER");
//----------------------------------------
u8g.setFont(u8g_font_unifont);
//----------------------------------------Conditions for displaying LUX value center align on OLED
if (result_lux < 10) {
x_LUX_val = 36;
} else if (result_lux < 100 && result_lux > 9) {
x_LUX_val = 32;
} else if (result_lux < 1000 && result_lux > 99) {
x_LUX_val = 28;
} else if (result_lux < 10000 && result_lux > 999) {
x_LUX_val = 24;
} else if (result_lux > 9999) {
x_LUX_val = 20;
}
//----------------------------------------
//----------------------------------------Mode = 1 for realtime reading of sensor values (LUX).
if (Mode == 1) {
u8g.setPrintPos(x_LUX_val, 60);
u8g.print(result_lux);
u8g.print(".");
u8g.print(lux_HR);
u8g.print(" lx");
}
//----------------------------------------
//----------------------------------------Mode = 2 to capture sensor value (LUX).
if (Mode == 2) {
if (Blink_Cap == false) {
u8g.setPrintPos(x_LUX_val, 60);
u8g.print(result_lux);
u8g.print(".");
u8g.print(lux_HR);
u8g.print(" lx");
} else {
u8g.setPrintPos(0, 60);
u8g.print(" ");
}
//----------------------------------------
}
}
//========================================================================
//========================================================================VOID SETUP
void setup(void) {
u8g.setFont(u8g_font_chikita);
pinMode(Button_Pin, INPUT_PULLUP);
Wire.begin(); //--> Initialize I2C bus
sensor.begin(ModeContinuous, ResolutionHigh); //--> Initialize sensor in continues mode, high 0.5 lx resolution
sensor.startConversion(); //--> Start conversion
}
//========================================================================
//========================================================================VOID LOOP
void loop(void) {
//----------------------------------------Read button
Button = digitalRead(Button_Pin);
if (Button == LOW) {
Mode++;
if (Mode > 2) Mode = 1;
//----------------------------------------Looping to check the button condition until the button is finished pressing to perform the next instruction.
while(Button == LOW) {
Button = digitalRead(Button_Pin);
delay(100);
}
//----------------------------------------
}
//----------------------------------------
//.................................................................................Millis for loop delay
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis; //--> save the last time currentMillis
//----------------------------------------Mode = 1 for realtime reading of sensor values (LUX).
if (Mode == 1) {
//----------------------------------------Wait for completion (blocking busy-wait delay)
if (sensor.isConversionCompleted()) {
read_lux = sensor.read(); //--> Read light
result_lux = read_lux / 2;
lux_HR = read_lux % 10;
}
//----------------------------------------
}
//----------------------------------------
if (Mode == 2) Blink_Cap = !Blink_Cap; //--> Toggle Blink_Cap
//----------------------------------------Converts sensor / LUX value to angle value
m = map(result_lux,0,65535,0,90);
//----------------------------------------
//----------------------------------------show needle and dial
xx = m;
if (xx<45){
xx=xx+135;
}
else {
xx=xx-45;
}
//----------------------------------------
//----------------------------------------picture loop (Loop for display on OLED)
u8g.firstPage();
do {
ShowLux_With_GaugeChart(xx);
}
while( u8g.nextPage() );
//----------------------------------------
}
//.................................................................................
}
Comentários