Hướng dẫn giao tiếp với màn hình SSD1306 OLED bằng Arduino

Interfacing SSD1306 OLED Display with Arduino

 

Chuẩn bị:

  • Màn hình hiển thị 128×64 OLED  Module (SSD1306) 7 chân ( 0.96 inch )
  • Arduino UNO/Nano
  • Bo mạch thử
  • Dây nối
  • Máy tính

 

Giới thiệu về màn hình OLED

Monochrome 7-pin SSD1306 0.96 OLED display back sideMonochrome 7-pin SSD1306 0.96 OLED display

Từ OLED viết tắt của Organic Light emitting diode, áp dụng công nghệ tương tự với hầu hết các tivi của chúng ta nhưng có ít pixel hơn.Ở đây chúng ta sẽ sử dụng module SSD1306 0.96 inch .Module này có 3 loại giao tiếp khác nhau SPI 3, SPI 4 và I2C nhưng hướng dẫn này sẽ hướng dẫn sử dụng giao tiếp SPI 4.

 

 

Chi tiết các chân

 

Chân số Tên chân Các tên khác Sử dụng
1 Gnd Ground Chân ground
2 Vdd Vcc, 5V Chân cấp nguồn (3-5V)
3 SCK D0,SCL,CLK Chân clock, được sử dụng cho cả giao tiếp I2C và SPI
4 SDA D1,MOSI Chân data, được sử dụng cho cả giao tiếp I2C và SPI
5 RES RST,RESET Reset module
6 DC A0 Chân command dùng cho giao thức SPI
7 CS Chip Select Hữu dụng khi có hơn một module được sử dụng dưới giao thức SPI

Thư viện dễ sử dụng nhất nhất có lẽ là Adafruit_SSD1306. Nếu dự án bạn chiếm nhiều bộ nhớ, có thể dùng thư viện U8g vì dung lượng ít hơn.

Phần cứng và kết nối

Bên dưới là sơ đồ nối Ardunio với màn hình

Arduino interfacing with Monochrome OLED display circuit

Số Tên chân module Tên chân Arduino
1 Gnd, Ground Ground
2 Vdd, Vcc, 5V 5V
3 SCK, D0,SCL,CLK 10
4 SDA, D1,MOSI 9
5 RES, RST,RESET 13
6 DC, A0 11
7 CS, Chip Select 12

 

Lưu ý: Có thể màn hình sẽ không sáng ngay,để thay đổi hiển thị của màn hình thì bạn phải lập trình để thấy sự thay đổi

 

Lập trình 

 

Bước 1:

Tải thư viện Adafruit và thư viện GFX từ Github dùng đường link dưới:

  1. Adafruit Library
  2. GFX Graphics Library

 

Bước 2: Thêm thư viện bằng cách

Sketch->Include Library -> Add Zip   library

including library for Arduino interfacing with OLED display

Bước 3:

File->Examples->Adafruit SSD1306 -> SSD1306_128*64_SPI.ino

using example arduino code- for interfacing OLED display

Bước 4:  Thêm vào dòng “#define SSD1306_LCDHEIGHT 64” như sau

code for Arduino interfacing with OLED display

Bước 5:

Tải code lên bại sẽ thấy màn hình hiển thị OLED hiện lên với code mẫu như dưới. Có video hướng dẫn ở cuối để các bạn xem và tham khảo.

 

Code này cho bạn thấy tất cả các đồ họa có thể hiển thị được trên màn hình OLED, đủ để bạn tạo bitmap, vẽ hình, hiển thị chuỗi xâu ở phông và kích thước khác nhau…

Hiển thị và xóa màn hình :

Các câu lệnh được dùng để viết và hiển thị :

display.display(); //Write to display

display.clearDisplay(); //clear the display

Hiển thị biến xâu

Code sau được dùng để hiển thị nội dung chứa trong một biến :

char i=5; //the variable to be displayed

display.setTextSize(1);  //Select the size of the text

display.setTextColor(WHITE);  //for monochrome display only whit is possible

display.setCursor(0,0); //0,0 is the top left corner of the OLED screen

display.write(i); //Write the variable to be displayed

 

Vẽ đường thẳng, đường tròn, hình chữ nhật, hình vuông:

Nếu bạn muốn vẽ các hình trên màn hình thì có  thể dùng code sau :

display.drawLine(display.width()-1, 0, i, display.height()-1, WHITE);
//void drawLine( x0,  y0,  x1,  y1, color);

