การใช้งานจอ OLED ด้วย ATtiny85
การใช้งานจอ OLED Display SSD1331 ด้วย ATtiny85



ไลบรารีกราฟิกสี (Colour Graphics Library)

นี่คือไลบรารีกราฟิกสีขนาดเล็กสำหรับจอแสดงผล OLED Colour SPI 96×64 ที่ใช้ ชิปไดรเวอร์ SD1331 ซึ่งช่วยให้คุณสามารถพล็อตจุดเส้นเติมสี่เหลี่ยมและเปิดและข้อความที่มีอักขระขนาดเล็กหรือใหญ่:

การใช้งานจอ OLED Display SSD1331 ด้วย ATtiny85

การใช้งานจอ OLED Display SSD1331 ด้วย ATtiny85

OLED Display SSD1331 โมดูลนี้ จะแตกต่างจากไลบรารีการแสดงผล SPI OLED อื่น ๆ ซึ่งส่วนใหญ่ ไม่จำเป็นต้องมีบัฟเฟอร์หน่วยความจำทำให้สามารถรันบนโปรเซสเซอร์ใดก็ได้ รวมทั้ง ATtiny85 โดยใช้เพียง 3 ขาในการให้จอแสดงผลทำงาน โดยมี 2 ขา ของ ATtiny85 ที่เหลือเพื่อเชื่อมต่อกับอุปกรณ์อื่น ๆ เช่นเซ็นเซอร์ I2C

OLED Display SSD1331 Module

การแสดงผลนี้ใช้ชิปไดรเวอร์ SD1331 ซึ่งมีเอกลักษณ์เฉพาะในการมีคำสั่งตัวเร่งกราฟิกที่ช่วยให้คุณสามารถลากเส้นและสี่เหลี่ยมได้โดยไม่ต้องเขียนลงในหน่วยความจำข้อมูลกราฟิก คำสั่งตัวเร่งกราฟิกนั้นเร็วมาก วิธีปกติในการล้างหน้าจอคือการเขียนเลขศูนย์ลงในหน่วยความจำข้อมูลกราฟิกทั้งหมดและขั้นตอนการทดสอบที่ฉันเขียนเพื่อทำสิ่งนี้ใช้เวลา 91 มิลลิวินาที การใช้คำสั่ง Clear Window graphics Accelerator ใช้เวลาน้อยกว่าหนึ่งมิลลิวินาทีซึ่งเร็วกว่า 100 เท่า!

ด้วยคำสั่งตัวเร่งกราฟิกทำให้สามารถสร้างไลบรารีกราฟิกที่ไม่จำเป็นต้องเขียนข้อมูลโดยตรงไปยังหน่วยความจำแสดงผลโดยตรง นอกเหนือจากความรวดเร็วแล้วยังมีข้อได้เปรียบเพิ่มเติมในการเพิ่มขา DC ซึ่งสามารถผูกไว้ต่ำอย่างถาวรได้ ตอนนี้ ATtiny85 มีขาว่าง 2 ขา ซึ่งเพียงพอที่จะให้อินเทอร์เฟซ I2C เพื่อเชื่อมต่อเซ็นเซอร์และอุปกรณ์อื่น ๆ

ขั้นตอนการทํางาน

1 : ทำเครื่องโปรแกรม AVR เพื่อใช้อัพโหลดโปรแกรม


ขั้นตอนการใช้บอร์ด Arduino UNO เป็น เครื่องเขียนโปรแกรม ตามลิงค์ด้านล่าง

Arduino UNO เป็น เครื่องเขียนโปรแกรม




2 : อัพโหลดโปรแกรมให้กับ ATtiny85

เปิดโปรแกรม Arduino IDE เขียนโปรแกรมและอัพโหลดโค้ดด้านล่างนี้ ไปที่ ATtiny85


// ATtiny85 Pins
int const data = 1;
int const cs = 3;
int const clk = 4;

