معرفی برد Wemos Lolin۳۲ with built-in OLED

 

برد Wemos Lolin32 مجتمع شده با یک نمایشگر OLED، بر اساس تراشه ESP32 و یک نمایشگر OLED، 0.96 اینچی (168 در 64 پیکسل) ساخته شده است. نمایشگر تعبیه شده بر روی برد، توسط کنترلر SSD1306 و به وسیله باس I2C کنترل می شود.

برد Wemos Lolin32 با OLED تعبیه شده روی آن

در این برد، 19 پایه ورودی/خروجی در اختیار برنامه نویس قرار گرفته شده (ماژول ESP32 به تنهایی دارای 38 پایه می‌باشد) که 11 عدد از آن ها ورودی آنالوگ به دیجیتال (ADC) هستند. پایه‌های 4 (SDA) و 5 (SCL) برای باس I2C استفاده شده که نمایشگر OLED نیز به همین دو پایه متصل شده است. این برد دارای دو دکمه BOOT و EN (RST) می باشد که در بعضی از مدل ها بر روی برد و در بعضی از مدل ها در پشت برد تعبیه شده است.

مشخصات پایانه‌های روی برد

مشخصات ماژول ESP-WROOM-32

  • میکروپروسسور دو هسته ای با فرکانس MHz240 باMB  4 حافظه فلش SPI
  • پشتیبانی از حافظه فلش تاMB 16
  • وایفای b / g / n 11
  • بلوتوث 0 LE
  • میزان مصرف در حالت Sleep : 5 μA
  • حسگرهای تعبیه شده بر روی ماژول
    • اثر هال

نصب کتابخانه های مورد نیاز برای استفاده از OLED در محیط Arduino

در محیط آردوینو، از منوی Sketch ← Include Library ← Manage Libraries پنجره Library Manager را باز و عبارت SSD1306 را جستجو نمایید. در نهایت کتابخانه Adafruit SSD1306 را نصب کنید.

کتابخانه SSD1306

حال با جستجو عبارت GFX کتابخانه Adafruit GFX Library را نیز نصب نمایید.

کتابخانه GFX

در نهایت بعد از نصب این کتابخانه ها، با باز و بسته کردن Arduino آن را ریستارت نمایید.

نمایش بر روی OLED

کتابخانه های Adafruit به صورت پیش فرض از پایه‌های 21 و 22 برای ارتباط I2C استفاده می‌نماید. جهت عوض کردن این دو پایه در بخش setup()، دستور زیر را اضافه نمایید :

Wire.begin(5, 4);

همچنین برای راه‌اندازی نمایشگر از کد زیر استفاده نمایید :

display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false, false)

مقدار false در پارامترهای دوم و سوم در این تابع مشخص می‌کند که به جای استفاده از پین‌های پیش‌فرض از پین‌های اختصاص یافته در کد برای باس I2C استفاده شود.

تست نمایشگر

از منوی File ← Examples ← Adafruit SSD1306 ← ssd1306_128X64_i2c را انتخاب نمایید. کد زیر در یک پنجره جدید بارگزاری می‌شود :

کد تست نمایشگر

 

/*********

Complete project details at https://randomnerdtutorials.com

This is an example for our Monochrome OLEDs based on SSD1306 drivers. Pick one up today in the adafruit shop! ——> http://www.adafruit.com/category/63_98

This example is for a 128×32 pixel display using I2C to communicate 3 pins are required to interface (two I2C and one reset).

Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!

Written by Limor Fried/Ladyada for Adafruit Industries, with contributions from the open source community. BSD license, check license.txt for more information All text above, and the splash screen below must be included in any redistribution.

*********/

#include <SPI.h>

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels

#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)

#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define NUMFLAKES 10 // Number of snowflakes in the animation example

#define LOGO_HEIGHT 16

#define LOGO_WIDTH 16

static const unsigned char PROGMEM logo_bmp[] =

{ B00000000, B11000000,

B00000001, B11000000,

B00000001, B11000000,

B00000011, B11100000,

B11110011, B11100000,

B11111110, B11111000,

B01111110, B11111111,

B00110011, B10011111,

B00011111, B11111100,

B00001101, B01110000,

B00011011, B10100000,

B00111111, B11100000,

B00111111, B11110000,

B01111100, B11110000,

B01110000, B01110000,

B00000000, B00110000 };

