تشخیص حرکت • HC-SR501 • ESP32 / Arduino

یک آشکارساز حرکت بسازیم، نه شمارنده انسان

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

تمرکز آموزش روی راه‌اندازی مطمئن، تفاوت جامپر H و L و پیدا کردن علت تحریک کاذب است. مدار آزمایشی فقط با ولتاژ پایین DC کار می‌کند و جایگزین سامانه حفاظتی تأییدشده نیست.

نمای واقعی پشت برد PIR با تراشه BISS0001، دو پتانسیومتر زمان و حساسیت و جامپر تحریک مجدد
عکس واقعی یک برد PIR مستند در راهنمای Adafruit؛ جای پایه‌ها و محدوده تغذیه نوشته‌شده روی این نمونه را به تمام HC-SR501های بازار تعمیم ندهید. تصویر: lady ada / Adafruit با مجوز CC BY-SA 3.0؛ تغییر اندازه متناسب، حاشیه سفید و تبدیل WebP، بدون برش یا تغییر برچسب‌ها. تصویر مشتق با همین مجوز ارائه می‌شود.

۱. چرا HC-SR501 موضوع کاربردی بازار ایران است؟

اعلان حرکت در میز آزمایش، روشن‌کردن نشانگر هنگام عبور و ثبت زمان فعالیت، کاربردهای مناسبی برای شروع هستند. در بررسی امروز، ECA همین ماژول را موجود نشان داد و پرسش‌های دارای نشان خریدار درباره نصب و پایه‌ها داشت. آفتاب رایانه نیز صفحه همین مدل را دارد، هرچند هنگام بررسی ناموجود بود. این شواهد نشان‌دهنده استفاده عملی و عرضه شناخته‌شده‌اند، نه آمار فروش یا تضمین مشتری.

برای شروع، نیاز را دقیق بنویسید: «پس از فعال‌شدن خروجی، LED چند ثانیه روشن بماند» قابل آزمون است؛ «هر انسان همیشه تشخیص داده شود» با یک ماژول ساده قابل تضمین نیست. مسیر موضوعی حرکت و موقعیت را برای انتخاب حسگر متناسب با مسئله ببینید.

۲. PIR چگونه حرکت را حس می‌کند؟

PIR مخفف مادون قرمز غیرفعال است؛ برخلاف یک فرستنده مادون قرمز، برای تشخیص، نور به هدف نمی‌تاباند. عنصر پیروالکتریک به تغییر تابش حرارتی پاسخ می‌دهد و لنز فرسنل ناحیه دید را به بخش‌هایی تقسیم می‌کند. حرکت یک منبع گرم میان این نواحی می‌تواند خروجی مدار را فعال کند.

بنابراین این ماژول دوربین، فاصله‌سنج یا دماسنج نیست. از یک خروجی صفر و یک نمی‌توان تعداد افراد، هویت، فاصله دقیق یا جهت حرکت را استخراج کرد. توضیح سازوکار در راهنمای اصلی Adafruit آمده است.

۳. دیتاشیت قطعه را از مشخصات ماژول جدا بخوانید

نام HC-SR501 روی بردهای متعددی دیده می‌شود؛ کیفیت قطعات، مدار زمان‌بندی و حتی آرایش پایه‌های نمونه‌ها ممکن است فرق کند. اطلاعات تراشه BISS0001 به‌تنهایی محدوده مجاز تغذیه کل برد را تعیین نمی‌کند. برای سیم‌بندی باید سند ماژول واقعی و نوشته‌های همان برد را کنار هم بگذارید.

پارامترمرجع مستندبرداشت درست
تغذیه نسخه Joy-IT SEN-HC-SR501۵ ولت DCدر مثال از منبع تنظیم‌شده ۵ ولت و ماژول سازگار استفاده می‌کنیم.
منطق خروجی نسخه Joy-IT۳ ولت در صفحه سازندهولتاژ تغذیه ماژول با سطح OUT یکسان نیست؛ نمونه واقعی را بررسی کنید.
محدوده دید اعلامی همان نسخهبرد حداکثر ۷ متر، زاویه کمتر از ۱۲۰ درجهاین حدود معرفی محصول‌اند، نه تضمین پوشش همه اتاق‌ها.
تنظیم‌هاحساسیت، زمان نگه‌داری و تحریک تکی/تکراریتنظیم زمان سخت‌افزار را با تأخیر برنامه اشتباه نگیرید.

