در قسمت قبل از آموزش آردوینو با قابلیتهای پیشرفته LCDهای متنی آشنا شدیم و یاد گرفتیم چگونه کاراکترهای سفارشی بسازیم، اعداد بزرگ نمایش دهیم و حتی نمودار میلهای روی LCD ایجاد کنیم. در این قسمت آموزش برنامه نویسی آردوینو از نمایشگرهای متنی عبور میکنیم و وارد دنیای نمایشگرهای گرافیکی با آردوینو میشویم.
ابتدا بررسی میکنیم هنگام انتخاب یک نمایشگر گرافیکی باید به چه مشخصاتی توجه کنیم. سپس یک نمایشگر TFT رنگی مبتنی بر ST7735 را راهاندازی میکنیم و در ادامه با OLED تکرنگ SSD1306 و کتابخانههای Adafruit_GFX، Adafruit_SSD1306 و u8g2 آشنا میشویم.
اگر بخواهیم علاوه بر متن، اشکال هندسی، نمودار، تصاویر یا یک رابط کاربری گرافیکی روی پروژه نمایش دهیم، LCDهای متنی دیگر کافی نیستند و باید از یک نمایشگر گرافیکی استفاده کنیم. نمایشگرهای گرافیکی مختلفی برای Arduino وجود دارند و انتخاب مدل مناسب به نیاز پروژه بستگی دارد. برخی از مهمترین عوامل هنگام انتخاب نمایشگر عبارتاند از:

