]> vault307.fbx.one Git - SensorLib.git/blob - bh1750.py
sensors
[SensorLib.git] / bh1750.py
1 # https://github.com/flrrth/pico-bh1750
2
3 import math
4
5 from micropython import const
6 from utime import sleep_ms
7
8
9 class BH1750:
10 """Class for the BH1750 digital Ambient Light Sensor
11
12 The datasheet can be found at https://components101.com/sites/default/files/component_datasheet/BH1750.pdf
13 """
14
15 MEASUREMENT_MODE_CONTINUOUSLY = const(1)
16 MEASUREMENT_MODE_ONE_TIME = const(2)
17
18 RESOLUTION_HIGH = const(0)
19 RESOLUTION_HIGH_2 = const(1)
20 RESOLUTION_LOW = const(2)
21
22 MEASUREMENT_TIME_DEFAULT = const(69)
23 MEASUREMENT_TIME_MIN = const(31)
24 MEASUREMENT_TIME_MAX = const(254)
25
26 def __init__(self, address, i2c):
27 self._address = address
28 self._i2c = i2c
29 self._measurement_mode = BH1750.MEASUREMENT_MODE_ONE_TIME
30 self._resolution = BH1750.RESOLUTION_HIGH
31 self._measurement_time = BH1750.MEASUREMENT_TIME_DEFAULT
32
33 self._write_measurement_time()
34 self._write_measurement_mode()
35
36 def configure(self, measurement_mode: int, resolution: int, measurement_time: int):
37 """Configures the BH1750.
38
39 Keyword arguments:
40 measurement_mode -- measure either continuously or once
41 resolution -- return measurements in either high, high2 or low resolution
42 measurement_time -- the duration of a single measurement
43 """
44 if measurement_time not in range(BH1750.MEASUREMENT_TIME_MIN, BH1750.MEASUREMENT_TIME_MAX + 1):
45 raise ValueError("measurement_time must be between {0} and {1}"
46 .format(BH1750.MEASUREMENT_TIME_MIN, BH1750.MEASUREMENT_TIME_MAX))
47
48 self._measurement_mode = measurement_mode
49 self._resolution = resolution
50 self._measurement_time = measurement_time
51
52 self._write_measurement_time()
53 self._write_measurement_mode()
54
55 def _write_measurement_time(self):
56 buffer = bytearray(1)
57
58 high_bit = 1 << 6 | self._measurement_time >> 5
59 low_bit = 3 << 5 | (self._measurement_time << 3) >> 3
60
61 buffer[0] = high_bit
62 self._i2c.writeto(self._address, buffer)
63
64 buffer[0] = low_bit
65 self._i2c.writeto(self._address, buffer)
66
67 def _write_measurement_mode(self):
68 buffer = bytearray(1)
69
70 buffer[0] = self._measurement_mode << 4 | self._resolution
71 self._i2c.writeto(self._address, buffer)
72 sleep_ms(24 if self._measurement_time == BH1750.RESOLUTION_LOW else 180)
73
74 def reset(self):
75 """Clear the illuminance data register."""
76 self._i2c.writeto(self._address, bytearray(b'\x07'))
77
78 def power_on(self):
79 """Powers on the BH1750."""
80 self._i2c.writeto(self._address, bytearray(b'\x01'))
81
82 def power_off(self):
83 """Powers off the BH1750."""
84 self._i2c.writeto(self._address, bytearray(b'\x00'))
85
86 @property
87 def measurement(self) -> float:
88 """Returns the latest measurement."""
89 if self._measurement_mode == BH1750.MEASUREMENT_MODE_ONE_TIME:
90 self._write_measurement_mode()
91
92 buffer = bytearray(2)
93 self._i2c.readfrom_into(self._address, buffer)
94 lux = (buffer[0] << 8 | buffer[1]) / (1.2 * (BH1750.MEASUREMENT_TIME_DEFAULT / self._measurement_time))
95
96 if self._resolution == BH1750.RESOLUTION_HIGH_2:
97 return lux / 2
98 else:
99 return lux
100
101 def measurements(self) -> float:
102 """This is a generator function that continues to provide the latest measurement. Because the measurement time
103 is greatly affected by resolution and the configured measurement time, this function attemts to calculate the
104 appropriate sleep time between measurements.
105
106 Example usage:
107
108 for measurement in bh1750.measurements(): # bh1750 is an instance of this class
109 print(measurement)
110 """
111 while True:
112 yield self.measurement
113
114 if self._measurement_mode == BH1750.MEASUREMENT_MODE_CONTINUOUSLY:
115 base_measurement_time = 16 if self._measurement_time == BH1750.RESOLUTION_LOW else 120
116 sleep_ms(math.ceil(base_measurement_time * self._measurement_time / BH1750.MEASUREMENT_TIME_DEFAULT))