تحلیل Qwiic OpenLog؛ از دادهٔ حسگر تا فایل قابل اتکا روی کارت حافظه
Qwiic OpenLog دادهٔ ارسالی میزبان را روی کارت حافظه ثبت میکند. مدار و کد آن نشان میدهند افت تغذیه، مکث کارت و گزارش ناقص خطا چگونه بر نتیجه اثر میگذارند و برای ثبت مطمئنتر چه باید تغییر کند.
فهرست مطالب
برای ثبت دمای یک اتاق در طول شب، لازم نیست کامپیوتر همیشه روشن بماند. یک برد کوچک میتواند عددهای اندازهگیریشده را روی کارت حافظه بنویسد تا بعداً آنها را بخوانیم. پروژهٔ Qwiic OpenLog همین کار را از راه ارتباط I²C انجام میدهد. نکتهٔ اصلی طراحی آن، فقط وصلکردن کارت نیست: تغذیه باید هنگام نوشتن پایدار بماند، میزبان مکث کارت را تحمل کند و برنامه بداند چه زمانی داده واقعاً ذخیره شده است.
این تحلیل دربارهٔ برد SparkFun با شناسهٔ DEV-15164 و نسخهٔ مشخص مخزن Qwiic_OpenLog است؛ شناسهٔ commit برابر f3f6a3ec3f70fe4c14612b38fac360f26ee79a4c و تاریخ آن ۱۲ مهٔ ۲۰۲۳ است. شماتیک، PCB و چهار فایل firmware همین نسخه مبنای بررسیاند. پروژه متعلق به SparkFun است؛ این نوشته تحلیل طراحی و پیشنهاد برای توسعهٔ آن است.
خرید برد و انتخاب کارت حافظه
مدل دقیق، SparkFun Qwiic OpenLog، DEV-15164 است؛ یک برد مونتاژشده با ATmega328P در پکیج TQFP، نه OpenLog سریال UART با شناسهٔ DEV-13712 و نه OpenLog Artemis. در بررسی ۲۶ اکتبر ۲۰۲۶، صفحهٔ مستقیم SparkFun وضعیت موجود را نشان میداد. این وضعیت، گزارش همان فروشنده در زمان بررسی است. برای خرید ایران، صفحهٔ مستقیمِ قابل تأیید برای همین برد و موجودی آن پیدا نشد؛ بنابراین مدل مشابه را جایگزینِ تأییدشده معرفی نمیکنیم.
صفحهٔ جاری سازنده، کارت microSD با ظرفیت ۶۴ مگابایت تا ۳۲ گیگابایت و قالب FAT16 یا FAT32 را ذکر میکند. README مخزن ادعای گستردهتری دربارهٔ ظرفیت دارد؛ برای شروع به همان محدودهٔ مستند محصول تکیه کنید. کارت ۶۴ گیگابایتی با قالب پیشفرض exFAT را صرفاً بهدلیل جاخوردن در سوکت سازگار فرض نکنید. قالب فایلسیستم، روشی است که نام و جای فایلها روی کارت نگهداری میشود؛ اندازهٔ کارت بهتنهایی سازگاری را تعیین نمیکند.
مسئلهای که این معماری حل میکند
حسگر، ویژگیای مانند دما را به مقداری قابل خواندن تبدیل میکند. میزبان، مثلاً بردی با یک میکروکنترلر، مقدار را میخواند و تصمیم میگیرد چه چیزی ثبت شود. میکروکنترلر تراشهای است که برنامه را اجرا میکند و پایههای ورودی و خروجی دارد. OpenLog میزبانِ همهٔ حسگرها نیست؛ میزبان اصلی باید داده را برای آن بفرستد. وجود دو سوکت Qwiic نیز به این معنی نیست که برد خودش از حسگر کنار دستش نمونه میگیرد.
I²C داده را با دو خط SDA و SCL میان وسایل جابهجا میکند: یکی داده را حمل میکند و دیگری زمان جابهجایی را مشخص میکند. در این پروژه میزبان فرمان میدهد و OpenLog پاسخ میدهد. پردازندهٔ OpenLog سپس کارت را با رابط دیگری به نام SPI اداره میکند. این جداسازی، برنامهٔ میزبان را از بخشی از کار فایلسازی راحت میکند، اما محدودیت زمان و خطا را حذف نمیکند. اگر آشنایی اولیه لازم دارید، درس عیبیابی ارتباط I²C مسیر بررسی اتصال و پاسخ وسیله را توضیح میدهد؛ شمارهٔ پایههای ESP32 آن درس، نقشهٔ این برد نیست.
تغذیه؛ ورودی این برد فقط ۳٫۳ ولت است
در شماتیک همین نسخه، خط ۳٫۳ ولت مستقیماً به پایههای VCC و AVCC پردازندهٔ U2، تغذیهٔ کارت J1 و سوکتهای J2 و J4 وصل است. رگولاتوری برای تبدیل ۵ ولت روی این مسیر دیده نمیشود. بنابراین تغذیه یا منطق ۵ ولتی را مستقیم وصل نکنید. منبع تنظیمشدهٔ مناسب، زمین مشترک و میزبانِ سازگار با سطح ۳٫۳ ولت لازم است. سوکت UART برنامهریزی J6 نیز به همین تغذیه وصل است؛ دو خروجی تغذیه را بیبررسی به هم نبندید.
خازن C1 برابر ۴٫۷ میکروفاراد و C3 برابر ۰٫۱ میکروفاراد بین تغذیه و زمین قرار دارند. خازن مقداری انرژی الکتریکی نگه میدارد و میتواند بخشی از تغییر سریع جریان را محلی تأمین کند. وجود آن جای منبع مناسب و مسیر کممقاومت را نمیگیرد. راهنمای سازنده مصرف نوشتن را حدود ۲۰ تا ۲۳ میلیآمپر و وابسته به کارت بیان میکند؛ این عدد را حد بالای جهش لحظهای جریان یا بودجهٔ قطعی هر کارت نگیرید.
برای مثالِ صرفاً فرضی، اگر بار ۵۰ میلیآمپری باید ۲۰ میلیثانیه با افت مجاز ۰٫۳ ولت ادامه دهد، رابطهٔ ایدئال C = I × Δt / ΔV به 0.05 × 0.02 / 0.3 ≈ 0.00333 F، یعنی حدود ۳۳۳۰ میکروفاراد میرسد. این محاسبه انتخاب نهایی خازن نیست: مقاومت داخلی خازن، جریان راهاندازی، کمترین ولتاژ مجاز کارت و پردازنده، مدار تشخیص قطع برق و مدت واقعی پایان نوشتن هنوز باید معلوم شوند. خازن ۴٫۷ میکروفارادی موجود، ذخیرهٔ تضمینشده برای پایان هر نوشتن هنگام قطع برق نیست.
خطوط ارتباط، بالاکش و ساعت پردازنده
خط SDA به PC4 و SCL به PC5 پردازنده میروند. مقاومتهای R5 و R4 هرکدام ۲٫۲ کیلواهماند و از طریق جامپر I2C به ۳٫۳ ولت وصل میشوند. این مقاومتها خطوط آزاد را بالا نگه میدارند. با فرض ولتاژ پایین نزدیک صفر، جریان هر مقاومت حدود 3.3 / 2200 = 1.5 mA است. اگر دو برد هرکدام بالاکش ۲٫۲ کیلواهم داشته باشند، مقاومت معادل ۱٫۱ کیلواهم و جریان تقریبی دو برابر میشود. پیش از افزودن وسیله، بالاکشهای کل مسیر و توان کشیدن خط به صفر را بررسی کنید؛ بردهای زنجیرهشده همیشه به بالاکش جداگانه نیاز ندارند.
نشانی پیشفرض ۷بیتی، 0x2A است. بستن جامپر ADR، پایهٔ PD3 را پایین میکشد و تابع startI2C نشانی 0x29 را تحمیل میکند. مسیر نرمافزاریِ تنظیم نشانی در همین firmware نیز وجود دارد؛ چند وسیله را ابتدا جداگانه تنظیم کنید تا روی یک نشانی پاسخ ندهند. پس از راهاندازی دوباره، اثر فایل config.txt و EEPROM را هم بررسی کنید. اعداد نشانی، ولتاژ و شمارهٔ پایه یک مفهوم نیستند.
قطعهٔ Q1 در فایل مدار یک رزوناتور ۱۶ مگاهرتزی است؛ آن را صرفاً به اتکای عبارت crystal در راهنما، کریستال معرفی نمیکنیم. در دیتاشیت ATmega328/P، بخش Speed Grades، حداکثر فرکانس مجاز به ولتاژ وابسته است و نقطهٔ ۱۶ مگاهرتز در ۳٫۳ ولت بیرون ناحیهٔ تضمینشدهٔ نمودار قرار میگیرد. این یک محدودیت طراحی برای بازاستفاده است، نه شاهد خرابی همهٔ بردها. برای نسخهٔ جدید میتوان ساعت پایینترِ منطبق را بررسی کرد؛ تغییر ساعت به بازبینی تنظیم F_CPU، bootloader، زمانبندی UART، SPI و ظرفیت پاسخگویی I²C نیاز دارد. بالا بردن تغذیهٔ کل برد به ۵ ولت راهحل نیست، چون کارت و رابطها روی همان خطاند.
آنچه PCB نشان میدهد
در فایل برد، U2 در مختصات (12.7, 13.97) mm و Q1 در (19.05, 19.05) mm قرار دارند. سوکت کارت J1 روی سمت پشت نصب میشود و J2 و J4 در دو طرفاند. مدار SPI شامل PB3 به ورودی DI کارت، PB4 به خروجی DO و PB5 به SCK است؛ انتخاب کارت از PB2 و با بالاکش ۱۰ کیلواهمی R3 انجام میشود. این بالاکش، انتخابنشدن کارت هنگام آزادبودن پایه را کمک میکند؛ جای ترتیب درست راهاندازی را نمیگیرد.
برای زمین در هر دو لایه polygon تعریف شده است، اما وجود تعریف زمین، پیوستگی همهٔ مسیرهای برگشت را ثابت نمیکند. خروجی پُرشده و مسیر جریان کارت را در نرمافزار PCB هم بررسی کنید. C1 کنار ناحیهٔ کارت است؛ در توسعهٔ برد، مسیر تغذیه و برگشت خازن را کوتاه نگه دارید و جریان کارت را از مسیر باریک مشترک با مرجع حسگر عبور ندهید. چراغ سبز D3 از طریق R6 با مقدار ۳۳۰ اهم به SCK متصل است؛ چشمک آن فعالیت کلاک را نشان میدهد، نه صحت فایل یا ذخیرهٔ دائمی داده. نزدیکبودن رزوناتور به پردازنده و کوتاهماندن مسیرهای آن نیز در طراحی بعدی حفظ شود.
firmware واقعاً چگونه داده را مینویسد؟
فایل Qwiic_OpenLog.ino در این commit مقدار نسخه را ۳٫۱ اعلام میکند. جدول فرمانها، ثبات 0x0C را به writeFile و 0x11 را به syncFile متصل میکند. اینجا ثبات، شمارهای در قرارداد پیام است که میگوید برد با بقیهٔ پیام چه کند. آرایهٔ Wire برای این هدف ۳۲ بایت در نظر گرفته شده است؛ یک بایت به شمارهٔ فرمان اختصاص مییابد، پس حداکثر ۳۱ بایت در یک پیام متعارف برای داده میماند. کتابخانهٔ میزبان باید پیامهای بلندتر را مناسب قطعهقطعه کند.
آرایهٔ incomingData در کد ۲۵۷ بایت جا دارد، اما receiveEvent در ابتدای هر پیام شمارنده را صفر و آرایه را پاک میکند و همانجا تابع فرمان را صدا میزند. پس نباید این آرایه را صف پیوستهٔ ۲۵۶ بایتی برای جذب مکث کارت معرفی کرد. عملیات فایل در مسیر callback دریافت I²C انجام میشود. وقتی کارت معطل میکند، میزبان باید رفتار کشدادن کلاک و زمان انتظار سازگار داشته باشد؛ صرف انتخاب کلاک ۴۰۰ کیلوهرتز، سرعت ثابت ثبت را تضمین نمیکند. اگر صف مستقلی به حلقهٔ اصلی منتقل شود، طراحی تأیید فرمان، ازدحام و همزمانی هم باید تغییر کند.
در commands.ino، writeFile طول را با strlen میگیرد. این تابع تا اولین بایت صفر میشمارد: برای پیام فرضی 41 00 42، طول یک است، نه سه. بنابراین ثبت متن ساده و ثبت دلخواه دادهٔ دودویی یکسان نیستند. برای دادهٔ دودویی باید طول صریح و قرارداد پیام بازبینی شود، یا در میزبان آن را به متن/کدگذاری مناسب تبدیل کرد؛ کدگذاری حجم را بیشتر میکند.
محاسبهٔ حجم؛ سرعت نمونهبرداری با سرعت فایل یکی نیست
فرض کنید هر خط، شامل شماره، زمان و دما، دقیقاً ۲۴ بایت با پایان خط باشد و در هر ثانیه ۱۰ خط تولید شود. نرخ داده 24 × 10 = 240 byte/s و حجم یک شبانهروز 240 × 86400 = 20,736,000 byte، حدود ۲۰٫۷ مگابایت دهدهی، میشود. این اندازه شامل سربار فایلسیستم نیست و مقدار آن برای قالب واقعی شما باید دوباره شمرده شود. هر خط در ظرفیت ۳۱ بایتی پیام جا میگیرد؛ شمارهٔ فرمان و نشانی و بیتهای تأیید همچنان روی سیم زمان میبرند.
در مثال دیگری، هزار نمونه در ثانیه با ۱۶ بایت برای هر نمونه، 16,000 byte/s تولید میکند. این نرخ به ادعای حدود ۲۰ هزار بایت بر ثانیهٔ صفحهٔ محصول نزدیک است، اما ادعای سازنده تضمین هر کارت و هر الگوی پیام نیست. حتی یک صف واقعی ۲۵۶ بایتی نیز در این نرخ فقط 256 / 16000 = 0.016 s، یعنی ۱۶ میلیثانیه، فرصت میدهد. آرایهٔ فعلی آن صف نیست. اگر کاربرد شما لرزش یا صوت پیوسته است، بیشترین مکث کارت و تحمل ازدحام را اندازه بگیرید و معماری را بر اساس بدترین زمان بسازید، نه صرفاً میانگین سرعت.
قطع برق؛ چرا دریافت موفق کافی نیست؟
writeFile نتیجهٔ workingFile.write را بررسی نمیکند و سپس بیت موفقیت را تنظیم میکند. syncFile نیز نتیجهٔ sync را نادیده میگیرد و موفقیت را اعلام میکند. بنابراین این بیت در همین نسخه، شاهد کافیِ نوشتن کامل یا موفقیت همگامسازی نیست. اصلاح مشخص این است که تعداد بایت نوشتهشده با طول مورد انتظار مقایسه و نتیجهٔ sync نیز در وضعیت گزارش شود. سمت میزبان هم باید این وضعیت را بخواند و برای خطا تصمیم داشته باشد؛ تکرار بیحساب نوشتن ممکن است رکورد تکراری بسازد.
نام MAX_IDLE_TIME_MSEC مقدار ۵۰۰ را تداعی میکند، اما حلقهٔ loop در شاخهٔ بیکاری، تجهیزات را خاموش و پردازنده را خواب میکند؛ در همان شاخه فراخوانی workingFile.sync وجود ندارد. پس از نام متغیر یا توضیح قدیمی کد نتیجه نگیرید که هر ۵۰۰ میلیثانیه داده تضمینشده روی کارت میرود. همگامسازی صریح، پایان کار مرتب و تغذیهٔ کافی لازماند. حتی sync موفق نیز ادعای تحمل قطع برق در هر کارت نیست؛ رفتار کنترلکنندهٔ داخلی کارت و خرابی احتمالی فایلسیستم باید جداگانه آزموده شود.
بهبودهای مشخص و هزینهٔ هرکدام
| شاهد و نیاز | تغییر پیشنهادی و هزینه | روش بررسی |
|---|---|---|
| مصرف کارت از همان خط ۳٫۳ ولت پردازنده تأمین میشود. | منبع با حاشیهٔ جریان مناسب و در صورت نیاز ذخیرهٔ انرژی و تشخیص افت برق اضافه شود؛ هزینهٔ قطعه، فضا و جریان راهاندازی بیشتر است. | ولتاژ را کنار J1 و U2 هنگام نوشتن و شروع کار کارت ثبت کنید؛ آزمون قطع برق با کارت آزمایشی و فایل غیرضروری باشد. |
| writeFile و syncFile نتیجه را کنترل نمیکنند. | گزارش خطا و شمار بایت واقعی اضافه شود؛ قرارداد میزبان و logger باید هماهنگ تغییر کند. | نوشتن کوتاه یا خطای sync را در آزمون نرمافزار تزریق کنید؛ سپس نبود کارت و پرشدن آن را روی نمونهٔ آزمایشی بررسی کنید. |
| عملیات فایل داخل callback دریافت انجام میشود. | برای میزبان حساس به مکث، صف محدود و پردازش در حلقهٔ اصلی بررسی شود؛ RAM، مدیریت ازدحام و وضعیت busy لازم میشود. | بیشترین تأخیر و زمان انتظار میزبان را با کارتهای هدف اندازه بگیرید؛ شمارهٔ ترتیبی رکوردها فقدان یا تکرار را آشکار کند. |
| strlen داده را در اولین بایت صفر کوتاه میکند. | برای دادهٔ دودویی، طول صریح و پیامبندی تعریف شود؛ یا متن ذخیره شود که حجم و تبدیل بیشتری دارد. | ورودیهای صفر، طول صفر، ۳۱ بایت و چندپیامی را با خروجی فایل مقایسه کنید. |
| ساعت ۱۶ مگاهرتز با تغذیهٔ ۳٫۳ ولت نیازمند بازبینی محدودهٔ تضمینشده است. | در طراحی تازه، ساعت و firmware و bootloader منطبق انتخاب شوند؛ کاهش ساعت ممکن است توان پردازش را کم کند. | شرایط بدترین ولتاژ و دما، زمانبندی ارتباط و نرخ ثبت بررسی شوند؛ کارکرد یک نمونه جای محدودهٔ دیتاشیت را نمیگیرد. |
راهاندازی مرحلهبهمرحله و سنجش نتیجه
- مدل دقیق برد و فرمت کارت را مشخص کنید. قبل از تغذیه، جهت اتصال، زمین و نبود اتصال کوتاه را بررسی کنید. برای شروع هیچ بار یا سیم بلند اضافی لازم نیست.
- با منبع ۳٫۳ ولتی مناسب روشن کنید و ولتاژ کنار کارت را بسنجید. اگر میزبان ۵ ولتی است، سازگاری تغذیه و خطوط را جداگانه حل کنید؛ اتصال مکانیکی بهتنهایی سازگاری نیست.
- ابتدا فقط پاسخ نشانی 0x2A، یا با جامپر بسته 0x29، را بررسی کنید. سپس وضعیت آمادهبودن کارت و بازبودن فایل را بخوانید؛ ACK تنها حضور یک پاسخدهنده را نشان میدهد.
- چند خط کوتاهِ شمارهدار بنویسید، فرمان موجود sync را اجرا و کار را مرتب پایان دهید. کارت را با قطع امن تغذیه خارج کنید و تعداد و محتوای خطها را روی کامپیوتر مقایسه کنید.
- نرخ را بهتدریج بالا ببرید و تأخیر، رکورد گمشده و رکورد تکراری را جدا ثبت کنید. زمان نمونهبرداری را میزبان در داده بنویسد؛ این طرح، ساعت واقعیِ تقویمی روی برد ندارد.
- فقط پس از موفقیت مسیر عادی، خطاهای کارت و قطع برق کنترلشده را با دادهٔ قابل حذف بررسی کنید. معیار پذیرش از پیش روشن باشد: چه مقدار داده ممکن است از دست برود و پس از وصل برق چه بازیابیای لازم است؟
فایل وابستگی firmware نسخهٔ SdFat 1.1.4 یا پیش از شاخهٔ 2 را توصیه میکند و SerialPort را هم لازم میداند. فایلهای HEX در مخزن وجود دارند، اما وجود آنها اثبات بازتولید باینری با کتابخانههای امروز نیست. در این بررسی firmware کامپایل یا روی برد اجرا نشده است؛ نتیجهها از خواندن مدار، PCB و کد و بررسی محاسباتاند. برای شروع کار عملی، کتابخانهٔ میزبان SparkFun و نسخهٔ سازگار آن را جدا انتخاب و ثبت کنید؛ این مخزنِ وابسته با commit سختافزار یکی نیست.
منابع، فایل محاسبه و حدود بررسی
فایل محاسبات مثالها ده بررسی عددی ساده دارد؛ شبیهسازی مدار یا کارت نیست. شماتیک و PCB و مسیرهای اصلی firmware در commit ذکرشده خوانده شدند؛ هیچ بردی ساخته یا فلش نشده، آزمون فیزیکی، اندازهگیری نویز و آزمون دوام قطع برق انجام نشده است. بخش اختیاری توسعهٔ firmware برای کسی است که با برنامهنویسی و ابزار AVR آشناست؛ فهم مسئله به اجرای کد یا خرید برد وابسته نیست.
سختافزار متعلق به SparkFun Electronics است و سرآیند firmware نام Nathan Seidle را دارد. فایل مجوز پروژه سختافزار را CC BY-SA 4.0 و نرمافزار را MIT معرفی میکند؛ متن public-domain/Beerware در سرآیند فایل اصلی نیز باید هنگام بازاستفاده حفظ و بررسی شود. شکلهای توضیحی از طراحی بازترسیم شدهاند و عکس برد نیستند؛ مجوز و تغییرات شکلها جدا در دسترس است. ارزش این پروژه برای یادگیری، امکان دنبالکردن مسیر کامل از دادهٔ حسگر تا فایل و دیدن فاصلهٔ میان «کار میکند» و «در خطا هم قابل اتکاست» است.
پرسش و پاسخ مقاله
سوال فنی خود را مطرح کنید
پرسشها و پاسخها پس از بررسی مدیر منتشر میشوند. نویسنده، پیشنویس در انتظار بررسی را میبیند.
هنوز پرسش تاییدشدهای برای این مقاله ثبت نشده است.