یکی از اولین تصمیمها هنگام انتخاب نمایشگر، انتخاب بین مدل رنگی و تکرنگ است. این تصمیم فقط به ظاهر پروژه مربوط نمیشود. عواملی مانند اندازه نمایشگر، مصرف انرژی، قابلیت Touch، نوع اتصال و مقدار حافظه موردنیاز برنامه نیز در انتخاب تأثیر دارند. نمایشگرهای گرافیکی رایج در پروژههای Arduino معمولاً بر پایه دو فناوری هستند:
OLED برخلاف LCD معمولی برای دیدهشدن در محیط تاریک به نور پسزمینه نیاز ندارد. این موضوع میتواند در برخی کاربردها باعث کاهش مصرف انرژی شود. در مقابل، نمایشگرهای OLED معمولاً در اندازه مشابه قیمت بیشتری دارند و مدلهایی که برای پروژههای Arduino عرضه میشوند اغلب کوچکتر هستند. OLEDهای رنگی نیز وجود دارند، اما نمونههای مناسب Arduino معمولاً کوچک و گرانتر هستند.
نمایشگر تکرنگ گزینه مناسبی است اگر:
حافظه موردنیاز برای کار با یک نمایشگر تکرنگ معمولاً کمتر از یک نمایشگر رنگی است و این موضوع در بردهای دارای حافظه محدود اهمیت زیادی دارد.
یکی از کتابخانههای قدرتمند برای نمایشگرهای تکرنگ، u8g2 است. این کتابخانه از تعداد زیادی کنترلر نمایشگر پشتیبانی میکند.
از جمله کنترلرهای پشتیبانیشده میتوان به موارد زیر اشاره کرد:
| 1 2 3 4 5 6 7 8 9 10 | SSD1305 SSD1306 SSD1309 SSD1322 SSD1325 SSD1327 SH1106 ST7565 ST7920 KS0108 |
این کتابخانه از روشهای ارتباطی I2C، SPI و Parallel نیز پشتیبانی میکند.
برای نمایشگرهای رنگی، کتابخانه Adafruit GFX یک مجموعه مشترک از توابع گرافیکی در اختیار برنامهنویس قرار میدهد. کتابخانههای مخصوص کنترلرهایی مانند ST7735، HX8340B، HX8357D، ILI9340/ILI9341 و PCD8544 میتوانند از قابلیتهای این کتابخانه استفاده کنند.
در بخش 11.10 کتاب به سراغ یک نمایشگر گرافیکی تمامرنگی مبتنی بر ST7735 میرویم. کتابخانه Adafruit ST7735 and ST7789 از نمایشگرهای مبتنی بر کنترلرهای ST7735 و ST7789 پشتیبانی میکند و برای رسم عناصر گرافیکی از Adafruit_GFX استفاده میشود. مثال اصلی کتاب برای برد Adafruit HalloWing M0 نوشته شده است. برنامه ابتدا سه متن با اندازههای مختلف نمایش میدهد و سپس یک توپ زرد را روی صفحه حرکت میدهد.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | /* * Adafruit GFX ST7735 sketch * Display text and a moving ball on the display */ #include <Adafruit_GFX.h> #include <Adafruit_ST7735.h> #include <SPI.h> #define TFT_CS 39 #define TFT_RST 37 #define TFT_DC 38 #define TFT_BACKLIGHT 7 Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); void setup(void) { tft.initR(INITR_144GREENTAB); pinMode(TFT_BACKLIGHT, OUTPUT); digitalWrite(TFT_BACKLIGHT, HIGH); tft.setRotation(2); tft.fillScreen(ST77XX_BLACK); tft.setCursor(0, 0); tft.setTextWrap(false); tft.setTextColor(ST77XX_RED); tft.setTextSize(1); tft.println("Small"); tft.setTextColor(ST77XX_GREEN); tft.setTextSize(2); tft.println("Medium"); tft.setTextColor(ST77XX_BLUE); tft.setTextSize(3); tft.println("Large"); } int ballDir = 1; int ballDiameter = 8; int ballX = ballDiameter; void loop() { if(ballX >= tft.width() - ballDiameter || ballX < ballDiameter) { ballDir *= -1; } ballX += ballDir; int ballY = tft.getCursorY() + ballDiameter * 2; tft.fillCircle( ballX, ballY, ballDiameter / 2, 0xffff00 ); delay(25); tft.fillCircle( ballX, ballY, ballDiameter / 2, 0x000000 ); } |
دستور زیر نمایشگر را مقداردهی اولیه میکند:
| 1 | tft.initR(INITR_144GREENTAB); |
مدلهای مختلف ST7735 ممکن است به پارامتر متفاوتی برای initR() نیاز داشته باشند، بنابراین باید مدل دقیق نمایشگر و مستندات کتابخانه بررسی شود.
جهت نمایش با دستور زیر تعیین میشود:
| 1 | tft.setRotation(2); |
و کل صفحه با رنگ مشکی پر میشود:
| 1 | tft.fillScreen(ST77XX_BLACK); |
در این مثال سه متن با سه اندازه و رنگ مختلف نمایش داده میشوند:
| 1 2 3 4 5 6 7 8 9 10 11 | tft.setTextColor(ST77XX_RED); tft.setTextSize(1); tft.println("Small"); tft.setTextColor(ST77XX_GREEN); tft.setTextSize(2); tft.println("Medium"); tft.setTextColor(ST77XX_BLUE); tft.setTextSize(3); tft.println("Large"); |
متغیر ballDir جهت حرکت توپ را تعیین میکند.
زمانی که توپ به لبه صفحه نزدیک میشود، جهت حرکت معکوس میشود:
| 1 2 3 4 5 | if(ballX >= tft.width() - ballDiameter || ballX < ballDiameter) { ballDir *= -1; } |
سپس توپ با تابع fillCircle() رسم و با رنگ مشکی پاک میشود تا حرکت آن روی صفحه دیده شود.

