Skip to content

Instantly share code, notes, and snippets.

@oskar456
Created June 20, 2015 15:26
Show Gist options
  • Save oskar456/95c66d564c58361ecf9f to your computer and use it in GitHub Desktop.
Save oskar456/95c66d564c58361ecf9f to your computer and use it in GitHub Desktop.
BH1750 python library
#!/usr/bin/python2
# vim: expandtab ts=4 sw=4
# Inspired by http://www.raspberrypi-spy.co.uk/2015/03/bh1750fvi-i2c-digital-light-intensity-sensor/
import smbus
import time
class BH1750():
""" Implement BH1750 communication. """
# Define some constants from the datasheet
POWER_DOWN = 0x00 # No active state
POWER_ON = 0x01 # Power on
RESET = 0x07 # Reset data register value
# Start measurement at 4lx resolution. Time typically 16ms.
CONTINUOUS_LOW_RES_MODE = 0x13
# Start measurement at 1lx resolution. Time typically 120ms
CONTINUOUS_HIGH_RES_MODE_1 = 0x10
# Start measurement at 0.5lx resolution. Time typically 120ms
CONTINUOUS_HIGH_RES_MODE_2 = 0x11
# Start measurement at 1lx resolution. Time typically 120ms
# Device is automatically set to Power Down after measurement.
ONE_TIME_HIGH_RES_MODE_1 = 0x20
# Start measurement at 0.5lx resolution. Time typically 120ms
# Device is automatically set to Power Down after measurement.
ONE_TIME_HIGH_RES_MODE_2 = 0x21
# Start measurement at 1lx resolution. Time typically 120ms
# Device is automatically set to Power Down after measurement.
ONE_TIME_LOW_RES_MODE = 0x23
def __init__(self, bus, addr=0x23):
self.bus = bus
self.addr = addr
self.power_down()
self.set_sensitivity()
def _set_mode(self, mode):
self.mode = mode
self.bus.write_byte(self.addr, self.mode)
def power_down(self):
self._set_mode(self.POWER_DOWN)
def power_on(self):
self._set_mode(self.POWER_ON)
def reset(self):
self.power_on() #It has to be powered on before resetting
self._set_mode(self.RESET)
def cont_low_res(self):
self._set_mode(self.CONTINUOUS_LOW_RES_MODE)
def cont_high_res(self):
self._set_mode(self.CONTINUOUS_HIGH_RES_MODE_1)
def cont_high_res2(self):
self._set_mode(self.CONTINUOUS_HIGH_RES_MODE_2)
def oneshot_low_res(self):
self._set_mode(self.ONE_TIME_LOW_RES_MODE)
def oneshot_high_res(self):
self._set_mode(self.ONE_TIME_HIGH_RES_MODE_1)
def oneshot_high_res2(self):
self._set_mode(self.ONE_TIME_HIGH_RES_MODE_2)
def set_sensitivity(self, sensitivity=69):
""" Set the sensor sensitivity.
Valid values are 31 (lowest) to 254 (highest), default is 69.
"""
if sensitivity < 31:
self.mtreg = 31
elif sensitivity > 254:
self.mtreg = 254
else:
self.mtreg = sensitivity
self.power_on()
self._set_mode(0x40 | (self.mtreg >> 5))
self._set_mode(0x60 | (self.mtreg & 0x1f))
self.power_down()
def get_result(self):
""" Return current measurement result in lx. """
data = self.bus.read_word_data(self.addr, self.mode)
count = data >> 8 | (data&0xff)<<8
mode2coeff = 2 if (self.mode & 0x03) == 0x01 else 1
ratio = 1/(1.2 * (self.mtreg/69.0) * mode2coeff)
return ratio*count
def wait_for_result(self, additional=0):
basetime = 0.018 if (self.mode & 0x03) == 0x03 else 0.128
time.sleep(basetime * (self.mtreg/69.0) + additional)
def do_measurement(self, mode, additional_delay=0):
"""
Perform complete measurement using command
specified by parameter mode with additional
delay specified in parameter additional_delay.
Return output value in Lx.
"""
self.reset()
self._set_mode(mode)
self.wait_for_result(additional=additional_delay)
return self.get_result()
def measure_low_res(self, additional_delay=0):
return self.do_measurement(self.ONE_TIME_LOW_RES_MODE, additional_delay)
def measure_high_res(self, additional_delay=0):
return self.do_measurement(self.ONE_TIME_HIGH_RES_MODE_1, additional_delay)
def measure_high_res2(self, additional_delay=0):
return self.do_measurement(self.ONE_TIME_HIGH_RES_MODE_2, additional_delay)
def main():
#bus = smbus.SMBus(0) # Rev 1 Pi uses 0
bus = smbus.SMBus(1) # Rev 2 Pi uses 1
sensor = BH1750(bus)
while True:
print "Sensitivity: {:d}".format(sensor.mtreg)
for measurefunc, name in [(sensor.measure_low_res, "Low Res "),
(sensor.measure_high_res, "HighRes "),
(sensor.measure_high_res2, "HighRes2")]:
print "{} Light Level : {:3.2f} lx".format(name, measurefunc())
print "--------"
sensor.set_sensitivity((sensor.mtreg + 10) % 255)
time.sleep(1)
if __name__=="__main__":
main()
@bwaldvogel
Copy link

any chance this could be uploaded to PyPI and/or this script converted to a repository?

@anselmobattisti
Copy link

Thanks!

@sergeantpol
Copy link

sergeantpol commented Feb 11, 2020

I came up with an error line 125:
print "Sensitivity: {:d}".format(sensor.mtreg)
>"
SyntaxError: invalid syntax

@sergeantpol
Copy link

I came up with an error line 125:
print "Sensitivity: {:d}".format(sensor.mtreg)

"
SyntaxError: invalid syntax

I just used parenthesis to all printing commands

@oskar456
Copy link
Author

I came up with an error line 125:
print "Sensitivity: {:d}".format(sensor.mtreg)

"
SyntaxError: invalid syntax

Yeah, this is some legacy Python2 code :(

@houserockr
Copy link

This lib just made my day, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment