วันอังคารที่ 7 มีนาคม พ.ศ. 2560

การใช้งานจอ Character LCD กับ Arduino แบบละเอียด

คำว่า LCD ย่อมาจากคำว่า Liquid Crystal Display ซึ่งเป็นจอที่ทำมาจากผลึกคริสตอลเหลว หลักการคือด้านหลังจอจะมีไฟส่องสว่าง หรือที่เรียกว่า Backlight อยู่ เมื่อมีการปล่อยกระแสไฟฟ้าเข้าไปกระตุ้นที่ผลึก ก็จะทำให้ผลึกโปร่งแสง ทำให้แสงที่มาจากไฟ Backlight แสดงขึ้นมาบนหน้าจอ ส่วนอื่นที่โดนผลึกปิดกั้นไว้ จะมีสีที่แตกต่างกันตามสีของผลึกคริสตอล เช่น สีเขียว หรือ สีฟ้า ทำให้เมื่อมองไปที่จอก็จะพบกับตัวหนังสือสีขาว แล้วพบกับพื้นหลังสีต่างๆกัน
จอ LCD จะแบ่งเป็น 2 แบบใหญ่ๆตามลักษณะการแสดงผลดังนี้
1. Character LCD เป็นจอที่แสดงผลเป็นตัวอักษรตามช่องแบบตายตัว เช่น จอ LCD ขนาด 16x2 หมายถึงใน 1 แถว มีตัวอักษรใส่ได้ 16 ตัว และมีทั้งหมด 2 บรรทัดให้ใช้งาน ส่วน 20x4 จะหมายถึงใน 1 แถว มีตัวอักษรใส่ได้ 20 ตัว และมีทั้งหมด 2 บรรทัด
2. Graphic LCD เป็นจอที่สามารถกำหนดได้ว่าจะให้แต่ละจุดบนหน้าจอกั้นแสง หรือปล่อยแสงออกไป ทำให้จอนี้สามารถสร้างรูปขึ้นมาบนหน้าจอได้ การระบุขนาดจะระบุในลักษณะของจำนวนจุด (Pixels) ในแต่ละแนว เช่น 128x64 หมายถึงจอที่มีจำนวนจุดตามแนวนอน 128 จุด และมีจุดตามแนวตั้ง 64 จุด
ในบทความนี้จะกล่าวถึง Character LCD เพียงอย่างเดียว เนื่องจากใช้งานได้ง่าย และนิยมใช้งานในโปรเจคทั่วๆไปมากกว่าครับ

การเชื่อมต่อกับจอ Character LCD

การเชื่อมต่อจะมีด้วยกัน 2 แบบ คือ
  • การเชื่อมต่อแบบขนาน - เป็นการเชื่อมต่อจอ LCD เข้ากับบอร์ด Arduino โดยตรง โดยจะแบ่งเป็นการเชื่อมต่อแบบ 4 บิต และการเชื่อมต่อแบบ 8 บิต ใน Arduino จะนิยมเชื่อมต่อแบบ 4 บิต เนื่องจากใช้สายในการเชื่อมต่อน้อยกว่า
  • การเชื่อมต่อแบบอนุกรม - เป็นการเชื่อต่อกับจอ LCD ผ่านโมดูลแปลงรูปแบบการเชื่อมต่อกับจอ LCD จากแบบขนาน มาเป็นการเชื่อมต่อแบบอื่นที่ใช้สายน้อยกว่า เช่น การใช้โมดูล I2C Serial Interface จะเป็นการนำโมดูลเชื่อมเข้ากับตัวจอ LCD แล้วใช้บอร์ด Arduino เชื่อมต่อกับบอร์ดโมดูลผ่านโปรโตคอล I2C ทำให้ใช่สายเพียง 4 เส้น ก็ทำให้หน้าจอแสดงผลข้อความต่างๆออกมาได้

การใช้งาน Character LCD กับ Arduino

การเชื่อมต่อแบบขนาน