اگر بهجای HalloWing از Arduino Uno و یک ماژول ST7735 مستقل استفاده شود، کتاب پایههای زیر را برای مثال Arduino Uno معرفی میکند:
| 1 2 3 4 5 6 7 | #define TFT_CS 10 #define TFT_RST 9 #define TFT_DC 8 #define TFT_BACKLIGHT 7 Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); |
در این اتصال:
TFT_CS برای Chip Select است.TFT_DC خط Data/Command است.TFT_RST برای Reset نمایشگر استفاده میشود.در صورت نیاز میتوان پایههای MOSI و Clock را نیز بهصورت نرمافزاری مشخص کرد:
| 1 2 3 4 5 6 7 8 9 10 11 | #define TFT_SCLK 5 #define TFT_MOSI 6 Adafruit_ST7735 tft = Adafruit_ST7735( TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST ); |
اما Software SPI سرعت کمتری نسبت به Hardware SPI دارد. همچنین کتاب اشاره میکند که اگر ماژول LCD دارای SD Card باشد، SD با این شیوه Software SPI کار نخواهد کرد.
در بخش 11.11 کتاب به سراغ OLED تکرنگ SSD1306 میرویم. مثال کتاب از یک نمایشگر 128×32 و ارتباط SPI استفاده میکند.
کتابخانههای موردنیاز عبارتاند از:
| 1 2 3 | #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | /* * OLED SSD13xx sketch * Display text and a moving ball on an OLED display. */ #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define WIDTH 128 #define HEIGHT 32 #define OLED_DC 8 #define OLED_CS 10 #define OLED_RESET 9 Adafruit_SSD1306 display( WIDTH, HEIGHT, &SPI, OLED_DC, OLED_RESET, OLED_CS ); #define MODE SSD1306_SWITCHCAPVCC void setup() { Serial.begin(9600); if(!display.begin(MODE)) { Serial.println("Could not initialize display"); while(1); } showAndScroll("Small", 1); showAndScroll("Medium", 2); showAndScroll("Large", 3); } void showAndScroll(String text, int textSize) { display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.clearDisplay(); display.setTextSize(textSize); display.println(text); display.display(); display.startscrollright(0x00, 0x0F); delay(3000); display.stopscroll(); } int ballDir = 1; int ballDiameter = 8; int ballX = ballDiameter; int ballY = ballDiameter * 2; void loop() { display.clearDisplay(); if(ballX >= WIDTH - ballDiameter || ballX < ballDiameter) { ballDir *= -1; } ballX += ballDir; display.fillCircle( ballX, ballY, ballDiameter / 2, SSD1306_INVERSE ); display.display(); delay(25); display.fillCircle( ballX, ballY, ballDiameter / 2, SSD1306_INVERSE ); display.display(); } |

ابتدا ابعاد نمایشگر مشخص میشوند:
| 1 2 | #define WIDTH 128 #define HEIGHT 32 |
سپس پایههای موردنیاز رابط SPI تعیین میشوند:
| 1 2 3 | #define OLED_DC 8 #define OLED_CS 10 #define OLED_RESET 9 |
در setup() نمایشگر راهاندازی میشود:
| 1 2 3 4 5 | if(!display.begin(MODE)) { Serial.println("Could not initialize display"); while(1); } |
اگر راهاندازی موفق نباشد، پیام خطا در Serial Monitor نمایش داده میشود و برنامه متوقف میشود.
تابع showAndScroll() متن و اندازه آن را دریافت میکند.
ابتدا رنگ متن سفید انتخاب میشود:
| 1 | display.setTextColor(SSD1306_WHITE); |
سپس مکاننما به گوشه صفحه منتقل و Buffer پاک میشود:
| 1 2 | display.setCursor(0, 0); display.clearDisplay(); |
اندازه متن مشخص میشود:
| 1 | display.setTextSize(textSize); |
و متن در Buffer نوشته میشود:
| 1 | display.println(text); |
در SSD1306 دستورهای رسم ابتدا در حافظه Buffer ذخیره میشوند. برای انتقال نتیجه به خود نمایشگر باید دستور زیر اجرا شود:
| 1 | display.display(); |
این یکی از تفاوتهای مهم این مثال با TFT بخش قبلی است؛ در TFT بسیاری از عملیات رسم مستقیماً روی نمایشگر دیده میشوند، اما در SSD1306 باید Buffer به صفحه ارسال شود.
در مثال کتاب متن برای سه ثانیه به سمت راست Scroll میشود:
| 1 2 3 4 5 | display.startscrollright(0x00, 0x0F); delay(3000); display.stopscroll(); |
در حلقه اصلی، توپ بین دو سمت صفحه حرکت میکند. برای رسم توپ از دستور زیر استفاده میشود:
| 1 2 3 4 5 6 | display.fillCircle( ballX, ballY, ballDiameter / 2, SSD1306_INVERSE ); |
استفاده از SSD1306_INVERSE باعث معکوسشدن وضعیت پیکسلها میشود. به همین دلیل با اجرای مجدد همان دستور در همان موقعیت، توپ پاک میشود.
در صورت نیاز میتوان ارتباط SPI را بهصورت نرمافزاری انجام داد:
| 1 2 3 4 5 6 7 8 9 10 11 12 | #define OLED_CLK 5 #define OLED_MOSI 6 Adafruit_SSD1306 display( WIDTH, HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS ); |
برخی مدلهای SSD1306 از I2C استفاده میکنند. در این حالت تعداد سیمهای موردنیاز کمتر میشود. کتاب برای این حالت نمونه زیر را ارائه میکند:
| 1 2 3 4 5 6 7 8 9 10 11 12 | #include <Wire.h> #define WIDTH 128 #define HEIGHT 32 #define OLED_RESET 13 Adafruit_SSD1306 display( WIDTH, HEIGHT, &Wire, OLED_RESET ); |
در این روش ارتباط اصلی از طریق SCL و SDA انجام میشود.

