Bh1750 lux sensor question

Hi,
I have a project where I want to trigger the shutter of a dslr camera with a bh1750 lux sensor, the reason why Iam using this device is because it was already laying around in my project box and I dont want to spend time and money waiting for a simple device to use.

I used this code for the sensor and it work well:

#include <Wire.h> //BH1750 IIC Mode 
#include <math.h> 
int BH1750address = 0x23; //setting i2c address
 
byte buff[2];
void setup()
{
  Wire.begin();
  Serial.begin(57600);//init Serail band rate
}
 
void loop()
{
  int i;
  uint16_t val=0;
  BH1750_Init(BH1750address);
  delay(200);
 
  if(2==BH1750_Read(BH1750address))
  {
    val=((buff[0]<<8)|buff[1])/1.2;
    Serial.print(val,DEC);     
    Serial.println("[lx]"); 
  }
  delay(150);
}
 
int BH1750_Read(int address) //
{
  int i=0;
  Wire.beginTransmission(address);
  Wire.requestFrom(address, 2);
  while(Wire.available()) //
  {
    buff[i] = Wire.read();  // receive one byte
    i++;
  }
  Wire.endTransmission();  
  return i;
}
 
void BH1750_Init(int address) 
{
  Wire.beginTransmission(address);
  Wire.write(0x10);//1lx reolution 120ms
  Wire.endTransmission();
} :relaxed:

But now, I dont know how I can store the value of the lux displayed to use an If statement to trigger the shutter, for exemple:
if lux>35000
trigger camera

Mayb there is other way, I need help on this what would be a good way to do this? I only need to raise the value of a digitial pin to high a fraction of second for the camera shutter to work, I just dont know how to implement this with the code of the light sensor above.
Thank you for your help
Bob

What do you mean, "store the value" ?

You are reading the value from the sensor repeatedly, and it is going into your variable "val".

Do you only want to take one photo, the first time the light level reaches your specified value ?

hi thank you for your reply.

By looking at the code ( took from the internet), it seem that its storing the value in th evariable val, but to print it in decimal value, he must specifie the DEC like that : Serial.print(val,DEC);

How can I compare that variable "val" with a if statement, comparing it with a decimal value, ranging from 0 to 65535? (if val>35000 then took a picture......)

Is "val" have to be a global variable?

Or else?, as you can my , my programming skill is at its basis.
Thank you for your help.

edit: Yes , I want to take a photo the first time it reach the specified value, but that specified value can be reached many time, so I want to take a photo that many time also.

that device could be used to take photo of a lighting, by exemple, triggering the shutter when it sense a bust of light.
It can also be used with a laser. With some experimentation i've made, when I point a laser pointer directly into the light sensor, the value is saturated, the reading == 0 (more than the max value, I know because when I point the laser a little offset it read high value like 45000-55000 lux)
So it can be used for taking a shot when something pass throug the laser beam and cut it, in that case, "if val=!0 (or if val==true) trigger a photo..

Mayb that can help visualise what the device is.

The photo shutter is connected on a optocoupler, when I raise the value of the pin its connected to at High, its triggering the shutter, that simple.

Ok i found how, heres the code i wrote. I first put the variable "val" as a global variable.
[code#include <Wire.h> //BH1750 IIC Mode 
#include <math.h> 
int BH1750address = 0x23; //setting i2c address
uint16_t val=0;
 
byte buff[2];
void setup()
{
  Wire.begin();
  Serial.begin(57600);//init Serail band rate
}
 
void loop()
{
  int i;
  val=0;
  BH1750_Init(BH1750address);
  delay(200);
 
  if(2==BH1750_Read(BH1750address))
  {
    val=((buff[0]<<8)|buff[1])/1.2;
    Serial.print(val,DEC);     
    Serial.println("[lx]"); 
    if (val>25000)
  {
  
    Serial.println("higher than 25000lux");     
    
  }
  }
  

}

   
int BH1750_Read(int address) //
{
  int i=0;
  Wire.beginTransmission(address);
  Wire.requestFrom(address, 2);
  while(Wire.available()) //
  {
    buff[i] = Wire.read();  // receive one byte
    i++;
  }
  Wire.endTransmission();  
  return i;
}
  
 
void BH1750_Init(int address) 
{
  Wire.beginTransmission(address);
  Wire.write(0x10);//1lx reolution 120ms
  Wire.endTransmission();
}]

I'll fiddle around with this now.

The loop() function in your arduino is going to run many times a second.

If you try and take a photo whenever the light level is greater than 35000 lux, your
camera won't be able to keep up.

You need to be clearer about your intention for when, and how often, you want
to take a photo.

Its something that look like this :

