Pada artikel ini, Anda akan belajar menggunakan Sensor Ultrasonik HC-SR04 dengan ESP32 dan ESP8266 untuk mengukur jarak ke suatu objek menggunakan firmware MicroPython. Tutorial ini mencakup cara menghubungkan sensor ke papan ESP32 dan ESP8266, serta menyediakan skrip MicroPython sederhana untuk mendapatkan jarak ke objek dan menampilkannya pada layar OLED.
Mengenal Sensor Ultrasonik HC-SR04
Sensor ultrasonik HC-SR04 menggunakan prinsip sonar untuk menentukan jarak ke suatu objek. Sensor ini dapat membaca jarak dari 2cm hingga 400cm (0,8 inci hingga 157 inci) dengan akurasi 0,3cm (0,1 inci), yang sudah cukup baik untuk sebagian besar proyek hobi. Modul ini dilengkapi dengan modul pemancar (transmitter) dan penerima (receiver) ultrasonik.
Data Teknis HC-SR04
Tabel berikut menunjukkan fitur utama dan spesifikasi sensor ultrasonik HC-SR04. Untuk informasi lebih detail, silakan merujuk ke datasheet sensor.
Pinout Sensor Ultrasonik HC-SR04
Berikut adalah pinout (konfigurasi pin) Sensor Ultrasonik HC-SR04.
Bagaimana Cara Kerja Sensor Ultrasonik HC-SR04?
Sensor ultrasonik menggunakan prinsip sonar untuk menentukan jarak ke suatu objek. Berikut adalah cara kerjanya:
1. Pemancar ultrasonik (trig pin) memancarkan suara frekuensi tinggi (40 kHz).
2. Suara merambat melalui udara. Jika menemui objek, suara akan dipantulkan kembali ke modul.
3. Penerima ultrasonik (echo pin) menerima suara yang dipantulkan (gema/echo).
Dengan mempertimbangkan kecepatan suara di udara dan waktu tempuh (selang waktu antara pemancaran dan penerimaan sinyal), kita dapat menghitung jarak ke objek. Berikut rumusnya:
distance to an object = ((speed of sound in the air)*time)/2
Kecepatan suara di udara pada suhu 20°C (68°F) = 343 m/detik
Komponen yang Diperlukan
Untuk menyelesaikan tutorial ini, Anda membutuhkan komponen-komponen berikut:
- Sensor Ultrasonik HC-SR04
- ESP32 atau ESP8266 (baca: [ESP32 vs ESP8266](tautan))
- Papan breadboard
- Kabel jumper
Skematik – ESP32 dengan Sensor Ultrasonik HC-SR04
Hubungkan sensor ultrasonik HC-SR04 ke ESP32 seperti yang ditunjukkan pada diagram skematik berikut. Kami menghubungkan pin Trig ke GPIO 5 dan pin Echo ke GPIO 18, namun Anda dapat menggunakan pin lain yang sesuai. Lanjut ke bagian berikutnya jika Anda menggunakan papan ESP8266.
Skematik – ESP8266 dengan Sensor Ultrasonik HC-SR04
Hubungkan sensor ultrasonik HC-SR04 ke ESP8266 seperti yang ditunjukkan pada diagram skematik berikut. Kami menghubungkan pin Trig ke GPIO 12 dan pin Echo ke GPIO 14, namun Anda dapat menggunakan pin lain yang sesuai.
Library MicroPython untuk HC-SR04
Ada beberapa cara untuk mendapatkan jarak ke suatu objek menggunakan HC-SR04 dan papan ESP32/ESP8266 dengan firmware MicroPython.
Library yang akan kita gunakan tidak termasuk dalam pustaka standar MicroPython secara default. Oleh karena itu, Anda perlu mengunggah pustaka berikut ke papan ESP32/ESP8266 Anda (simpan dengan nama `hcsr04.py`).
import machine, time
from machine import Pin
__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
Ikuti serangkaian instruksi berikut sesuai dengan IDE yang Anda gunakan:
- Unggah Pustaka HC-SR04 dengan uPyCraft IDE
- Unggah Pustaka HC-SR04 dengan Thonny IDE
Unggah Pustaka HC-SR04 dengan uPyCraft IDE
Bagian ini menunjukkan cara mengunggah pustaka menggunakan uPyCraft IDE. Jika Anda menggunakan Thonny IDE, silakan baca bagian berikutnya.
Pertama, pastikan koneksi antara IDE dan papan Anda telah terbangun. Buka Tools > Serial dan pilih port COM yang sesuai. Buka Tools > Board dan pilih jenis papan Anda. Kemudian, klik tombol Connect.
1. Buat file baru dengan menekan tombol New File (1).
2. Salin kode pustaka HC-SR04 ke dalam file tersebut. Kode pustaka HC-SR04 dapat ditemukan [di sini](tautan).
3. Setelah menyalin kode, simpan file dengan menekan tombol Save (2).
4. Beri nama file baru ini `hcsr04.py` dan tekan OK.
5. Klik tombol Download and Run (3).
Setelah itu, file tersebut akan tersimpan di folder perangkat dengan nama `hcsr04.py`, seperti yang ditunjukkan pada gambar berikut.
Sekarang, Anda dapat menggunakan fungsi-fungsi pustaka dalam kode Anda dengan mengimpornya.
Unggah Pustaka HC-SR04 dengan Thonny IDE
Jika Anda menggunakan Thonny IDE, ikuti langkah-langkah berikut:
1. Salin kode pustaka ke dalam file baru. Kode pustaka HC-SR04 dapat ditemukan [di sini](tautan).
2. Buka File > Save as….
3. Pilih opsi simpan ke "MicroPython device" (Simpan ke perangkat MicroPython):
4. Beri nama file Anda `hcsr04.py` dan tekan tombol OK:
Selesai. Pustaka telah berhasil diunggah ke papan Anda. Untuk memastikan pengunggahan berhasil, buka File > Save as… dan pilih MicroPython device. File Anda akan terdaftar di sana:
Setelah library berhasil diunggah ke papan ESP, Anda dapat menggunakan fungsinya dalam kode dengan mengimpornya.
Sensor Ultrasonik HC-SR04
Setelah mengunggah pustaka ke ESP32 atau ESP8266, salin kode berikut ke file `main.py` atau `boot.py`. Kode ini akan mencetak jarak ke objek terdekat setiap detik (contoh diadaptasi dari halaman pustaka).
from hcsr04 import HCSR04
from time import sleep
# ESP32
sensor = HCSR04(trigger_pin=5, echo_pin=18, echo_timeout_us=10000)
# ESP8266
#sensor = HCSR04(trigger_pin=12, echo_pin=14, echo_timeout_us=10000)
while True:
distance = sensor.distance_cm()
print('Distance:', distance, 'cm')
sleep(1)
Cara Kerja Kode
Pertama, Anda perlu mengimpor pustaka yang diperlukan: impor kelas `HCSR04` dari pustaka `hcsr04`. Selain itu, Anda juga perlu mengimpor pustaka `time` untuk memberikan jeda (delay) dalam kode.
from hcsr04 import HCSR04
from time import sleep
Kemudian, buat objek `HCSR04` bernama `sensor` yang merujuk ke sensor HC-SR04. Berikan argumen berupa pin trigger (pemicu), pin echo, dan timeout (waktu tempuh maksimum gelombang suara - saat sensor kemungkinan berada di luar jangkauan).
sensor = HCSR04(trigger_pin=5, echo_pin=18, echo_timeout_us=10000)
Jika Anda menggunakan ESP8266, komentari baris sebelumnya dan hapus komentar pada baris berikut untuk menggunakan pin yang berbeda:
sensor = HCSR04(trigger_pin=12, echo_pin=14, echo_timeout_us=10000)
Untuk mendapatkan jarak dalam satuan sentimeter (cm), Anda hanya perlu memanggil metode `distance_cm()` pada objek `sensor`. Simpan hasilnya dalam variabel `distance`.
distance = sensor.distance_cm()
Pustaka ini juga menyediakan metode untuk mendapatkan jarak dalam milimeter (mm) tanpa menggunakan bilangan pecahan (floating point). Anda hanya perlu memanggil:
distance = sensor.distance_mm()
Cetak jarak tersebut di shell MicroPython.
print('Distance:', distance, 'cm')
Terakhir, kami menambahkan jeda selama satu detik (jarak akan diperbarui setiap detik):
sleep(1)
Demonstrasi
Setelah mengunggah kode ke papan Anda, tekan tombol RST untuk menjalankannya. Jarak ke objek terdekat akan dicetak di shell MicroPython.
Menampilkan Jarak (HC-SR04) pada Layar OLED
Setelah Anda mengetahui cara mendapatkan jarak ke objek terdekat menggunakan sensor ultrasonik HC-SR04, kita akan menampilkan pembacaan sensor tersebut pada layar OLED.
Diagram Skematik
Tambahkan layar OLED I2C ke rangkaian sebelumnya. Ikuti diagram skematik untuk papan yang Anda gunakan.
ESP32
ESP8266
File yang Diperlukan
Untuk contoh ini, Anda membutuhkan tiga file:
1. hcsr04.py: File yang berisi semua metode untuk menggunakan sensor HC-SR04. Ini adalah file yang telah Anda unggah sebelumnya.
2. ssd1306.py: Pustaka untuk layar OLED SSD1306 berbasis I2C. Anda perlu mengunggahnya ke papan untuk dapat berkomunikasi dan menulis ke layar.
3. main.py: Skrip utama untuk mendapatkan jarak dan menampilkannya di layar OLED.
ssd1306.py
Buat file baru bernama `ssd1306.py` dan salin kode berikut. Kemudian, unggah ke papan ESP Anda.
import time
import framebuf
# register definitions
SET_CONTRAST = const(0x81)
SET_ENTIRE_ON = const(0xa4)
SET_NORM_INV = const(0xa6)
SET_DISP = const(0xae)
SET_MEM_ADDR = const(0x20)
SET_COL_ADDR = const(0x21)
SET_PAGE_ADDR = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP = const(0xa0)
SET_MUX_RATIO = const(0xa8)
SET_COM_OUT_DIR = const(0xc0)
SET_DISP_OFFSET = const(0xd3)
SET_COM_PIN_CFG = const(0xda)
SET_DISP_CLK_DIV = const(0xd5)
SET_PRECHARGE = const(0xd9)
SET_VCOM_DESEL = const(0xdb)
SET_CHARGE_PUMP = const(0x8d)
class SSD1306:
def __init__(self, width, height, external_vcc):
self.width = width
self.height = height
self.external_vcc = external_vcc
self.pages = self.height // 8
# Note the subclass must initialize self.framebuf to a framebuffer.
# This is necessary because the underlying data buffer is different
# between I2C and SPI implementations (I2C needs an extra byte).
self.poweron()
self.init_display()
def init_display(self):
for cmd in (
SET_DISP | 0x00, # off
# address setting
SET_MEM_ADDR, 0x00, # horizontal
# resolution and layout
SET_DISP_START_LINE | 0x00,
SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
SET_MUX_RATIO, self.height - 1,
SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
SET_DISP_OFFSET, 0x00,
SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12,
# timing and driving scheme
SET_DISP_CLK_DIV, 0x80,
SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1,
SET_VCOM_DESEL, 0x30, # 0.83*Vcc
# display
SET_CONTRAST, 0xff, # maximum
SET_ENTIRE_ON, # output follows RAM contents
SET_NORM_INV, # not inverted
# charge pump
SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,
SET_DISP | 0x01): # on
self.write_cmd(cmd)
self.fill(0)
self.show()
def poweroff(self):
self.write_cmd(SET_DISP | 0x00)
def contrast(self, contrast):
self.write_cmd(SET_CONTRAST)
self.write_cmd(contrast)
def invert(self, invert):
self.write_cmd(SET_NORM_INV | (invert & 1))
def show(self):
x0 = 0
x1 = self.width - 1
if self.width == 64:
# displays with width of 64 pixels are shifted by 32
x0 += 32
x1 += 32
self.write_cmd(SET_COL_ADDR)
self.write_cmd(x0)
self.write_cmd(x1)
self.write_cmd(SET_PAGE_ADDR)
self.write_cmd(0)
self.write_cmd(self.pages - 1)
self.write_framebuf()
def fill(self, col):
self.framebuf.fill(col)
def pixel(self, x, y, col):
self.framebuf.pixel(x, y, col)
def scroll(self, dx, dy):
self.framebuf.scroll(dx, dy)
def text(self, string, x, y, col=1):
self.framebuf.text(string, x, y, col)
class SSD1306_I2C(SSD1306):
def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):
self.i2c = i2c
self.addr = addr
self.temp = bytearray(2)
# Add an extra byte to the data buffer to hold an I2C data/command byte
# to use hardware-compatible I2C transactions. A memoryview of the
# buffer is used to mask this byte from the framebuffer operations
# (without a major memory hit as memoryview doesn't copy to a separate
# buffer).
self.buffer = bytearray(((height // 8) * width) + 1)
self.buffer[0] = 0x40 # Set first byte of data buffer to Co=0, D/C=1
self.framebuf = framebuf.FrameBuffer1(memoryview(self.buffer)[1:], width, height)
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.temp[0] = 0x80 # Co=1, D/C#=0
self.temp[1] = cmd
self.i2c.writeto(self.addr, self.temp)
def write_framebuf(self):
# Blast out the frame buffer using a single I2C transaction to support
# hardware I2C interfaces.
self.i2c.writeto(self.addr, self.buffer)
def poweron(self):
pass
class SSD1306_SPI(SSD1306):
def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
self.rate = 10 * 1024 * 1024
dc.init(dc.OUT, value=0)
res.init(res.OUT, value=0)
cs.init(cs.OUT, value=1)
self.spi = spi
self.dc = dc
self.res = res
self.cs = cs
self.buffer = bytearray((height // 8) * width)
self.framebuf = framebuf.FrameBuffer1(self.buffer, width, height)
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs.high()
self.dc.low()
self.cs.low()
self.spi.write(bytearray([cmd]))
self.cs.high()
def write_framebuf(self):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs.high()
self.dc.high()
self.cs.low()
self.spi.write(self.buffer)
self.cs.high()
def poweron(self):
self.res.high()
time.sleep_ms(1)
self.res.low()
time.sleep_ms(10)
self.res.high()
hcsr04.py
Unggah file `hcsr04.py` ke papan Anda.
import machine, time
from machine import Pin
__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
main.py
Di dalam file `main.py` inilah kita akan mendapatkan jarak dan menampilkannya di layar OLED.
from machine import Pin, I2C
import ssd1306
from hcsr04 import HCSR04
from time import sleep
# ESP32 Pin assignment
i2c = I2C(scl=Pin(22), sda=Pin(21))
sensor = HCSR04(trigger_pin=5, echo_pin=18, echo_timeout_us=10000)
# ESP8266 Pin assignment
#i2c = I2C(scl=Pin(5), sda=Pin(4))
#sensor = HCSR04(trigger_pin=12, echo_pin=14, echo_timeout_us=10000)
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
while True:
oled.fill(0)
#oled.show()
distance = sensor.distance_mm()
print('Distance:', distance, 'mm')
oled.text("Distance (mm)", 0, 15)
oled.text(str(distance), 0, 35)
oled.show()
sleep(1)
Kode dimulai dengan mengimpor pustaka-pustaka yang diperlukan.
from machine import Pin, I2C
import ssd1306
from hcsr04 import HCSR04
from time import sleep
Atur pin untuk layar OLED dan sensor ultrasonik.
i2c = I2C(scl=Pin(5), sda=Pin(4))
sensor = HCSR04(trigger_pin=12, echo_pin=14, echo_timeout_us=10000)
Tentukan lebar (width) dan tinggi (height) OLED, lalu inisialisasi layar OLED.
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
Di dalam perulangan `while`-lah kita akan mendapatkan jarak dan menampilkannya di OLED.
Pertama, bersihkan layar pada setiap iterasi dengan `oled.fill(0)`.
oled.fill(0)
Dapatkan jarak dalam milimeter (mm) dan simpan dalam variabel `distance`.
distance = sensor.distance_mm()
Cetak jarak di konsol (shell).
print('Distance:', distance, 'mm')
Tampilkan jarak di layar. Perhatikan bahwa Anda perlu mengubah nilai jarak menjadi string menggunakan fungsi `str()`.
oled.text("Distance (mm)", 0, 15)
oled.text(str(distance), 0, 35)
Terakhir, panggil `oled.show()` untuk benar-benar menampilkan teks di layar.
oled.show()
Jarak akan diperbarui setiap detik.
sleep(1)
Demonstrasi
Unggah semua file sebelumnya ke papan ESP32 atau ESP8266 Anda dengan urutan berikut:
1. `ssd1306.py`
2. `hcsr04.py`
3. `main.py`
Setelah kode terunggah, program akan langsung berjalan dan menampilkan jarak dalam milimeter (mm) di layar OLED.
Siap Untuk Membuat Proyek Impianmu Menjadi Kenyataan?
Klik di sini untuk chat langsung via WhatsApp dan dapatkan dukungan langsung dari tim ahli kami!










.png)

%20button.png)





%20on%20OLED%20Display.png)





0 on: "Tutorial MicroPython ESP32/ESP8266 - Sensor Ultrasonik HC-SR04 untuk Pengukur Jarak"