def main(): "The main function: loads an input and waits until terminated." try: try: channel = VoltageRatioInput() except PhidgetException as e: sys.stderr.write( "Runtime Error -> Creating VoltageRatioInput: \n\t") display_error(e) raise except RuntimeError as e: sys.stderr.write( "Runtime Error -> Creating VoltageRatioInput: \n\t" + e) raise channel.setChannel(0) channel.setOnAttachHandler(on_attach) channel.setOnErrorHandler(on_error) channel.setOnVoltageRatioChangeHandler(on_voltage_change) channel.setOnSensorChangeHandler(on_sensor_change) print("\nOpening and Waiting for Attachment...") try: channel.openWaitForAttachment(5000) # Set the sensor type to the 10-80cm distance one channel.setSensorType( VoltageRatioSensorType.SENSOR_TYPE_1101_SHARP_2Y0A21) except PhidgetException as e: print_open_error(e, channel) return print("Sampling data for 10 seconds.") while True: time.sleep(60) return except PhidgetException as e: sys.stderr.write("\nExiting with error(s)...") display_error(e) traceback.print_exc() return finally: print("Cleaning up...") channel.setOnVoltageRatioChangeHandler(None) channel.setOnSensorChangeHandler(None) channel.close()
class Distance: """A glorified wrapper over the distance sensor.""" name = None # type: str value = None # type: float valid = None # type: Optional[bool] def __init__(self, name: str, channel: int): self.name = name self.value = 0 self.valid = None self.lock = threading.Lock() self.phidget = VoltageRatioInput() self.phidget.setChannel(channel) self.phidget.setOnSensorChangeHandler(self._on_change) self.phidget.setOnErrorHandler(self._on_error) def _on_change(self, _, value, _unit): "Callback for when the sensor's input is changed." "" with self.lock: if not self.valid or abs(self.value - value) > 0.05: # Update properties and notify observers if self.name == "front_dist_0" or self.name == "front_dist_1": LOG.debug("%s = %s%s", self.name, value, _unit.symbol) self.value = value self.valid = True def get(self) -> float: """ Returns the value of the sensors data """ with self.lock: data = self.value return data def get_valid(self) -> Optional[bool]: """ Returns the true/false if the sensor reading is valid""" with self.lock: return self.valid def _on_error(self, ph, code, msg): """Callback for when the sensor detects receives an error. We have a special implementation, as we want to handle the case where the input is out of range. """ if code == 4103: # Mark as malformed and notify observers with self.lock: if self.valid or self.valid is None: LOG.warning("%s is out of bounds", self.name) self.valid = False else: on_error(ph, code, msg) def __enter__(self): """Attach this sensor and configure it with various properties. For now, we subscribe to updates every 50ms (20Hz). """ self.phidget.openWaitForAttachment(ATTACHMENT_TIMEOUT) self.phidget.setDataInterval(50) self.phidget.setSensorType( VoltageRatioSensorType.SENSOR_TYPE_1101_SHARP_2D120X) LOG.info("Attached %s", self.name) return self def __exit__(self, _a, _b, _c): self.phidget.setOnErrorHandler(None) self.phidget.setOnSensorChangeHandler(None) self.phidget.close()