when the laser point directly at the sensor, the reading value is=o (too many lux sensor overlimit?) what i can do is point it a little offset so the reading is something like 55000
I will need in order, when the laser beam is cut by a object to
-turn the laser off (laser is connected to a 5v pin in arduino)
-trigger the flash (set a digital pin to high, then low, flash is connected to a optoisolator)
-trigger the camera shutter (set a digital pin to high, the low, shutter is connected to a optoisolator)
-then wait couple of milliseconds
-then turn the laser on again
-wait couple of millisecond
then the whole process can loop again, until memory card is full......

that make sense?

Yeah, that makes sense. Not sure how the light level comes into it, though.

You seem to have pretty much sorted out the logic flowchart for it, now just implement that
in code.

You might need to experiement to find out how often you can trigger the camera. Start with
a big delay. As in, if you just took a photo, don't try taking another photo until at least a
second later. Then try making that time smaller, after you get it to work.

The simplest way to do this, is to define a variable, external to the loop function. Each time
you take a photo, save the current millis() time into that variable. Each time you go
through the loop, if your criteria for taking a photo are met, check the current time,
and if it is isn't at least 1000 milliseconds since the last photo, then don't take another one.

Hi here is the code i wrote :

#include <Wire.h> //BH1750 IIC Mode 
#include <math.h> 
int laserPin =31;
int shutterPin= 39;
int flashPin =49;
int BH1750address = 0x23; //setting i2c address
uint16_t val=0;

 
byte buff[2];
void setup()
{
  pinMode(laserPin, OUTPUT);
  pinMode(shutterPin, OUTPUT);
  pinMode(flashPin, OUTPUT);
  Wire.begin();
  Serial.begin(57600);//init Serail band rate
}
 
void loop()
{
  
  digitalWrite(laserPin, HIGH); // start with laser on
  digitalWrite (shutterPin, LOW); // shutter trigger on a high
  digitalWrite(flashPin,LOW); // shutter trigger on a high
  int i;
  val=0;
  BH1750_Init(BH1750address);
  delay(200);
 
  if(2==BH1750_Read(BH1750address))
  {
    val=((buff[0]<<8)|buff[1])/1.2;
    Serial.print(val,DEC);     
    Serial.println("[lx]"); 
    if (val>25000)
  {
      digitalWrite (laserPin,LOW); // shut off laser
      digitalWrite (shutterPin, HIGH); // trigger shutter ( I triggered the shutter before the flash because it have a slower reaction time)
      delay(300);
      digitalWrite(flashPin,HIGH); // trigger flash
      delay (100);
      
      
    Serial.println("taking picture!");     
    
  }
  }
  

}

   
int BH1750_Read(int address) //
{
  int i=0;
  Wire.beginTransmission(address);
  Wire.requestFrom(address, 2);
  while(Wire.available()) //
  {
    buff[i] = Wire.read();  // receive one byte
    i++;
  }
  Wire.endTransmission();  
  return i;
}
  
 
void BH1750_Init(int address) 
{
  Wire.beginTransmission(address);
  Wire.write(0x10);//1lx reolution 120ms
  Wire.endTransmission();
}

I have to put a delay of 300ms between the trigger and the flash for synchonisation. The shutter take 300ms longer than the flash to trigger.
Thats a problem with high speed photography, if I want to take a photo of a lighting, I'll have to reduce that delay.
Any idea where it come from?

It may come from the camera hardware
It may come from the arduino code
It may come from the photoresistor (ilq74) wich is medium speed i think.....

I have no power to speed up camera hardware, but I can play with the arduino code and interfacing electronique to mayb gain couple of ms, you have an idea to speed things up?

Thank you.

Mayb instead of using photoisolator for shutter I can use a NPN transistor to short circuit the 2 wires for trigger, but is it safe ? will it be faster?

well there is another problem, on line 17, in the loop section, there is a delay of 200ms, this line :
BH1750_Init(BH1750address);
delay(200);

If i change the delay with a lower value, it dont work, It will output me always the same value without changing it. for exemple, if it output me 635 lux, it will output me 635 over and over again, at a faster rate .

I have to put 200ms so the sensor can read a value, but the problem is if I cut the laser beam fast (not that fast 200ms is slow) like just my finger cutting the beam in a snap, not even a snap, the sensor dont change value, its too fast.
It seem that I cant go forward with this project with that kind of sensor, I will really need to invest in a photoresistance....

I wrote about it on instructables , with Special library for it

Artical :

http://www.instructables.com/id/BH1750-Digital-Light-Sensor/

Library download on Github :

GitHub - Genotronex/BH1750FVI_Master: Digital Light Sensor BH1750

Any suggestion , feedback , will be welcome