00001 #!/usr/bin/env python 00002 00003 import time 00004 00005 import pigpio 00006 00007 class ranger: 00008 """ 00009 This class encapsulates a type of acoustic ranger. In particular 00010 the type of ranger with separate trigger and echo pins. 00011 00012 A pulse on the trigger initiates the sonar ping and shortly 00013 afterwards a sonar pulse is transmitted and the echo pin 00014 goes high. The echo pins stays high until a sonar echo is 00015 received (or the response times-out). The time between 00016 the high and low edges indicates the sonar round trip time. 00017 """ 00018 00019 def __init__(self, pi, trigger, echo): 00020 """ 00021 The class is instantiated with the Pi to use and the 00022 gpios connected to the trigger and echo pins. 00023 """ 00024 self.pi = pi 00025 self._trig = trigger 00026 self._echo = echo 00027 00028 self._ping = False 00029 self._high = None 00030 self._time = None 00031 00032 self._triggered = False 00033 00034 self._trig_mode = pi.get_mode(self._trig) 00035 self._echo_mode = pi.get_mode(self._echo) 00036 00037 pi.set_mode(self._trig, pigpio.OUTPUT) 00038 pi.set_mode(self._echo, pigpio.INPUT) 00039 00040 self._cb = pi.callback(self._trig, pigpio.EITHER_EDGE, self._cbf) 00041 self._cb = pi.callback(self._echo, pigpio.EITHER_EDGE, self._cbf) 00042 00043 self._inited = True 00044 00045 def _cbf(self, gpio, level, tick): 00046 if gpio == self._trig: 00047 if level == 0: # trigger sent 00048 self._triggered = True 00049 self._high = None 00050 else: 00051 if self._triggered: 00052 if level == 1: 00053 self._high = tick 00054 else: 00055 if self._high is not None: 00056 self._time = tick - self._high 00057 self._high = None 00058 self._ping = True 00059 00060 def read(self): 00061 """ 00062 Triggers a reading. The returned reading is the number 00063 of microseconds for the sonar round-trip. 00064 00065 round trip cms = round trip time / 1000000.0 * 34030 00066 """ 00067 if self._inited: 00068 self._ping = False 00069 self.pi.gpio_trigger(self._trig) 00070 start = time.time() 00071 while not self._ping: 00072 if (time.time()-start) > 5.0: 00073 return 20000 00074 time.sleep(0.001) 00075 return self._time 00076 else: 00077 return None 00078 00079 def cancel(self): 00080 """ 00081 Cancels the ranger and returns the gpios to their 00082 original mode. 00083 """ 00084 if self._inited: 00085 self._inited = False 00086 self._cb.cancel() 00087 self.pi.set_mode(self._trig, self._trig_mode) 00088 self.pi.set_mode(self._echo, self._echo_mode) 00089 00090 if __name__ == "__main__": 00091 00092 import time 00093 00094 import pigpio 00095 00096 import sonar_trigger_echo 00097 00098 pi = pigpio.pi() 00099 00100 sonar = sonar_trigger_echo.ranger(pi, 23, 18) 00101 00102 end = time.time() + 600.0 00103 00104 r = 1 00105 while time.time() < end: 00106 00107 print("{} {}".format(r, sonar.read())) 00108 r += 1 00109 time.sleep(0.03) 00110 00111 sonar.cancel() 00112 00113 pi.stop() 00114