display.drawRect(i, i, display.width()-2*i, display.height()-2*i, WHITE);
//void drawRect( x0, y0,  w, h,  color);

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);
//void drawTriangle( x0,  y0,  x1,  y1,  x2,  y2,  color);

display.drawCircle(display.width()/2, display.height()/2, i, WHITE);
//void drawCircle( x0,  y0,  r,  color);

Hiển thị một chuỗi xâu trên màn hình với tùy chỉnh cỡ chữ và màu chữ:

display.setTextSize(2); //set the size of the text

display.setTextColor(WHITE); //color setting

display.setCursor(10,0); //The string will start at 10,0 (x,y)

display.clearDisplay(); //Eraser any previous display on the screen

display.println(“Circuit Digest”); //Print the string here “Circuit Digest”

display.display(); //send the text to the screen

Hiển thị hình ảnh bitmap :

Nếu bạn muốn hiển thị một hình ảnh thì dùng code sau :

static const unsigned char PROGMEM logo16_glcd_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 };

display.drawBitmap(XPO], YPOS, bitmap, w, h, WHITE);

//void drawBitmap( x,  y,  *bitmap,  w,  h,  color);

 

Để cho tiện thì các bạn có thể sử dụng trang này để chuyển đổi một hình ảnh thành các giá trị trên bitmap và cho vào mảng trên. Chỉ cần tải ảnh lên, bấm “generate code” rồi copy paste vào mảng. Đây là mẫu logo batman hiển thị trên màn hình :

convert image into bit map values OLED-display

batman logo on Monochrome 7 pin SSD1306 0.96-OLED display

 

Vẫn còn nhiều thứ các bạn có thể làm với thư viện này, các bạn có thể lên trang Adafruit GFX graphics Primitives để tham khảo thêm cách sử dụng màn hình OLED.

Code mẫu : 

/*********************************************************************
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×64 size display using SPI to communicate
4 or 5 pins are required to interface
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.
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// If using software SPI (the default case):
#define OLED_MOSI   9
#define OLED_CLK   10
#define OLED_DC    11
#define OLED_CS    12
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
/* Uncomment this block to use hardware SPI
#define OLED_DC     6
#define OLED_CS     7
#define OLED_RESET  8
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
*/
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16
static const unsigned char PROGMEM logo16_glcd_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 };
#define SSD1306_LCDHEIGHT 64
#if (SSD1306_LCDHEIGHT != 64)
#error(“Height incorrect, please fix Adafruit_SSD1306.h!”);
#endif
void setup()   {
Serial.begin(9600);
  // by default, we’ll generate the high voltage from the 3.3v line internally! (neat!)
display.begin(SSD1306_SWITCHCAPVCC);
// init done

// Show image buffer on the display hardware.
// Since the buffer is intialized with an Adafruit splashscreen
// internally, this will display the splashscreen.
display.display();
delay(2000);

  // Clear the buffer.
display.clearDisplay();
  // draw a single pixel
display.drawPixel(10, 10, WHITE);
// Show the display buffer on the hardware.
// NOTE: You _must_ call display after making any drawing commands
// to make them visible on the display hardware!
display.display();
delay(2000);
display.clearDisplay();
  // draw many lines
testdrawline();
display.display();
delay(2000);
display.clearDisplay();
  // draw rectangles
testdrawrect();
display.display();
delay(2000);
display.clearDisplay();
  // draw multiple rectangles
testfillrect();
display.display();
delay(2000);
display.clearDisplay();
  // draw mulitple circles
testdrawcircle();
display.display();
delay(2000);
display.clearDisplay();
  // draw a white circle, 10 pixel radius
display.fillCircle(display.width()/2, display.height()/2, 10, WHITE);
display.display();
delay(2000);
display.clearDisplay();
  testdrawroundrect();
delay(2000);
display.clearDisplay();
  testfillroundrect();
delay(2000);
display.clearDisplay();
  testdrawtriangle();
delay(2000);
display.clearDisplay();

testfilltriangle();
delay(2000);
display.clearDisplay();

  // draw the first ~12 characters in the font
testdrawchar();
display.display();
delay(2000);
display.clearDisplay();
  // draw scrolling text
testscrolltext();
delay(2000);
display.clearDisplay();
  // text display tests
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println(“Hello, world!”);
display.setTextColor(BLACK, WHITE); // ‘inverted’ text
display.println(3.141592);
display.setTextSize(2);
display.setTextColor(WHITE);
display.print(“0x”); display.println(0xDEADBEEF, HEX);
display.display();
delay(2000);
display.clearDisplay();
  // miniature bitmap display
display.drawBitmap(30, 16,  logo16_glcd_bmp, 16, 16, 1);
display.display();
  // invert the display
display.invertDisplay(true);
delay(1000);
display.invertDisplay(false);
delay(1000);
display.clearDisplay();
  // draw a bitmap icon and ‘animate’ movement
testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
}
void loop() {
}
void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
uint8_t icons[NUMFLAKES][3];

