آموزش HC-SR04 با ESP32 و آردوینو؛ مقایسه با VL53L0X
فاصلهسنج HC-SR04 با ESP32 و Arduino: اتصال ایمن Echo، کد timeout و فیلتر، رفع قرائت صفر، مقایسه با VL53L0X و خرید در ایران.
فاصلهسنجی • HC-SR04 • ESP32 / Arduino
فاصله را بخوانیم؛ خطا را با صفر اشتباه نگیریم
در این پروژه یک فاصلهسنج رومیزی میسازیم که علاوه بر عدد، معتبر بودن اندازهگیری را گزارش میکند. HC-SR04 برای یادگیری زمانسنجی و آزمایش فاصله تا یک هدف مناسب است؛ اما داشتن یک عدد در سریال، صحت اندازهگیری یا ایمنی سامانه را ثابت نمیکند. از اتصال امن Echo شروع میکنیم، زمان پالس را میخوانیم و سپس فیلتر ساده و مقایسه با VL53L0X را بررسی میکنیم.

۱. کاربرد و دلیل انتخاب برای بازار ایران
اندازهگیری روی میز، ثبت تغییر فاصله یک صفحه و تمرین تشخیص نزدیکشدن مانع، نقطه شروعهای خوبی هستند. در بررسی امروز، ECA این مدل را موجود نشان داد؛ تجربه دارای نشان خریدار درباره کار با ماژول و مشکل خواندن صفر در نبود بازتاب نیز دیده شد. این شواهد از استفاده عملی حکایت میکنند، نه آمار فروش یا تضمین مشتری. صفحه همان مدل در آفتاب رایانه هم بررسی شد، ولی ناموجود بود.
این آموزش مدار ایمنی خودرو، جلوگیری تضمینی از برخورد یا کنترل خودکار پمپ نیست. نخست فقط گزارش سریال را آزمایش کنید؛ یک قرائت نامعتبر نباید فرمان حرکت یا روشنشدن بار ایجاد کند.
۲. فاصله چگونه از زمان به دست میآید؟
در رابط معمول Trig/Echo، میکروکنترلر یک پالس تحریک میفرستد. ماژول موج صوتی ارسال میکند و مدت پالس Echo نماینده زمان رفتوبرگشت است. رابطه آموزشی ما d = t × c / 2 است؛ تقسیم بر دو مسیر برگشت را حذف میکند.
با فرض سرعت ۳۴۰ متر بر ثانیه، ضریب تبدیل برابر 0.034 cm/µs میشود. مثلاً پالس فرضی ۱۰۰۰ میکروثانیه، در همین مدل محاسباتی ۱۷ سانتیمتر میدهد. این مثال حسابی است، نه نتیجه آزمایش سختافزاری. ضریب ثابت، تغییر شرایط هوا را جبران نمیکند.
۳. مشخصات و روش خواندن دیتاشیت
| مورد | مرجع HC-SR04 معمولی | برداشت کاربردی |
|---|---|---|
| تغذیه | ۵ ولت DC | تغذیه و سطح منطقی Echo را جدا بررسی کنید. |
| پالس Trig | حداقل ۱۰ میکروثانیه HIGH | کد یک پالس ۱۰ میکروثانیهای درخواست میکند. |
| ارسال صوت | هشت سیکل با فرکانس ۴۰ کیلوهرتز | این عدد با فاصله زمانی دو اندازهگیری یکی نیست. |
| محدوده معرفیشده | ۲ تا ۴۰۰ سانتیمتر | بیرون این بازه در مثال معتبر حساب نمیشود؛ داخل بازه هم صحت تضمین نیست. |
| فاصله دو تحریک | بیش از ۶۰ میلیثانیه پیشنهاد شده | در برنامه ۱۰۰ میلیثانیه انتخاب کردهایم. |
منبع: دیتاشیت HC-SR04 با نام ELECFREAKS، میزبانیشده در SparkFun؛ همین فایل در بخش دانلود راهنمای رسمی Adafruit معرفی شده است. حدود مندرج در فایل به شرایط و هدف مناسب وابستهاند؛ عدد دقت تبلیغشده را تضمین همه بردهای بینام بازار ندانید.
اول نام و نسخه برد، سپس تغذیه، منطق ورودی/خروجی و نمودار زمانی را بخوانید. برخی بردهای جدید با ظاهر مشابه رابطهای اضافه دارند؛ این مقاله فقط رابط Trig/Echo سازگار با HC-SR04 معمولی را آموزش میدهد. وجود I2C، UART یا سازگاری مستقیم با ۳٫۳ ولت را از ظاهر حدس نزنید.
۴. قطعات مورد نیاز
- ماژول HC-SR04 با نسخه و برچسب پایههای مشخص، برد ESP32 کلاسیک یا Arduino Uno.
- منبع تنظیمشده ۵ ولت سازگار با ماژول، بردبورد و سیم کوتاه.
- برای ESP32: مقاومت ۱۰ کیلواهم و ۱۵ کیلواهم، ترجیحاً یک درصد، برای تقسیم ولتاژ Echo.
- خطکش و یک صفحه صاف نسبتاً بزرگ برای آزمون تکرارپذیر؛ مولتیمتر برای تغذیه و ترجیحاً اسیلوسکوپ برای سطح پالس.
اتصال برق را قبل از جابهجایی سیمها قطع کنید. اگر USB و منبع خارجی همزمان وصل میشوند، مسیر تغذیه برد توسعه را بررسی کنید تا دو منبع به یکدیگر متصل نشوند.
۵. سیمکشی امن به ESP32 و Uno
| پایه ماژول | ESP32 کلاسیک در مثال | Arduino Uno در مثال |
|---|---|---|
| VCC | ۵ ولت تنظیمشده، مطابق نسخه ماژول | |
| GND | زمین مشترک منبع، سنسور و میکروکنترلر | |
| Trig | GPIO26 | D9 |
| Echo | از تقسیم مقاومتی به GPIO27؛ اتصال مستقیم ممنوع | D10 برای Uno با منطق ۵ ولت |
Echo نسخه معمولی، خروجی با منطق ۵ ولت است. آن را مستقیم به ESP32 متصل نکنید. راهنمای پایههای Adafruit کاهش سطح Echo و پذیرش Trig با منطق ۳ یا ۵ ولت را برای نمونه خود توضیح میدهد. نمونه واقعی را کنترل کنید.
HC-SR04 Echo ---- 10k (1%) ----+---- GPIO27 (ESP32)
|
15k (1%)
|
GND
HC-SR04 GND ------------------+---- ESP32 GNDدر این تقسیم، مقاومت ۱۰ کیلواهم بین Echo و گره ورودی و مقاومت ۱۵ کیلواهم بین همان گره و زمین قرار دارد. برای Echo دقیقاً ۵ ولت، خروجی محاسبهشده 5 × 15 / (10 + 15) = 3.0 V است. این طراحی مثال است، نه تضمین سطح همه ماژولها. سطح واقعی HIGH، تلرانس مقاومت، تغذیه و لبههای پالس باید بررسی شوند.
در دیتاشیت ESP32، جدول DC Characteristics حداقل HIGH برابر 0.75 × VDD آمده؛ در ۳٫۳ ولت، ۲٫۴۷۵ ولت میشود. بنابراین صرف «کمتر از ۳٫۳ بودن» کافی نیست و ولتاژ باید از حد HIGH نیز بالاتر باشد. ولتاژ ۵ ولت ورودی مجاز فرض نمیشود. میانگین مولتیمتر روی پالس، جای اندازهگیری دامنه با اسیلوسکوپ نیست.
شماره GPIOها انتخاب این مثالاند؛ برای C3، S3 یا بردی با پایههای مصرفشده باید عوض شوند. مستندات GPIO را همراه نقشه برد بخوانید. ترتیب فیزیکی پایهها را از نامهای چاپشده روی برد مشخص کنید، نه از رنگ سیم.
۶. راهاندازی گامبهگام
- با تغذیه قطع، پایهها، زمین مشترک و تقسیم ولتاژ را کنترل کنید.
- برنامه خام فایل دانلودی را باز کنید و برد درست را انتخاب کنید. کتابخانه اضافی لازم نیست.
- Serial Monitor را روی ۱۱۵۲۰۰ قرار دهید. ابتدا فقط زمان Echo و پیام خطا را مشاهده کنید.
- یک صفحه صاف را روبهروی سنسور قرار دهید و در چند فاصله قابلاندازهگیری آزمایش کنید.
- هدف را بردارید یا زاویه آن را تغییر دهید؛ پیام نامعتبر باید از عدد فاصله جدا بماند.
- پس از تأیید سیگنال خام، برنامه اصلی با فیلتر را اجرا و دو خروجی خام و فیلترشده را مقایسه کنید.
مقادیر قبلی را هنگام خطا بهعنوان قرائت تازه نمایش ندهید. اگر با برداشتن هدف همچنان عدد دارید، ممکن است بازتاب جسم دیگری دریافت شده باشد؛ آزمایش محیط را تغییر دهید و علت را جدا کنید.
۷. کد عملی با timeout و فیلتر میانه
کد زیر هر ۱۰۰ میلیثانیه یک تلاش انجام میدهد. سه نمونه معتبر پیاپی برای فیلتر لازم است و هر خطا فیلتر را پاک میکند. این برنامه کاملاً غیرمسدودکننده نیست: pulseIn تا پایان پالس یا timeout منتظر میماند. برای کار همزمان حساس به زمان، باید ثبت لبه یا سختافزار زمانسنج جداگانه طراحی شود.
#include <Arduino.h>
#if defined(ARDUINO_ARCH_ESP32)
const uint8_t TRIG_PIN = 26, ECHO_PIN = 27; // Classic ESP32 only
#else
const uint8_t TRIG_PIN = 9, ECHO_PIN = 10; // Arduino Uno
#endif
const uint32_t PERIOD_MS = 100; // Application choice; >60 ms between triggers
const unsigned long TIMEOUT_US = 30000;
const float SOUND_CM_PER_US = 0.0340f; // 340 m/s approximation, not compensated
float windowCm[3];
uint8_t validCount = 0, nextSlot = 0;
uint32_t lastSample = 0;
bool nearState = false;
void invalidReading(const __FlashStringHelper *reason) {
validCount = nextSlot = 0;
nearState = false; // Internal reset; output is UNKNOWN, not CLEAR.
Serial.print(F("INVALID,")); Serial.println(reason);
}
float median3(float a, float b, float c) {
if (a > b) { float t = a; a = b; b = t; }
if (b > c) { float t = b; b = c; c = t; }
if (a > b) { float t = a; a = b; b = t; }
return b;
}
void setup() {
Serial.begin(115200);
pinMode(TRIG_PIN, OUTPUT);
digitalWrite(TRIG_PIN, LOW);
pinMode(ECHO_PIN, INPUT); // ESP32: external voltage divider is mandatory.
Serial.println(F("HC-SR04: invalid does NOT mean zero distance or clear path."));
}
void loop() {
uint32_t now = millis();
if ((uint32_t)(now - lastSample) < PERIOD_MS) { delay(1); return; }
lastSample = now;
if (digitalRead(ECHO_PIN) == HIGH) { invalidReading(F("ECHO_ALREADY_HIGH")); return; }
digitalWrite(TRIG_PIN, LOW); delayMicroseconds(3);
digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
unsigned long us = pulseIn(ECHO_PIN, HIGH, TIMEOUT_US);
if (us == 0) { invalidReading(F("NO_COMPLETE_ECHO")); return; }
float cm = us * SOUND_CM_PER_US / 2.0f;
if (cm < 2.0f || cm > 400.0f) { invalidReading(F("OUTSIDE_EXAMPLE_RANGE")); return; }
windowCm[nextSlot] = cm;
nextSlot = (nextSlot + 1) % 3;
if (validCount < 3) ++validCount;
Serial.print(F("echo_us=")); Serial.print(us);
Serial.print(F(",raw_cm=")); Serial.print(cm, 1);
if (validCount < 3) { Serial.println(F(",WARMING_FILTER")); return; }
float filtered = median3(windowCm[0], windowCm[1], windowCm[2]);
if (filtered < 30.0f) nearState = true;
else if (filtered > 35.0f) nearState = false;
Serial.print(F(",median_cm=")); Serial.print(filtered, 1);
Serial.println(nearState ? F(",NEAR") : F(",NOT_NEAR"));
// Educational indicator only: no safety, braking or automatic pump control.
}دانلود برنامه اصلی، برنامه خام و راهنمای اتصال. هر فایل ino را در پوشه همنام خودش قرار دهید. آزمون این بسته در حد کامپایل نرمافزاری است؛ روی سنسور فیزیکی آزمایش نشده است.
۸. تحلیل کد و معنی وضعیتها
ECHO_ALREADY_HIGH: پیش از تحریک، ورودی HIGH بوده است؛ بهجای تحریک دوباره، اندازهگیری نامعتبر گزارش میشود.NO_COMPLETE_ECHO: تابع صفر برگردانده است. این حالت، صفر سانتیمتر یا مسیر خالی نیست.OUTSIDE_EXAMPLE_RANGE: نتیجه تبدیل خارج بازه پذیرفتهشده مثال است.WARMING_FILTER: هنوز سه نمونه معتبر پیاپی نداریم؛ تصمیم فیلترشده منتشر نمیشود.NEARوNOT_NEAR: فقط نتیجه مقایسه آموزشیاند، نه تشخیص ایمن مانع.
طبق مستندات Arduino برای pulseIn، زمان پالس بر حسب میکروثانیه بازگردانده میشود و timeout بهصورت صریح قابل تنظیم است. ما ۳۰٬۰۰۰ میکروثانیه انتخاب کردهایم؛ این یک حد انتظار نرمافزاری است، نه مشخصه تضمینی سنسور.
فیلتر میانه از سه مقدار، مقدار وسط را انتخاب میکند و میتواند یک نمونه پرت منفرد را کماثر کند؛ خطای ثابت، هدف نامناسب و سیمبندی اشتباه را درمان نمیکند. آستانههای ۳۰ و ۳۵ سانتیمتر عمداً متفاوتاند تا در مرز تصمیم نوسان کمتری ایجاد شود. این فاصلهها انتخاب آموزشیاند و باید برای پروژه واقعی آزموده شوند. پس از خطا، خروجی معتبر قبلی حفظ نمیشود؛ برنامه دوباره سه نمونه معتبر میخواهد.
۹. آزمون دقت، تکرارپذیری و تأثیر دما
برای یک آزمون پیشنهادی، در فاصلههای ۲۰، ۵۰ و ۱۰۰ سانتیمتر از یک مبنای ثابت، در هر نقطه ۱۰ قرائت ثبت کنید. عدد مرجع، حداقل، حداکثر و تعداد خطاها را کنار هم بنویسید. این فاصلهها و تعداد تکرار، برنامه آزمایش پیشنهادیاند؛ هیچ نتیجهای از پیش برای آنها ادعا نمیکنیم.
اگر همه اعداد نزدیک هم ولی دور از مرجعاند، تکرارپذیری خوب لزوماً به معنی دقت خوب نیست. خطای مبدا، هندسه نصب و ضریب تبدیل را بررسی کنید. در مقابل، پراکندگی زیاد با عوضشدن زاویه هدف را با یک ضریب کالیبراسیون ثابت پنهان نکنید.
سرعت صوت با دما تغییر میکند. راهنمای Adafruit درباره سرعت صوت نمونه جبران وابسته به دما دارد. کد فعلی عمداً با فرض ثابت ۳۴۰ متر بر ثانیه کار میکند؛ اگر دقت بیشتری لازم است، ابتدا دمای نماینده مسیر صوت را بسنجید و روش جبران را جدا اعتبارسنجی کنید. برای شروع خواندن دما، آموزش DS18B20 در دسترس است.
۱۰. خطاهای رایج و عیبیابی
| نشانه | بررسی عملی |
|---|---|
| همیشه نامعتبر | زمین مشترک، پایههای Trig/Echo، سطح ورودی بعد از تقسیم و هدف آزمایش را کنترل کنید. |
| فاصله با برداشتن هدف صفر میشود | کدی که صفر تابع را به فاصله تبدیل میکند اصلاح کنید؛ صفر تابع یعنی قرائت معتبر نداریم. |
| عدد با تغییر زاویه میپرد | آزمون را با هدف صاف و روبهرو تکرار کنید؛ بازتاب جانبی را بررسی کنید. |
| با اضافهشدن موتور رفتار عوض میشود | نخست موتور را از آزمایش حذف و تغذیه و زمین را بررسی کنید؛ متوسطگیری جای رفع علت نیست. |
| چند سنسور نتیجه نامطمئن میدهند | تنها یکی را فعال کنید و سپس زمانبندی نوبتی را با آزمون واقعی توسعه دهید. |
| Echo از ابتدا HIGH است | سیمبندی و نسخه برد را کنترل کنید؛ در صورت نیاز، با قطع امن تغذیه آزمون را از نو شروع کنید. |
برای دیدن پالس Trig و Echo از اسیلوسکوپ یا ورودی تحلیلگر منطقیِ سازگار با همان سطح ولتاژ استفاده کنید. واردکردن ۵ ولت به ورودی ابزار ۳٫۳ ولتی هم مجاز فرض نمیشود.
۱۱. HC-SR04 یا VL53L0X؟
| معیار | HC-SR04 معمولی | VL53L0X |
|---|---|---|
| اصل سنجش | رفتوبرگشت صوت | زمان پرواز نور؛ فرستنده ۹۴۰ نانومتر |
| رابط این مقایسه | Trig/Echo و زمانسنجی پالس | I2C و خواندن نتیجه پردازششده |
| نکته اتصال | برای ESP32 سطح Echo باید سازگار شود. | تغذیه و مبدل سطح روی برد واسط بررسی شود؛ تراشه خام با ماژول یکی نیست. |
| روش تصمیم | با هدف و محیط واقعی خودتان بیازمایید. | برای همان هدف، نتیجه و وضعیت خطا را کنار آزمایش اول بگذارید. |
مرجع ویژگیهای VL53L0X، صفحه رسمی ST است. برای سیمکشی و کد آن، آموزش مستقل VL53L0X را ببینید. صرف مقایسه حداکثر برد اسمی، برنده همه کاربردها را تعیین نمیکند. ابتدا اندازه هدف، محیط، فاصله مورد نیاز و رفتار هنگام خطا را مشخص کنید.
۱۲. نکات طراحی و توسعه
برد را محکم نصب کنید و جلوی دو مبدل را نپوشانید. شکل هدف و محل نصب باید بخشی از برنامه آزمون باشند. برد معمولی را برای زیر آب یا محیط خیس مناسب فرض نکنید؛ برای سطح مخزن، حفاظت محیطی و محدودیت کاربرد باید جداگانه تأیید شود. در پروژه چندحسگری، تداخل را با فعالکردن نوبتی و ثبت نتایج بررسی کنید، نه با فرض اینکه همه پالسها مستقلاند.
اگر گزارش را با BLE میفرستید، علاوه بر فاصله، معتبر بودن و زمان آخرین اندازهگیری را نیز ارسال کنید؛ آموزش پروژههای مقدماتی BLE شروع مناسبی است. برای تشخیص صرف حرکت، PIR مسئله متفاوتی را حل میکند و خروجی آن جای فاصله نیست.
۱۳. خرید در ایران؛ بررسی ۱۹ شهریور ۱۴۰۵
وضعیت زیر در ۱۰ سپتامبر ۲۰۲۶ / ۱۹ شهریور ۱۴۰۵ بررسی شد و تضمین موجودی آینده نیست. قیمت ثابت درج نمیکنیم. هر دو لینک به صفحه HC-SR04 هستند؛ نسخه دقیق برد ارسالی را پیش از سفارش تأیید کنید.
- خرید HC-SR04 از ECA — کد 3011009001
هنگام بررسی: موجود در انبار و قابل افزودن به سبد خرید. پرسشها و تجربههای دارای نشان خریدار، شاهد استفاده عملیاند؛ آمار فروش از آنها استخراج نکردهایم.
- صفحه HC-SR04 در آفتاب رایانه — کد 104-82-1047
هنگام بررسی: ناموجود. برای پیگیری همان مدل معرفی شده، نه خرید فوری کالای موجود.
در بازار، چینش قطعات پشت برد و قابلیتهای نسخهها تغییر میکند. نام HC-SR04 بهتنهایی تضمین نمیکند تصویر، ولتاژ یا رابطهای اضافی تمام فروشندگان یکسان باشد. لینک US-100، SRF05 یا مدل ضدآب را به جای این محصول معرفی نکردهایم. منابع فروشگاهی فقط برای وضعیت خرید و شواهد بازار استفاده شدهاند.
۱۴. پرسشهای متداول
آیا Echo را مستقیم به ESP32 وصل کنم؟
برای HC-SR04 معمولی خیر؛ Echo با منطق ۵ ولت است و باید با تقسیم ولتاژ یا مبدل مناسب به سطح سازگار تبدیل شود.
آیا صفر شدن pulseIn یعنی فاصله صفر است؟
خیر. در این برنامه صفر تابع یعنی پالس کامل در زمان انتظار دریافت نشده و قرائت نامعتبر است، نه فاصله صفر یا مسیر خالی.
آیا کد کاملاً غیرمسدودکننده است؟
خیر. برنامه فاصله زمانی نمونهها را کنترل میکند، اما pulseIn هنگام انتظار برای پالس میتواند اجرای حلقه را تا timeout متوقف کند.
آیا فیلتر میانه دقت قطعی ایجاد میکند؟
خیر. فیلتر میتواند اثر یک نمونه پرت را کاهش دهد، ولی خطای ثابت، هندسه نامناسب و اتصال اشتباه را اصلاح نمیکند.
آیا HC-SR04 همیشه از VL53L0X بهتر است؟
خیر. اصل سنجش و رابط این دو متفاوت است؛ انتخاب باید با هدف، محیط و آزمون خطاهای پروژه انجام شود، نه فقط حداکثر برد اسمی.
۱۵. جمعبندی و منابع اصلی
فاصلهسنج مفید فقط عدد تولید نمیکند؛ باید هنگام نبود داده معتبر هم رفتار روشنی داشته باشد. ابتدا سطح Echo و زمان خام را بررسی کنید، سپس فیلتر و تصمیمگیری را اضافه کنید. در مسیر فاصله و سطح و راهنمای سنسورها میتوانید موضوعهای مرتبط را ادامه دهید.
- دیتاشیت اصلی HC-SR04 با نام ELECFREAKS: مشخصات و نمودار زمانی.
- راهنمای رسمی Adafruit: تفکیک نسخهها و اتصال.
- دیتاشیت ESP32 و GPIO API: سطح منطقی و پایهها.
- Arduino pulseIn: واحد و timeout.
- Adafruit: سرعت صوت: ضرورت توجه به دما.
- ST VL53L0X: مبنای مقایسه فناوری.
متن و مثال آموزشی: LCENJ. کد برای کامپایل روی ESP32 کلاسیک و Arduino Uno بررسی میشود؛ آزمایش سختافزاری انجام نشده و نتیجه اندازهگیری واقعی ادعا نشده است.
برای یک مسیر منظم از مبانی تا انتخاب و آزمون حسگر، دوره سنسورها در ۷ قدم را دنبال کنید.
پرسش و پاسخ مقاله
سوال فنی خود را مطرح کنید
پرسشها و پاسخها پس از بررسی مدیر منتشر میشوند. نویسنده، پیشنویس در انتظار بررسی را میبیند.
هنوز پرسش تاییدشدهای برای این مقاله ثبت نشده است.