// Character set for text - stored in program memory
const uint8_t CharMap[96][6] PROGMEM = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 
{ 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00 }, 
{ 0x00, 0x07, 0x00, 0x07, 0x00, 0x00 }, 
{ 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00 }, 
{ 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00 }, 
{ 0x23, 0x13, 0x08, 0x64, 0x62, 0x00 }, 
{ 0x36, 0x49, 0x56, 0x20, 0x50, 0x00 }, 
{ 0x00, 0x08, 0x07, 0x03, 0x00, 0x00 }, 
{ 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00 }, 
{ 0x00, 0x41, 0x22, 0x1C, 0x00, 0x00 }, 
{ 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00 }, 
{ 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00 }, 
{ 0x00, 0x80, 0x70, 0x30, 0x00, 0x00 }, 
{ 0x08, 0x08, 0x08, 0x08, 0x08, 0x00 }, 
{ 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 }, 
{ 0x20, 0x10, 0x08, 0x04, 0x02, 0x00 }, 
{ 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00 }, 
{ 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00 }, 
{ 0x72, 0x49, 0x49, 0x49, 0x46, 0x00 }, 
{ 0x21, 0x41, 0x49, 0x4D, 0x33, 0x00 }, 
{ 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00 }, 
{ 0x27, 0x45, 0x45, 0x45, 0x39, 0x00 }, 
{ 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00 }, 
{ 0x41, 0x21, 0x11, 0x09, 0x07, 0x00 }, 
{ 0x36, 0x49, 0x49, 0x49, 0x36, 0x00 }, 
{ 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00 }, 
{ 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 }, 
{ 0x00, 0x40, 0x34, 0x00, 0x00, 0x00 }, 
{ 0x00, 0x08, 0x14, 0x22, 0x41, 0x00 }, 
{ 0x14, 0x14, 0x14, 0x14, 0x14, 0x00 }, 
{ 0x00, 0x41, 0x22, 0x14, 0x08, 0x00 }, 
{ 0x02, 0x01, 0x59, 0x09, 0x06, 0x00 }, 
{ 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00 }, 
{ 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00 }, 
{ 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00 }, 
{ 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00 }, 
{ 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00 }, 
{ 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00 }, 
{ 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00 }, 
{ 0x3E, 0x41, 0x41, 0x51, 0x73, 0x00 }, 
{ 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00 }, 
{ 0x00, 0x41, 0x7F, 0x41, 0x00, 0x00 }, 
{ 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00 }, 
{ 0x7F, 0x08, 0x14, 0x22, 0x41, 0x00 }, 
{ 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00 }, 
{ 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00 }, 
{ 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00 }, 
{ 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00 }, 
{ 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00 }, 
{ 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00 }, 
{ 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00 }, 
{ 0x26, 0x49, 0x49, 0x49, 0x32, 0x00 }, 
{ 0x03, 0x01, 0x7F, 0x01, 0x03, 0x00 }, 
{ 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00 }, 
{ 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00 }, 
{ 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00 }, 
{ 0x63, 0x14, 0x08, 0x14, 0x63, 0x00 }, 
{ 0x03, 0x04, 0x78, 0x04, 0x03, 0x00 }, 
{ 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00 }, 
{ 0x00, 0x7F, 0x41, 0x41, 0x41, 0x00 }, 
{ 0x02, 0x04, 0x08, 0x10, 0x20, 0x00 }, 
{ 0x00, 0x41, 0x41, 0x41, 0x7F, 0x00 }, 
{ 0x04, 0x02, 0x01, 0x02, 0x04, 0x00 }, 
{ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00 }, 
{ 0x00, 0x03, 0x07, 0x08, 0x00, 0x00 }, 
{ 0x20, 0x54, 0x54, 0x78, 0x40, 0x00 }, 
{ 0x7F, 0x28, 0x44, 0x44, 0x38, 0x00 }, 
{ 0x38, 0x44, 0x44, 0x44, 0x28, 0x00 }, 
{ 0x38, 0x44, 0x44, 0x28, 0x7F, 0x00 }, 
{ 0x38, 0x54, 0x54, 0x54, 0x18, 0x00 }, 
{ 0x00, 0x08, 0x7E, 0x09, 0x02, 0x00 }, 
{ 0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x00 }, 
{ 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00 }, 
{ 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00 }, 
{ 0x20, 0x40, 0x40, 0x3D, 0x00, 0x00 }, 
{ 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00 }, 
{ 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00 }, 
{ 0x7C, 0x04, 0x78, 0x04, 0x78, 0x00 }, 
{ 0x7C, 0x08, 0x04, 0x04, 0x78, 0x00 }, 
{ 0x38, 0x44, 0x44, 0x44, 0x38, 0x00 }, 
{ 0xFC, 0x18, 0x24, 0x24, 0x18, 0x00 }, 
{ 0x18, 0x24, 0x24, 0x18, 0xFC, 0x00 }, 
{ 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00 }, 
{ 0x48, 0x54, 0x54, 0x54, 0x24, 0x00 }, 
{ 0x04, 0x04, 0x3F, 0x44, 0x24, 0x00 }, 
{ 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00 }, 
{ 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00 }, 
{ 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00 }, 
{ 0x44, 0x28, 0x10, 0x28, 0x44, 0x00 }, 
{ 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00 }, 
{ 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00 }, 
{ 0x00, 0x08, 0x36, 0x41, 0x00, 0x00 }, 
{ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00 }, 
{ 0x00, 0x41, 0x36, 0x08, 0x00, 0x00 }, 
{ 0x02, 0x01, 0x02, 0x04, 0x02, 0x00 }, 
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 },
};

