24
24
25
25
The HC-SR04 functions by sending an ultrasonic signal, which is reflected by
26
26
many materials, and then sensing when the signal returns to the sensor. Knowing
27
- that sound travels through air at 343.2 meters per second
27
+ that sound travels through dry air at `343.2 meters per second (at 20 °C)
28
+ <https://en.wikipedia.org/wiki/Speed_of_sound>`_, it's pretty straightforward
29
+ to calculate how far away the object is by timing how long the signal took to
30
+ go round-trip and do some simple arithmetic, which is handled for you by this
31
+ library.
28
32
29
33
.. warning::
30
34
31
35
The HC-SR04 uses 5V logic, so you will have to use a `level shifter
32
36
<https://www.adafruit.com/product/2653?q=level%20shifter&>`_ between it
33
37
and your CircuitPython board (which uses 3.3V logic).
34
38
35
- * Author(s): Mike Mabey
39
+ * Authors:
40
+
41
+ - Mike Mabey
42
+ - Jerry Needell - modified to add timeout while waiting for echo (2/26/2018)
36
43
"""
37
44
import board
38
45
from digitalio import DigitalInOut , DriveMode
39
46
from pulseio import PulseIn
40
- from time import sleep
47
+ import time
41
48
42
49
43
50
class HCSR04 :
@@ -55,20 +62,24 @@ class HCSR04:
55
62
except KeyboardInterrupt:
56
63
pass
57
64
"""
58
- def __init__ (self , trig_pin , echo_pin ):
65
+ def __init__ (self , trig_pin , echo_pin , timeout_sec = .1 ):
59
66
"""
60
67
:param trig_pin: The pin on the microcontroller that's connected to the
61
68
``Trig`` pin on the HC-SR04.
62
69
:type trig_pin: str or microcontroller.Pin
63
70
:param echo_pin: The pin on the microcontroller that's connected to the
64
71
``Echo`` pin on the HC-SR04.
65
72
:type echo_pin: str or microcontroller.Pin
73
+ :param float timeout_sec: Max seconds to wait for a response from the
74
+ sensor before assuming it isn't going to answer. Should *not* be
75
+ set to less than 0.05 seconds!
66
76
"""
67
77
if isinstance (trig_pin , str ):
68
78
trig_pin = getattr (board , trig_pin )
69
79
if isinstance (echo_pin , str ):
70
80
echo_pin = getattr (board , echo_pin )
71
81
self .dist_cm = self ._dist_two_wire
82
+ self .timeout_sec = timeout_sec
72
83
73
84
self .trig = DigitalInOut (trig_pin )
74
85
self .trig .switch_to_output (value = False , drive_mode = DriveMode .PUSH_PULL )
@@ -117,13 +128,15 @@ def dist_cm(self):
117
128
def _dist_two_wire (self ):
118
129
self .echo .clear () # Discard any previous pulse values
119
130
self .trig .value = 1 # Set trig high
120
- sleep (0.00001 ) # 10 micro seconds 10/1000/1000
131
+ time . sleep (0.00001 ) # 10 micro seconds 10/1000/1000
121
132
self .trig .value = 0 # Set trig low
122
-
133
+ timeout = time . monotonic ()
123
134
self .echo .resume ()
124
135
while len (self .echo ) == 0 :
125
136
# Wait for a pulse
126
- pass
137
+ if (time .monotonic () - timeout ) > self .timeout_sec :
138
+ self .echo .pause ()
139
+ return - 1
127
140
self .echo .pause ()
128
141
if self .echo [0 ] == 65535 :
129
142
return - 1
@@ -151,6 +164,6 @@ def test(trig, echo, delay=2):
151
164
try :
152
165
while True :
153
166
print (sonar .dist_cm ())
154
- sleep (delay )
167
+ time . sleep (delay )
155
168
except KeyboardInterrupt :
156
169
pass
0 commit comments