วันอาทิตย์ที่ 30 กันยายน พ.ศ. 2561
MINI project arduino เปิดปิดไฟบ้านด้วยบลูทูธ hc-05
วันอังคารที่ 25 กันยายน พ.ศ. 2561
LiquidCrystal
บทความ การใช้งาน Character LCD Display กับ Arduino
(ตอนที่1 - รูปแบบการเชื่อมต่อแบบ Parallel)

ความรู้ทั่วไปเกี่ยวกับ LCD Display
จอ Liquid Crystal Display (LCD) เป็นจอแสดงผลรูปแบบหนึ่งที่นิยมนำมาใช้งานกันกับระบบสมองกลฝังตัวอย่างแพร่หลาย จอ LCD มีทั้งแบบแสดงผลเป็นตัวอักขระเรียกว่า Character LCD ซึ่งมีการกำหนดตัวอักษรหรืออักขระที่สามารถแสดงผลไว้ได้อยู่แล้ว และแบบที่สามารถแสดงผลเป็นรูปภาพหรือสัญลักษณ์ได้ตามความต้องการของผู้ใช้งานเรียกว่า Graphic LCD นอกจากนี้บางชนิดเป็นจอที่มีการผลิตขึ้นมาใช้เฉพาะงาน ทำให้มีรูปแบบและรูปร่างเฉพาะเจาะจงในการแสดงผล เช่น นาฬิกาดิจิตอล เครื่องคิดเลข หรือ หน้าปัดวิทยุ เป็นต้น

โครงสร้างโดยทั่วไปของ LCD
โครงสร้างของ LCD ทั่วไปจะประกอบขึ้นด้วยแผ่นแก้ว 2 แผ่นประกบกันอยู่ โดยเว้นช่องว่างตรงกลางไว้ 6-10 ไมโครเมตร ผิวด้านในของแผ่นแก้วจะเคลือบด้วยตัวนำไฟฟ้าแบบใสเพื่อใช้แสดงตัวอักษร ตรงกลางระหว่างตัวนำไฟฟ้าแบบใสกับผลึกเหลวจะมีชั้นของสารที่ทำให้โมเลกุลของผลึกรวมตัวกันในทิศทางที่แสงส่องมากระทบเรียกว่า Alignment Layer และผลึกเหลวที่ใช้โดยทั่วไปจะเป็นแบบ Magnetic โดย LCD สามารถแสดงผลให้เรามองเห็นได้ทั้งหมด 3 แบบด้วยกันคือ
- แบบใช้การสะท้อนแสง (Reflective Mode) LCD แบบนี้ใช้สารประเภทโลหะเคลือบอยู่ที่แผ่นหลังของ LCD ซึ่ง LCD ประเภทนี้เหมาะกับการนำมาใช้งานในที่ที่มีแสงสว่างเพียงพอ
- แบบใช้การส่งผ่าน (Transitive Mode) LCD แบบนี้วางหลอดไฟไว้ด้านหลังจอ เพื่อทำให้การอ่านค่าที่แสดงผลทำได้ชัดเจน
- แบบส่งผ่านและสะท้อน (Transflective Mode) LCD แบบนี้เป็นการนำเอาข้อดีของจอแสดงผล LCD ทั้ง 2 แบบมารวมกัน
ในบทความนี้เราจะกล่าวถึงจอ LCD ที่แสดงผลเป็นอักขระหรือตัวอักษร ตามท้องตลาดทั่วไปจะมีหลายแบบด้วยกัน มีทั้ง 16 ตัวอักษร 20 ตัวอักษรหรือมากกว่า และจำนวนบรรทัดจะมีตั้งแต่ 1 บรรทัด 2 บรรทัด 4 บรรทัดหรือมากกว่าตามแต่ความต้องการและลักษณะของงานที่ใช้ หรืออาจจะมีแบบสั่งทำเฉพาะงานก็เป็นได้ ในบทความนี้เราจะยกตัวอย่างจอ LCD ขนาด 16x2 Character หรือที่นิยมเรียกกันว่าจอ LCD 16 ตัวอักษร 2 บรรทัด สามารถหาซื้อได้ง่ายและมีราคาไม่สูง เหมาะสมกับการใช้งานแสดงผลไม่มากในหน้าจอเดียว
จอ LCD 16x2 Character ที่นิยมวางจำหน่ายจะมีอยู่ 2 แบบด้วยกันคือ LCD แบบปกติที่เชื่อมต่อแบบขนาน (Parallel) และ LCD แบบที่เชื่อมต่ออนุกรม (Serial) แบบ I2C โดยทั้ง 2 แบบตัวจอมีลักษณะเดียวกันเพียงแต่แบบ I2C จะมีบอร์ดเสริมทำให้สื่อสารแบบ I2C ได้เชื่อมต่อได้สะดวกขึ้น