// OLED 96x64 colour display **********************************************

// Initialisation sequence for OLED module
int const InitLen = 6;
const unsigned char Init[InitLen] PROGMEM = {
  0xA0,       // Driver remap and colour depth
  0x22,       // COM split, flip horizontal
  0xA8, 0x3F, // Multiplex
  0xAD, 0x8E, // External supply
};

// Send a byte to the display
void Send (uint8_t d) {  
  for (uint8_t bit = 0x80; bit; bit >>= 1) {
    PINB = 1<<clk;                        // clk low
    if (d & bit) PORTB = PORTB | (1<<data); else PORTB = PORTB & ~(1<<data);
    PINB = 1<<clk;                        // clk high
  }
}

void InitDisplay () {
  PINB = 1<<cs;                           // cs low
  for (uint8_t c=0; c<InitLen; c++) Send(pgm_read_byte(&Init[c]));
  PINB = 1<<cs;                           // cs high
}

// Display off = 0, on = 1
void DisplayOn (uint8_t on) {
  PINB = 1<<cs;                           // cs low
  Send(0xAE + on);
  PINB = 1<<cs;                           // cs high
}

// Graphics **********************************************

// Global plot parameters
uint8_t x0 = 0;
uint8_t y0 = 0;
uint8_t ForeR = 0x3F, ForeG = 0x3F, ForeB = 0x3F;
uint8_t BackR = 0x00, BackG = 0x00, BackB = 0x00;
uint8_t Scale = 1; // Text size - 2 for big characters

// Clear display
void ClearDisplay () {
  PINB = 1<<cs;                           // cs low
  Send(0x25);                             // Clear Window
  Send(0); Send(0); Send(95); Send(63);
  PINB = 1<<cs;                           // cs high
  delay(1);
}

void MoveTo (uint8_t x, uint8_t y) {
  x0 = x; y0 = y;
}

// Draw line to (x,y) in foreground colour
void DrawTo (uint8_t x, uint8_t y) {
  PINB = 1<<cs;                           // cs low
  Send(0x21);                             // Draw Line
  Send(x0); Send(y0); Send(x); Send(y);
  Send(ForeR); Send(ForeG); Send(ForeB);
  PINB = 1<<cs;                           // cs high
  x0 = x; y0 = x;
}