مرجع: صفحه رسمی Joy-IT و راهنمای سازنده، نسخه ۱۶ آوریل ۲۰۲۴. این مقادیر به نسخه مستند تعلق دارند؛ فروشگاه‌های پایین مقاله لزوماً همین برند را نمی‌فروشند.

۴. تشخیص حرکت با تشخیص حضور ثابت فرق دارد

یک نفر ممکن است داخل اتاق بی‌حرکت بماند و خروجی PIR پایین بیاید. حیوان، تغییر سریع شرایط حرارتی یا قرارگیری نامناسب هم می‌تواند نتیجه را عوض کند. پشت شیشه معمولی، برای دیدن انسان به این روش تکیه نکنید. اختلاف دمای کم بین هدف و پس‌زمینه نیز می‌تواند تشخیص را دشوارتر کند.

این‌ها محدودیت‌های عمومی فناوری PIR هستند، نه مشخصات اختصاصی برند خاص. پرسش‌های فنی Panasonic اثر شیشه، دمای محیط و شرایط نصب را توضیح می‌دهد. برای حضور ثابت یا شمارش عبور، معماری و حسگر مناسب دیگری لازم است.

۵. قطعات لازم برای آزمایش کم‌خطر

در این مثال فقط LED کم‌مصرف راه‌اندازی می‌شود. سیم‌کشی برق شهر، رله قدرت، موتور یا لامپ را به OUT سنسور یا GPIO وصل نکنید. برای بار واقعی، درایور و حفاظت متناسب با بار لازم است و طراحی آن مرحله جداگانه‌ای است.

پایه ۵V بعضی بردهای توسعه ورودی است و بعضی هنگام USB خروجی تغذیه دارد؛ قبل از اتصال منبع خارجی و USB هم‌زمان، مستندات برد خودتان را ببینید تا دو منبع را ناخواسته به هم متصل نکنید.

۶. سیم‌کشی HC-SR501 به ESP32 و Uno

اتصالESP32 کلاسیک در مثالArduino Uno در مثالنکته
VCC ماژول۵ ولت تنظیم‌شده، فقط برای ماژول سازگاراز ظاهر مشابه برد، محدوده ولتاژ را حدس نزنید.
GND ماژولGNDGNDزمین منبع و میکروکنترلر مشترک باشد.
OUT ماژولGPIO27D2برای ESP32 فقط خروجی با سطح سازگار با ۳٫۳ ولت.
پول‌داون ورودیمقاومت ۱۰۰ کیلو‌اهم از ورودی PIR به GNDهنگام جداشدن سیم، ورودی کمتر شناور می‌ماند؛ تشخیص خرابی قطعی نیست.
LED خارجیGPIO26 → مقاومت سری → آند LEDD8 → مقاومت سری → آند LEDکاتد LED به GND؛ مقاومت سری ۱ کیلو‌اهم.

شماره پایه‌ها انتخاب این مثال است. آن‌ها را برای ESP32-C3، ESP32-S3 یا بردی که این پایه‌ها را مصرف کرده، بدون بررسی کپی نکنید. راهنمای GPIO رسمی Espressif نیز روی محدودیت پایه‌ها و بررسی نقشه برد تأکید دارد.

OUT را ابتدا بدون اتصال به ESP32، نسبت به GND اندازه بگیرید و مشخصات نسخه را کنترل کنید. خروجی ۵ ولتی یا پول‌آپ به ۵ ولت برای ESP32 مجاز فرض نمی‌شود. ترتیب چپ و راست پایه‌ها را از روی عکس اینترنتی یا رنگ کابل تعیین نکنید.

۷. جامپر H و L، حساسیت و زمان چه می‌کنند؟

در بردهایی با برچسب H/L مطابق راهنمای Adafruit، حالت H امکان تحریک مجدد را می‌دهد: حرکت تازه می‌تواند فعال‌ماندن خروجی را تمدید کند. در حالت L، رفتار غیرقابل تحریک مجدد انتخاب می‌شود؛ طول پالس و فاصله بین پالس‌ها را مدار تعیین می‌کند. پس یک HIGH طولانی لزوماً به معنی خرابی یا چند نفر نیست.