การเชื่อมต่อแบบขนานแบบ 4 บิต สามารถต่อได้ตามวงจรด้านล่างนี้
เมื่อต่อวงจรเรียบร้อยแล้ว ต่อสาย USB เข้ากับบอร์ด Arduino จะเห็นกล่องสีเหลี่ยมทั้งหมด 16 ตัว (หากเป็นจอ 16x2) ในบรรทัดแรก หากไม่พบกล่อง ให้ปรับความชัดได้จาก VR ที่ต่ออยู่กับขา V0
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // RS, E, D4, D5, D6, D7

void setup() {
  lcd.begin(16, 2); // จอกว้าง 16 ตัวอักษร 2 บรรทัด
  lcd.print("LCDisplay"); // แสดงผลคำว่า Hello, world! ออกหน้าจอ
  lcd.setCursor(0, 1); // เลื่อนเคเซอร์ไปบรรทัดที่ 2 ลำดับที่ 0 (ก่อนหน้าตัวอักษรแรก)
  lcd.print("www.ioxhop.com"); // แสดงผลคำว่า www.ioxhop.com
  delay(3000); // หน่วงเวลา 3 วินาที
  lcd.clear(); // ล้างหน้าจอ
}

void loop() {
  lcd.setCursor(0, 0);
  lcd.print(" InFunction ");
  lcd.setCursor(0, 1);
  lcd.print(" void loop(){ ");
  delay(500); // หน่วงเวลา 0.5 วินาที
  lcd.clear(); // ล้างหน้าจอ
  delay(500); // หน่วงเวลา 0.5 วินาที
}
เมื่ออัพโหลดโค้ดลงไปเรียบร้อยแล้ว หากมองไม่เห็นตัวอักษร หรือเห็นไม่ชัด ให้ปรับความคมชัดที่ VR 10K อีกครั้ง เมื่อปรับอยู่ในระดับที่พอดี กดปุ่ม Reset บนบอร์ด Arduino จะได้ผลออกมาตามคลิปด้านล่างเป็นผลลัพธ์ที่ถูกต้อง

การควบคุมไฟแบล็คไลท์

ย้ายขา A ที่ต่ออยู่กับขั้วบวก มาต่อที่ขา Digital Pin แทน จากนั้นใช้คำสั่ง pinMode() และ digitalWrite() สั่งเปิด-ปิดไฟแบล็คไลท์ได้แบบเดียวกับการควบคุมการติดดับของหลอด LED

การเชื่อมต่อแบบอนุกรม (LCD I2C)

การเชื่อมต่อแบบอนุกรม จะใช้งานโมดูล I2C Serial Interface Board Module มาเชื่อมต่อระหว่าง Arduino กับจอ LCD
วงจรที่เชื่อมต่อจะเป็นไปตามรูปนี้ (กรณีใช้บอร์ดรุ่นอื่น จะต้องต่อ SDA เข้า A4 และ SCL เข้ากับ A5)
ดาว์โหลดไลบารี่ได้จาก : LiquidCrystal_I2C.zip แล้วเพิ่มไลบารี่ตามขั้นตอนต่อไปนี้
เปิดโปรแกรม Arduino IDE ขึ้นมา จากนั้นกดไปที่ Tool > Include Library > Add .ZIP Library
เลือกไฟล์ที่ได้ดาว์โหลดไว้ในขั้นตอนที่แล้ว จากนั้นกดปุ่ม Open
ไลบารี่ได้ถูกเพิ่มเข้ามาแล้ว นำโค้ดต่อไปนี้อัพโหลดลงบอร์ด Arduino
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Set the LCD address to 0x27 in PCF8574 by NXP and Set to 0x3F in PCF8574A by Ti
LiquidCrystal_I2C lcd(0x3F, 16, 2); // จอกว้าง 16 ตัวอักษร 2 บรรทัด รหัสประจำตัว 0x3F