// Plot a point at (x,y)
void PlotPoint (uint8_t x, uint8_t y) {
  MoveTo(x, y);
  DrawTo(x, y);
}

// Draw a rectangle in foreground colour optionally filled with background colour
void DrawRect (boolean filled, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
  PINB = 1<<cs;                           // cs low
  Send(0x26); Send(filled);               // Enable fill
  Send(0x22);                             // Draw rectangle
  Send(x1); Send(y1); Send(x2); Send(y2);
  Send(ForeR); Send(ForeG); Send(ForeB);
  Send(BackR); Send(BackG); Send(BackB);
  PINB = 1<<cs;                           // cs high
  delay(1);
}

// Plot character in foreground colour
void PlotChar (uint8_t ch) {
  PINB = 1<<cs;                           // cs low
  for (uint8_t c = 0 ; c < 6; c++) {      // Column range
    uint8_t bits = pgm_read_byte(&CharMap[ch-32][c]);
    uint8_t r = 0;
    while (bits) {
      while ((bits & 1) == 0) {r++; bits = bits>>1; }
      uint8_t on = (7-r)*Scale;
      while ((bits & 1) != 0) {r++; bits = bits>>1; }
      uint8_t off = (7-r)*Scale+1;
      for (int i=0; i<Scale; i++) {
        uint8_t h = x0+c*Scale+i;
        Send(0x21);                         // Draw line
        Send(h); Send(y0+on); Send(h); Send(y0+off);
        Send(ForeR); Send(ForeG); Send(ForeB);
      }
    }
  }
  PINB = 1<<cs;                             // cs high
  x0 = x0+6*Scale;
}

// Plot text from program memory
void PlotText(PGM_P p) {
  while (1) {
    char c = pgm_read_byte(p++);
    if (c == 0) return;
    PlotChar(c);
  }
}

// Setup **********************************************

void setup() {
  // Define pins
  DDRB = 1<<clk | 1<<cs | 1<<data;    // All outputs
  PORTB = 1<<clk | 1<<cs;             // clk and cs high
  InitDisplay();
  ClearDisplay();
  DisplayOn(1);
}

// Demo display
void loop () {
  MoveTo(1, 56);
  ForeR=ForeG=ForeB=0x3F;              // White
  PlotText(PSTR("Graphics Display"));
  for (int x=-48; x<48; x++) {
    for (int y=-26; y<26; y++) {
      int fun = (x * (x + y) + y * y)/8;
      ForeB = abs((fun & 0x3F)-32);
      ForeG = abs(((fun + 12) & 0x3F)-32);
      ForeR = abs(((fun + 24) & 0x3F)-32);
      PlotPoint(x+48, y+26);
    }
  }
  for(;;);
}
การใช้งานจอ OLED ด้วย ATtiny85


3 : อธิบายโค้ด การเขียนลงจอแสดงผล

ATtiny85 และโปรเซสเซอร์ AVR อื่น ๆ รองรับการสลับบิตอย่างน้อยหนึ่งบิตในพอร์ตดังนั้นหากคุณตั้งค่าขาทั้งหมดเป็นสถานะปิดใช้งานเมื่อเริ่มต้นเพื่อความเร็วในการเข้าถึงการแสดงผลสามารถสลับขาที่เหมาะสมเพื่อเปิดหรือปิดใช้งานได้

ฟังก์ชั่น Send () จะส่งไบต์ไปยังจอแสดงผลโดยการสลับขา clock , clk สำหรับแต่ละบิตบนขา data:

void Send (uint8_t d) {  
  for (uint8_t bit = 0x80; bit; bit >>= 1) {
    PINB = 1<<clk;                        // clk low
    if (d & bit) PORTB = PORTB | (1<<data); else PORTB = PORTB & ~(1<<data);
    PINB = 1<<clk;                        // clk high
  }
}


