unsigned int BH1750_read_word(void)
{
unsigned long value = 0x0000;
unsigned char num_of_bytes = 0x02;
unsigned char bytes[2] = {0x00, 0x00};
while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
I2C_GenerateSTART(ENABLE);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(BH1750_addr, I2C_DIRECTION_RX);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
while(num_of_bytes)
{
if(I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))
{
if(num_of_bytes == 0)
{
I2C_AcknowledgeConfig(I2C_ACK_NONE);
I2C_GenerateSTOP(ENABLE);
}
bytes[(num_of_bytes - 1)] = I2C_ReceiveData();
num_of_bytes--;
}
};
value = ((bytes[1] << 8) | bytes[0]);
return value;
}
As with SPI, we need to check first if I2C hardware is free. We, then, initiate a I2C start condition and
check master/slave mode selection. Next, we send out slave device’s ID or address with read
command, signalling that we wish to read from the slave. Again, a flag is checked before continuing.
Here the sensor gives 16-bit light output data and so we need to extract two 8-bit data values. This is
done in the while loop. At the end of data extraction process, we must generate stop as well as take
care of acknowledgement. Finally, the two bytes are joined to form a word value representing light
output.
The following function simplifies the task of determining lux value from the sensor. It selects mode of
operation and latency. We will call this function in the main loop to extract average light value in lux.
unsigned int get_lux_value(unsigned char mode, unsigned int delay_time)
{
unsigned long lux_value = 0x00;
unsigned char dly = 0x00;
unsigned char s = 0x08;
while(s)
{
BH1750_write(power_up);
BH1750_write(mode);
lux_value += BH1750_read_word();
for(dly = 0; dly < delay_time; dly += 1)
{
delay_ms(1);
}
BH1750_write(power_down);