📏 سنسور اولتراسونیک HC-SR04 با میکروپایتون روی رزبری پای پیکو (time_pulse_us)

✍️ تیم ووکوی فارسی ·

سنسور اولتراسونیک HC-SR04 مثل خفاش کار می‌کند: یک صدای خیلی زیر (۴۰ کیلوهرتز، بالاتر از شنوایی ما) می‌فرستد و از روی زمان برگشت پژواک، فاصله را حساب می‌کند. این سنسور در ربات مسیریاب، سنسور پارک، سطل زباله‌ی هوشمند و اندازه‌گیری ارتفاع آب مخزن به کار می‌رود. در این آموزش آن را با میکروپایتون روی رزبری پای پیکو راه می‌اندازیم: پالس تریگر می‌فرستیم، طول پالس Echo را با time_pulse_us اندازه می‌گیریم، به سانتی‌متر تبدیل می‌کنیم و با یک فیلتر میانه خوانش‌های پرت را حذف می‌کنیم.

HC-SR04 چطور کار می‌کند؟

  1. برد یک پالس ۱۰ میکروثانیه‌ای به پایه‌ی TRIG می‌دهد.
  2. سنسور هشت موج صوتی ۴۰ کیلوهرتزی می‌فرستد و پایه‌ی ECHO را بالا (HIGH) می‌کند.
  3. وقتی پژواک برمی‌گردد، ECHO پایین می‌آید. طول زمانی که ECHO بالا بوده همان زمان رفت و برگشت صداست.

سرعت صوت در هوای ۲۰ درجه حدود ۳۴۳ متر بر ثانیه است، یعنی ۰٫۰۳۴۳ سانتی‌متر در هر میکروثانیه. چون صدا رفته و برگشته، فاصله نصف مسیر است:

فاصله (سانتی‌متر) = زمان (میکروثانیه) × ۰٫۰۳۴۳ ÷ ۲ — یا تقریباً زمان تقسیم بر ۵۸.

بازه‌ی کاری سنسور از حدود ۲ سانتی‌متر تا ۴ متر است. تعریف کوتاه‌تر را در سنسور اولتراسونیک در واژه‌نامه ببین.

قطعه‌ها

سیم‌کشی و مسئله‌ی ۵ ولت

HC-SR04 معمولی با ۵ ولت کار می‌کند و پایه‌ی ECHO آن هم ۵ ولت بیرون می‌دهد. پایه‌های پیکو ۳٫۳ ولتی‌اند، پس Echo را با یک تقسیم ولتاژ پایین می‌آوریم: ۵ × ۲ ÷ (۱ + ۲) ≈ ۳٫۳ ولت.

پایه‌ی سنسوراتصال
VCCVBUS پیکو (پایه‌ی فیزیکی ۴۰، پنج ولت USB)
GNDGND پیکو
TRIGمستقیم به GP15 (پایه‌ی فیزیکی ۲۰)
ECHOبه مقاومت ۱ کیلو؛ سر دیگر آن به GP14 (پایه‌ی ۱۹)
نقطه‌ی GP14از راه مقاومت ۲ کیلو به GND

برای حساب مقاومت‌های دیگر ماشین‌حساب تقسیم ولتاژ را ببین. اگر مدل HC-SR04P یا RCWL-1601 داری که با ۳٫۳ ولت هم کار می‌کند، VCC را به 3V3(OUT) بزن و تقسیم ولتاژ لازم نیست.

کد کامل میکروپایتون

from machine import Pin, time_pulse_us
import time

trig = Pin(15, Pin.OUT)
echo = Pin(14, Pin.IN)
led = Pin("LED", Pin.OUT)          # on-board LED as a "too close" warning

SOUND_CM_PER_US = 0.0343           # speed of sound at about 20 C
TIMEOUT_US = 30000                 # 30 ms, about 5 m round trip

def distance_cm():
    trig.value(0)
    time.sleep_us(2)
    trig.value(1)
    time.sleep_us(10)              # the 10 us trigger pulse
    trig.value(0)
    duration = time_pulse_us(echo, 1, TIMEOUT_US)
    if duration < 0:               # -1 or -2: timeout, nothing measured
        return None
    return duration * SOUND_CM_PER_US / 2