รูปที่ 1 จอ LCD 16x2 Character (Parallel)


รูปที่ 2 จอ LCD 16x2 Character (I2C)
ต่อมาเราจะมาดูกันว่าทั้ง 2 แบบมีขาหรือ Pin ในการเชื่อมต่อแตกต่างกันอย่างไร โดยแบบแรกเป็นแบบ Parallel มีทั้งหมด 16 ขาด้วยกัน ส่วนแบบที่สองเป็นแบบ I2C มีเพียง 4 ขา สามารถแยกออกตามตารางด้านล่างครับ
1. แบบ Parallel มี 16 ขา

รูปที่ 3 ด้านหน้าจอ LCD 16x2 (Parallel)

ตารางที่ 1 ตารางขาของจอ LCD 16x2 แบบ Parallel
2. แบบ I2C มี 4 ขา (คลิกอ่าน บทความการเชื่อมต่อแบบ I2C)


รูปที่ 4 ด้านหลังจอ LCD 16x2 (I2C)

ตารางที่ 2 ตารางขาของจอ LCD 16x2 แบบ I2C
การควบคุมการแสดงผลของ LCD
ในการควบคุมหรือสั่งงาน ตัวจอ LCD นั้นมีส่วนควบคุม (Controller) รวมไว้ในตัวแล้ว ผู้ใช้สามารถส่งรหัสคำสั่งควบคุมการทำงานของจอ LCD ผ่าน Controller ว่าต้องการใช้แสดงผลอย่างไร โดย LCD Controller ของจอตัวนี้เป็น Hitachi เบอร์ HD44780 และขาในการเชื่อมต่อระหว่าง LCD กับ Microcontroller มีดังนี้
1. GND เป็นกราวด์ใช้ต่อระหว่าง Ground ของระบบ Microcontroller กับ LCD
2. VCC เป็นไฟเลี้ยงวงจรที่ป้อนให้กับ LCD ขนาด +5VDC
3. VO ใช้ปรับความสว่างของหน้าจอ LCD
4. RS ใช้บอกให้ LCD Controller ทราบว่า Code ที่ส่งมาทางขา Data เป็นคำสั่งหรือข้อมูล
5. R/W ใช้กำหนดว่าจะอ่านหรือเขียนข้อมูลกับ LCD Controller
6. E เป็นขา Enable หรือ Chips Select เพื่อกำหนดการทำงานให้กับ LCD Controller
7-14. DB0-DB7 เป็นขาสัญญาณ Data ใช้สำหรับเขียนหรืออ่านข้อมูล/คำสั่ง กับ LCD Controller
วิธีการสั่งงานจะแตกต่างกันไป โดย LCD Controller สามารถรับรหัสคำสั่งจาก Microcontroller ได้จากสัญญาณ RS R/W และ DB0-DB7 ในขณะที่สัญญาณ E มีค่า Logic เป็น “1” ซึ่งสัญญาณเหล่านี้จะใช้ร่วมกันเพื่อกำหนดเป็นรหัสคำสั่งสำหรับสั่งงาน LCD โดยหน้าที่ของแต่ละสัญญาณพอสรุปได้ดังนี้
- E เป็นสัญญาณ Enable เมื่อมีค่าเป็น
“1” เป็นการบอกให้ LCD ทราบว่าอุปกรณ์ภายนอกต้องการติดต่ออ่านหรือเขียนข้อมูล
“0” ให้ LCD ไม่สนใจสัญญาณ RS R/W และ DB7-DB0
- RS เป็นสัญญาณสำหรับกำหนดให้ LCD ทราบว่าอุปกรณ์ภายนอกต้องการติดต่อกับ LCD ในขณะนั้นเป็นรหัสคำสั่งหรือข้อมูล โดยถ้า
RS = “0” หมายถึง คำสั่ง
RS = “1” หมายถึง ข้อมูล
- R/W เป็นสัญญาณสำหรับบอกให้ LCD ทราบว่าอุปกรณ์ภายนอกต้องการอ่านหรือเขียนกับ LCD โดยถ้า
R/W = “0” หมายถึง เขียน
R/W = “1” หมายถึง อ่าน
- DB0-DB7 เป็นสัญญาณแบบ 2 ทิศทาง โดยจะสัมพันธ์กับสัญญาณ R/W ใช้สำหรับรับสั่ง คำสั่งและข้อมูลระหว่าง LCD กับอุปกรณ์ภายนอก โดยถ้า R/W = “0” สัญญาณ DB7-DB0 จะส่งจากอุปกรณ์ภายนอกมาที่ LCD แต่ถ้า R/W = “1” สัญญาณ DB7-DB0 จะส่งจาก LCD ไปยังอุปกรณ์ภายนอก
การเชื่อมต่อสัญญาณขาข้อมูลระหว่าง Microcontroller กับ LCD Controller
การเชื่อมต่อสัญญาณขาข้อมูลระหว่าง Microcontroller กับ LCD Controller สามารถทำได้ 2 ลักษณะ คือ การเชื่อมต่อแบบ 8 บิต (DB0-DB7) และการเชื่อมต่อแบบ 4 บิต (DB4-DB7) ทั้งสองแบบแตกต่างกันเพียงจำนวนขาที่ใช้คือ 8 หรือ 4 ขา และยังสามารถทำงานได้เหมือนกัน อย่างที่แน่นอนในการส่งข้อมูลแบบ 4 ขา ย่อมทำได้ช้ากว่า 8 ขา แต่ไม่ได้ช้ามากจนสังเกตุได้ด้วยสายตา ในการต่อกับ Arduino นั้นจึงนิยมต่อเพียง 4 ขา หรือ 4 บิตเท่านั้น เพื่อเป็นการประหยัดขาในการต่อใช้งานไปไว้ต่อกับอุปกรณ์อื่น ตัวอย่างเช่น Arduino UNO R3 นั้นมีขาให้ใช้งานค่อนข้างน้อย
ขาที่ใช้ในการเชื่อมต่อกับ Arduino UNO R3

