docs: def read(sensor):
      """
      distance of object in front of sensor in CM.
      """
      import time
      import RPi.GPIO as GPIO
      
      # Disable any warning message such as GPIO pins in use
      GPIO.setwarnings(False)
      
      # use the values of the GPIO pins, and not the actual pin number
      # so if you connect to GPIO 25 which is on pin number 22, the 
      # reference in this code is 25, which is the number of the GPIO 
      # port and not the number of the physical pin
      GPIO.setmode(GPIO.BCM)
      
      if sensor.gpio_in is 0:
          raise RuntimeError('gpio_in, gpio_out attribute of Sensor object must be assigned before calling read')
      else:
          gpio_in = sensor.gpio_in
          gpio_out = sensor.gpio_out
  
          # point the software to the GPIO pins the sensor is using
          # change these values to the pins you are using
          # GPIO output = the pin that's connected to "Trig" on the sensor
          # GPIO input = the pin that's connected to "Echo" on the sensor
          GPIO.setup(gpio_out, GPIO.OUT)
          GPIO.setup(gpio_in, GPIO.IN)
          GPIO.output(gpio_out, GPIO.LOW)
          
          # found that the sensor can crash if there isn't a delay here
          # no idea why. If you have odd crashing issues, increase delay
          time.sleep(0.3)
          
          # sensor manual says a pulse ength of 10Us will trigger the 
          # sensor to transmit 8 cycles of ultrasonic burst at 40kHz and 
          # wait for the reflected ultrasonic burst to be received
          
          # to get a pulse length of 10Us we need to start the pulse, then
          # wait for 10 microseconds, then stop the pulse. This will 
          # result in the pulse length being 10Us.
          
          # start the pulse on the GPIO pin 
          # change this value to the pin you are using
          # GPIO output = the pin that's connected to "Trig" on the sensor
          GPIO.output(gpio_out, True)
          
          # wait 10 micro seconds (this is 0.00001 seconds) so the pulse
          # length is 10Us as the sensor expects
          time.sleep(0.00001)
          
          # stop the pulse after the time above has passed
          # change this value to the pin you are using
          # GPIO output = the pin that's connected to "Trig" on the sensor
          GPIO.output(gpio_out, False)
  
          # listen to the input pin. 0 means nothing is happening. Once a
          # signal is received the value will be 1 so the while loop
          # stops and has the last recorded time the signal was 0
          # change this value to the pin you are using
          # GPIO input = the pin that's connected to "Echo" on the sensor
          while GPIO.input(gpio_in) == 0:
            signaloff = time.time()
          
          # listen to the input pin. Once a signal is received, record the
          # time the signal came through
          # change this value to the pin you are using
          # GPIO input = the pin that's connected to "Echo" on the sensor
          while GPIO.input(gpio_in) == 1:
            signalon = time.time()
          
          # work out the difference in the two recorded times above to 
          # calculate the distance of an object in front of the sensor
          timepassed = signalon - signaloff
          
          # we now have our distance but it's not in a useful unit of
          # measurement. So now we convert this distance into centimetres
          distance = timepassed * 17000
  
          # we're no longer using the GPIO, so tell software we're done
          GPIO.cleanup()
  
          return distance