پتانسیومتر TIME مدت نگه‌داری خروجی را تغییر می‌دهد؛ پتانسیومتر حساسیت روی میزان پاسخ‌گویی اثر می‌گذارد. جهت چرخش را از سند همان برد بگیرید: حتی راهنماهای نمونه‌های مختلف در این جزئیات یکسان نیستند. برد را خاموش کنید، تغییر کوچک بدهید و با همان سناریوی عبور دوباره آزمایش کنید.

برای شروع، زمان سخت‌افزاری کوتاه و حساسیت متوسط انتخاب کنید؛ این‌ها نقطه شروع آزمایش‌اند، نه تنظیم بهینه همگانی. شرح دو حالت در آزمایش PIR در Adafruit آمده است.

۸. راه‌اندازی گام‌به‌گام

  1. با تغذیه قطع، نام پایه‌ها و اتصال زمین و LED را کنترل کنید.
  2. برنامه تشخیص خام را اجرا کنید؛ Serial Monitor روی ۱۱۵۲۰۰ باشد.
  3. پس از روشن‌شدن، زمان نشست سنسور را رعایت کنید. راهنمای Adafruit برای نمونه خود انتظار حدود ۳۰ تا ۶۰ ثانیه را توصیه می‌کند؛ عدد دقیق به نسخه و شرایط بستگی دارد.
  4. با محیط آرام، خروجی پایین را مشاهده کنید؛ سپس از عرض ناحیه دید عبور کنید و تغییر خروجی را ثبت کنید.
  5. برنامه اصلی را بارگذاری کنید. این برنامه ۶۰ ثانیه نخست را نادیده می‌گیرد و بعد برای مسلح‌شدن به یک ثانیه LOW پیوسته نیاز دارد.
  6. جامپر و زمان سخت‌افزاری را عوض کنید و تفاوت سیگنال خام و LED نهایی را بسنجید.

اعداد ۶۰ ثانیه و یک ثانیه در برنامه انتخاب طراحی آموزشی‌اند؛ اگر ماژول پس از این مدت پایدار نشده، مشکل را با حذف انتظار پنهان نکنید. در حالت H و با حرکت مداوم، منتظر ماندن برنامه برای LOW طبیعی است.

۹. کد عملی با زمان‌بندی غیرمسدودکننده

کتابخانه اضافی لازم نیست. هر مثال را در پوشه هم‌نام فایل ino خودش قرار دهید. کد اصلی رویدادهای سیگنال را ثبت می‌کند، یک تأیید نرم‌افزاری کوتاه دارد و LED را پس از پایین‌آمدن سیگنال نیز مدتی روشن نگه می‌دارد.

#include <Arduino.h>

#if defined(ARDUINO_ARCH_ESP32)
const uint8_t PIR_PIN = 27, LED_PIN = 26; // classic ESP32; check your board
#else
const uint8_t PIR_PIN = 2, LED_PIN = 8;   // Arduino Uno
#endif

// Application choices, NOT guaranteed sensor specifications.
const uint32_t WARMUP_MS = 60000;
const uint32_t ARM_LOW_MS = 1000;
const uint32_t FILTER_MS = 50;
const uint32_t HOLD_MS = 5000;

enum Phase { WARMUP, WAIT_LOW, ARMED };
Phase phase = WARMUP;
uint32_t bootAt, lowSince, rawChangedAt, lastHighAt;
uint32_t eventCount = 0;
bool timingLow = false, rawState = false, stableState = false;
bool haveActivity = false, ledOn = false;

void setup() {
  Serial.begin(115200);
  pinMode(PIR_PIN, INPUT); // External 100k pulldown to GND, no 5V pullup.
  digitalWrite(LED_PIN, LOW);
  pinMode(LED_PIN, OUTPUT);
  bootAt = millis();
  Serial.println(F("Warmup 60 s: output ignored, LED off."));
}