ตารางขาที่ใช้ในการเชื่อมต่อกับ Arduino UNO R3

รายละเอียดคำสั่งในการสั่งงานระหว่าง Arduino กับ จอ LCD
คำสั่งในการควบคุมจอ LCD ของ Arduino นั้น ทาง Arduino.cc เขียนเป็น Library มาให้เพื่อสะดวกในการนำไปใช้งาน หลังจากต่อสายเสร็จเรียบร้อย ขั้นตอนแรกในการเริ่มเขียนโปรแกรมคือการเรียกใช้ Library ของ LCD จากไฟล์ชื่อ LiquidCrystal.h หลังจากนั้นมาดูกันว่ามีฟังก์ชั่นที่สำคัญอะไรบ้างที่ใช้สั่งงานให้จอ LCD
ฟังก์ชั่น LiquidCrystal(); ใช้ประกาศขาที่ต้องการส่งข้อมูลไปยังจอ LCD รูปแบบในการสั่งงานคือ
LiquidCrystal lcd(rs, enable, d4, d5, d6, d7) <<<<<<< ในกรณีใช้งานแบบ 4 บิต
LiquidCrystal lcd(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7) <<<<<<< ในกรณีใช้งานแบบ 8 บิต
ในบทความนี้ใช้แบบ 4 บิต คือ LiquidCrystal lcd(12, 11, 4, 5, 6, 7); ก็หมายถึงการเชื่อมต่อ rs ที่ขา 12 , Enable ที่ขา 11 , และ DB4-DB7 ที่ขา 4-7 ของ Arduino ตามลำดับ
ฟังก์ชั่น begin(); ใช้กำหนดขนาดของจอ ในบทความนี้เราใช้ขนาด 16 ตัวอักษร 2 บรรทัด จึงประกาศเป็น lcd.begin(16, 2);
ฟังก์ชั่น setCursor(); ใช้กำหนดตำแหน่งและบรรทัดของ Cursor เช่น lcd.setCursor(0, 1); คือ ให้เคอร์เซอร์ไปที่ตำแหน่งที่ 0 บรรทัดที่ 1 การนับตำแหน่งเริ่มจาก 0 ดังนั้น LCD 16x2 มีตำแหน่ง 0 – 15 บรรทัด คือ 0 กับ 1
ฟังก์ชั่น print(); ใช้กำหนดข้อความที่ต้องการแสดง เช่น lcd.print("ThaiEasyElec"); คือ ให้แสดงข้อความ “ThaiEasyElec” ออกทางหน้าจอ LCD
แปลง push switch ให้เป็น trigger สวิตซ์ ด้วย Arduino UNO
แปลง push switch ให้เป็น trigger สวิตซ์ ด้วย Arduino UNO

