Created
June 20, 2015 15:26
-
-
Save oskar456/95c66d564c58361ecf9f to your computer and use it in GitHub Desktop.
BH1750 python library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This lib just made my day, thank you!