آموزش راه اندازی و اتصال نمایشگر OLED با SPI در میکرو پایتون MicroPython

آموزش راه اندازی و اتصال نمایشگر OLED با SPI در میکرو پایتون MicroPython ، وقتی در دنیای میکروکنترلرها کار میکنی، یکی از جذابترین کاربردها نمایشگرها هستند. نمایشگر OLED به دلیل کنتراست بالا، مصرف انرژی پایین (به خصوص وقتی پیکسلها خاموشاند) و وضوح مناسب، انتخاب محبوبی برای پروژههای کوچک است. اما رساندن دادهها به نمایشگر به شیوهای سریع، مطمئن و بدون خطا، چالشی است. در این بین، پروتکل SPI یکی از گزینههای قدرتمند و پُر سرعت است که در بسیاری از میکروکنترلرها و پلتفرمها پشتیبانی میشود.
در این مقاله، ابتدا پروتکل SPI را به شکلی کاربردی و قابل درک معرفی میکنم، سپس نشان خواهم داد چطور میتوانی یک نمایشگر OLED (مثلاً مبتنی بر درایور SSD1306 یا مشابه) را با استفاده از MicroPython به کمک SPI کنترل کنی. در هر بخش، نکات عملی و ترفندهایی را که تجربهآموختهام میآورم تا راه را برای تو هموارتر کنم.
کلمات کلیدی مهم که در سراسر متن استفاده میشوند: SPI در میکروپایتون، OLED کنترل با SPI، SSD1306 SPI، میکروپایتون نمایشگر OLED، ارتباط SPI.
پروتکل SPI اصول، مزایا و محدودیتها
قبل از ورود به MicroPython، باید یکبار دیگر SPI را از دید سختافزاری و منطقی بررسی کنیم چون بدون درک عمیق از آن، ممکن است در پروژهها دچار سردرگمی و اشکال شوی.
چیستی SPI
SPI (مخفف Serial Peripheral Interface) یک پروتکل ارتباط سریال سنکرون است که بین یک «مستر» (معمولاً میکروکنترلر) و یک یا چند «اسلیو» (مثلاً نمایشگر، حافظه فلش، سنسور) برقرار میشود. ویژگیهای اصلی SPI:
- سگنالهای پایه:
- SCLK (Clock) سیگنال کلاک
- MOSI (Master Out, Slave In) دادهای که مستر به اسلیو میفرستد
- MISO (Master In, Slave Out) دادهای که اسلیو به مستر میفرستد (اگر نیاز باشد)
- CS یا SS (Chip Select / Slave Select) برای انتخاب اسلیوی که با آن در ارتباط هستیم
- ارتباط سنکرون: دادهها همزمان با لبههای کلاک منتقل میشوند، یعنی گیرنده و فرستنده باید هماهنگ با کلاک باشند.
- فولداپلکس یا نیمداپلکس: در حالت کامل، هم ارسال و هم دریافت همزمان ممکن است، اما در بسیاری از کاربردهای نمایشگر، فقط ارسال داده به نمایشگر کافی است.
مزایا و معایب SPI نسبت به سایر پروتکلها
مزایا:
- سرعت بالا چون نیازی به ارسال آدرس و تأیید نیست، انتقال دادهها سریعتر انجام میشود.
- سادگی منطق داده به محض داشتن پینها، پیادهسازی نسبتاً ساده است.
- قابلیت استفاده از چند اسلیو با پینهای جداگانه CS برای هر اسلیو میتوان چند دستگاه را به همان رابط متصل کرد.
معایب/محدودیتها:
- تعداد پین بیشتر نسبت به I2C که فقط دو سیم داده و کلاک نیاز دارد، SPI حداقل به ۴ سیم نیاز دارد.
- مسیر سیمبندی حساس اگر سیمهای MOSI، SCLK یا CS طولانی باشند، نویز یا تأخیر ممکن است باعث خطا شود.
- پشتیبانی محدود کتابخانهها بعضی کتابخانهها برای نمایشگرها تمرکز بیشتری روی I2C دارند؛ استفاده از SPI ممکن است نیاز به تغییر یا نوشتن خودت داشته باشد.
- عدم آدرسدهی اتوماتیک برخلاف I2C که هر دستگاه آدرس دارد، در SPI خودت باید پین CS را مدیریت کنی.
با این مقدمه، اگر بخوای روی سرعت و کارایی تمرکز کنی، استفاده از SPI برای نمایشگر OLED خیلی منطقی است به شرطی که سیمبندی دقیق، نویز کم و اشکالزدایی را جدی بگیری.
معرفی نمایشگر OLED و درایورهای رایج
پیش از اینکه سراغ پیادهسازی با MicroPython برویم، لازم است با نمایشگر OLED و درایور آن آشنا باشی تا بفهمی دقیقاً چه چیزی را کنترل میکنی.
OLED چیست؟
OLED مخفف Organic Light Emitting Diode است. تفاوت اصلی OLED با LCD این است که در OLED از آرایههای آلی استفاده میشود که خودشان نور تولید میکنند، پس نیاز به نور پسزمینه (backlight) ندارند. این باعث میشود:
- کنتراست بسیار بالا (مشکی واقعی)
- مصرف انرژی پایینتر وقتی پیکسلها خاموش هستند
- زاویه دید عالی
اما معایبی هم دارد مثل محدودیت در روشنایی در محیطهای با نور زیاد یا دوام کمتر در برخی رنگها (در مدلهای رنگی).
درایور SSD1306 و نسخههای مشابه
یکی از رایجترین درایورهای نمایشگر OLED کوچک، SSD1306 است. این درایور تک رنگ (معمولاً سفید، آبی یا زرد) را پشتیبانی میکند و رزولوشنهای رایجش 128×64 یا 128×32 است. بسیاری از ماژولهای OLED کوچک برای پروژههای امبدد از این درایور استفاده میکنند. کتابخانههای MicroPython معمولاً نسخه SPI و I2C برای SSD1306 دارند.
از طرف دیگر، در برخی ماژولهای جدیدتر ممکن است درایورهایی مانند SH1107 یا SH1106 استفاده شود. برای آنها نیز نسخههای MicroPython وجود دارد یا باید کمی تغییر بدهی. (مثلاً پروژه SH1107 با پشتیبانی SPI و I2C در مخازن گیتهاب موجود است)
نکته مهم: وقتی ماژولی تهیه میکنی، دقیقاً باید بدانیم چه درایوری دارد (SSD1306 یا غیر آن) و آیا پشتیبانی SPI دارد یا صرفاً I2C. اگر فقط I2C داشته باشد، آن بخش از مقاله را فقط به عنوان مرجع بخوان.
طراحی سختافزاری اتصال OLED به میکروپایتون (بُرد)
در این بخش، شیوه اتصال سختافزاری نمایشگر OLED به بُردی که میخواهی از آن در میکروپایتون استفاده کنی (مثلاً ESP32، ESP8266، Raspberry Pi Pico، یا هر MCU سازگار) را بررسی میکنم. من در اینجا فرض میکنم که بُرد تو از رابط SPI پشتیبانی میکند.
انتخاب پینها و سیمبندی
برای مثال، فرض کن از ESP32 استفاده میکنی، اما همین اصول را برای سایر بُردها نیز میتوان به کار برد:
- SCLK: یکی از پینهای SPI Clock (مثلاً GPIO18 در ESP32)
- MOSI: یکی از پینهای SPI MOSI (مثلاً GPIO23 در ESP32)
- MISO: اگر نمایشگر بازخورد نمیدهد، ممکن است نیازی به استفاده از این خط نداشته باشی
- CS (Chip Select): هر نمایشگر نیاز به یک پین فعال-پایین دارد که وقتی آن پین پایین است، نمایشگر “فعال” است
- DC (Data/Command): پینی است که بین ارسال دستور (command) و ارسال داده (data) تمایز قائل میشود
- RESET (RST): برای ریست سختافزاری نمایشگر اختیاری ولی توصیهشده
- VCC و GND: تأمین تغذیه معمولاً 3.3 ولت ترجیح داده میشود
یک مثال واقعی برای MicroPython (مطابق مستندات رسمی) برای حالت SPI به صورت زیر است:
from machine import Pin, SPI
import ssd1306
hspi = SPI(1) # انتخاب رابط SPI
dc = Pin(4) # پین DC
rst = Pin(5) # پین Reset
cs = Pin(15) # پین Chip Select
display = ssd1306.SSD1306_SPI(128, 64, hspi, dc, rst, cs)
این روش در مستندات رسمی میکروپایتون برای ماژول SSD1306 ذکر شده است.
نکتهای که همواره باید رعایت شود: سرعت کلاک را به تدریج بالا ببر و در هر مرحله بررسی کن که نمایشگر به درستی دادهها را نمایش میدهد؛ اگر در سرعت بالا مشکل داشت، ممکن است سیمهای طولانی یا نویز باعث خطا شوند.
نکات عملی و توصیهها
- اگر طول سیمها زیاد شود، نویز و تداخل ممکن است باعث دریافت ناصحیح داده شود بهتر است سیمها را کوتاه نگه داری و در صورت امکان از سیمهای شیلددار استفاده کنی.
- اگر بُرد و نمایشگر زمین (GND) مشترک نداشته باشند، سطح سیگنال ممکن است ناصحیح باشد حتماً GND ها را مشترک کن.
- اگر پین RST را نداری یا آزاد باشد، باید نمایشگر را به درستی راهاندازی نرمافزاری کنی (ریست نرم).
- اگر بُردت چندین اسلیو SPI داشته باشد (مثلاً حسگر، حافظه، نمایشگر)، باید برای هر دستگاه پین CS جداگانه تعریف کنی و در لحظۀ استفاده، تنها آن را فعال کنی.
پیادهسازی در MicroPython مراحل و کد
حالا که ساختار سختافزاری آماده است، نوبت به بخش نرمافزاری میرسد. در اینجا مراحل کلی را با مثال کد واقعی توضیح میدهم، همراه با نکات تست و اشکالزدایی.
۱. آمادهسازی محیط
- ابتدا مطمئن باش MicroPython روی بُردت فلش شده است و میتوانی با محیطی مثل Thonny یا uPyCraft به آن وصل شوی.
- به کتابخانه
ssd1306.pyنیاز داری (که شامل نسخه SPI و I2C است). اگر به صورت پیشفرض در فریمورک نیست، باید این فایل را به فایل سیستم میکروکنترلر منتقل کنی. - پیش از اجرای نمایشگر، پیشنهاد میکنم یک اسکریپت تستی ساده بنویسی که فقط چند پیکسل را روشن کند تا ببینی ارتباط اصلی برقرار است.
۲. نمونه کد راهاندازی SPI و نمایشگر OLED
در ادامه یک مثال کامل را میبینی:
from machine import Pin, SPI
import time
import ssd1306
# پیکربندی SPI — پارامترها ممکن است بسته به بُرد متفاوت باشند
hspi = SPI(1, baudrate=10_000_000, polarity=0, phase=0, sck=Pin(14), mosi=Pin(13))
# پیکربندی پینهای کنترل نمایشگر
dc = Pin(4, Pin.OUT)
rst = Pin(5, Pin.OUT)
cs = Pin(15, Pin.OUT)
# ریست سختافزاری نمایشگر
rst.value(0)
time.sleep_ms(50)
rst.value(1)
# ساخت شیء نمایشگر با رابط SPI
oled = ssd1306.SSD1306_SPI(128, 64, hspi, dc, rst, cs)
# تست اولیه
oled.fill(0) # تمام پیکسلها خاموش
oled.text("Hello, SPI OLED!", 0, 0)
oled.show()
# حلقه نمایشی ساده
while True:
oled.fill(0)
oled.text("Time: {}".format(time.ticks_ms()), 0, 0)
oled.show()
time.sleep(1)
در این کد چند نکته حیاتی وجود دارد:
baudrate=10_000_000یک مقدار نمونه است؛ اگر در سرعت بالا خطا دیدی، آن را کاهش بده.polarityوphaseباید با درایور نمایشگر همخوانی داشته باشند (معمولاً Polarity=0، Phase=0 یا 1).- وضعیت پین CS باید کنترل شود: بعضی نسخههای کتابخانه بهطور خودکار آن را مدیریت میکنند؛ بعضی دیگر باید خودت قبل و بعد از ارسال فعال و غیرفعال کنی.
- بعد از ساخت شیء، باید دستور
oled.show()را فراخوانی کنی تا آنچه در بافر داخلی نوشته شده است روی نمایشگر نمایش داده شود.
۳. نقشه حافظه و مدیریت بافر (FrameBuffer)
نمایشگرهای SSD1306 در MicroPython بر پایه کلاس FrameBuffer کار میکنند. به این معنی که تمام ترسیمها (متن، خطوط، پیکسل) ابتدا در حافظهای به نام بافر (buffer) انجام میشوند و سپس oled.show() آن را به نمایشگر میفرستد. این کار دو مزیت دارد:
- امکان ترکیب چند دستور (مثلاً نوشتن متن + رسم خط) قبل از ارسال
- امکان آمادگی دادهها پیش از نمایش
اما نکتهای که اغلب باعث سردرگمی میشود این است که اگر بین فراخوانیهای fill()، text() و show() تغییری ندهی، تغییری ثبت نمیشود. بنابراین، ترتیب دستورات را باید به دقت رعایت کنی.
۴. نکات اشکالزدایی
- اگر نمایشگر اصلاً روشن نمیشود، اول پین RESET را بررسی کن، کلاک SPI را کم کن، و ببین که آیا خطا در ارسال ایجاد میشود یا نه.
- اگر تصویر خراب یا ناهمگون ظاهر میشود، ممکن است تنظیمات polarity/phase نادرست باشد. تغییر آنها را امتحان کن.
- اگر در سرعت بالا کار نمیکند ولی در سرعت پایین کار میکند، مشکل به نویز یا انعکاس سیگنال است سیمها را کوتاهتر کن یا از خازنهای بایپَس استفاده کن.
- از تابع
i2c.scan()(اگر در همان بُرد I2C هم استفاده کردهای) یا چک کردن بازگشت کتابخانه برای شناسایی دستگاهها استفاده کن تا مطمئن شوی نمایشگر شناسایی شده است. (در I2C این کار رایج است.) - در انجمنهای میکروپایتون دیده شده که برخی کاربران با خطاهایی مانند
OSError: EIOمواجه میشوند وقتی ارتباط فیزیکی یا تغذیه به درستی برقرار نیست.
مقایسه SPI و I2C برای OLED در میکروپایتون
حتماً شنیدهای که در اغلب پروژهها توصیه میشود از I2C برای OLED استفاده شود. چرا؟ چون فقط دو سیم نیاز دارد، ساده است و کتابخانههای زیادتری برای آن نوشته شدهاند. اما وقتی سرعت یا حجم داده زیاد باشد، SPI برتری خود را نشان میدهد.
در مستندات MicroPython، نسخه SPI کتابخانه SSD1306 به صراحت توضیح داده شده است.
از طرفی، در بسیاری از آموزشهای آنلاین، استفاده از I2C آسانتر توضیح داده شده است تا برای مبتدیان دردسر ایجاد نشود. مثلاً در آموزش ESP32 + OLED در RandomNerdTutorials، تمرکز بر I2C است.
اما اگر بخوای پروژهای مثل نمایش انیمیشن، یا بهروزرسانی سریع صفحه با داده زیاد اجرا کنی، SPI به خاطر سرعت برتر خود انتخاب بهتری است.
چند شاخص مقایسه:
| ویژگی | SPI | I2C |
|---|---|---|
| سرعت انتقال داده | بالا (میلیون بیت بر ثانیه) | محدودتر (معمولاً تا 400 کیلوبیت یا کمتر) |
| تعداد سیم | بیشتر | کمتر |
| سادگی کتابخانه | ممکن است نیاز به تنظیم بیشتر باشد | معمولاً کتابخانههای آماده بیشتر وجود دارد |
| مناسب برای پروژههای سریع یا با گرافیک | بله | ممکن است محدود باشد |
| ریسک تداخل و نویز | بیشتر | کمتر در پروژههای کم سرعت |
در نهایت، انتخاب بین SPI و I2C بستگی به نیاز پروژهات دارد: اگر نمایش ساده، متن یا داده کم است و میخواهی سیم کم مصرف کنی، I2C گزینه خوبی است؛ اگر به سرعت و کارایی نیاز داری، SPI انتخاب بهتری است (به شرطی که بتوانی مسائل فیزیکی آن را کنترل کنی).
چالشها، نکات پیشرفته و دیدگاه من به عنوان کسی که پروژهها را عملی کرده
میخواهم چند نکته را برات بگویم که در سایتها معمولاً نمیبینی از تجربه شخصی:
- کنترل مصرف انرژی
اگر پروژهات با باتری کار میکند، باید دقت کنی که وقتی نمایشگر بهروزرسانی ندارد، آن را در حالت کممصرف نگه داری. در OLED، خاموش کردن نمایشگر کامل یا کاهش فرکانس بهروزرسانی کمک میکند. - نمایش گرافیک/تصاویر
اگر بخوای تصویری روی OLED نمایش بدهی، باید آن را به بیتمپ مونو تبدیل کنی و در بافر بنویسی، سپس ارسال کنی. کتابخانههای SSD1306 موجود این امکان را دارند. پروژههایی مانند TimHanewich/MicroPython-SSD1306 نمونههایی از این کار هستند.
اما وقتی تصویر بزرگ باشد، ارسال کامل آن ممکن است زمانبر شود. راهحل: ارسال بخش به بخش (قطعهبندی) یا استفاده از حافظه خارجی اگر وجود دارد. - چند نمایشگر بر روی یک بُرد
اگر بخوای چند OLED را روی یک میکروکنترلر داشته باشی، باید دقت کنی پین CS هر کدام را جداگانه کنترل کنی و هر بار تنها یکی فعال باشد. اگر کتابخانه به درستی طراحی نشده باشد، ممکن است تداخل دادهها ایجاد شود. - هماهنگی فاز/قطبیت کلاک و تنظیمات سازگار
گاه تنظیماتpolarityوphaseدر SPI روی وضعیت مناسب نیست و باعث میشود دادههایی که میفرستی، ناهمخوان خوانده شوند. اگر نتیجه نمایش به هم ریخته بود، این دو گزینه را تغییر بده. - نسخه کتابخانه و هماهنگی با فریمورک MicroPython
چون MicroPython بر روی بُردهای مختلف با نسخهها و پورتهای متفاوت عرضه میشود، ممکن است کتابخانهssd1306.pyکه داری با ورژن بُردت ناسازگار باشد. مثلا برخی بُردها نسخهای از این کتابخانه را خودشان دارند و اگر نسخه متفاوتی آپلود کنی، تداخل پیش میآید. پس همیشه نسخه کتابخانه را بررسی کن.
پروژه GitHub “MicroPython SPI & I2C Display Driver for SSD1306” نمونهای از کتابخانهای است که هم SPI و هم I2C را پشتیبانی میکند. Github - پایداری در درازمدت و دمای محیط
اگر نمایشگر را در محیط با دمای بالا یا تغییر زیاد دما قرار دهی، ممکن است عملکردش دستخوش تغییر شود. پس اگر پروژه نهاییات قرار است در محیط متفاوت کار کند، تستش را در شرایط دمایی مختلف انجام بده.
در کل، من وقتی پروژهای طراحی میکنم، ابتدا با سرعت پایین شروع میکنم و پس از تأیید عملکرد، هر جزء را بهینه میکنم سرعت SPI، نحوه ارسال بخش به بخش، مدیریت انرژی، و در نهایت به فکر افزودن گرافیک یا انیمیشن میافتم.
نتیجهگیری
در این مقاله، ابتدا پروتکل SPI را به شکلی کاربردی بررسی کردیم، سپس نمایشگرهای OLED و درایورهای رایج را معرفی کردیم. بعد به طراحی سختافزاری اتصال به میکروکنترلر پرداختیم و در نهایت پیادهسازی کامل در MicroPython را با مثال کد ارائه دادم. همچنین نکات تجربی و چالشهایی که در پروژههای واقعی ممکن است با آنها مواجه شوی را با تو در میان گذاشتم.
اگر این مقاله آموزش راه اندازی و اتصال نمایشگر OLED با SPI در میکرو پایتون MicroPython برای شما مفید بود، آن را با دوستان خود به اشتراک بگذارید و برای مشاهده آموزشهای بیشتر به سایت ما سر بزنید.
مطلب پیشنهادی
آموزش ارتباط I2C در میکروپایتون برای خواندن داده از سنسور MPU6050
دیدگاههای محترمانه: لطفاً نظرات خود را با رعایت احترام به دیگران و به صورت محترمانه ارسال کنید. از بهکار بردن زبان توهینآمیز، تهدیدآمیز یا نژادپرستانه خودداری کنید.
حفظ حریم خصوصی: از درج اطلاعات شخصی خود یا دیگران مانند شماره تماس، آدرس و هرگونه اطلاعات حساس خودداری کنید.
محتوای تبلیغاتی: ارسال دیدگاههای تبلیغاتی، لینکهای خارجی یا هر نوع محتوای تجاری که مرتبط با موضوع نباشد، ممنوع است.
موافقت با قوانین: با ارسال دیدگاه خود، شما تأیید میکنید که قوانین فوق را خوانده و با آنها موافقید. تیم ما حق دارد نظرات غیرمجاز را حذف کند.
پروژه های پیشنهادی
پروژه ریموت کنترل کدلرن حرفه ای
مشاهده پروژهپروژه امپلی فایر صوتی استریو با TDA2030
مشاهده پروژهپروژه قفل دیجیتال با ماژول RFID RC522
مشاهده پروژه