void setup() {
  lcd.begin();
  lcd.print("LCDisplay"); // แสดงผลคำว่า Hello, world! ออกหน้าจอ
  lcd.setCursor(0, 1); // เลื่อนเคเซอร์ไปบรรทัดที่ 2 ลำดับที่ 0 (ก่อนหน้าตัวอักษรแรก)
  lcd.print("www.ioxhop.com"); // แสดงผลคำว่า www.ioxhop.com
  delay(3000); // หน่วงเวลา 3 วินาที
  lcd.clear(); // ล้างหน้าจอ
}

void loop() {
  lcd.setCursor(3, 0);
  lcd.print("InFunction ");
  lcd.setCursor(2, 1);
  lcd.print("void loop(){ ");
  delay(500); // หน่วงเวลา 0.5 วินาที
  lcd.clear(); // ล้างหน้าจอ
  delay(500); // หน่วงเวลา 0.5 วินาที
}
ตรง 0x3F หากอัพโหลดแล้วไม่สามารถใช้งานได้ (ไม่มีอะไรแสดงผลออกทางหน้าจอ) ลองแก้เป็น 0x27 แล้วอัพโหลดเข้าไปใหม่อีกครั้ง
ผลที่ได้ก็จะเป็นไปตามคลิปนี้

การเปลี่ยนหมายเลขประจำตัว (I2C Address)

ในกรณีที่ต้องการต่อจอหลายๆจอโดยใช้ไมโครฯตัวเดียวกัน สามารถเปลี่ยนหมายเลขประจำตัว หรือ Address ได้จากการจั้มแนวยาว A0 หรือ A1 หรือ A2 ทำให้ A0 หรือ A1 หรือ A2 มีลอจิกเป็น 0 ทำให้หมายเลขประจำตัวเปลี่ยนไปดังตารางด้านล่างนี้
กรณีชิปบนโมดูลเป็นเบอร์ PCF8574
กรณีชิปบนโมดูลเป็นเบอร์ PCF8574A

ฟังก์ชั่นสั่งงานจอ LCD

lcd.clear()
> ใช้ล้างหน้าจอ เมื่อมีตัวอักษรใดๆอยู่บนหน้าจอ จะถูกล้างออกทั้งหมด
lcd.home()
> ใช้ปรับให้เคเซอร์กลับไปอยู่ที่ตำแหน่งแรกด้านซ้าย เมื่อใช้คำสั่ง lcd.print() จะไปเริ่มแสดงผลทางด้านบนซ้าย
lcd.setCursor(ลำดับตัวอักษรนับจากทางซ้าย, บรรทัด)
> ใช้ตั้งค่าเคเซอร์ เช่น lcd.setCursor(2, 0); หมายถึงเซ็ตเคเซอร์ไปตัวอักษรที่ 2 นับจากทางซ้าย และอยู่บรรทัดแรก เมื่อใช้คำสั่ง lcd.print() ตัวอักษรตัวแรกจะอยู่ลำดับที่ 3 นับจากทางซ้าย
lcd.write(ข้อมูลที่ต้องการเขียนออกไป)
> ใช้สำหรับเขียนข้อมูลออกไปทีละตัวอักษร
lcd.print(ข้อมูลที่ต้องการให้เขียนออกไป [, รูปแบบข้อมูล])
> ใช้เขียนข้อมูลออกไปทั้งข้อความ
lcd.cursor()
> ใช้สั่งให้แสดงเคเซอร์บนหน้าจอ
lcd.noCursor()
> ใช้สั่งให้ไม่แสดงเคเซอร์บนหน้าจอ
lcd.display()
> แสดงตัวอักษรบนหน้าจอ
lcd.noDisplay()
> ปิดการแสดงตัวอักษรในหน้าจอ
lcd.scrollDisplayLeft()
> เลือนตัวอักษรไปทางซ้าย 1 ตัว
lcd.scrollDisplayRight()
> เลื่อนตัวอักษรไปทางขวา 1 ตัว
lcd.autoscroll()
> เลื่อนตัวอักษรไปทางขวาอัตโนมัติหากใช้คำสั่ง lcd.print() หรือ lcd.write() เมื่อตัวอักษรเต็มหน้าจอ
lcd.noAutoscroll()
> ปิดการเลื่อนตัวอักษรอัตโนมัติ
lcd.leftToRight()
> เมื่อใช้คำสั่ง lcd.print() หรือ lcd.write() ตัวอักษรจะเขียนจากซ้ายไปขวา
lcd.rightToLeft()
> เมื่อใช้คำสั่ง lcd.print() หรือ lcd.write() ตัวอักษรจะเขียนจากขวาไปซ้าย

