diff --git a/adafruit_us100.py b/adafruit_us100.py index 79d4b46..6fb2052 100644 --- a/adafruit_us100.py +++ b/adafruit_us100.py @@ -40,6 +40,8 @@ __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_US100.git" +import time + class US100: """Control a US-100 ultrasonic range sensor.""" @@ -51,34 +53,54 @@ def __init__(self, uart): def distance(self): """Return the distance measured by the sensor in cm. This is the function that will be called most often in user code. - If no signal is received, we'll throw a RuntimeError exception. This means - either the sensor was moving too fast to be pointing in the right + If no signal is received, return ``None``. This can happen when the + object in front of the sensor is too close, the wiring is incorrect or the + sensor is not found. If the signal received is not 2 bytes, return ``None``. + This means either the sensor was moving too fast to be pointing in the right direction to pick up the ultrasonic signal when it bounced back (less likely), or the object off of which the signal bounced is too far away - for the sensor to handle. In my experience, the sensor can detect + for the sensor to handle. In my experience, the sensor can not detect objects over 460 cm away. :return: Distance in centimeters. :rtype: float """ - self._uart.write(bytes([0x55])) - data = self._uart.read(2) # 2 bytes return for distance - if not data: - raise RuntimeError("Sensor not found. Check your wiring!") + for _ in range(2): # Attempt to read twice. + self._uart.write(bytes([0x55])) + time.sleep(0.1) + data = self._uart.read(2) # 2 byte return for distance. + if data: # If there is a reading, exit the loop. + break + time.sleep(0.1) # You need to wait between readings, so delay is included. + else: + # Loop exited normally, so read failed twice. + # This can happen when the object in front of the sensor is too close, if the wiring + # is incorrect or the sensor is not found. + return None if len(data) != 2: - raise RuntimeError("Did not receive distance response") + return None + dist = (data[1] + (data[0] << 8)) / 10 return dist @property def temperature(self): """Return the on-chip temperature, in Celsius""" - self._uart.write(bytes([0x50])) - data = self._uart.read(1) # 1 byte return for temp - if not data: - raise RuntimeError("Sensor not found. Check your wiring!") + for _ in range(2): # Attempt to read twice. + self._uart.write(bytes([0x50])) + time.sleep(0.1) + data = self._uart.read(1) # 1 byte return for temp + if data: # If there is a reading, exit the loop. + break + time.sleep(0.1) # You need to wait between readings, so delay is included. + else: + # Loop exited normally, so read failed twice. + # This can happen when the object in front of the sensor is too close, if the wiring + # is incorrect or the sensor is not found. + return None if len(data) != 1: - raise RuntimeError("Did not receive temperature response") + return None + temp = data[0] - 45 return temp