การใช้งาน LCD กับ Arduino
สัปดาห์นี้เรามาพูกถึงการใช้งานจอ LCD กันครับ
ที่พวกเราเรียกว่า LCD นั้น มาจากคำว่า Liquid Crystal Display ครับ หลักการทำงานของมันอาศัย-ของเหลวพิเศษที่มีคุณสมบัติการบิดแกนโพราไรซ์ของแสงครับ ถ้าจ่ายแรงดันไฟฟ้าเข้าไประหว่างสารเหลวนี้ โมเลกุลของมันจะบิดตัวและทำให้แสงไม่สามารถผ่านกระจกออกมาได้ ถ้าไม่มีการจ่ายแรงดันไฟฟ้าแสงจะทะลุผ่านออกมาได้
รูปด้านล่างอธิบายความได้เป็นอย่างดีครับ การทำงานของมันเกิดจากกระจกโพลาไรซ์ 2 แผ่น ที่มีแกนตั้งฉากกัน ดังนั้นถ้าไม่ทำอะไรเลยแสงจะไม่สามารถลอดผ่านออกมาได้ เหมือนเอาแว่นตาโพลาไรซ์สองอันมาบิดทำมุมตั้งฉากกัน แสงจะไม่ลอดผ่าน ทีนี้มีคนไปพบว่ามีของเหลวชนิดนึงที่ปกติแล้วจะสามารถ "บิดแกนโพลาไรซ์ของแสง" ได้ ก็เลยเกิดความคิดเอามาทำจอ LCD
ถ้าไม่มีการจ่ายแรงดันเข้าไป สารเหลวที่ว่านี้จะบิดแกนโพลาไรซ์ของแสงไป 90 องศา ทำให้แสงสามารถลอดออกมาได้จากกระจกโพลาไรซ์คู่นี้ได้ ในทางกลับกัน ถ้ามีแรงดันจ่ายไประหว่างสารเหลวนี้ จะไม่เกิดการปิดตัวของแสง ทำให้แสง "ไม่สามารถ" ลอดออกมาได้ครับ
คลิปวีดีโอด้านล่างอาจจะทำให้เข้าใช้ได้ง่ายขึ้นครับ
ทีนี้ก็มีการนำหลักการนี้มาใช้หลายแบบครับ แบบแรกง่ายๆ ก็คือการเอาอิเล็กโทรดที่บังคับการทำงานของของเหลวได้นี้มาทำเป็นรูปตัวเลข ก็จะเห็นแบบที่ใช้ในเครื่องคิดเลข หรือ โดยประกอบเซลล์เล็กๆ ขึ้นมาเป็นเมตริกซ์ ทำให้สามารถควบคุมให้เป็นตัวอักษร หรือ รูปภาพได้
แรกๆที่ทำออกมาก็ไม่ซับซ้อนครับ ใช้ทำเครื่องคิดเลขบ้าง นาฬิกาบ้าง ต่อมาก็เอามาทำจอ LCD Matrix จากนั้นเริ่มมีการผสมสี RGB และทำให้จอมีความละเอียดมากขึ้น (Pixel ต่อ พื้นที่่) ก็เลยกลายเป็นทีวีจอ LCD สีที่เราเห็นครับ
ในบทความนี้ผมจะพูดถึงเฉพาะ LCD ชนิดที่เป็น matrix ซึ่งใช้แสดงตัวอักษรมาตรฐานนะครับ จึงอยู่ว่าจอ LCD matrix สามารถแสงเป็นภาพ หรือ ตัวอักษรตามแต่ผู้ใช้จะควบคุม แต่บทความนี้เอาแบบสั้นๆ คนทั่วไปใช้ละกันครับ เลยเขียนเฉพาะการควบคุมให้แสดงตัวอักษรมาตรฐาน
หลักการทำงานก็จบไป มาถึงรายละเอียดของตัว LCD กันบ้างว่ามีอะไรกันบ้าง มีกี่ Pin ตารางด้านล่างนี้เป็นรายละเอียดของ PIN ของ LCD แบบที่นิยมใช้กันมากๆ คือ 16 x 2 (หมายถึง 16 ตัวอักษร 2 บรรทัดนะครับ) ถ้าดูที่แต่ละตัวอักษรจะเห็นว่ามันเป็น matrix 5x8 ซึ่งแสดงถึงความละเอียดของตัวอักษรนะครับ
ทีนี้ Pin ของ LCD ก็จะมี 16 Pin ตามรายละเอียดในตารางครับ
Pin Description:
Pin No
|
Function
|
Name
|
1
|
Ground (0V)
|
Ground
|
2
|
Supply voltage; 5V (4.7V – 5.3V)
|
Vcc
|
3
|
Contrast adjustment; through a variable resistor
|
VEE
|
4
|
Selects command register when low; and data register when high
|
Register Select
|
5
|
Low to write to the register; High to read from the register
|
Read/write
|
6
|
Sends data to data pins when a high to low pulse is given
|
Enable
|
7
|
8-bit data pins
|
DB0
|
8
|
DB1
| |
9
|
DB2
| |
10
|
DB3
| |
11
|
DB4
| |
12
|
DB5
| |
13
|
DB6
| |
14
|
DB7
| |
15
|
Backlight VCC (5V)
|
Led+
|
16
|
Backlight Ground (0V)
|
Led-
|
16 PIN ที่ว่าก็จะมีตั้งแต่ไฟเลี้ยง กราวด์ Data การควบคุมแสง การควบคุมการแสดงครับ
สำหรับการให้ข้อมูลการแสดงบนหน้าจอ หรือ การติดต่อควบคุมการทำงานของ LCD ก็จะทำโดยผ่าน IC ของบริษัท Hitachi เบอร์ HD44780 เจ้านี้เขาทำเจ้าแรกๆ จนกลายเป็นมาตรฐานของโลกไปแล้วครับ
HD44780 สามารถคุยด้วยได้ 2 แบบหลักคือ แบบ 4 Bit (DB4 - DB7) และ แบบ 8 Bit (DB0 - DB7) ทั้งสองแบบนี้ก็ต่างกันตรงที่ใช้จำนวน pin จาก Arduino 4 pin กับ 8 pin ครับ ก็แน่นอนครับ เราคงไม่อยากใช้ Port เปลือง ดังนั้นส่วนมากคนก็จะนิยมใช้แบบ 4 Pin กันครับ แต่ก็มีความเร็วในการส่งข้อมูลช้ากว่าแบบ 8 pin ครับ แต่ความเร็วที่ว่าก็ไม่ได้เป็นอุปสรรคเลยครับ 4 bit ก็เร็วมากจนสายตาของเราแยกไม่ออกแล้วครับ สรุปก็คือว่าผมแนะนำการต่อแบบ 4 bit ละกันนะครับ ตามภาพด้านบนก็ได้ครับ แล้วแบบ 8 bit มีไว้ทำไมละ คำตอบก็คือ ในยุคแรกๆ ไมโครคอนโทรลเลอร์เขาออกมาเป็นแบบ 8 bit แล้วเพื่อให้เขียนโปรแกรมไม่ซับซ้อนมากนัก ก็เลยใช้ 8 bit ให้เหมือนกัน register ในไมโครคอนโทรลเลอร์ซะครับ
สำหรับ Arduino แล้ว เราจะใช้ LCD แบบบ้านๆ ที่มีขายตามบ้านหม้อ (ถ้าดูภาพแรกก็คือ LCD อันล่าง) หรือจะใช้เป็นแบบ LCD Shield ก็มีหลักการทำงานเดียวกัน ใช้ library เดียวกันครับ ถ้าใช้แบบ LCD เดี่ยวๆ ก็ต้องมาต่อขากันเองนิดหน่อย แต่ถ้าใช้ LCD Shield ก็จับยัดได้เลยครับ แถมมีปุ่มกดมาให้ด้วยครับ ก็แล้วแต่งานที่ต้องเอาไปประยุกต์ใช้ครับ
และก็ตามสไตล์ของ Arduino ครับคือการมี library ที่่ทำให้ใช้งานได้สะดวกมากๆ ใครที่เคยใช้ ไมโครคอนโทรลเลอร์ตัวอื่นมาก่อนจะรู้สึกถึงความแตกต่างชัดเจนครับ Library ของ LCD ก็คือ มีคำสั่งที่สำคัญดังนี้ครับ
- LiquidCrystal() ก็ใช้ในการประกาศ Pin ที่เราจะส่งข้อมูลไปที่จอ LCD ครับ เช่น LiquidCrystal lcd(8, 9, 4, 5, 6, 7); ก็หมายถึง RS ที่ Pin 8 Enable ที่ Pin 9 และ DB4 - DB 7 ที่ขา 4, 5, 6, 7 ตามลำดับครับ ถ้าดูรายละเอียดในคำสั่งนี้ เราจะสามารถใช้การส่งข้อมูลแบบ 8 บิตได้ด้วยครับ
- begin() ใช้ในการกำหนดลักษณะการแสดงของจอ เช่น lcd.begin(16, 2); คือการแสดงภาพ 16 ตัวอักษร 2 แถวครับ
- print() ใช้ในการเขียนข้อความ เช่น lcd.print("Hello !!!");
- setCursor() ใช้ในการกำหนดตำแหน่งของ Cursor เช่น lcd.setCursor(13, 1); คือให้เคอร์เซอร์ไปที่ ตัวอักษรที่ 13 และแถวที่ 1 (อย่าลืมนะครับ มันจะเริ่มนับจาก 0 ตามสไตล์ภาษา C)
- cursor() ก็คือการแสดงตัว Cursor บนหน้าจอครับ เช่น lcd.cursor();
- noCursor() ก็คือการซ่อน Cursor
ที่เหลือ รบกวนไปที่ Arduino.cc นะครับ
สำคัญคือการต่อนะครับ ต้องต่อตามที่เขียนไว้ในคำสั่ง LiquidCrystal() นะครับ Arduino จะได้สั่งงานไปถูกขา
ทีนี้เอาแบบง่ายๆ คือ Hello Arduitronics ครับ ผมสาธิตโดยการใช้ LCD Shield นะครับ ทีนี้ตัว LCD Shield นี้มันก็มีการต่อขาไว้ที่ตัว LCD แบบตายตัวแล้ว เปลี่ยนไม่ได้ซะด้วย ก็ใช้ตามนี้เลยนะครับ
liquidCrystal lcd(8, 9, 4, 5, 6, 7);
ถ้าต่อเองก็เลือกเอาตามอัธยาสัยได้เลยครับ
/*LiquidCrystal Library - "Hello !!!! Arduitronics"Demonstrates the use a 16x2 LCD display. The LiquidCrystallibrary works with all LCD displays that are compatible with theHitachi HD44780 driver. There are many of them out there, and youcan usually tell them by the 16-pin interface.This sketch prints "Hello !!!! Arduitronics" to the LCDand shows the time.The circuit:* LCD RS pin to digital pin 8* LCD Enable pin to digital pin 9* LCD D4 pin to digital pin 4* LCD D5 pin to digital pin 5* LCD D6 pin to digital pin 6* LCD D7 pin to digital pin 7* LCD R/W pin to ground* 10K resistor:* ends to +5V and ground* wiper to LCD VO pin (pin 3)Library originally added 18 Apr 2008by David A. Mellislibrary modified 5 Jul 2009by Limor Fried (http://www.ladyada.net)example added 9 Jul 2009by Tom Igoemodified 22 Nov 2010by Tom IgoeModified by ArduitronicsThis example code is in the public domain.http://www.arduino.cc/en/Tutorial/LiquidCrystal*/// include the library code:#include <LiquidCrystal.h> // initialize the library with the numbers of the interface pinsLiquidCrystal lcd(8, 9, 4, 5, 6, 7);void setup() {// set up the LCD's number of columns and rows:lcd.begin(16, 2);// Print a message to the LCD.lcd.print("Hello !!!");lcd.setCursor(0, 1);lcd.print("Arduitronics");}void loop() {// set the cursor to column 0, line 1// (note: line 1 is the second row, since counting begins with 0):lcd.setCursor(13, 1);// print the number of seconds since reset:lcd.print(millis()/1000);} |
ถ้าต่อถูกต้องก็ตามภาพด้านล่างนี้เลยครับ
อีกตัวอย่างครับ ทีนี้เราจะเริ่มมีการใช้ปุ่มกดกันบ้าง อันนี้ผมได้ตัวอย่างมาจากผู้ผลิตนะครับ DFROBOT
//Sample using LiquidCrystal library#include/*******************************************************This program will test the LCD panel and the buttonsMark Bramwell, July 2010********************************************************/// select the pins used on the LCD panelLiquidCrystal lcd(8, 9, 4, 5, 6, 7);// define some values used by the panel and buttonsint lcd_key = 0;int adc_key_in = 0;#define btnRIGHT 0#define btnUP 1#define btnDOWN 2#define btnLEFT 3#define btnSELECT 4#define btnNONE 5// read the buttonsint read_LCD_buttons(){adc_key_in = analogRead(0); // read the value from the sensor// my buttons when read are centered at these valies: 0, 144, 329, 504, 741// we add approx 50 to those values and check to see if we are closeif (adc_key_in > 1000) return btnNONE;// the 1st option for speed reasons since it will be the most likely result // For V1.1 us this thresholdif (adc_key_in < 50) return btnRIGHT;if (adc_key_in < 250) return btnUP;if (adc_key_in < 450) return btnDOWN;if (adc_key_in < 650) return btnLEFT;if (adc_key_in < 850) return btnSELECT;// For V1.0 comment the other threshold and use the one below:/*if (adc_key_in < 50) return btnRIGHT;if (adc_key_in < 195) return btnUP;if (adc_key_in < 380) return btnDOWN;if (adc_key_in < 555) return btnLEFT;if (adc_key_in < 790) return btnSELECT;*/return btnNONE; // when all others fail, return this...}void setup(){lcd.begin(16, 2); // start the librarylcd.setCursor(0,0);lcd.print("Push the buttons"); // print a simple message}void loop(){lcd.setCursor(9,1); // move cursor to second line "1" and 9 spaces overlcd.print(millis()/1000); // display seconds elapsed since power-uplcd.setCursor(0,1); // move to the begining of the second linelcd_key = read_LCD_buttons(); // read the buttonsswitch (lcd_key) // depending on which button was pushed, we perform an action{case btnRIGHT:{lcd.print("RIGHT ");break;}case btnLEFT:{lcd.print("LEFT ");break;}case btnUP:{lcd.print("UP ");break;}case btnDOWN:{lcd.print("DOWN ");break;}case btnSELECT:{lcd.print("SELECT");break;}case btnNONE:{lcd.print("NONE ");break;}}} |
เช่นกันครับ ถ้าต่อถูกก็ตามนี้ครับ
สำหรับ Data Sheet ของ LCD ก็ตามนี้ครับ
ถ้าเป็น LCD Shield ก็ตามนี้ครับ ข้อดีอีกอันของการใช้ Shield ก็คือ มี R ปรับค่าได้ไว้ปรับความสว่างของหน้าจอมาให้ด้วยนะครับ
แถมอีกนิดครับ เนื่องจากที่ผมเขียนมาทั้งหมด ก็ยังมีคนรู้สึกว่ามันยังต้องใช้ Pin เยอะอยู่ดี ดังนั้นเลยต้องการลดการใช้ PIN ลงอีก จึงประยุกต์ใช้การสื่อสารแบบอนุกรม แบบ I2C (Inter - IC communication) ซะเลย จึงลดขา DB ต่างๆ ลงมาอีก ให้เหลือแค่ 2 PIN
นาย สุธรรม แสงทรง
อ้างอิง
https://www.arduitronics.com/article/28/การใช้งาน-lcd-กับ-arduino
ไม่มีความคิดเห็น:
แสดงความคิดเห็น