1

I'm using a BH1750 light sensor with arduino to display the lux values on an LCD. But in the code, I'm unable to get the formula. Can anybody explain me the formula?

I tried to find it in the datasheet of BH1750, but I was not able to understand this line:

value = ((buff[0]<<8)|buff[1])/1.2;

The whole code:

#include<Wire.h>
#include<LiquidCrystal.h>

int BH1750address = 0x23;
byte buff[2];
LiquidCrystal lcd (7,6,5,4,3,2); //RS, E, D4, D5, D6, D7

void setup()
{
  Wire.begin();
  lcd.begin(16,2);
  lcd.print("  BH1750 Light  ");
  lcd.setCursor(0,1);
  lcd.print("Intensity Sensor");
  delay(2000);
}

void loop()
{
  int i;
  uint16_t value=0;
  BH1750_Init(BH1750address);
  delay(200);

  if(2==BH1750_Read(BH1750address))
  {
    value=((buff[0]<<8)|buff[1])/1.2; //This is where the problem is
    lcd.clear();
    lcd.print("Intensity in LUX");
    lcd.setCursor(6,1);
    lcd.print(value);
  }
  delay(150);
}

int BH1750_Read(int address) 
{
  int i=0;
  Wire.beginTransmission(address);
  Wire.requestFrom(address, 2);
  while(Wire.available()) 
  {
    buff[i] = Wire.read();
    i++;
  }
  Wire.endTransmission();  
  return i;
}

void BH1750_Init(int address) 
{
  Wire.beginTransmission(address);
  Wire.write(0x10);
  Wire.endTransmission();
}
melpomene
  • 84,125
  • 8
  • 85
  • 148

2 Answers2

1

<< is a shift operator, so the value in buff[0] is shifted by 8 bit to the left, then this value is linked by a or function. Finally the resulting value is divided by 1.2

Example:

buff[0] = 0000 0001              // assume this value for buff[0] (1 in decimal)
buff[1] = 0110 1000              // assume this value for buff[1] (104 in decimal)

buff[0]<<8:                      // move 8 bit to the left
0000 0001 0000 0000

buff[0]<<8 | buff[1]:            // link by or function
0000 0001 0000 0000 | 0000 0000 0110 1000 = 0000 0001 0110 1000     // 360 in decimal

so

value = 360 / 1.2 = 300 

be aware that value is an int and thus it will neglect decimal digits

Berger
  • 299
  • 3
  • 13
0

a << b shifts the bits (i.e. digits in the binary representation) of a to the left by b places.

For comparison, if you shift a number 4 places to the left in decimal (an operation that doesn't exist in programming languages):

      42009  | shift left by 4
= 420090000

This corresponds to a multiplication by 104.

It's the same in binary, only << 8 means "multiply by 28".

So

value = ((buff[0]<<8)|buff[1])/1.2;

is really just

value = ((buff[0] * 256)|buff[1])/1.2;

| is bitwise or. It doesn't do anything interesting here because both buff[0] and buff[1] are bytes, i.e. numbers in the range 0 .. 255. By multiplying one of them by 256 we ensure that they have no bits in common, in which case | is identical to addition:

value = ((buff[0] * 256) + buff[1]) / 1.2;

The / 1.2 part is slightly bizarre. You don't often see bitwise operations combined with floating-point division, only for the result to be converted back to an integer.

Mathematically speaking 1.2 is just 6/5, so dividing by 1.2 is just multiplying by 5/6.

value = (buff[0] * 256 + buff[1]) * 5 / 6;
melpomene
  • 84,125
  • 8
  • 85
  • 148