void setup() {

Serial.begin(115200);

// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {

Serial.println(F(“SSD1306 allocation failed”));

for(;;); // Don’t proceed, loop forever

}

// Show initial display buffer contents on the screen —

// the library initializes this with an Adafruit splash screen.

display.display();

delay(2000); // Pause for 2 seconds

// Clear the buffer

display.clearDisplay();

// Draw a single pixel in white

display.drawPixel(10, 10, WHITE);

// Show the display buffer on the screen. You MUST call display() after

// drawing commands to make them visible on screen!

display.display();

delay(2000);

// display.display() is NOT necessary after every single drawing command,

// unless that’s what you want…rather, you can batch up a bunch of

// drawing operations and then update the screen all at once by calling

// display.display(). These examples demonstrate both approaches…

testdrawline(); // Draw many lines

testdrawrect(); // Draw rectangles (outlines)

testfillrect(); // Draw rectangles (filled)

testdrawcircle(); // Draw circles (outlines)

testfillcircle(); // Draw circles (filled)

testdrawroundrect(); // Draw rounded rectangles (outlines)

testfillroundrect(); // Draw rounded rectangles (filled)

testdrawtriangle(); // Draw triangles (outlines)

testfilltriangle(); // Draw triangles (filled)

testdrawchar(); // Draw characters of the default font

testdrawstyles(); // Draw ‘stylized’ characters

testscrolltext(); // Draw scrolling text

testdrawbitmap(); // Draw a small bitmap image

// Invert and restore display, pausing in-between

display.invertDisplay(true);

delay(1000);

display.invertDisplay(false);

delay(1000);

testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps

}

void loop() {

}

void testdrawline() {

int16_t i;

display.clearDisplay(); // Clear display buffer

for(i=0; i<display.width(); i+=4) {

display.drawLine(0, 0, i, display.height()-1, WHITE);

display.display(); // Update screen with each newly-drawn line

delay(1);

}

for(i=0; i<display.height(); i+=4) {

display.drawLine(0, 0, display.width()-1, i, WHITE);

display.display();

delay(1);

}

delay(250);

display.clearDisplay();

for(i=0; i<display.width(); i+=4) {

display.drawLine(0, display.height()-1, i, 0, WHITE);

display.display();

delay(1);

}

for(i=display.height()-1; i>=0; i-=4) {

display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);

display.display();

delay(1);

}

delay(250);

display.clearDisplay();

for(i=display.width()-1; i>=0; i-=4) {

display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);

display.display();

delay(1);

}

for(i=display.height()-1; i>=0; i-=4) {

display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);

display.display();

delay(1);

}

delay(250);

display.clearDisplay();

for(i=0; i<display.height(); i+=4) {

display.drawLine(display.width()-1, 0, 0, i, WHITE);

display.display();

delay(1);

}

for(i=0; i<display.width(); i+=4) {

display.drawLine(display.width()-1, 0, i, display.height()-1, WHITE);

display.display();

delay(1);

}

delay(2000); // Pause for 2 seconds

}

void testdrawrect(void) {

display.clearDisplay();

for(int16_t i=0; i<display.height()/2; i+=2) {

display.drawRect(i, i, display.width()-2*i, display.height()-2*i, WHITE);

display.display(); // Update screen with each newly-drawn rectangle

delay(1);

}

delay(2000);

}

void testfillrect(void) {

display.clearDisplay();

for(int16_t i=0; i<display.height()/2; i+=3) {

// The INVERSE color is used so rectangles alternate white/black

display.fillRect(i, i, display.width()-i*2, display.height()-i*2, INVERSE);

display.display(); // Update screen with each newly-drawn rectangle

delay(1);

}

delay(2000);

}

void testdrawcircle(void) {

display.clearDisplay();

for(int16_t i=0; i<max(display.width(),display.height())/2; i+=2) {

display.drawCircle(display.width()/2, display.height()/2, i, WHITE);

display.display();

delay(1);

}

delay(2000);

}