วิดีโอตัวอย่างการทำงาน push สวิตซ์ กดติด กดดับ
อุปกรณ์ที่ใช้ต่อวงจร
- Board Arduino UNO r3
- push switch
- บอร์ดเอนกประสงค์ (Bread board)
- ตัวต้านทาน 5K – 20K Ohms
- หลอด LED 3.3V และ ตัวต้านทาน 220 Ohms เพื่อลดแรงดัน 5v เข้า LED
การต่อวงจร Arduino push switch กดติด กดดับ

ส่วน output จาก pin 13 ไปยังหลอด LED
- ไฟจากขา 13 ไปยัง ตัวต้านทาน 220 โอห์ม เพื่อลดแรงดัน 5v จาก บอร์ดป้องกัน LED เสียหาย
- ไฟที่เหลือจาก ตัวต้านทาน 220 โอห์ม ไปยังขาบวก ของ LED
- จากขาลบ ของ LED เพื่อลง ground
ส่วน input จาก pin 8 เพื่ออ่านค่าไฟเข้ามายัง board
- กระแส 5v ต่อออกจากบอร์ดไปยัง push switch
- จาก push switch เข้าไปยัง pin 8
- จาก push switch ไปยังตัวต้านทาน 10K โอห์ม
- จาก ตัวต้านทาน 10k โอห์มไปยัง Ground

Concept การทำงานของโปรแกรม switch กดติดกดดับด้วย State Change
- ยังไม่กด – สถานะครั้งก่อนเป็น LOW สถานะปัจจุบันเป็น LOW
- ตอนกำลังกดลง – สถานะครั้งก่อนเป็น LOW สถานะปัจจุบันเป็น HIGH
- ตอนกดแช่ไว้ – สถานะครั้งก่อนเป็น HIGH สถานะปัจจุบันเป็น HIGH
- ตอนกำลังปล่อย – สถานะครั้งก่อนเป็น HIGH สถานะปัจจุบันเป็น LOW
- ตอนปล่อยแล้ว – สถานะครั้งก่อนเป็น LOW สถานะปัจจุบันเป็น LOW
การเขียนโปรแกรมเพื่อรับค่า push switch มาปิด/เปิด led
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
|
const int buttonPin = 8; // ขา pin ที่เราจะใช้อ่านค่าการกด push button
const int ledPin = 13; // ขา pin ที่เราใช้ส่งออกไฟไปยัง LED
int currentButtonState = LOW; // ค่าสถานะปัจจุบนของปุ่ม
int previousButtonState = LOW; // ค่าสถานะของปุ่มกดครั้งที่แล้ว
bool isLedOn = false; // ค่าสถานะของ led เริ่มต้นเป้นหลอดปิด
void setup() {
// บอกระบบว่าเราจะใช้ขา 13 เป้นตัวส่งค่าออก
pinMode(ledPin, OUTPUT);
// บอกระบบว่า เราจะใช้ขา 8 เป็นตัวรับค่าเข้ามา
pinMode(buttonPin, INPUT);
}
void loop() {
// อ่านค่าสถานะของ push switch (ว่ากด หรือ ไม่กด)
currentButtonState = digitalRead(buttonPin);
// ตรวจสอบกรณีที่สถานะปุ่มกดไม่เหมือนครั้งที่แล้วและครั้งนี้สถานะเป็นปล่อย
// ซึ่งก็คือปุ่มถูกกดค้างไว้และได้ถูกปล่อยออกนั่นเอง
if ((currentButtonState != previousButtonState) && previousButtonState == HIGH){
// สั่งให้ค่า led เป็นตรงกันข้าม (ถ้าเปิดให้ปิด ถ้าปิดให้เปิด)
isLedOn = !isLedOn;
// ส่งค่าไปยังขา 13 เพื่อให้เปิดหรือปิด led ตามสถานะปัจจุบัน
digitalWrite(ledPin, isLedOn);
// หน่วงเวลา 0.1 วินาทีหน่วงค่าความคลาดเคลื่อนตอนเริ่มต้นกด switch
delay(100);
}
// จำค่าการกดปุ่ม ณ ปัจจุบันไว้ เพื่อนำไปใช้เปรียบเทียบครั้งต่อไป
previousButtonState = currentButtonState;
}
|
อธิบายการทำงานของโปรแกรม
ตรวจในกรณีที่สถานะของสวิตซ์ในรอบที่แล้วไม่เหมือนปัจจุบัน และ สถานะรอบที่แล้วเป็น HIGH (แสดงว่าเพิ่งปล่อยปุ่มกด) ให้ดำเนินการบรรทัดที่ 22-27 แต่ถ้าไม่ใช่ให้ข้ามไป


