3.29. أنماط الطاقة المنخفضة والسكون¶
لا تحتاج الكاميرات التي تعمل بالبطارية والمستشعرات النشطة بشكل متقطع إلى تشغيل وحدة المعالجة المركزية بكامل سرعتها طوال الوقت. تُتيح وحدة machine أربع حالات لتوفير الطاقة تزداد عمقًا تدريجيًا -- active، و idle()، و lightsleep()، و deepsleep(). كل خطوة أعمق تُطفئ جزءًا أكبر من الشريحة وتوفّر طاقة أكثر، مقابل وقت استيقاظ أطول. اختيار الحالة الصحيحة هو مفاضلة بين كمية الطاقة التي توفّرها الكاميرا ومدى سرعة تفاعلها عند حدوث شيء ما.
3.29.1. الحالة النشطة (Active)¶
الحالة الافتراضية. تعمل وحدة المعالجة المركزية بتشغيل Python، وكل طرفية تتلقى نبضات الساعة، ويكون سحب التيار في أعلى مستوياته -- عشرات الميلي أمبير على خط منطق الكاميرا، إضافة إلى ما تسحبه أي ملحقات متصلة عبره.
3.29.2. idle()¶
تُوقف machine.idle() ساعة وحدة المعالجة المركزية حتى تُطلَق أي مقاطعة (طرفية، أو مؤقت، أو مقاطعة دبوس IRQ). تظل الذاكرة العشوائية نشطة، وتبقى الطرفيات قيد التشغيل، وتستمر الساعات في العمل -- فقط وحدة المعالجة المركزية نفسها هي المتوقفة، وتستيقظ خلال ميكروثوانٍ عندما يكون هناك عمل يجب القيام به.
استخدمها داخل أي حلقة استطلاع محكمة تنتظر حدوث شيء خارجي:
import machine
while not button_pressed():
machine.idle()
تتوقف وحدة المعالجة المركزية عن إهدار الدورات على فحص while نفسه وتستيقظ طبيعيًا عند وصول الحدث التالي -- توفير صغير يتراكم على مدى حلقة تعمل ملايين المرات.
3.29.3. lightsleep()¶
machine.lightsleep() هي الخطوة التالية للأسفل. تتوقف وحدة المعالجة المركزية تمامًا وتُطفأ معظم ساعات الشريحة الداخلية، لكن تُحفظ الذاكرة العشوائية وحالة الطرفيات. عندما يُطلَق مصدر الاستيقاظ، يستأنف البرنامج النصي من النقطة ذاتها التي استدعى فيها lightsleep -- مع بقاء المتغيرات والمقابض المفتوحة والبيانات المعلقة كلها سليمة -- بعد مدة من رتبة الميلي ثانية.
import machine
from machine import Pin
wake_pin = Pin("P0", Pin.IN, Pin.PULL_UP)
wake_pin.irq(lambda _: None, trigger=Pin.IRQ_FALLING, wake=machine.SLEEP)
while True:
do_work()
machine.lightsleep() # wakes on a falling edge on P0
يجب تهيئة مصدر الاستيقاظ -- وهو هنا مقاطعة دبوس IRQ -- قبل استدعاء السكون. ينخفض سحب الطاقة بشكل ملحوظ مقارنة بالحالة النشطة؛ والرقم الدقيق يعتمد على اللوحة وعلى الطرفيات التي لا تزال مُهيّأة.
3.29.4. deepsleep()¶
machine.deepsleep() هي الحالة الأعمق. تتوقف وحدة المعالجة المركزية، وتُفصل الطاقة عن الطرفيات، وقد تُفقد محتويات الذاكرة العشوائية. الأشياء الوحيدة التي لا تزال تسحب طاقة هي دائرة الاستيقاظ وقدر صغير من المنطق الدائم التشغيل.
عندما يُطلَق مصدر الاستيقاظ، تُقلِع الشريحة من بداية البرنامج النصي الرئيسي -- فـ deepsleep لا تعود. يميّز البرنامج النصي استيقاظ deepsleep عن التشغيل من جديد أو إعادة التعيين الصلبة باستخدام machine.reset_cause():
import machine
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
# Woke from deepsleep -- restore state from non-volatile storage,
# take a measurement, etc.
pass
else:
# Fresh boot
pass
do_work()
machine.deepsleep(60_000) # arm RTC wake for 60 s, sleep, then restart
وسيط الميلي ثانية المُمرَّر إلى deepsleep() يُسلّح إنذار ساعة الزمن الحقيقي (RTC) المدمجة داخليًا -- فساعة الزمن الحقيقي هي ما يحمل توقيت الاستيقاظ خلال السكون، لأن معظم المؤقتات الأخرى مفصولة الطاقة. أما استدعاء deepsleep() بدون وسيط فيترك الاستيقاظ لأي مصدر هيّأته بشكل منفصل (مقاطعة دبوس IRQ، أو إنذار RTC مُسلَّح خارجيًا).
ولأن البرنامج النصي يُعاد تشغيله، فإن أي شيء تحتاجه التكرارة التالية يجب إما إعادة بنائه في أعلى main.py أو حفظه في ذاكرة الفلاش (أو في سجلات النسخ الاحتياطي الخاصة بـ RTC، في الأجزاء التي تملكها). يمنح deepsleep أكبر توفير للطاقة لكنه يفرض أكبر قدر من إعادة هيكلة البرنامج -- إذ يجب أن يتصرف التطبيق كسلسلة من "دفعات قياس" قصيرة يفصل بينها سكون، بدلًا من حلقة طويلة الأمد بحالة في الذاكرة العشوائية.
3.29.5. اختيار حالة¶
تعتمد الحالة الصحيحة على ما تنتظره الكاميرا:
حلقة استطلاع محكمة تنتظر ميلي ثوانٍ. استخدم
idle(). التوفير صغير لكل دورة لكنه كبير في المجموع، والاستيقاظ غير ملحوظ.خمول لثوانٍ أو دقائق بين الأحداث. استخدم
lightsleep(). تُحفظ الحالة، والاستيقاظ سريع، وسحب الطاقة جزء يسير من الحالة النشطة.خمول لدقائق أو أكثر بين دفعات عمل قصيرة. استخدم
deepsleep(). الشريحة مُطفأة فعليًا بين الأحداث، وتتحول بنية البرنامج النصي إلى حلقة استيقاظ ثم قياس ثم سكون.
أيًا كانت الحالة، فإن مصدر الاستيقاظ لا يقل أهمية عن الحالة نفسها -- فـ deepsleep الذي يستيقظ على مؤقت فقط هو حلقة قياس ذات دورة تشغيل؛ و lightsleep الذي يستيقظ على مقاطعة دبوس IRQ هو مستشعر مدفوع بالأحداث. توفّر دوال السكون في وحدة machine، وإنذارات RTC، و irq() معًا اللبنات الأساسية.