void testfillcircle(void) {

display.clearDisplay();

for(int16_t i=max(display.width(),display.height())/2; i>0; i-=3) {

// The INVERSE color is used so circles alternate white/black

display.fillCircle(display.width() / 2, display.height() / 2, i, INVERSE);

display.display(); // Update screen with each newly-drawn circle

delay(1);

}

delay(2000);

}

void testdrawroundrect(void) {

display.clearDisplay();

for(int16_t i=0; i<display.height()/2-2; i+=2) {

display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i,

display.height()/4, WHITE);

display.display();

delay(1);

}

delay(2000);

}

void testfillroundrect(void) {

display.clearDisplay();

for(int16_t i=0; i<display.height()/2-2; i+=2) {

// The INVERSE color is used so round-rects alternate white/black

display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i,

display.height()/4, INVERSE);

display.display();

delay(1);

}

delay(2000);

}

void testdrawtriangle(void) {

display.clearDisplay();

for(int16_t i=0; i<max(display.width(),display.height())/2; i+=5) {

display.drawTriangle(

display.width()/2 , display.height()/2-i,

display.width()/2-i, display.height()/2+i,

display.width()/2+i, display.height()/2+i, WHITE);

display.display();

delay(1);

}

delay(2000);

}

void testfilltriangle(void) {

display.clearDisplay();

for(int16_t i=max(display.width(),display.height())/2; i>0; i-=5) {

// The INVERSE color is used so triangles alternate white/black

display.fillTriangle(

display.width()/2 , display.height()/2-i,

display.width()/2-i, display.height()/2+i,

display.width()/2+i, display.height()/2+i, INVERSE);

display.display();

delay(1);

}

delay(2000);

}

void testdrawchar(void) {

display.clearDisplay();

display.setTextSize(1); // Normal 1:1 pixel scale

display.setTextColor(WHITE); // Draw white text

display.setCursor(0, 0); // Start at top-left corner

display.cp437(true); // Use full 256 char ‘Code Page 437’ font

// Not all the characters will fit on the display. This is normal.

// Library will draw what it can and the rest will be clipped.

for(int16_t i=0; i<256; i++) {

if(i == ‘\n’) display.write(‘ ‘);

else display.write(i);

}

display.display();

delay(2000);

}

void testdrawstyles(void) {

display.clearDisplay();

display.setTextSize(1); // Normal 1:1 pixel scale

display.setTextColor(WHITE); // Draw white text

display.setCursor(0,0); // Start at top-left corner

display.println(F(“Hello, world!”));

display.setTextColor(BLACK, WHITE); // Draw ‘inverse’ text

display.println(3.141592);

display.setTextSize(2); // Draw 2X-scale text

display.setTextColor(WHITE);

display.print(F(“0x”)); display.println(0xDEADBEEF, HEX);

display.display();

delay(2000);

}

void testscrolltext(void) {

display.clearDisplay();

display.setTextSize(2); // Draw 2X-scale text

display.setTextColor(WHITE);

display.setCursor(10, 0);

display.println(F(“scroll”));

display.display(); // Show initial text

delay(100);

// Scroll in various directions, pausing in-between:

display.startscrollright(0x00, 0x0F);

delay(2000);

display.stopscroll();

delay(1000);

display.startscrollleft(0x00, 0x0F);

delay(2000);

display.stopscroll();

delay(1000);

display.startscrolldiagright(0x00, 0x07);

delay(2000);

display.startscrolldiagleft(0x00, 0x07);

delay(2000);

display.stopscroll();

delay(1000);

}

void testdrawbitmap(void) {

display.clearDisplay();

display.drawBitmap(

(display.width() – LOGO_WIDTH ) / 2,

(display.height() – LOGO_HEIGHT) / 2,

logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);

display.display();

delay(1000);

}

#define XPOS 0 // Indexes into the ‘icons’ array in function below

#define YPOS 1

#define DELTAY 2