void loop() {
  uint32_t now = millis();
  bool sample = digitalRead(PIR_PIN) == HIGH;

  if (phase == WARMUP) {
    if ((uint32_t)(now - bootAt) >= WARMUP_MS) {
      phase = WAIT_LOW;
      Serial.println(F("Waiting for 1 s of LOW; leave detection area."));
    }
  } else if (phase == WAIT_LOW) {
    if (sample) timingLow = false;
    else {
      if (!timingLow) { timingLow = true; lowSince = now; }
      if ((uint32_t)(now - lowSince) >= ARM_LOW_MS) {
        phase = ARMED;
        rawState = stableState = false;
        rawChangedAt = now;
        Serial.println(F("ARMED: monitoring PIR signal, not counting people."));
      }
    }
  } else {
    if (sample != rawState) {
      rawState = sample;
      rawChangedAt = now;
    }
    if (rawState != stableState &&
        (uint32_t)(now - rawChangedAt) >= FILTER_MS) {
      stableState = rawState;
      if (stableState) {
        haveActivity = true;
        ++eventCount;
        Serial.print(F("PIR_HIGH event=")); Serial.println(eventCount);
      } else Serial.println(F("PIR_LOW: no active signal; NOT proof of empty room."));
    }
    if (stableState) lastHighAt = now;
    bool nextLed = haveActivity &&
                   (stableState || (uint32_t)(now - lastHighAt) < HOLD_MS);
    if (nextLed != ledOn) {
      ledOn = nextLed;
      digitalWrite(LED_PIN, ledOn ? HIGH : LOW);
      Serial.println(ledOn ? F("LED_ON") : F("LED_OFF"));
    }
    // Clear activity after the tail; prevents rollover from reviving an old event.
    if (!nextLed && !stableState) haveActivity = false;
  }
  delay(1); // Cooperative yield, not the warmup or hold timer.
}

دانلود برنامه اصلی، تشخیص خام و راهنمای اتصال. کدها برای Arduino Uno و ESP32 کلاسیک کامپایل شده‌اند؛ آزمون روی سنسور فیزیکی انجام نشده است. نمایش رویداد در سریال به‌تنهایی صحت نصب نهایی را ثابت نمی‌کند.

۱۰. تحلیل کد؛ سه زمان متفاوت را قاطی نکنید

در هر دور، تفاضل بدون علامت زمان جاری و زمان ثبت‌شده بررسی می‌شود. بنابراین لازم نیست با یک تأخیر چندثانیه‌ای کل حلقه را متوقف کنیم. delay(1) فقط مکث بسیار کوتاه حلقه است. این الگو با ایده Blink Without Delay در Arduino سازگار است.

شمارنده eventCount تعداد لبه‌های تأییدشده سیگنال را می‌شمارد، نه تعداد افراد. پیام PIR_LOW نیز عمداً به معنی خالی‌بودن اتاق تعبیر نشده است.

۱۱. برنامه آزمون قابل تکرار

آزمایشچه چیزی ثبت شود؟چه نتیجه‌ای نباید گرفت؟
محیط بدون حرکت پس از روشن‌شدنمدت ناپایداری و زمان رسیدن به LOWیک پالس شروع کار، اثبات حضور شخص نیست.
چند عبور مشابه از عرض محدودهتعداد تشخیص موفق در تعداد آزمون مشخصموفقیت چند بار، تضمین پوشش دائمی نیست.
ایستادن بی‌حرکت پس از عبورزمان افت OUT و خاموش‌شدن LEDخاموش‌شدن به معنی نبود شخص نیست.
H و L با TIME یکسانشکل و مدت پالس در برنامه خامهر پالس را یک عبور مستقل حساب نکنید.
فعال‌شدن مصرف‌کننده دیگر در مدارهم‌زمانی تحریک ناخواسته با افت تغذیه یا سوئیچینگبا افزایش تأخیر، علت الکتریکی را حل‌شده ندانید.

برنامه خام، زمان از شروع و وضعیت ورودی را هر ۱۰۰ میلی‌ثانیه چاپ می‌کند. این نرخ برای مشاهده آموزشی پالس‌ها انتخاب شده و جای اسیلوسکوپ برای دیدن پالس‌های خیلی کوتاه را نمی‌گیرد.

۱۲. عیب‌یابی تحریک کاذب یا خروجی ثابت