ก่อนและหลังเข้าถึงจอแสดงผลคุณต้องสลับพินเลือกชิป cs ด้วยคำสั่ง:

PINB = 1<<cs;



การล้างการแสดงผล

ในการล้างการแสดงผลเราใช้คำสั่ง Clear Window ของตัวเร่งกราฟิก (graphics accelerator):

void ClearDisplay () {
  PINB = 1<<cs;                           // cs low
  Send(0x25);                             // Clear Window
  Send(0); Send(0); Send(95); Send(63);
  PINB = 1<<cs;                           // cs high
  delay(1);
}



โปรดสังเกตว่าคำสั่งนี้และคำสั่งอื่น ๆ บางคำสั่งมีการหน่วงเวลา 1ms เพื่อให้คำสั่งดำเนินการ แม้ว่าจะไม่พบสิ่งนี้ที่กล่าวถึงใน datasheet แต่ก็พบว่ามันจำเป็นในทางปฏิบัติ

graphics accelerator เป็นอุปกรณ์อิเลคโทรนิคส์ขนาดเล็ก ซึ่งให้โปรแกรมคอมพิวเตอร์สามารถ off load การส่งและ refresh ภาพไปที่จอภาพ และคำนวณการใช้ Special effect จาก 2 มิติ เป็น 3 มิติ graphics accelerator จะเพิ่มความเร็วในการแสดงภาพบนจอ เช่น การแสดงภาพขนาดใหญ่ หรือเกมส์ แบบ inter active ซึ่งต้องการภาพที่ตอบสนองต่อผู้ใช้ได้เร็ว



สี

องค์ประกอบสีแดงสีน้ำเงินและสีเขียวของสีพื้นหน้าและพื้นหลังถูกกำหนดโดยตัวแปร (global variables) ที่ประกาศไว้ภายนอกฟังก์ชันหลัก 6 ตัวแปร ในขั้นต้นจะตั้งค่าเป็น 0x3F สีขาวและ 0x00 สีดำตามลำดับ:

uint8_t ForeR = 0x3F, ForeG = 0x3F, ForeB = 0x3F;
uint8_t BackR = 0x00, BackG = 0x00, BackB = 0x00;



วาดเส้นและพล็อตจุด

เขียนกราฟิกพื้นฐานสำหรับการพล็อตจุดและวาดเส้น สิ่งเหล่านี้ทำงานบนระบบพิกัดแบบเดิมโดยมีจุดเริ่มต้นที่ด้านล่างซ้าย:

การแสดงผลด้วยจอ OLED Display


ตำแหน่งการวาดปัจจุบันถูกเก็บไว้ในตัวแปรส่วนกลาง x0 และ y0 คุณสามารถเปลี่ยนแปลงได้ด้วยคำสั่ง MoveTo () :

void MoveTo (uint8_t x, uint8_t y) {
  x0 = x; y0 = y;
}



การลากเส้นเพียงแค่เรียกตัวเร่งกราฟิกคำสั่ง Draw Line:

void DrawTo (uint8_t x, uint8_t y) {
  PINB = 1<<cs;                           // cs low
  Send(0x21);                             // Draw Line
  Send(x0); Send(y0); Send(x); Send(y);
  Send(ForeR); Send(ForeG); Send(ForeB);
  PINB = 1<<cs;                           // cs high
  x0 = x; y0 = x;
}



คำสั่งตัวเร่งกราฟิกไม่มีคำสั่งที่ชัดเจนในการพล็อตจุด แต่คุณสามารถทำได้โดยลากเส้นยาวหนึ่งพิกเซล:

void PlotPoint (uint8_t x, uint8_t y) {
  MoveTo(x, y);
  DrawTo(x, y);
}



การวาดรูปสี่เหลี่ยม

