تشخیص حرکت • HC-SR501 • ESP32 / Arduino
ماژول PIR راه سادهای برای ثبت فعالیت در یک محدوده است. اما روشنشدن خروجی آن به معنی شناسایی قطعی انسان نیست و خاموششدنش هم خالیبودن اتاق را ثابت نمیکند. در این پروژه، HC-SR501 را میخوانیم، خروجیهای شروع کار را کنار میگذاریم و یک LED کممصرف را با زمانبندی نرمافزاری روشن نگه میداریم.
تمرکز آموزش روی راهاندازی مطمئن، تفاوت جامپر H و L و پیدا کردن علت تحریک کاذب است. مدار آزمایشی فقط با ولتاژ پایین DC کار میکند و جایگزین سامانه حفاظتی تأییدشده نیست.

اعلان حرکت در میز آزمایش، روشنکردن نشانگر هنگام عبور و ثبت زمان فعالیت، کاربردهای مناسبی برای شروع هستند. در بررسی امروز، ECA همین ماژول را موجود نشان داد و پرسشهای دارای نشان خریدار درباره نصب و پایهها داشت. آفتاب رایانه نیز صفحه همین مدل را دارد، هرچند هنگام بررسی ناموجود بود. این شواهد نشاندهنده استفاده عملی و عرضه شناختهشدهاند، نه آمار فروش یا تضمین مشتری.
برای شروع، نیاز را دقیق بنویسید: «پس از فعالشدن خروجی، LED چند ثانیه روشن بماند» قابل آزمون است؛ «هر انسان همیشه تشخیص داده شود» با یک ماژول ساده قابل تضمین نیست. مسیر موضوعی حرکت و موقعیت را برای انتخاب حسگر متناسب با مسئله ببینید.
PIR مخفف مادون قرمز غیرفعال است؛ برخلاف یک فرستنده مادون قرمز، برای تشخیص، نور به هدف نمیتاباند. عنصر پیروالکتریک به تغییر تابش حرارتی پاسخ میدهد و لنز فرسنل ناحیه دید را به بخشهایی تقسیم میکند. حرکت یک منبع گرم میان این نواحی میتواند خروجی مدار را فعال کند.
بنابراین این ماژول دوربین، فاصلهسنج یا دماسنج نیست. از یک خروجی صفر و یک نمیتوان تعداد افراد، هویت، فاصله دقیق یا جهت حرکت را استخراج کرد. توضیح سازوکار در راهنمای اصلی Adafruit آمده است.
نام HC-SR501 روی بردهای متعددی دیده میشود؛ کیفیت قطعات، مدار زمانبندی و حتی آرایش پایههای نمونهها ممکن است فرق کند. اطلاعات تراشه BISS0001 بهتنهایی محدوده مجاز تغذیه کل برد را تعیین نمیکند. برای سیمبندی باید سند ماژول واقعی و نوشتههای همان برد را کنار هم بگذارید.
| پارامتر | مرجع مستند | برداشت درست |
|---|---|---|
| تغذیه نسخه Joy-IT SEN-HC-SR501 | ۵ ولت DC | در مثال از منبع تنظیمشده ۵ ولت و ماژول سازگار استفاده میکنیم. |
| منطق خروجی نسخه Joy-IT | ۳ ولت در صفحه سازنده | ولتاژ تغذیه ماژول با سطح OUT یکسان نیست؛ نمونه واقعی را بررسی کنید. |
| محدوده دید اعلامی همان نسخه | برد حداکثر ۷ متر، زاویه کمتر از ۱۲۰ درجه | این حدود معرفی محصولاند، نه تضمین پوشش همه اتاقها. |
| تنظیمها | حساسیت، زمان نگهداری و تحریک تکی/تکراری | تنظیم زمان سختافزار را با تأخیر برنامه اشتباه نگیرید. |
مرجع: صفحه رسمی Joy-IT و راهنمای سازنده، نسخه ۱۶ آوریل ۲۰۲۴. این مقادیر به نسخه مستند تعلق دارند؛ فروشگاههای پایین مقاله لزوماً همین برند را نمیفروشند.
یک نفر ممکن است داخل اتاق بیحرکت بماند و خروجی PIR پایین بیاید. حیوان، تغییر سریع شرایط حرارتی یا قرارگیری نامناسب هم میتواند نتیجه را عوض کند. پشت شیشه معمولی، برای دیدن انسان به این روش تکیه نکنید. اختلاف دمای کم بین هدف و پسزمینه نیز میتواند تشخیص را دشوارتر کند.
اینها محدودیتهای عمومی فناوری PIR هستند، نه مشخصات اختصاصی برند خاص. پرسشهای فنی Panasonic اثر شیشه، دمای محیط و شرایط نصب را توضیح میدهد. برای حضور ثابت یا شمارش عبور، معماری و حسگر مناسب دیگری لازم است.
پایه ۵V بعضی بردهای توسعه ورودی است و بعضی هنگام USB خروجی تغذیه دارد؛ قبل از اتصال منبع خارجی و USB همزمان، مستندات برد خودتان را ببینید تا دو منبع را ناخواسته به هم متصل نکنید.
| اتصال | ESP32 کلاسیک در مثال | Arduino Uno در مثال | نکته |
|---|---|---|---|
| VCC ماژول | ۵ ولت تنظیمشده، فقط برای ماژول سازگار | از ظاهر مشابه برد، محدوده ولتاژ را حدس نزنید. | |
| GND ماژول | GND | GND | زمین منبع و میکروکنترلر مشترک باشد. |
| OUT ماژول | GPIO27 | D2 | برای ESP32 فقط خروجی با سطح سازگار با ۳٫۳ ولت. |
| پولداون ورودی | مقاومت ۱۰۰ کیلواهم از ورودی PIR به GND | هنگام جداشدن سیم، ورودی کمتر شناور میماند؛ تشخیص خرابی قطعی نیست. | |
| LED خارجی | GPIO26 → مقاومت سری → آند LED | D8 → مقاومت سری → آند LED | کاتد LED به GND؛ مقاومت سری ۱ کیلواهم. |
شماره پایهها انتخاب این مثال است. آنها را برای ESP32-C3، ESP32-S3 یا بردی که این پایهها را مصرف کرده، بدون بررسی کپی نکنید. راهنمای GPIO رسمی Espressif نیز روی محدودیت پایهها و بررسی نقشه برد تأکید دارد.
OUT را ابتدا بدون اتصال به ESP32، نسبت به GND اندازه بگیرید و مشخصات نسخه را کنترل کنید. خروجی ۵ ولتی یا پولآپ به ۵ ولت برای ESP32 مجاز فرض نمیشود. ترتیب چپ و راست پایهها را از روی عکس اینترنتی یا رنگ کابل تعیین نکنید.
در بردهایی با برچسب H/L مطابق راهنمای Adafruit، حالت H امکان تحریک مجدد را میدهد: حرکت تازه میتواند فعالماندن خروجی را تمدید کند. در حالت L، رفتار غیرقابل تحریک مجدد انتخاب میشود؛ طول پالس و فاصله بین پالسها را مدار تعیین میکند. پس یک HIGH طولانی لزوماً به معنی خرابی یا چند نفر نیست.
پتانسیومتر TIME مدت نگهداری خروجی را تغییر میدهد؛ پتانسیومتر حساسیت روی میزان پاسخگویی اثر میگذارد. جهت چرخش را از سند همان برد بگیرید: حتی راهنماهای نمونههای مختلف در این جزئیات یکسان نیستند. برد را خاموش کنید، تغییر کوچک بدهید و با همان سناریوی عبور دوباره آزمایش کنید.
برای شروع، زمان سختافزاری کوتاه و حساسیت متوسط انتخاب کنید؛ اینها نقطه شروع آزمایشاند، نه تنظیم بهینه همگانی. شرح دو حالت در آزمایش PIR در Adafruit آمده است.
اعداد ۶۰ ثانیه و یک ثانیه در برنامه انتخاب طراحی آموزشیاند؛ اگر ماژول پس از این مدت پایدار نشده، مشکل را با حذف انتظار پنهان نکنید. در حالت 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 کلاسیک کامپایل شدهاند؛ آزمون روی سنسور فیزیکی انجام نشده است. نمایش رویداد در سریال بهتنهایی صحت نصب نهایی را ثابت نمیکند.
WARMUP_MS فقط شروع کار را پوشش میدهد. پس از عبور از این مرحله، سرریز شمارنده زمان نباید دوباره برنامه را وارد گرمشدن کند.FILTER_MS برابر ۵۰ میلیثانیه، انتخاب نرمافزاری برای پذیرش تغییر پایدار ورودی است؛ درمان قطعی نویز یا تشخیص انسان نیست.HOLD_MS برابر ۵ ثانیه، نگهداری اضافه LED پس از افت سیگنال تأییدشده است. این زمان به زمان سختافزاری TIME افزوده میشود، نه جایگزین آن.در هر دور، تفاضل بدون علامت زمان جاری و زمان ثبتشده بررسی میشود. بنابراین لازم نیست با یک تأخیر چندثانیهای کل حلقه را متوقف کنیم. 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 در ابتدای آموزش، تصویر کالای این فروشگاهها نیست. توضیحات بازار از فروشگاهها و نکات فنی از منابع اولیه زیر گرفته شدهاند.
خیر. PIR به تغییر تابش حرارتی پاسخ میدهد و پایینبودن خروجی، خالیبودن اتاق را ثابت نمیکند.
فقط وقتی سطح خروجی همان نسخه با ورودی ۳٫۳ ولتی سازگار باشد. تغذیه ۵ ولتی ماژول به معنی خروجی ۵ ولتی یا مجازبودن آن برای ESP32 نیست.
در بردهای مطابق این برچسبگذاری، H تحریک مجدد و تمدید فعالماندن خروجی را ممکن میکند؛ L حالت غیرقابل تحریک مجدد است. زمانبندی دقیق به مدار همان ماژول وابسته است.
برنامه بعد از انتظار اولیه، یک ثانیه LOW پیوسته میخواهد. زمان سختافزاری طولانی یا حرکت مداوم در حالت H میتواند رسیدن به این شرط را عقب بیندازد.
خیر. یک نفر ممکن است چند پالس بسازد یا چند نفر در یک پالس دیده شوند؛ شمارنده مثال فقط تغییرهای تأییدشده سیگنال را ثبت میکند.
راهاندازی مفید PIR با شناخت محدودیت آغاز میشود: پایهها و سطح ولتاژ را بررسی کنید، شروع کار و دو نوع زمانبندی را جدا کنید، سپس خروجی خام را در محیط واقعی بسنجید. برای مرور مسیر یادگیری، راهنمای سنسورها و دوره سنسورها در ۷ قدم در دسترساند.
متن و مثال آموزشی: LCENJ. وضعیت تست: کامپایل نرمافزاری؛ بدون آزمایش روی سختافزار فیزیکی. منابع مدلهای مختلف برای توضیح همان بخش مشخص استفاده شدهاند، نه تعمیم همه مشخصات به تمام بردهای بازار.