نشانهبررسی پیشنهادی
همیشه صفرVCC/GND/OUT، پایه انتخاب‌شده، تغذیه و خروجی خام را کنترل کنید؛ فقط LED ملاک نباشد.
همیشه یکTIME طولانی، حالت H، حرکت مداوم، سیم‌بندی و سطح واقعی OUT را بررسی کنید.
در WAIT_LOW می‌مانداز محدوده خارج شوید و زمان پالس سخت‌افزار را صبر کنید؛ این انتظار برای جلوگیری از پذیرش HIGH اولیه است.
با روشن‌شدن بار، تحریک می‌شودمسیر تغذیه و زمین، سیم بلند و نزدیکی به مسیر سوئیچینگ را جداگانه بررسی کنید.
فرد نشسته را از دست می‌دهدمحدودیت تشخیص تغییر حرارتی را در نظر بگیرید؛ صرف افزایش حساسیت، حسگر حضور دقیق نمی‌سازد.
LED دیر خاموش می‌شودمدت HIGH سخت‌افزار و پنج ثانیه نگه‌داری برنامه هر دو مؤثرند.

۱۳. نکات نصب و توسعه پروژه

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

برای روشنایی وابسته به تاریکی، می‌توانید شرط نور محیط را با BH1750 اضافه کنید. اگر به اندازه‌گیری فاصله نیاز دارید، VL53L0X مسیر متفاوتی است؛ خروجی PIR فاصله نیست. برای ارسال رویدادها، پروژه‌های مقدماتی BLE را ببینید. ارسال یا ذخیره داده حضور افراد باید با اطلاع و رضایت مناسب انجام شود.

۱۴. خرید در ایران؛ موجودی با تاریخ مشخص

بررسی در انجام شد. قیمت ثابت درج نمی‌کنیم و وضعیت زیر تضمین موجودی آینده نیست. هر دو لینک به ماژول HC-SR501 هستند، نه عنصر PIR خام، لنز تنها یا رله آماده برق شهر.

پیش از سفارش، تصویر نسخه ارسالی، برچسب پایه‌ها، وجود جامپر و پتانسیومترها و ولتاژ تغذیه و خروجی را تأیید کنید. عکس Adafruit در ابتدای آموزش، تصویر کالای این فروشگاه‌ها نیست. توضیحات بازار از فروشگاه‌ها و نکات فنی از منابع اولیه زیر گرفته شده‌اند.

۱۵. پرسش‌های متداول

آیا HC-SR501 فرد بی‌حرکت را همیشه تشخیص می‌دهد؟

خیر. PIR به تغییر تابش حرارتی پاسخ می‌دهد و پایین‌بودن خروجی، خالی‌بودن اتاق را ثابت نمی‌کند.

آیا OUT ماژول را می‌توان مستقیم به ESP32 وصل کرد؟

فقط وقتی سطح خروجی همان نسخه با ورودی ۳٫۳ ولتی سازگار باشد. تغذیه ۵ ولتی ماژول به معنی خروجی ۵ ولتی یا مجازبودن آن برای ESP32 نیست.

تفاوت جامپر H و L چیست؟

در بردهای مطابق این برچسب‌گذاری، H تحریک مجدد و تمدید فعال‌ماندن خروجی را ممکن می‌کند؛ L حالت غیرقابل تحریک مجدد است. زمان‌بندی دقیق به مدار همان ماژول وابسته است.

چرا برنامه پس از یک دقیقه هنوز منتظر است؟

برنامه بعد از انتظار اولیه، یک ثانیه LOW پیوسته می‌خواهد. زمان سخت‌افزاری طولانی یا حرکت مداوم در حالت H می‌تواند رسیدن به این شرط را عقب بیندازد.

آیا تعداد رویدادهای PIR همان تعداد افراد است؟

خیر. یک نفر ممکن است چند پالس بسازد یا چند نفر در یک پالس دیده شوند؛ شمارنده مثال فقط تغییرهای تأییدشده سیگنال را ثبت می‌کند.

۱۶. جمع‌بندی و منابع اصلی

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

متن و مثال آموزشی: LCENJ. وضعیت تست: کامپایل نرم‌افزاری؛ بدون آزمایش روی سخت‌افزار فیزیکی. منابع مدل‌های مختلف برای توضیح همان بخش مشخص استفاده شده‌اند، نه تعمیم همه مشخصات به تمام بردهای بازار.