diff --git a/adafruit_vl53l0x.py b/adafruit_vl53l0x.py index 8a75fa8..2ea0d13 100644 --- a/adafruit_vl53l0x.py +++ b/adafruit_vl53l0x.py @@ -145,6 +145,7 @@ def __init__(self, i2c, address=41, io_timeout_s=0): self._i2c = i2c self._device = i2c_device.I2CDevice(i2c, address) self.io_timeout_s = io_timeout_s + self._data_ready = False # Check identification registers for expected values. # From section 3.2 of the datasheet. if ( @@ -528,6 +529,15 @@ def range(self): self.do_range_measurement() return self.read_range() + @property + def data_ready(self): + """Check if data is available from the sensor. If true a call to .range + will return quickly. If false, calls to .range will wait for the sensor's + next reading to be available.""" + if not self._data_ready: + self._data_ready = self._read_u8(_RESULT_INTERRUPT_STATUS) & 0x07 != 0 + return self._data_ready + def do_range_measurement(self): """Perform a single reading of the range for an object in front of the sensor, but without return the distance. @@ -555,7 +565,6 @@ def do_range_measurement(self): def read_range(self): """Return a range reading in millimeters. - Note: Avoid calling this directly. If you do single mode, you need to call `do_range_measurement` first. Or your program will stuck or timeout occurred. @@ -563,7 +572,7 @@ def read_range(self): # Adapted from readRangeContinuousMillimeters in pololu code at: # https://github.com/pololu/vl53l0x-arduino/blob/master/VL53L0X.cpp start = time.monotonic() - while (self._read_u8(_RESULT_INTERRUPT_STATUS) & 0x07) == 0: + while not self.data_ready: if ( self.io_timeout_s > 0 and (time.monotonic() - start) >= self.io_timeout_s @@ -573,6 +582,7 @@ def read_range(self): # fractional ranging is not enabled range_mm = self._read_u16(_RESULT_RANGE_STATUS + 10) self._write_u8(_SYSTEM_INTERRUPT_CLEAR, 0x01) + self._data_ready = False return range_mm @property