void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {

int8_t f, icons[NUMFLAKES][3];

// Initialize ‘snowflake’ positions

for(f=0; f< NUMFLAKES; f++) {

icons[f][XPOS] = random(1 – LOGO_WIDTH, display.width());

icons[f][YPOS] = -LOGO_HEIGHT;

icons[f][DELTAY] = random(1, 6);

Serial.print(F(“x: “));

Serial.print(icons[f][XPOS], DEC);

Serial.print(F(” y: “));

Serial.print(icons[f][YPOS], DEC);

Serial.print(F(” dy: “));

Serial.println(icons[f][DELTAY], DEC);

}

for(;;) { // Loop forever…

display.clearDisplay(); // Clear the display buffer

// Draw each snowflake:

for(f=0; f< NUMFLAKES; f++) {

display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);

}

display.display(); // Show the display buffer on the screen

delay(200); // Pause for 1/10 second

// Then update coordinates of each flake…

for(f=0; f< NUMFLAKES; f++) {

icons[f][YPOS] += icons[f][DELTAY];

// If snowflake is off the bottom of the screen…

if (icons[f][YPOS] >= display.height()) {

// Reinitialize to a random position, just off the top

icons[f][XPOS] = random(1 – LOGO_WIDTH, display.width());

icons[f][YPOS] = -LOGO_HEIGHT;

icons[f][DELTAY] = random(1, 6);

}

}

}

}

بعد از آپلود کد، بر روی نمایشگر خطوط و متن های مختلف رسم خواهند شد (دقت نمایید که قبل از آپلود کد، پین های باس I2C را از حالت پیش‌فرض تغییر داده و بر روی پین‌های 4 و 5 تنظیم نمایید).

تست نمایشگر روی برد

نمایش متن بر روی نمایشگر

کد زیر متن “Hello World” را بر روی نمایشگر نشان می‌دهد.

کد نمایش Hello World بر روی نمایشگر

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels

#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {

Serial.begin(115200);

Wire.begin(5, 4);

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false, false)) { // Address 0x3D for 128×64

Serial.println(F(“SSD1306 allocation failed”));

for(;;);

}

delay(2000);

display.clearDisplay();

display.setTextSize(1);

display.setTextColor(WHITE);

display.setCursor(0, 10);

// Display static text

display.println(“Hello, world!”);

display.display();

}

void loop() {

}

بررسی و توضیح دستورهای مهم در کد

دستور

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

اندازه تصویر و پروتکل ارتباطی مورد استفاده را به عنوان پارامترهای ورودی به شی display می‌دهد. پارامتر چهارم (-1) به معنی این است که نمایشگر دارای پین Reset نمی‌باشد.

بعد از راه اندازی نمایشگر توسط کد

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false, false))

با استفاده از دستور delay(2000); یک تاخیر با اندازه دو ثانیه‌ ایجاد می‌کنیم، تا نمایشگر فرصت تنظیم شدن را پیدا نماید.

دستور

display.clearDisplay();

باعث پاکسازی بافر نمایشگر خواهد شد.

با استفاده از دستورهای

display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0);

به ترتیب اندازه، رنگ و مکان قرارگیری متن را مشخص می‌نماییم.

سپس با استفاده از دستور

display.println(“Hello, world!”);

متن مورد نظر خود (که در اینجا “Hello World!”) می باشد را بر روی نمایشگر چاپ می‌نماییم.

در نهایت با استفاده از دستور

display.display();

متن مورد نظر جهت نمایش به نمایشگر ارسال می‌شود.


منابع :

[1] “Unpacking Wemos ESP32 LoLin clone with 0.96” SSD1306 monochrome OLED display,” 14 04 2021. [Online]. Available: https://diyprojects.io/unpacking-wemos-esp32-lolin-clone-0-96-ssd1306-monochrome-oled-display/.

[2] “ESP32 Built-in OLED Board (Wemos Lolin32): Pinout, Libraries and OLED Control,” randomnerdtutorials, [Online]. Available: https://randomnerdtutorials.com/esp32-built-in-oled-ssd1306/. [Accessed 14 04 2021].

[3] “ESP32 OLED Display with Arduino IDE,” [Online]. Available: https://randomnerdtutorials.com/esp32-ssd1306-oled-display-arduino-ide/. [Accessed 14 04 2021].

نوشته های مشابه

دیدگاهتان را بنویسید

آدرس ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

forty six − = thirty six

بستن