کتاب علاوه بر کتابخانه Adafruit SSD1306، یک مثال با u8g2 نیز ارائه میکند. در u8g2 نحوه بهروزرسانی صفحه متفاوت است و از Page Buffer استفاده میشود.
ابتدا دستور زیر اجرا میشود:
| 1 | u8g2.firstPage(); |
سپس دستورات رسم داخل یک حلقه do...while قرار میگیرند:
| 1 2 3 4 5 | do { // drawing commands } while(u8g2.nextPage()); |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | /* * u8g2 oled sketch * Draw some text, move a ball. */ #include <Arduino.h> #include <U8g2lib.h> #include <SPI.h> #define OLED_DC 8 #define OLED_CS 10 #define OLED_RESET 9 U8G2_SSD1306_128X32_UNIVISION_2_4W_HW_SPI u8g2( U8G2_R0, OLED_CS, OLED_DC, OLED_RESET ); u8g2_uint_t displayWidth; void setup(void) { u8g2.begin(); u8g2.setFontPosTop(); displayWidth = u8g2.getDisplayWidth(); showAndScroll("Small", u8g2_font_6x10_tf); showAndScroll("Medium", u8g2_font_9x15_tf); showAndScroll("Large", u8g2_font_10x20_tf); } int ballDir = 1; int ballRadius = 4; int ballX = ballRadius * 2; int ballY = ballRadius * 4; void loop(void) { u8g2.firstPage(); do { if(ballX >= displayWidth - ballRadius * 2 || ballX < ballRadius * 2) { ballDir *= -1; } ballX += ballDir; u8g2.drawDisc( ballX, ballY, ballRadius ); } while(u8g2.nextPage()); delay(25); } void showAndScroll(String text, uint8_t *font) { for(int i=0; i<20; i++) { u8g2.firstPage(); do { u8g2.setFont(font); u8g2.drawStr( 10 + i, 10, text.c_str() ); } while(u8g2.nextPage()); delay(125); } } |
هر دو کتابخانه امکان کنترل SSD1306 را فراهم میکنند، اما روش بهروزرسانی تصویر متفاوت است.
در Adafruit SSD1306 ابتدا تصویر در Buffer رسم میشود و سپس:
| 1 | display.display(); |
برای انتقال تصویر به نمایشگر اجرا میشود.
در u8g2 از چرخه:
| 1 2 3 4 5 6 7 | u8g2.firstPage(); do { // drawing } while(u8g2.nextPage()); |
استفاده میشود و کتابخانه در چند مرحله محتوای صفحه را تولید میکند.
جمعبندی
در قسمت 62 آموزش آردوینو با نمایشگرهای گرافیکی آشنا شدیم. ابتدا بررسی کردیم هنگام انتخاب نمایشگر باید به عواملی مانند رزولوشن، اندازه، رنگ، مصرف انرژی، قابلیت Touch، نوع رابط و کتابخانههای موجود توجه کنیم.
سپس نمایشگر رنگی ST7735 را با کتابخانههای Adafruit_GFX و Adafruit_ST7735 راهاندازی کردیم و متنهای رنگی با اندازههای مختلف و یک توپ متحرک را نمایش دادیم. در ادامه OLED تکرنگ SSD1306 را بررسی کردیم و نحوه نمایش متن، Scroll، رسم اشکال و اتصال آن از طریق SPI و I2C را دیدیم. در پایان نیز با کتابخانه u8g2 و روش Page Buffer برای رسم محتوای گرافیکی آشنا شدیم.
با پایان این قسمت، فصل یازدهم آموزش و مبحث نمایشگرها در Arduino به پایان میرسد و در قسمت بعد وارد فصل جدید کتاب و مبحث زمان و تاریخ خواهیم شد.
سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.