ฟังก์ชั่น DrawRect () ใช้วาดรูปสี่เหลี่ยมที่เติมเต็มหรือจัดเค้าร่างโดยใช้คำสั่ง Draw Rectangle ของตัวเร่งกราฟิก:

void DrawRect (boolean filled, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
  PINB = 1<<cs;                           // cs low
  Send(0x26); Send(filled);               // Enable fill
  Send(0x22);                             // Draw rectangle
  Send(x1); Send(y1); Send(x2); Send(y2);
  Send(ForeR); Send(ForeG); Send(ForeB);
  Send(BackR); Send(BackG); Send(BackB);
  PINB = 1<<cs;                           // cs high
  delay(1);
}



ตั้งค่าให้เต็มเป็น 0 สำหรับเส้นสี่เหลี่ยมผืนผ้า หรือ 1 สำหรับสี่เหลี่ยมผืนผ้าที่เต็มไปด้วยสีพื้นหลัง

อักขระและข้อความ

ชุดอักขระถูกกำหนดโดยข้อมูลที่เก็บไว้ในหน่วยความจำโปรแกรม แผนผังอักขระแบบย่อมีดังนี้:

const uint8_t CharMap[96][6] PROGMEM = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 
{ 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00 }, 
...
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 }
};



แถวแรกกำหนดรูปแบบบิตสำหรับอักขระ ASCII 32 ช่องว่างและอื่น ๆ สูงสุดถึงอักขระ 127

PlotChar () แปลงประจำตัวอักษรเป็นชุดของเส้นที่สอดคล้องกับคอลัมน์ของพิกเซลที่ต่อเนื่องกันในบิตแมปตัวละครที่ ด้วยการเพิ่มประสิทธิภาพนี้ฉันพบว่าการพล็อตอักขระนั้นเร็วกว่าวิธีการเขียนไบต์ตามปกติในหน่วยความจำข้อมูลกราฟิก:

void PlotChar (uint8_t ch) {
  PINB = 1<<cs;                           // cs low
  for (uint8_t c = 0 ; c < 6; c++) {      // Column range
    uint8_t bits = pgm_read_byte(&CharMap[ch-32][c]);
    uint8_t r = 0;
    while (bits) {
      while ((bits & 1) == 0) {r++; bits = bits>>1; }
      uint8_t on = (7-r)*Scale;
      while ((bits & 1) != 0) {r++; bits = bits>>1; }
      uint8_t off = (7-r)*Scale+1;
      for (int i=0; i<Scale; i++) {
        uint8_t h = x0+c*Scale+i;
        Send(0x21);                         // Draw line
        Send(h); Send(y0+on); Send(h); Send(y0+off);
        Send(ForeR); Send(ForeG); Send(ForeB);
      }
    }
  }
  PINB = 1<<cs;                             // cs high
  x0 = x0+6*Scale;
}


การตั้งค่ามาตราส่วนเป็น 2 พล็อตอักขระขนาดสองเท่า

สุดท้าย PlotText () ให้คุณพล็อตข้อความจากสตริงในหน่วยความจำโปรแกรม:

void PlotText(PGM_P p) {
  while (1) {
    char c = pgm_read_byte(p++);
    if (c == 0) return;
    PlotChar(c);
  }
}



ในการกำหนดข้อความที่จะพล็อตว่าอยู่ในหน่วยความจำโปรแกรมให้ใช้มาโคร PSTR () (สำหรับโปรแกรมสตริง) ตัวอย่างเช่น:

 PlotText(PSTR("Graphics Display")); 



4 : เชื่อมต่ออุปกรณ์เข้ากับ ATtiny85 ตามวงจรด้านล่าง


การใช้งานจอ OLED Display SSD1331 ด้วย ATtiny85


การใช้งานจอ OLED ด้วย ATtiny85



5 : ผลลัพธ์การทำงาน

การใช้งานจอ OLED ด้วย ATtiny85


6 : อุปกรณ์ที่ใช้ในโปรเจค

credit : http://www.technoblogy.com/show?2EA7