การแสดงผลด้วยจอแอลอีดีขนาด 128×64 พิกเซล
จอแอลอีดีและการติดตั้งไลบรารี
จอแสดงผล
OLED
(Organic Light-Emitting Diode) display เป็นจอแสดงผลที่สร้างจากวัสดุสารกึ่งตัวนำอินทรีย์
(Organic Semiconductor) ที่มีลักษณะเป็นชั้นสารกึ่ง-ตัวนำบาง ๆ อยู่ระหว่างขั้วบวก (Anode) และขั้วลบ (Cathode)
และสามารถเปล่งแสงได้เมื่อมีกระแสไฟฟ้าไหลผ่าน
การเปล่งแสงนี้เรียกว่ากระบวนการ อิเล็คโทรลูมิเนสเซนส์ (Electroluminescence)
จอแสดงผล OLED มีข้อดีซึ่งแตกต่างจากจอแสดงผล LCD
(Liquid Crystal Display) ทั่วไปคือ จอ OLED
ไม่มีวงจรที่สร้างแสง Backlight จึงทำให้จอมีความหนาน้อยกว่าและเบากว่า
ใช้กำลังไฟฟ้าต่ำ นอกจากนั้นจะไม่มีการเปล่งแสงในบริเวณที่ต้องการให้เป็นสีดำ
ในปัจจุบันอุปกรณ์หลายอย่างเช่น โทรทัศน์, สมาร์ทโฟน (Smartphones)
และ แท็บเล็ต (Tablets) ได้เริ่มเปลี่ยนไปใช้จอแสดงผล
OLED กันมากขึ้น ในการทดลองนี้จะกล่าวถึง
การทดลองใช้งานโมดูลจอแสดงผลกราฟิกแบบ OLED ขนาดเล็ก
ซึ่งมีขนาด 128x64 พิกเซล ให้แสงเพียงสีเดียว (Monochrome)
โดยทดลองเขียนโค้ดและใช้งานร่วมกับบอร์ด NodeMCU v.3 และใช้วิธีเชื่อมต่อแบบบัส I2C (หรือ I2C, Inter-Integrated Circuit, อ่านว่าไอสแควร์ซี)
ลักษณะโครงสร้างโมดูล
OLED
128x64 พิกเซล
โมดูล OLED ที่ได้เลือกมาทดลองใช้งานนี้
มีขนาด 1.3" (วัดตามเส้นทแยงมุม) มีความละเอียด 128x64
พิกเซล สามารถแสดงผลได้แบบสีเดียว ซึ่งถือว่าเป็นจอขนาดเล็ก และใช้แรงดันไฟเลี้ยง
+3.3 V ได้
จอขนาดเล็กนี้เหมาะสำหรับนำไปใช้กับระบบสมองกลฝังตัว
ที่ต้องการส่วนแสดงผลกราฟิกบนพื้นที่จำกัด ภายในโมดูลจะมีชิป SH1106 เป็นตัวควบคุมการทำงาน สามารถเชื่อมต่อแบบอนุกรมโดยใช้บัส SPI
(Serial Peripheral Interface) หรือ I2C
ถ้าต้องการแสดงข้อความจะต้องมีข้อมูลของฟอนต์ตัวอักษร แต่ละตัว
ซึ่งจะมีลักษณะเป็นข้อมูลภาพแบบบิตแมปเก็บไว้ในหน่วยความจำ
การจัดการหน่วยความจำภายในของ SH1106 ที่เรียกว่า Graphic Display Data RAM (GDDRAM)
สำหรับขนาด 128x64 พิกเซล แบ่งเป็นคอลัมน์ (Column) และ เพจ (Page) ซึ่งมีทั้งหมด 128 คอลัมน์
(หมายเลข 0..127) และมีทั้งหมด 8 เพจ (หมายเลข 0,1, 2...7)
แต่ละเพจ จะประกอบด้วย 8 บรรทัด ดังนั้นจึงมี 8x8 = 64
บรรทัดหรือแถว (rows) การแสดงผลของจอภาพขึ้นอยู่กับค่าบิต (0
หรือ 1) สำหรับแต่ละพิกเซลที่ได้เขียนข้อมูลลงในหน่วยความจำ GDDRAM
การสื่อสารข้อมูลกับชิป SH1106 ทำได้โดยผ่านบัส SPI หรือ I2C โดยต้องส่งคำสั่งเพื่อกำหนดค่าต่าง ๆ ในการทำงาน
เช่น คำสั่งเปิด/ปิดการแสดงผล (turn on/off display)
คำสั่งเลือกโหมดการเข้าถึงหน่วยความจำ (memory addressing mode) คำสั่งกำหนดค่าตำแหน่งเริ่มต้น (Start Address)
และตำแหน่งสุดท้าย (End Address) สำหรับคอลัมน์และเพจ
และการเขียนข้อมูล (Data) เป็นการเขียนข้อมูลลงใน GDDRAM
การเชื่อมต่อขาของโมดูล
OLED
แบบ I2C
รูปที่ 6.1 แสดงรูปร่างของโมดูล OLED ที่ใช้การเชื่อมต่อแบบ I2C โดยมีขาที่ต้องเชื่อมต่อดังนี้
- VDD (หรือ VCC) เป็นขาสำหรับรับแรงดันไฟเลี้ยง +3.3
V
- GND เป็นขากราวด์ (Ground)
- SCK เป็นขา I/O สำหรับสัญญาณ Serial ClocK
(หรือ SCL (Serial CLock)
- SDA เป็นขา I/O สำหรับสัญญาณ SDA (Serial DAta)
สำหรับการส่งข้อมูล
หมายเหตุ OLED บางรุ่น อาจมีการเรียงตำแหน่งขา สลับกันระหว่าง SCK และ
SDA ดังนั้นขอให้ผู้ใช้ศึกษาแผ่นข้อมูลของอุปกรณ์ก่อนทำการทดลอง
รูปที่
6.1 รูปร่างของโมดูล OLED (ก) ด้านหน้า
และ (ข) ด้านหลัง
การติดตั้งไลบรารี
OLED
I2C
เนื่องจากโปรแกรม Arduino IDE ที่ติดตั้งมาในตอนเริ่มต้นไม่มีไลบรารีของ
OLED นี้
เราจึงจำเป็นต้องมีการติดตั้งเพิ่มเติมเข้าไปในโปรแกรม ซึ่งจะต้องใช้ไลบรารี
สามารถดาวน์โหลดจากลิงค์ https://github.com/ThingPulse/esp8266-oled-ssd1306
ดังรูปที่ 6.2 โดยให้ทำการคัดลอกโฟลเดอร์ที่โหลดมาไปเก็บไว้ที่ C:\Arduino18\libraries ดังรูปที่ 6.3
เมื่อคัดลอกลงมาแล้ว Arduino IDE จะสามารถเรียกใช้ฟังก์ชันสำหรับสั่งงาน
OLED นี้ได้ โดยเราจะต้องเพิ่มคำสั่งเรียกไลบรารี คือ #include
<Wire.h> และ #include <SH1106.h> เข้าไปที่ด้านบนของโค้ด (โดยฟังก์ชันใน Wire.h จะถูกเรียกใช้โดยฟังก์ชันใน SH1106.h อีกทีหนึ่ง)
รูปที่
6.2 การดาวน์โหลดไลบรารีของ OLED จาก github
รูปที่
6.3
การติดตั้งไลบรารีของ OLED ลงใน Arduino IDE
คำสั่งพื้นฐานควบคุมการแสดงผลของจอ
OLED
1.
คำสั่งกำหนดตำแหน่งขาที่ต่อใช้งานกับจอ OLED แบบ I2C
SH1106 display(0x3c, D1, D2);
เป็นการกำหนด Instance ของวัตถุชื่อ display และการกำหนดหน่วยความจำตำแหน่ง 0x3c ให้กับอุปกรณ์แสดงผลนี้ โดยต่อขา D1 กับ SDA และขา D2 ต่อกับ SCK
2.
คำสั่งตรวจสอบการเชื่อมต่อกับจอและจัดการหน่วยความจำ
display.init();
เป็นคำสั่งที่ใช้ก่อนการเริ่มต้นให้จอแสดงผล
(เรียกใช้ในฟังก์ชัน setup())
โดยวัตถุชื่อ display จะต้องถูกสร้างไว้ก่อนด้วยคำสั่งในข้อ
1 และอาจใช้ชื่ออื่นก็ได้
3.
การสั่งให้แสดงผลบนหน้าจอ OLED
display.display();
เป็นฟังก์ชันที่ใช้สั่งให้จอแสดงข้อมูลที่อยู่ในหน่วยความจำ
โดย display
ตัวแรกคือชื่อวัตถุที่ตั้งในข้อ 1 (อาจตั้งเป็นชื่ออื่นก็ได้)
และตัวที่สองคือชื่อฟังก์ชัน/เมธอด
4.
การลบการแสดงผลบนหน้าจอ
display.clear();
สำหรับข้อ
5-7 จะขอละคำว่า display
ไว้
5.
การแสดงตัวอักษร เราจะเริ่มจากการกำหนดฟอนต์ด้วยคำสั่ง
setFont(fontData);
โดย
fontData
ที่รองรับคือ ArialMT_Plain_10, ArialMT_Plain_16 และ ArialMT_
Plain_24 แล้วจากนั้นจึงกำหนดตำแหน่ง (x,y) ของข้อความและข้อความ (String) ด้วยคำสั่ง
drawString(int
x, int y, String);
6.
การแสดงรูปเราขาคณิตพื้นฐานต่าง ๆ จะมีคำสั่งที่สามารถเลือกใช้ได้
ได้แก่
6.1
คำสั่งวาดเส้นตรง
6.1.1
เส้นตรง drawLine(x1,
y1, x2, y2)
6.1.2
เส้นตามนอน drawHorizontalLine(x,
y, length)
6.1.3
เส้นตามตั้ง drawVerticalLine(x,
y, length)
6.2
คำสั่งวาดรูปสี่เหลี่ยม
6.2.1
สี่เหลี่ยมเปิด drawRect(x,
y, width, height)
6.2.2
สี่เหลี่ยมทึบ fillRect(x,
y, width, height)
6.3
คำสั่งวาดรูปวงกลม
6.3.1
วงกลมเปิด drawCircle(x,
y, radius)
6.3.2
วงกลมทึบ
fillCircle(x, y, radius)
โดยตัวแปรทุกตัวที่ส่งค่าไปจะต้องเป็นจำนวนเต็มค่าบวก
(unsigned
integer, uint) เท่านั้น
7.
การวาดภาพแบบพิกเซล
7.1
คำสั่งวาดแถบ Progress
Bar
drawProgressBar(x,
y, width, height, progress)
โดยตัวแปร progress จะมีค่าได้ระหว่าง
0 ถึง 100
7.2
คำสั่งวาดภาพบิตแมป
drawXbm(x, y,
width, height, picture);
โดยตัวแปร picture
คือภาพที่เก็บเป็นอาเรย์ของรหัสแอสกี (ชนิด char)
การทดลองแสดงผลบนจอ
OLED
วัตถุประสงค์
1.
สามารถต่อวงจรไมโครคอนโทรลเลอร์ NodeMCU v.3 กับจอ OLED เพื่อแสดงผลได้
2.
สามารถเขียนโปรแกรมแสดงข้อความและข้อมูลชนิดต่าง ๆ บนจอ OLED ได้อย่างถูกต้อง
อุปกรณ์ที่ใช้ในการทดลอง
1. เครี่องคอมพิวเตอร์ที่มีระบบปฏิบัติการ
Windows
(ตั้งแต่ Windows 7 ขึ้นไป)
พร้อมติดตั้งโปรแกรม Arduino IDE 1.8.8 IoT 1
เครื่อง
2. NodeMCU v.3 1
บอร์ด
3. NodeMCU Base
Ver 1.0 1
บอร์ด
4. บอร์ดโมดูล OLED Display ขนาด 128×64 พิกเซล 1
บอร์ด
5. สาย USB 1
เส้น
6. สายต่อวงจร (สายจัมพ์
เมีย-เมีย) 4
เส้น
วิธีการทดลอง
ตอนที่
1
1.
ตอวงจรตามรูปที่ 6.4 โดยให้ต่อขา D1 เข้ากับขา SDA ของโมดูล OLED,
ขา D2 เข้ากับขา SCK (หรือ SCL),
ต่อขาไฟเลี้ยง +3.3 V (3V3) ให้แก่โมดูล OLED ที่ขา VDD (หรือ VCC) และต่อขากราวด์ (GND)
ร่วมกัน
2.
เขียนโปรแกรมตามโค้ดที่แสดงในหน้าถัดไป
รูปที่
6.4 การเชื่อมต่อ NodeMCU v.3 กับจอแสดงผล OLED แบบ I2C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// Control OLED by NodeMCU ESP8266 #include <Wire.h> #include <SH1106.h> //SSD1306 display(Addr,SDA,SCL); SH1106 display(0x3c, D1, D2); void setup() { display.init(); } void loop() {
display.setFont(ArialMT_Plain_10); display.drawString(25, 0,
"Current = "); display.drawString(75, 0,
String(75.35)+" A"); display.display(); delay(200); } |
3.
เมื่อเขียนโปรแกรมตามโค้ดแล้ว ให้ทำการอัปโหลด จอจะแสดงผล Current = 75.35 A ดังรูปที่ 6.4
ตอนที่
2 เขียนโปรแกรมดังแสดงในโค้ดด้านล่างแล้วสังเกตผลลัพธ์ที่แสดงบนจอ
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 |
// Control OLED by NodeMCU ESP8266 #include <Wire.h> #include <SH1106.h> // SSD1306 display(Addr,SDA,SCL); SH1106 display(0x3c, D1, D2); void setup() { display.init(); } void loop() { // Display a line
display.drawVerticalLine(120, 5, 30); // Display a circle display.drawCircle(64, 32,
18); // Display a rectangle display.drawRect(0, 0,
128, 64); display.drawRect(0, 33,
100, 10); display.fillRect(0, 35,
45, 6); // Display a progress bar display.drawProgressBar(0,
48, 100, 10, 50); display.display(); delay(200); } |
ผลลัพธ์ของโค้ดในตอนที่ นี้แสดงในรูปที่ 6.5(ก)
ตอนที่
3 เขียนโปรแกรมดังแสดงในโค้ดด้านล่างแล้วสังเกตผลลัพธ์ที่แสดงบนจอ
โดยมีข้อสังเกตคือ
การเติม 0x
หน้าตัวเลขเป็นการบ่งชี้ในภาษา C ว่าข้อมูลที่ตามมานั้นแสดงอยู่ในรูปเลขฐานสิบหก
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 |
// Control
OLED by NodeMCU ESP8266 #include <Wire.h> #include <SH1106.h> // SSD1306 display(Addr, SDA, SCL); SH1106 display(0x3c, D1, D2); #define width 64 #define height 64 static unsigned char b2i[]
= { 0xFF, 0xFF, 0xFF, 0x3F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x0,
0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x1F, 0x0, 0x0,
0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x3,
0x0, 0x0,
0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0,
0x0, 0x0,
0x80, 0xFF, 0xFF, 0xFF, 0x7F, 0x0, 0x0, 0x0, 0x0,
0xFF, 0xFF, 0xFF, 0x1F, 0x0, 0x0, 0x0, 0x0,
0xFC, 0xFF, 0xFF, 0xF, 0x0, 0x0, 0x0, 0x0,
0xF8, 0xFF, 0xFF, 0x7, 0x0, 0x0, 0x0, 0x0,
0xF0, 0xFF, 0xFF, 0x3, 0x0, 0x0, 0x0, 0x0,
0xE0, 0xFF, 0xFF, 0x1, 0x0, 0x0, 0x0, 0x0,
0xC0, 0xFF, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0,
0x80, 0xFF, 0x7F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xFF, 0x3F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xFE, 0x3F, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0,
0xFE, 0x1F, 0x0, 0x0, 0x0, 0x0, 0xE0, 0x7,
0xFC, 0xF, 0x0, 0x0, 0x0, 0x0,
0x20, 0x2,
0xF8, 0xFF, 0x7,
0xFC, 0x83, 0xF, 0x30, 0xE6, 0xF8, 0xFF, 0x1F, 0xFE, 0x87, 0xF, 0x20, 0x22, 0xFF, 0xFF, 0x3F, 0xFF, 0x8F, 0xF, 0xF0, 0xE7, 0xF0, 0xFF, 0x7F, 0xFF, 0x9F, 0xF, 0xA0, 0x7,
0xE0, 0xFF, 0x7F, 0x9E, 0xBF, 0xF, 0x0, 0xC, 0xE0, 0x1F, 0xFC, 0xE, 0x3E, 0x0, 0x3,
0xF8, 0xFF, 0x1F, 0xFC, 0x6,
0xBE, 0x8F, 0x7,
0xF0, 0xFF, 0x1F, 0xF8, 0x6,
0xBE, 0x8F, 0xFC, 0x7, 0xC0, 0x1F, 0xF8, 0x6,
0xBE, 0x8F, 0xFC, 0xF, 0xC0, 0x1F, 0xF8, 0x6,
0xBE, 0xF, 0x7, 0x18, 0xC0, 0x1F, 0xF8, 0x0,
0xBE, 0xF, 0x0, 0xF0, 0xFF, 0x1F, 0xFC, 0x0,
0xBE, 0xF, 0x0, 0xE0, 0xFF, 0x1F, 0x7E, 0x0,
0x9F, 0xF, 0xC0, 0x0,
0x80, 0xFF, 0x7F, 0x0,
0x9F, 0xF, 0x20, 0x1,
0x80, 0xFF, 0x3F, 0x80, 0x9F, 0xF, 0x20, 0xFF, 0xFF, 0xFF, 0x1F, 0xC0, 0x8F, 0xF, 0x20, 0x1,
0x80, 0xFF, 0x3F, 0xC0, 0x87, 0xF, 0xC0, 0x0,
0x80, 0xFF, 0x7F, 0xE0, 0x87, 0xF, 0x2,
0xC0, 0xFF, 0x1F, 0xFE, 0xF0, 0x83, 0xF, 0x7,
0xE0, 0xFF, 0x1F, 0xFC, 0xF0, 0x81, 0xCF, 0x18, 0x30, 0xC0, 0x1F, 0xF8, 0xF8, 0x81, 0xCF, 0xF8, 0x1F, 0xC0, 0x1F, 0xF8, 0xFC, 0x80, 0xCF, 0xF8, 0xF, 0xC0, 0x1F, 0xF8, 0x7D, 0x80, 0xCF, 0x18, 0xF8, 0xFF, 0x1F, 0xF8, 0x7D, 0x80, 0xF, 0x7,
0xFC, 0xFF, 0x1F, 0xF8, 0x3D, 0x80, 0xF, 0x2, 0x6,
0xE0, 0x1F, 0xF8, 0x1C, 0x80, 0xF, 0x0, 0x3,
0xE0, 0x1F, 0xFC, 0x1C, 0x80, 0xF, 0xE0, 0xE1, 0xF0, 0x1F, 0xFE, 0xC, 0x80, 0xF, 0x20, 0x21, 0xFF, 0xFF, 0xFF, 0xFE, 0xBF, 0xF, 0x20, 0xA1, 0xF8, 0xFF, 0x7F, 0xFE, 0xBF, 0xF, 0xE0, 0x1,
0xF8, 0xFF, 0x3F, 0xFF, 0xBF, 0xF, 0x0,
0x0, 0xFC,
0xFF, 0x9F, 0xFF, 0xBF, 0xF, 0x0,
0x0, 0xFC,
0xFF, 0xC7, 0xFF, 0xBF, 0xF, 0x0, 0x0, 0xFE, 0x7F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0,
0x80, 0xFF, 0xFF, 0x1, 0x0, 0x0, 0x0, 0x0,
0xC0, 0xFF, 0xFF, 0x1, 0x0, 0x0, 0x0, 0x0,
0xC0, 0xFF, 0xFF, 0x7, 0x0, 0x0, 0x0, 0x0,
0xF0, 0xFF, 0xFF, 0xF, 0x0, 0x0, 0x0, 0x0,
0xF8, 0xFF, 0xFF, 0x1F, 0x0, 0x0, 0x0, 0x0,
0xFC, 0xFF, 0xFF, 0x3F, 0x0, 0x0, 0x0, 0x0,
0xFE, 0xFF, 0xFF, 0xFF, 0x0,
0x0, 0x0,
0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x3,
0x0, 0x0,
0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF, 0x0,
0x0, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x0, 0x0,
0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; void setup() { display.init(); } void loop() { display.clear(); display.drawXbm(32, 0, width, height, b2i); display.display(); delay(1000);
} |
ผลลัพธ์ของโค้ดในตอนที่ นี้แสดงในรูปที่ 6.5(ข) ด้วยวิธีการแสดงผลแบบกราฟฟิกทำให้ผู้ใช้สามารถนำข้อมูลภาพใด ๆ
มาแสดงก็ได้ ดังตัวอย่างในรูปที่ 6.6
รูปที่
6.5 ผลลัพธ์ที่ได้จากการรันโค้ดการทดลอง (ก) ตอนที่ 2
และ (ข) ตอนที่ 3
รูปที่
6.6 ตัวอย่างภาพโลโก้ที่แสดงด้วยจอ OLED