Difference between revisions of "Ultrasonic Sensor HC-SR04"
Jump to navigation
Jump to search
(8 intermediate revisions by 3 users not shown) | |||
Line 3: | Line 3: | ||
It sends out an ultrasound signal and detects the echo. By measuring the time you can calculate the distance. | It sends out an ultrasound signal and detects the echo. By measuring the time you can calculate the distance. | ||
+ | [[File:Hc-sr04-1.JPG|x300px]] | ||
[[File:Ultra1.JPG|x300px]] | [[File:Ultra1.JPG|x300px]] | ||
− | |||
more details: | more details: | ||
Line 43: | Line 43: | ||
= Related Tutorial Videos = | = Related Tutorial Videos = | ||
<youtube>PJdDUZWeIDs</youtube> | <youtube>PJdDUZWeIDs</youtube> | ||
+ | |||
+ | |||
+ | = Background = | ||
+ | connecting it to the ESP8266 and reading the signal in without a library/module. | ||
+ | |||
+ | Connect Trig to Pin5 and Echo to Pin4 of the ESP8266. | ||
+ | |||
+ | [[File:Hc-03.JPG|x300px]] | ||
+ | [[File:Hc04-03.JPG|x300px]] | ||
+ | [[File:Hc-sr04-1.JPG|x300px]] | ||
+ | |||
+ | |||
+ | <syntaxhighlight lang="python" line='line'> | ||
+ | import machine | ||
+ | import utime | ||
+ | |||
+ | |||
+ | while True: | ||
+ | trig=machine.Pin(5, machine.Pin.OUT) | ||
+ | trig.off() | ||
+ | utime.sleep_us(2) | ||
+ | trig.on() | ||
+ | utime.sleep_us(10) | ||
+ | trig.off() | ||
+ | echo=machine.Pin(4, machine.Pin.IN) | ||
+ | while echo.value() == 0: | ||
+ | pass | ||
+ | t1 = utime.ticks_us() | ||
+ | while echo.value() == 1: | ||
+ | pass | ||
+ | t2 = utime.ticks_us() | ||
+ | cm = (t2 - t1) / 58.0 | ||
+ | print(cm) | ||
+ | utime.sleep(2) | ||
+ | |||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Code for RP2040 (with the library in the main code) == | ||
+ | |||
+ | This is the version for the Arduino Nano Connect RP2040 using GPIO25 as trigger_pin and GPIO15 as echo_pin. | ||
+ | |||
+ | <syntaxhighlight lang="python" line='line'> | ||
+ | |||
+ | import machine, time | ||
+ | from machine import Pin | ||
+ | |||
+ | #acknowlegement for the library | ||
+ | __version__ = '0.2.0' | ||
+ | __author__ = 'Roberto Sánchez' | ||
+ | __license__ = "Apache License 2.0. https://www.apache.org/licenses/LICENSE-2.0" | ||
+ | |||
+ | class HCSR04: | ||
+ | """ | ||
+ | Driver to use the untrasonic sensor HC-SR04. | ||
+ | The sensor range is between 2cm and 4m. | ||
+ | |||
+ | The timeouts received listening to echo pin are converted to OSError('Out of range') | ||
+ | |||
+ | """ | ||
+ | # echo_timeout_us is based in chip range limit (400cm) | ||
+ | def __init__(self, trigger_pin, echo_pin, echo_timeout_us=500*2*30): | ||
+ | """ | ||
+ | trigger_pin: Output pin to send pulses | ||
+ | echo_pin: Readonly pin to measure the distance. The pin should be protected with 1k resistor | ||
+ | echo_timeout_us: Timeout in microseconds to listen to echo pin. | ||
+ | By default is based in sensor limit range (4m) | ||
+ | """ | ||
+ | self.echo_timeout_us = echo_timeout_us | ||
+ | # Init trigger pin (out) | ||
+ | self.trigger = Pin(trigger_pin, mode=Pin.OUT, pull=None) | ||
+ | self.trigger.value(0) | ||
+ | |||
+ | # Init echo pin (in) | ||
+ | self.echo = Pin(echo_pin, mode=Pin.IN, pull=None) | ||
+ | |||
+ | def _send_pulse_and_wait(self): | ||
+ | """ | ||
+ | Send the pulse to trigger and listen on echo pin. | ||
+ | We use the method `machine.time_pulse_us()` to get the microseconds until the echo is received. | ||
+ | """ | ||
+ | self.trigger.value(0) # Stabilize the sensor | ||
+ | time.sleep_us(5) | ||
+ | self.trigger.value(1) | ||
+ | # Send a 10us pulse. | ||
+ | time.sleep_us(10) | ||
+ | self.trigger.value(0) | ||
+ | try: | ||
+ | pulse_time = machine.time_pulse_us(self.echo, 1, self.echo_timeout_us) | ||
+ | return pulse_time | ||
+ | except OSError as ex: | ||
+ | if ex.args[0] == 110: # 110 = ETIMEDOUT | ||
+ | raise OSError('Out of range') | ||
+ | raise ex | ||
+ | |||
+ | def distance_mm(self): | ||
+ | """ | ||
+ | Get the distance in milimeters without floating point operations. | ||
+ | """ | ||
+ | pulse_time = self._send_pulse_and_wait() | ||
+ | |||
+ | # To calculate the distance we get the pulse_time and divide it by 2 | ||
+ | # (the pulse walk the distance twice) and by 29.1 becasue | ||
+ | # the sound speed on air (343.2 m/s), that It's equivalent to | ||
+ | # 0.34320 mm/us that is 1mm each 2.91us | ||
+ | # pulse_time // 2 // 2.91 -> pulse_time // 5.82 -> pulse_time * 100 // 582 | ||
+ | mm = pulse_time * 100 // 582 | ||
+ | return mm | ||
+ | |||
+ | def distance_cm(self): | ||
+ | """ | ||
+ | Get the distance in centimeters with floating point operations. | ||
+ | It returns a float | ||
+ | """ | ||
+ | pulse_time = self._send_pulse_and_wait() | ||
+ | |||
+ | # To calculate the distance we get the pulse_time and divide it by 2 | ||
+ | # (the pulse walk the distance twice) and by 29.1 becasue | ||
+ | # the sound speed on air (343.2 m/s), that It's equivalent to | ||
+ | # 0.034320 cm/us that is 1cm each 29.1us | ||
+ | cms = (pulse_time / 2) / 29.1 | ||
+ | return cms | ||
+ | |||
+ | |||
+ | # contributed at the UBISS2024 Seminar | ||
+ | |||
+ | from time import sleep | ||
+ | sensor = HCSR04(trigger_pin=25, echo_pin=15) | ||
+ | sleep(1) | ||
+ | i=0 | ||
+ | |||
+ | |||
+ | while True: | ||
+ | distance = sensor.distance_cm() | ||
+ | print(i, ': Distance:', distance, 'cm') | ||
+ | i=i+1 | ||
+ | sleep(0.5) | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | [[Category:Sensor]] |
Latest revision as of 15:15, 11 June 2024
Contents
Description[edit]
The HC-SR04 is an ultrasonic distance sensor that can measure distances from 2cm to 400cm. It sends out an ultrasound signal and detects the echo. By measuring the time you can calculate the distance.
more details:
- https://randomnerdtutorials.com/complete-guide-for-ultrasonic-sensor-hc-sr04/
- https://cdn.sparkfun.com/datasheets/Sensors/Proximity/HCSR04.pdf
How to connect it electrically[edit]
Required Module and Files[edit]
- We use hcsr04.py
- this is downloaded from https://github.com/rsc1975/micropython-hcsr04
- the original file is at https://github.com/rsc1975/micropython-hcsr04/blob/master/hcsr04.py
How to control it in MicroPython[edit]
1 from hcsr04 import HCSR04
2 from time import sleep
3
4 sensor = HCSR04(trigger_pin=12, echo_pin=14)
5 sleep(1)
6 i=0
7
8 while True:
9 distance = sensor.distance_cm()
10 print(i, ': Distance:', distance, 'cm')
11 i=i+1
12 sleep(0.5)
Related Tutorial Videos[edit]
Background[edit]
connecting it to the ESP8266 and reading the signal in without a library/module.
Connect Trig to Pin5 and Echo to Pin4 of the ESP8266.
1 import machine
2 import utime
3
4
5 while True:
6 trig=machine.Pin(5, machine.Pin.OUT)
7 trig.off()
8 utime.sleep_us(2)
9 trig.on()
10 utime.sleep_us(10)
11 trig.off()
12 echo=machine.Pin(4, machine.Pin.IN)
13 while echo.value() == 0:
14 pass
15 t1 = utime.ticks_us()
16 while echo.value() == 1:
17 pass
18 t2 = utime.ticks_us()
19 cm = (t2 - t1) / 58.0
20 print(cm)
21 utime.sleep(2)
Code for RP2040 (with the library in the main code)[edit]
This is the version for the Arduino Nano Connect RP2040 using GPIO25 as trigger_pin and GPIO15 as echo_pin.
1 import machine, time
2 from machine import Pin
3
4 #acknowlegement for the library
5 __version__ = '0.2.0'
6 __author__ = 'Roberto Sánchez'
7 __license__ = "Apache License 2.0. https://www.apache.org/licenses/LICENSE-2.0"
8
9 class HCSR04:
10 """
11 Driver to use the untrasonic sensor HC-SR04.
12 The sensor range is between 2cm and 4m.
13
14 The timeouts received listening to echo pin are converted to OSError('Out of range')
15
16 """
17 # echo_timeout_us is based in chip range limit (400cm)
18 def __init__(self, trigger_pin, echo_pin, echo_timeout_us=500*2*30):
19 """
20 trigger_pin: Output pin to send pulses
21 echo_pin: Readonly pin to measure the distance. The pin should be protected with 1k resistor
22 echo_timeout_us: Timeout in microseconds to listen to echo pin.
23 By default is based in sensor limit range (4m)
24 """
25 self.echo_timeout_us = echo_timeout_us
26 # Init trigger pin (out)
27 self.trigger = Pin(trigger_pin, mode=Pin.OUT, pull=None)
28 self.trigger.value(0)
29
30 # Init echo pin (in)
31 self.echo = Pin(echo_pin, mode=Pin.IN, pull=None)
32
33 def _send_pulse_and_wait(self):
34 """
35 Send the pulse to trigger and listen on echo pin.
36 We use the method `machine.time_pulse_us()` to get the microseconds until the echo is received.
37 """
38 self.trigger.value(0) # Stabilize the sensor
39 time.sleep_us(5)
40 self.trigger.value(1)
41 # Send a 10us pulse.
42 time.sleep_us(10)
43 self.trigger.value(0)
44 try:
45 pulse_time = machine.time_pulse_us(self.echo, 1, self.echo_timeout_us)
46 return pulse_time
47 except OSError as ex:
48 if ex.args[0] == 110: # 110 = ETIMEDOUT
49 raise OSError('Out of range')
50 raise ex
51
52 def distance_mm(self):
53 """
54 Get the distance in milimeters without floating point operations.
55 """
56 pulse_time = self._send_pulse_and_wait()
57
58 # To calculate the distance we get the pulse_time and divide it by 2
59 # (the pulse walk the distance twice) and by 29.1 becasue
60 # the sound speed on air (343.2 m/s), that It's equivalent to
61 # 0.34320 mm/us that is 1mm each 2.91us
62 # pulse_time // 2 // 2.91 -> pulse_time // 5.82 -> pulse_time * 100 // 582
63 mm = pulse_time * 100 // 582
64 return mm
65
66 def distance_cm(self):
67 """
68 Get the distance in centimeters with floating point operations.
69 It returns a float
70 """
71 pulse_time = self._send_pulse_and_wait()
72
73 # To calculate the distance we get the pulse_time and divide it by 2
74 # (the pulse walk the distance twice) and by 29.1 becasue
75 # the sound speed on air (343.2 m/s), that It's equivalent to
76 # 0.034320 cm/us that is 1cm each 29.1us
77 cms = (pulse_time / 2) / 29.1
78 return cms
79
80
81 # contributed at the UBISS2024 Seminar
82
83 from time import sleep
84 sensor = HCSR04(trigger_pin=25, echo_pin=15)
85 sleep(1)
86 i=0
87
88
89 while True:
90 distance = sensor.distance_cm()
91 print(i, ': Distance:', distance, 'cm')
92 i=i+1
93 sleep(0.5)