def median_distance(n=5):
    values = []
    for i in range(n):
        d = distance_cm()
        if d is not None:
            values.append(d)
        time.sleep_ms(60)          # let old echoes die out
    if not values:
        return None
    values.sort()
    return values[len(values) // 2]

while True:
    d = median_distance()
    if d is None:
        print("out of range")
        led.off()
    else:
        print(f"distance: {d:.1f} cm")
        led.value(d < 20)          # LED on when closer than 20 cm
    time.sleep_ms(100)

توضیح خط به خط

برای دقت بیشتر، دما را هم حساب کن: سرعت صوت تقریباً ۳۳۱٫۳ + ۰٫۶۰۶ × دما (متر بر ثانیه) است. در یک اتاق ۳۵ درجه‌ی تابستانی خطای فاصله بدون این اصلاح حدود ۳ درصد است. با یک سنسور DHT می‌توانی این اصلاح را خودکار کنی؛ DHT با میکروپایتون را ببین.

اجرا در شبیه‌ساز: صادقانه

پیکوی شبیه‌ساز تینکرکد فارسی تابع time_pulse_us را ندارد، پس خواندن خود HC-SR04 با میکروپایتون را روی برد واقعی امتحان کن. دو راه برای تمرین بدون برد داری:

from machine import Pin, ADC
import time

knob = ADC(26)                 # stands in for the sensor while practising
led = Pin("LED", Pin.OUT)

def distance_cm():
    # 0..65535 from the knob -> 2..400 cm, like the real sensor's range
    return 2 + knob.read_u16() * 398 / 65535

while True:
    d = distance_cm()
    print(f"distance: {d:.1f} cm")
    led.value(d < 20)
    time.sleep_ms(200)

وقتی برد واقعی رسید، فقط تابع distance_cm را با نسخه‌ی time_pulse_us عوض کن؛ بقیه‌ی برنامه دست نمی‌خورد.

اشکال‌های رایج

ایده‌های بعدی: سنسور را روی یک سروو بگذار و یک رادار بساز، یا با بازر یک سنسور دنده‌عقب درست کن. نسخه‌ی کامل یک پروژه‌ی واقعی با اولتراسونیک را در پارکینگ هوشمند با آردوینو ببین. برای پیدا کردن پایه‌ها پین اوت رزبری پای پیکو و برای همه‌ی امکانات برد صفحه‌ی رزبری پای پیکو را ببین.

فاصله‌سنج اولتراسونیک را رایگان امتحان کن 📏

سؤال‌های رایج

آیا HC-SR04 را می‌شود مستقیم به پیکو وصل کرد؟

TRIG را بله، چون ۳٫۳ ولت پیکو برای تریگر کافی است. ولی خروجی ECHO در مدل معمولی ۵ ولت است و پایه‌ی ۳٫۳ ولتی پیکو را تهدید می‌کند. با دو مقاومت ۱ و ۲ کیلواهم ولتاژ Echo را به حدود ۳٫۳ ولت برسان، یا مدل HC-SR04P را بگیر که با ۳٫۳ ولت کار می‌کند.

time_pulse_us چه عددی برمی‌گرداند؟

طول پالس بر حسب میکروثانیه. اگر تا پایان زمان timeout پالسی شروع نشود ۲- و اگر پالس شروع شود ولی تمام نشود ۱- برمی‌گرداند. پس هر عدد منفی یعنی «چیزی اندازه گرفته نشد».

این کد در شبیه‌ساز اجرا می‌شود؟

پیکوی شبیه‌ساز تینکرکد فارسی تابع time_pulse_us را ندارد، پس خواندن خود HC-SR04 با میکروپایتون را روی برد واقعی امتحان کن. مثال آماده‌ی فاصله‌سنج با آردوینو در شبیه‌ساز رایگان است، و بقیه‌ی منطق برنامه را می‌توانی روی پیکوی مجازی با یک پتانسیومتر به جای سنسور تمرین کنی.

مقاله‌های مرتبط

📟

راه‌اندازی LCD I2C با میکروپایتون روی رزبری پای پیکو (درایور i2c_lcd)

🌡️

سنسور دما و رطوبت DHT11 و DHT22 با میکروپایتون روی رزبری پای پیکو

⏱️

Timer در میکروپایتون: چند کار هم‌زمان روی رزبری پای پیکو بدون sleep

☀️

سنسور نور LDR (فتوسل) با آردوینو: مقسم ولتاژ، کد کامل و چراغ خواب خودکار

همه‌ی آموزش‌های رزبری پای پیکو و میکروپایتون ← · همه‌ی مقاله‌ها