// initialize
for (uint8_t f=0; f< NUMFLAKES; f++) {
icons[f][XPOS] = random(display.width());
icons[f][YPOS] = 0;
icons[f][DELTAY] = random(5) + 1;

Serial.print(“x: “);
Serial.print(icons[f][XPOS], DEC);
Serial.print(” y: “);
Serial.print(icons[f][YPOS], DEC);
Serial.print(” dy: “);
Serial.println(icons[f][DELTAY], DEC);
}

  while (1) {
// draw each icon
for (uint8_t f=0; f< NUMFLAKES; f++) {
display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
}
display.display();
delay(200);

// then erase it + move it
for (uint8_t f=0; f< NUMFLAKES; f++) {
display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, BLACK);
// move it
icons[f][YPOS] += icons[f][DELTAY];
// if its gone, reinit
if (icons[f][YPOS] > display.height()) {
icons[f][XPOS] = random(display.width());
icons[f][YPOS] = 0;
icons[f][DELTAY] = random(5) + 1;
}
}
}
}

void testdrawchar(void) {
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
  for (uint8_t i=0; i < 168; i++) {
if (i == ‘\n’) continue;
display.write(i);
if ((i > 0) && (i % 21 == 0))
display.println();
}
display.display();
}
void testdrawcircle(void) {
for (int16_t i=0; i<display.height(); i+=2) {
display.drawCircle(display.width()/2, display.height()/2, i, WHITE);
display.display();
}
}
void testfillrect(void) {
uint8_t color = 1;
for (int16_t i=0; i<display.height()/2; i+=3) {
// alternate colors
display.fillRect(i, i, display.width()-i*2, display.height()-i*2, color%2);
display.display();
color++;
}
}
void testdrawtriangle(void) {
for (int16_t i=0; i<min(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();
}
}
void testfilltriangle(void) {
uint8_t color = WHITE;
for (int16_t i=min(display.width(),display.height())/2; i>0; i-=5) {
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, WHITE);
if (color == WHITE) color = BLACK;
else color = WHITE;
display.display();
}
}
void testdrawroundrect(void) {
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();
}
}
void testfillroundrect(void) {
uint8_t color = WHITE;
for (int16_t i=0; i<display.height()/2-2; i+=2) {
display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, color);
if (color == WHITE) color = BLACK;
else color = WHITE;
display.display();
}
}

void testdrawrect(void) {
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();
}
}

void testdrawline() {
for (int16_t i=0; i<display.width(); i+=4) {
display.drawLine(0, 0, i, display.height()-1, WHITE);
display.display();
}
for (int16_t i=0; i<display.height(); i+=4) {
display.drawLine(0, 0, display.width()-1, i, WHITE);
display.display();
}
delay(250);

display.clearDisplay();
for (int16_t i=0; i<display.width(); i+=4) {
display.drawLine(0, display.height()-1, i, 0, WHITE);
display.display();
}
for (int16_t i=display.height()-1; i>=0; i-=4) {
display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
display.display();
}
delay(250);

display.clearDisplay();
for (int16_t i=display.width()-1; i>=0; i-=4) {
display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
display.display();
}
for (int16_t i=display.height()-1; i>=0; i-=4) {
display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
display.display();
}
delay(250);

  display.clearDisplay();
for (int16_t i=0; i<display.height(); i+=4) {
display.drawLine(display.width()-1, 0, 0, i, WHITE);
display.display();
}
for (int16_t i=0; i<display.width(); i+=4) {
display.drawLine(display.width()-1, 0, i, display.height()-1, WHITE);
display.display();
}
delay(250);
}
void testscrolltext(void) {
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(10,0);
display.clearDisplay();
display.println(“scroll”);
display.display();

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();
}

Video tham khảo : 

Chúc bạn thành công ! Các bạn có thể comment xuống dưới thành phẩm của bạn hoặc hỏi những vấn đề liên quan 😀

Nguồn : https://electronnicproject.blogspot.com