การทำโหมดประหยัดพลังงาน ปิดหน้าจอ LCD

การปิดหน้าจอจะต้องนำคำสั่ง 2 ตัวมาใช้ คือ คำสั่งสำหรับให้หน้าจอไม่แสดงข้อความใดๆออกไป และคำสั่งปิดไฟแบล็คไลท์ ซึ่งการเชื่อมต่อทั้ง 2 แบบที่ได้กล่าวมา โค้ดจะแตกต่างกันเล็กน้อย ทาง IOXhop เขียนเป็นฟังก์ชั่นมาให้ใช้งาน และทดลองง่ายๆแล้ว ดังนี้
การเชื่อมต่อแบบขนาน
#include <LiquidCrystal.h>

#define BacklightPin 7

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  pinMode(BacklightPin, OUTPUT);
  digitalWrite(BacklightPin, HIGH);
  lcd.begin(16, 2);
  lcd.print("LCD Safe Mode"); // แสดงคำว่า LCD Safe Mode ออกทางหน้าจอ
}

void loop() {
  LCD_ON(); // เปิดหน้าจอ
  delay(1000); // หน่วงเวลา 1 วินาที
  LCD_OFF(); // ปิดหน้าจอ
  delay(1000); // หน่วงเวลา 1 วินาที
}

void LCD_ON() {
  lcd.display(); // เปิดการแสดงตัวอักษร
  digitalWrite(BacklightPin, HIGH); // เปิดไฟแบล็กไลค์
}

void LCD_OFF() {
  lcd.noDisplay(); // ปิดการแสดงตัวอักษร
  digitalWrite(BacklightPin, LOW); // ปิดไฟแบล็กไลค์
}
ขา A ของจอ LCD จะต้องต่ออยู่กับขา Digital pin 7 เพื่อให้สามารถควบคุมไฟแบล็คไลท์ได้
การเชื่อมต่อแบบอนุกรม (LCD I2C)
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Set the LCD address to 0x27 in PCF8574 by NXP and Set to 0x3F in PCF8574A by Ti
LiquidCrystal_I2C lcd(0x3F, 16, 2);

void setup() {
  lcd.begin();
  lcd.print("LCD Safe Mode"); // แสดงคำว่า LCD Safe Mode ออกทางหน้าจอ
}

void loop() {
  LCD_ON(); // เปิดหน้าจอ
  delay(1000); // หน่วงเวลา 1 วินาที
  LCD_OFF(); // ปิดหน้าจอ
  delay(1000); // หน่วงเวลา 1 วินาที
}

void LCD_ON() {
  lcd.display(); // เปิดการแสดงตัวอักษร
  lcd.backlight(); // เปิดไฟแบล็กไลค์
}

void LCD_OFF() {
  lcd.noDisplay(); // ปิดการแสดงตัวอักษร
  lcd.noBacklight(); // ปิดไฟแบล็กไลค์
}

การสร้างตัวอักษร / ใส่รูปภาพ ลงจอ LCD

นอกจากจะใช้ตัวอักษร ABCD .... ตัวเลข เครื่องหมายต่างๆแล้ว ยังสามารถสร้างตัวอักษรเองให้เป็นลักษณะของรูปภาพได้ เพื่อเพิ่มความเข้าใจ และความสวยงามของการแสดงผลข้อมูลบนหน้าจอ
การสร้างตัวอักษรสามารถสร้างได้จากลิ้ง : http://maxpromer.github.io/LCD-Character-Creator/ ก๊อบโค้ดมาลองอัพเข้า Arduino ได้เลย
-----------------------------------------------------

ไม่มีความคิดเห็น:

แสดงความคิดเห็น