اگر تابحال در حوزه تکنولوژی فعالیت داشته اید، ممکن است نام ESP32 به گوشتان خوردهباشد. ESP32 یک میکروکنترلر قدرتمند و چندمنظوره است که توسط شرکت Espressif Systems طراحی و تولید میشود. این بورد به دلیل ویژگیهای منحصربهفرد در زمینه پروژههای اینترنت اشیاء(IoT)، ساخت ربات و دستگاههای هوشمند، توسعه برنامههای بلوتوث و WiFi و غیره استفاده میشود.
از ویژگیهای این بورد میتوان به قدرت محاسباتی بالا، اتصالات بیسیم (شامل ماژولهای WiFi و بلوتوث) و توانایی در رمزگذاری و رمزنگاری اطلاعات اشاره نمود. اما یکی از مهمترین خصوصیتهای این بورد دارا بودن حالت خواب یا همان sleep mode هست که به دستگاه این قابلیت را میدهد تا در مصرف انرژی و باتری صرفهجویی کند. درادامه این پست آموزشی به معرفی sleep mode ، الگوهای مختلف آن، قابلیتهای آنها و همچنین نحوه اجرایشان در کد میپردازیم.
Sleep mode و حالات مختلف آن:
همانطور که پیشتر در این پست آموزشی گفته شد، حالت sleep mode یکی از ویژگیهای بورد ESP32 میباشد که توانایی ذخیرهسازی باتری را با قراردادن دستگاه در حالت کممصرف فراهم میکند. Sleep mode دارای الگوهای مختلفی است که به کاربر این امکان را میدهد تا با توجه به نوع مصرف دستگاه از هریک از این الگوها استفاده کند؛ که عبارتند از:
- Modem Sleep Mode
- Light Sleep Mode
- Deep Sleep Mode
- Hibernation Mode
در هر یک از این حالتها بخش هایی از بورد غیرفعال میشود تا با افزایش طولعمر باتری، طولمدت کارکرد دستگاه افزایش یابد. در یک الگوی خواب، برای حفظ ارتباط و دریافت اطلاعات، ESP32 به طور متناوب و با کمک مکانیزمهای تحریککننده (مانند تایمر،سنسور لمس و…) اصطلاحاً بیدار میشود که به این الگوی متناوب، الگوی خواب منسجم میگویند. در این الگو،به طور پیدرپی و در بازه زمانیهای تعیین شده، دستگاه بین sleep mode و Active mode تغییر حالت میدهد.در ادامه به معرفی هریک از این حالات، قابلیتها ،نحوه استفادهشان و دیگر جزئیات خواهیم پرداخت.
Modem Sleep :
در این الگو با غیرفعال شدن ماژولهای بلوتوث و Wi-Fi ، دستگاه وارد فاز ذخیره باتری میشود. در مقایسه با حالت Active که در آن تمامی ماژولها فعال هستند و دستگاه 160 تا 260 میلیآمپر انرژی مصرف میکند، Modem sleep مصرف انرژی را به 20 الی 3 میلیآمپر کاهش میدهد.
این الگوی خواب، بورد ESP32 را بین دو حالت Active و Modem sleep سوئیچ میکند و برای تغییر حالت بین این دو الگو، ESP32 از مکانیزم DTIM beacon استفاده میکند.
مکانیزم DTIM beacon چیست؟
این مکانیزم، دادهها را به صورت چندگانه و با سیگنالهایی با دوره متناوب یکسان برای تمامی ایستگاههای متصل به شبکه (AP/Router) میفرستد و امکان دریافت دادههای به تعویقافتاده را فراهم میکند تا این ایستگاهها بتوانند در بازههای خودکار از حالت صرفهجویی بیدار شده و دادهها را دریافت کنند.
Light Sleep :
این الگوی خواب شبیه به Modem sleep هست و از الگوی خواب منسجم پیروی میکند. در این الگو، علاوه بر ماژولهای Wi-Fi و بلوتوث، CPU و بخشهایی از RAM متوقف میشوند و دستگاه باتری بیشتری ذخیره میکند و مصرف باتری را به 0.8 میلیآمپر میرساند.
در طول این الگو، درحالی که CPU متوقف میشود، ماژولهای RTC(Real-Time Clock) و پردازنده ULP(Ultra-Low Power) فعال باقی میمانند تا بتوانند زمان دقیق را اندازه گیری و تسکهای کوچک و ساده را انجام دهند.
Deep Sleep :
الگوی Deep sleep یا همان خواب عمیق، CPU و RAM را به همراه ماژولهای WiFi و بلوتوث و دیگر اجزای دیجیتال غیرفعال میکند و مصرف دستگاه را تا 10 میکروآمپر کاهش میدهد و فقط ماژولهای ULP و RTC فعال باقی میمانند. وظیفه پردازنده ULP ، خواندن داده از سنسورها و فعال کردن CPU در صورت نیاز است.
از آنجایی که RAM به همراه CPU غیرفعال میشود، تمام دادههای ذخیرهشده در آن از بین رفته و غیرقابلدسترس میشوند. هرچند که با فعال باقی ماندن ماژول RTC، حافظه RTC نیز فعال باقی مانده و میتواند دادههای WiFi و بلوتوث را پیش از ورود به حالت Deep Sleep در خود ذخیره کند و پس از بیدار شدن بورد، این دادهها را بازیابی و مورد استفاده قرار دهد.
Hibernation :
این الگو که بسیار شبیه به حالت Deep sleep است و به خواب زمستانی شناخته میشود، علاوه بر CPU و RAM ، پردازنده ULP را نیز غیرفعال میکند و تنها ماژول RTC فعال میماند و موجب میشود تا مصرف باتری به حدود 2.5 میکروآمپر برسد.
درحالت خواب زمستانی، بر خلاف Deep sleep، حافظه RTC نیز غیرفعال میشود؛ در نتیجه در طول این الگوی خواب دادهها را نمیتوان ذخیره و بازیابی کرد.
نحوه استفاده از Sleep Mode ها در کد:
حال که با هریک از الگوهای خواب آشنا شدیم، لازم است تا چگونگی استفاده از هریک از آنها را در قالب کد نیز بررسی کنیم.
در ادامه به بررسی syntax ها و Header file های لازم جهت فعال کردن Sleep Mode ها و غیرفعال کردنشان به کمک تایمر و همچنین ذکر مثال میپردازیم.
Modem Sleep Mode :
برای فعالسازی این حالت خواب، از فایل Header زیر استفاده میشود:
- `esp_sleep.h`
و همچنین تابع اصلی برای فعال کردن آن به صورت `()esp_wifi_set_ps` است که مقادیر زیر را میگیرد :
- `WIFI_PS_MIN_MODEM`
- `WIFI_PS_MAX_MODEM`
اما تفاوت این دو مقدار در چیست؟
`WIFI_PS_MIN_MODEM` به طور کلی نسبت به `WIFI_PS_MAX_MODEM` میزان بیشتری باتری مصرف میکند و البته سرعت پاسخگویی بهتری نیز دارد؛ بنابراین با توجه به مورد مصرف میتوان یکی از این دو مورد را انتخاب کرد.
حال این موارد را میتوانیم به صورت زیر در قالب کد ببینیم:
همچنین برای غیر فعال کردن این الگوی خواب میتوان از تابع `()esp_wifi_set_ps` استفاده کرد و مقدار آن را `WIFI_PS_NONE` قرار داد.
Light Sleep Mode :
Header file های استفاده شده در این الگو همانند الگوی خواب پیشین است. برای فعالسازی آن نیز از تابع `()esp_light_sleep_start` استفاده میشود.
حال نحوه فعالسازی در قالب کد را بررسی میکنیم:
برای بیدار کردن دستگاه از تابع `()esp_sleep_enable_timer_wakeup` استفاده شده است. از آنجایی که این تابع مقدار را به میکروثانیه میخواند، پس باید هر ثانیه را در 1000000 ضرب کرد تا به میکروثانیه تبدیل شود.
همانطور که میبینید تابع فعالسازی الگوی Light sleep در قسمت ()loop
به کار رفته است. کد از ابتدا اجرا میشود تا به تابع `()esp_light_sleep_start` برسد؛ سپس به خواب میرود و پس از 10 ثانیه بیدار میشود. بعد از بیدار شدن، کد دوباره از ابتدا اجرا میشود؛ بنابراین بعد از تابع `()esp_light_sleep_start`نباید کد دیگری نوشت زیرا انجام نخواهد شد.
Deep Sleep Mode :
همانطور که در قطعه کد بالا قابل مشاهده است، فعالسازی Deep Sleep Mode تفاوت چندانی با حالت Light sleep ندارد و تنها تفاوت آن در تابع `()esp_deep_sleep_start` میباشد.
Hibernation Mode :
بسیاری از موارد این حالت خواب شبیه به حالت Deep sleep هست؛ بنابراین با ذکر مثال نحوه استفاده از این حالت را در بستر کد بررسی میکنیم.
همانطور که در مثال بالا میبینید، تنها تابع جدیدی که به چشم میخورد `()esp_sleep_pd_config` میباشد که پارامترهای زیر را در طول دوره خواب کنترل میکند:
- ESP_PD_DOMAIN_RTC_SLOW_MEM
- ESP_PD_DOMAIN_RTC_FAST_MEM
کنترل حافظه RTC
- ESP_PD_DOMAIN_RTC_PERIPH
کنترل تایمر RTC
- ESP_PD_DOMAIN_RTC_IO
کنترل پین های ورودی/خروجی متصل به ماژول RTC
- ESP_PD_DOMAIN_RTC_FAST_CLK
کنترل کردن سیگنال و فرکانس تولید شده توسط ماژول RTC
پارامتر های نام برده شده به کمک مقادیر زیر کنترل میشوند:
- ESP_PD_OPTION_ON
پارامتر مورد نظر را در طول دوره خواب فعال (ON) نگه میدارد.
- ESP_PD_OPTION_OFF
پارامتر مورد نظر را در طول دوره خواب غیرفعال(OFF) نگه میدارد.
- ESP_PD_OPTION_AUTO
به بورد اجازه میدهد تا به صورت اتومات و بسته به نیاز دستگاه این پارامترها را در طول دوره خواب، فعال و یا غیرفعال کند.
دیگر توابع استفادهشده در حالت Hibernation همانند حالت Deep sleep مورد استفاده قرار میگیرند.
مثال:
در انتها، پس از توضیح الگوهای خواب و نحوه استفادشان، نوبت استفاده عملی در قالب کد و بررسی آن است.
در این مثال دستگاه فرضیای را در نظر بگیرید که در آن از میکروکنترلر ESP32 استفاده شده. هدف ساخت این دستگاه اندازهگیری دما، رطوبت و کیفیت هوا به کمک سنسورها و ارسال این دادهها به سرور مرکزی میباشد. قطعه کدهای زیر نحوه متصل شدن به WiFi، دریافت اطلاعات اولیه از سنسور، ارسال دادهها به سرور فرضی و وارد شدن به حالت Deep Sleep را نشان میدهند.
- متغیرهای ssid, password: دریافت IP address و password روتر(Router)
- متغیر sleepDuration: طول دوره خواب دستگاه.
- متغیر measurementInterval: دوره تناوب اندازه گیری داده توسط سنسورها (هر 60 ثانیه یکبار داده اندازه گیری میکند)
- تابع sendDataToServer: مقداردهی به شاخصهای اندازهگیری و فرستادن دیتا به سرور مرکزی به صورت JSON
- فراخوانی تابع sendDataToServer
- ست کردن تایمر برای خاتمه Sleep mode
- وارد شدن دستگاه به الگوی Deep sleep
منابع:
https://espressif-docs.readthedocs-hosted.com/projects/espressif-esp-iot-solution/en/latest/low_power_solution/esp32_lowpower_solution.html
https://m1cr0lab-esp32.github.io/sleep-modes