نوشتهها
ساخت سیستمهای نهفته و اینترنت اشیا با ESP32، ESP-IDF، Arduino و MQTT
از کیت کامل خانهٔ هوشمند نوراسیس تا دستگاههای NPWT بر پایهٔ ESP32 برای درمانجو؛ اینجا میگویم سختافزار متصل را چطور طراحی میکنم، کوچکترین کنترلرِ کافی را چطور انتخاب میکنم، چرا فریمور را خودم مینویسم و دستگاه را بیرون آزمایشگاه چطور قابل پیشبینی نگه میدارم.
فریمور بخشی از خود محصول است، نه ضمیمهاش
کار وب و اینترنت اشیای من از اول کنار هم رشد کردند؛ روی یک میز پروژههای Laravel و WordPress و روی میز دیگر الکترونیک مبتنی بر میکروکنترلر. همین همنشینی نگاهم به دستگاه متصل را ساخت: فریمور برنامهٔ کوچکی نیست که آخر کار به «محصول واقعی» اضافه شود. فریمور تعیین میکند سختافزار مثل یک سیستم رفتار کند یا نه، هنگام خطا چه کند، چقدر انرژی هدر بدهد و قابلیت بعدی یک تغییر محدود باشد یا انبوهی استثنا.
برای همین برنامهها را خودم مینویسم. در کار سیستمهای نهفته و اینترنت اشیا ممکن است با C روی ESP32 و ESP-IDF کار کنم، نمونهای بر پایهٔ Arduino بسازم یا روی برد اختصاصی از میکروهای خیلی کوچک ATtiny و PIC استفاده کنم. زبان و تراشه عوض میشوند، اصل نه: اگر نتوانم توضیح بدهم هر گره با ورودی عجیب چه میکند، هنوز دستگاه را به اندازهٔ کافی نمیشناسم.
از کوچکترین کنترلری شروع کن که صادقانه کافی است
در طراحی نهفته وسوسه این است که برای هر گره، قویترین برد دمدست را برداری. من برعکس میروم: اول خود کار، بعد کوچکترین کنترلری که بدون دروغ گفتن دربارهٔ زمانبندی، حافظه، مصرف و پایهها از پسش بربیاید. گرهی که فقط یک وضعیت را گزارش میکند به سیلیکونِ کنترلر متصل و پیچیده نیاز ندارد. تراشهٔ کمتر، خست نیست؛ راه ارزان، کممصرف و قابل فهم ماندن کل کیت است.
Arduino در این نردبان مفید است چون ایدهٔ فیزیکی را سریع جلوی چشمت میگذارد؛ اما نمونهٔ اولیه شاهد است، نه لزوماً معماری نهایی. وقتی دستگاه اتصال جدیتر، ساختار محکمتر یا کنترل دقیقتری لازم دارد، ESP32 و ESP-IDF جای بزرگترشان را پس میدهند. هنر کار این است که بدانی محصول واقعاً روی کدام پله ایستاده است؛ نه اینکه هر مسئله یا دمو باشد یا یک کامپیوتر لینوکسی مینیاتوری.
کیت نوراسیس: گرههای کوچک زیاد، یک مجموعه قاعده
کیت خانهٔ هوشمند نوراسیس روشنترین نمونهٔ این نگاه است: بستهای کامل برای امنیت و اتوماسیون خانه که جز پروتکلهای استاندارد ارتباطی، همه چیزش از صفر ساخته شده؛ دستگاه و برد و فریمور. بیشتر گرهها عمداً کوچکاند: ترافیک بیسیم روی رادیوهای nRF24L01 میچرخد، سنسورها و عملگرها با ATtiny13A یا PIC کار میکنند و MQTT در لایهٔ پیامرسانی همه را به هم وصل میکند.
نکتهٔ اصلی فهرست قطعات نیست؛ قاعدهٔ مشترک گرههاست. چون فریمور را خودم نوشتهام، نه ماژولهای بیربط را کنار هم چیدهام، معنای پیام، رفتار هنگام خطا و مسیر گسترش در کل کیت یکدست میماند. همین یکدستی سختافزار را به کسبوکار عمومی نوراسیس هم وصل میکند: خورشیدی، برق اضطراری و خانهٔ هوشمند برای مشتری یک مسئلهاند و مهندسی هم باید همینطور خوانده شود، نه جعبهای از قطعات باهوش.
ESP-IDF برای وقتی «تقریباً کار میکند» جواب نیست
دستگاههای NPWT درمانجو آن سر همین طیفاند: واحدهای قابل حمل درمان زخم با فشار منفی که دور ESP32، سنسورهای فشار و بردهای الکترونیکی اختصاصی ساخته میشوند. سهم من فقط مهندسی است: حس و کنترل مطمئن فشار، طراحی برد بر اساس محدودیتهای واقعی و نوشتن فریمور با C و ESP-IDF.
در سختافزار نزدیک به حوزهٔ پزشکی، رفتار مبهم گران تمام میشود. سنسور ممکن است غیرمنتظره بخواند و برق ممکن است بدرفتاری کند؛ دنیای بیرون هم کاری به مسیر خوشبینانهٔ تو ندارد. فریمور کوچک و قابل فهم و طراحی دقیق برد است که دستگاه را در آن لحظهها قابل پیشبینی نگه میدارد. این همان غریزهای است که برای سیستمهای ایجنت با Rust گفتم: چیز متغیر را داخل قاب قطعی نگه دار؛ فقط اینجا چیز متغیر مدل نیست، فیزیک است.
برای دقیقهٔ بد طراحی کن، نه فقط برای دمو
دستگاه متصل بیشتر عمرش را در همان دقیقهٔ بد میگذراند: پیام نمیرسد، لینک رادیویی نویز میگیرد، سنسور چرت میخواند یا برق دقیقاً در بدترین لحظه میپرد. پس فریمور خوب به همان اندازه که برای قابلیت وقت میگذارد، برای مرزها وقت میگذارد: خوانش معتبر یعنی چه؟ گره وقتی به بقیهٔ سیستم نمیرسد چه کند؟ کدام وضعیت را نگه دارد، کدام را از نو بسازد و چه اتفاقی فقط به خاطر تکرار یک پیام نباید دوبار بیفتد؟
MQTT کمک میکند چون برای سیستم یک لایهٔ پیامرسانی صریح میسازد، به جای اینکه هر دستگاه گفتوگوی خودش را بداهه بسازد؛ اما پروتکل، طراحی نیست. طراحی همان تصمیمهای بالاسری است: معنای پیام، مسئولیت هر گره، پیشفرضها و ریکاوری. همین جداسازی را در سمت نرمافزار درمانجو هم میبینی که پلتفرمش را با پشتهٔ SvelteKit ساختهام. کلاینت چه مرورگر باشد چه برد، مرز مبهم بالاخره صورتحسابش را به عملیات میدهد.
قابل نگهداری بودن هم از همین جداسازی میآید. واقعیتهای مخصوص هر برد — پایه و سنسور و رفتار رادیو و سقف کنترلر — باید نزدیک همان سختافزاری بمانند که مالکشان است. قواعد لایهٔ بالاتر بهتر است با زبان محصول حرف بزنند: این گره گزارش میدهد، آن کنترلر تصمیم میگیرد و این عملگر وضعیت را عوض میکند. وقتی نسخهٔ تازهٔ برد میرسد یا خانهای قابلیت دیگری میخواهد، همین ساختار میگوید کدام لایه باید عوض شود و کدام قولها باید دستنخورده بمانند. فریموری که همهٔ دغدغهها را در یک حلقه قاطی کند شاید تست امروز را رد کند، اما تغییر سختافزار فردا را به بازنویسی رفتار تبدیل میکند.
امروز پشتهٔ نهفته را چطور انتخاب میکنم؟
ترتیب سؤالهایم ثابت است: این گره چه چیزی را حس یا کنترل میکند؟ هر واحد چقدر حق دارد برق و پول خرج کند؟ اتصال مستقیم لازم دارد یا بهتر است گره رادیویی کوچکتری به سیستم بزرگتر گزارش بدهد؟ وقتی ارتباط قطع شد چه میشود؟ فقط بعد از اینهاست که میان میکروی خیلی کوچک، مسیر نمونهسازیِ Arduino یا ESP32 با ESP-IDF انتخاب میکنم. شروع از کاتالوگ تراشه، نمونهٔ اولیهٔ پرزرقوبرق و محصول گران میسازد.
اگر دستگاه متصلی لازم داری که به چشم یک سیستم طراحی شود — برد، فریمور، پیامرسانی و نرمافزار دورش با هم — آن نگاه سرتاسری همان کاری است که ذیل سیستمهای نهفته و اینترنت اشیا انجام میدهم. نمونههای عمومیاش کیت نوراسیس و سختافزار NPWT هستند و قصهٔ کاملتر از تجربهٔ وب و اینترنت اشیای من شروع میشود.
