วันนี้เรามาติดตามภาคต่อของการใช้งานจอแบบ TFT กันครับ
เริ่มต้นกันด้วยการแนะนำชนิดต่างๆของจอ Touch Screen กันครับ ในปัจจุบัน จอสัมผัส หรือ Touch Screen ที่นิยมใช้กันมากที่สุดน่าจะเป็นจอแบบ Capacitive Touch Screen ที่เห็นใช้งานกันโทรศัพท์ Smart Phone หรือ Ipad I Phone สารพัดตระกูล "ไอ" ครับ
ส่วนที่มีเหลือใช้งานกันอยู่บ้างก็จะเป็นพวก Resistive Touch Screen ซึ่งใช้งานกับโทรศัพท์ หรือ พวก PDA อย่าง Palm เมื่อซักเกือบ 10 ปีที่แล้วครับ ที่อาจจะเห็นบ่อยๆ อีกตัวคือ Nintendo DS ครับ
จะเห็นว่าจอ Touch Screen นั้นทำหน้าที่สำคัญในการติดต่อแสดงผล และ รับคำสั่งจากผู้ใช้งานโดยการสัมผัสที่หน้าจอครับ (นึกถึงเมนูของ Tablet หรือ Smart Phone แล้วจะเข้าใจ)
แต่จะว่าไปแล้วจอแบบ Touch Screen นี้ก็มีการใช้งานเป็น Consumer electronics วางขายกันตั้งแต่ยุุค 1980s กันแล้ว โดยเริ่มเปิดตลาดด้วย คอมพิวเตอร์ HP Series 100 HP-150 ca.
ภาพจาก http://en.wikipedia.org/wiki/Touchscreen
ในบทความนี้จะเขียนถึงเรื่องของ Resistive Touch Screen เยอะหน่อยนะครับ เพราะอุปกรณที่เราใช้ในการทดลองวันนี้จะเป็นแบบ Resistive Touch Screen นี้ เหตุผลเพราะราคาครับ ตอนนี้จอแสดงผลแบบนี้ราคาถูกลงมากแล้ว และสามารถทำราคาโดยให้พวกนักเรียนนักศึกษา หรือ มือสมัครเล่นที่นิยม Hobby electronics หาซื้อกันได้ครับ
มาดูหลักการทำงานกันนิดนึงครับ ง่ายๆเลยครับ Resistive Touch Screen ระบุตำแหน่งโดยใช้การหาค่าทีละแกน (สแกนบนแกน X และ สแกนบนแกน Y ทีละแกน) โครงสร้างของจอ Resistive Touch Screen จะเป็นแผ่นที่ทำจากวัสดุใส 2 ชั้น โดยมีช่องว่างอยู่ตรงกลาง แผ่นวัสดุใสดังกล่าวมีคุณสมบัติเป็นตัวต้านทาน เมื่อผู้ใช้กดลงไปบนหน้าจอโดยการใช้ Stylus หรือใช้นิ้วกดลงไปที่จอ จะทำให้แผ่นวัสดุชั้นบนถูกกดลงไปสัมผัสกับชั้นล่าง
โดยแต่ละแกน เราสามารถหาค่าตำแหน่ง (ระยะจากขอบจอ) โดยใช้หลักการแบ่งแรงดันตามสมการในรูปด้านล่างครับ เสร็จการสแกนแกนแรกก็ย้ายไปหาค่าในแกนที่เหลือ (ภายในเวลาสั้นๆ)
โดยมี CPU หรือ ส่วนที่ใช้ในการควบคุมการสลับแกนและคำนวณระยะห่างจากขอบจอของแกนทั้งสอง และดังที่เห็นในภาพนะครับ ส่วนที่ใช้ในการระบุตำแหน่งบนจอสัมผัส จะซ้อนอยู่ด้านบนของจอแสดงภาพอีกที
ข้อดีของจอแบบ Resistive Touch Screen คือ การที่จอสามารถระบุตำแหน่งโดยไม่ต้องมีการสัมผัสโดยตรงกับผู้ใช้งาน (ไม่เหมือนกับ Capacitive Touch Screen) แต่สามารถกดโดยใช้วัสดุใดก็ได้ในการกดลงบนหน้าจอ ทำให้สามารถใช้ในโรงงานอุตสาหกรรมที่ผู้ปฏิบัติงานต้องใส่ถุงมือ หรือ ในงานที่เกี่ยวกับการแพทย์ซึ่งไม่ต้องการให้ผู้ปฏิบัติงานสัมผัสโดยตรงกับหน้าจอครับ
แต่ข้อเสียก็มีครับ ข้อเสียที่สำคัญที่สุดคือความละเอียดของจอไม่สูงครับ ทำให้การระบุตำแหน่งมีความแม่นยำน้อยกว่าจอแบบอื่น เช่น Capacitive Touch Screen
สำหรับจอแบบ Capacitive Touch Screen ที่ใช้กับอุปกรณ์ประเภท Smart Phone ในปัจจุบัน นั้น คร่าวๆคือ ตำแหน่งที่สัมผัสบนจอจะถูกระบุโดยการสแกนหาตำแหน่งที่มีการเปลี่ยนแปลงของสนามไฟฟ้าเนื่องจากมีนิ้วมือมารับการถ่ายประจุออกไปจากหน้าจอครับ ทีนี้อาจจะสงสัยว่าแล้วทำไมการใช้ Stylus ก็สามารถใช้แทนนิ้วมือได้ ถ้าสังเกตดูนะครับ Stylus ที่สามารถใช้ได้กับจอ Capacitive Touch Screen นั้น จะต้องทำจากวัสดุนำไฟฟ้า เนื่องจากต้องมีความสามารถในการถ่ายประจุจากจอไปที่มือของผู้ใช้ครับ
ทีนี้มาดูจอที่เราจะใช้ในการทดลองกันวันนี้ครับ ตามภาพด้านล่างครับ จอ Capacitive Touch Screen ที่มีขายจะมีหลายขนาดครับ โดยสามารถเลือกให้มีขนาดเท่ากับ Board Arduino รุ่น UNO R3 หรือ Arduino Mega 2560 ก็ได้ครับ
และเช่นเดียวกับการใช้แสดงผล บอร์ดต้องติดต่อกับจอโดยใช้แรงดันที่ระดับ 3.3 V นะครับ ถ้าใช้ 5 V ก็อาจจะเสียได้ ดังนั้นจึงต้องใช้ร่วมกับอุปกรณ์เสริม TFT LCD Mega Shield V2.2 หรือ TFT01 Arduino Shield V2.0 by Elecfreaks ตามรูปด้านล่างครับ
มาถึงการใช้งานอุปกรณ์ของเราครับ
ในบทความนี้ผมใช้ Arduino Mega ADK คู่กับ TFT LCD Mega Shield V2.2 และจอ 3.2 inch TFT LCD module Display with touch panel SD การใช้งานก็ง่ายๆ ครับ แค่
1. ต่อซ้อนกันขึ้นไปดังรูป
2. เสร็จแล้วลง Library ชื่อ UTouch และ UTFT โหลดได้จาก
http://www.henningkarlsen.com/electronics/download.php?f=UTouch.rar
http://www.henningkarlsen.com/electronics/download.php?f=UTFT.rar
|
3. ติดตั้งใน Folder C:\\arduino-1.xx\libraries\UTouch
4. Restart Arduino IDE ซะอีกครั้งก่อนที่จะลุยต่อครับ
5. ให้เปิด example UTouch_QuickPaint.ino จากนั้นก็เลือกชนิดของบอร์ดและจอให้ถูกต้อง (UNO กับ Mega ใช้ Library คนละตัวครับ) สำหรับบอร์ดและจอที่ร้านเราขาย ให้เลือกตามนี้ครับ
// Uncomment the next two lines for the Arduino Mega
UTFT myGLCD(ITDB32S, 38,39,40,41); // Remember to change the model parameter // to suit your display module!
UTouch myTouch(6,5,4,3,2);
เสร็จแล้วลอง Upload Sketch UTouch_QuickPaint ลงไปในบอร์ดครับ อย่าลืมเลือกชนิดของบอร์ดให้ถูกใน Arduino IDE นะครับ
สำหรับ Arduino IDE นั้น ผมได้ทดสอบกับการทำงานของ Version 1.02 , 1.05 และ 1.5 ใช้งานได้ทุกเวอร์ชั่นที่ว่ามาครับ
// UTouch_QuickPaint (C)2013 Henning Karlsen// web: http://www.henningkarlsen.com/electronics//// This program is a quick demo of how to use the library.//// This program requires the UTFT library and a display// module with at least 320x240 pixels resolution.//// It is assumed that the display module is connected to an// appropriate shield or that you know how to change the pin// numbers in the setup.//#include#include // Declare which fonts we will be usingextern uint8_t BigFont[];// Uncomment the next two lines for the Arduino 2009/UNO//UTFT myGLCD(ITDB24D,19,18,17,16); // Remember to change the model parameter to suit your display module!//UTouch myTouch(15,10,14,9,8);// Uncomment the next two lines for the Arduino Mega/DueUTFT myGLCD((TFT01_32W,38,39,40,41); // Remember to change the model parameter to suit your display module!UTouch myTouch(6,5,4,3,2);int color = 0;word colorlist[] = {VGA_WHITE, VGA_BLACK, VGA_RED, VGA_BLUE, VGA_GREEN, VGA_FUCHSIA, VGA_YELLOW, VGA_AQUA};int bsize = 4;void drawColorMarkerAndBrushSize(int col){myGLCD.setColor(VGA_BLACK);myGLCD.fillRect(25, 0, 31, 239);myGLCD.fillRect(myGLCD.getDisplayXSize()-31, 161, myGLCD.getDisplayXSize()-1, 191);myGLCD.setColor(VGA_WHITE);myGLCD.drawPixel(25, (col*30)+15);for (int i=1; i<7; i++)myGLCD.drawLine(25+i, ((col*30)+15)-i, 25+i, ((col*30)+15)+i);if (color==1)myGLCD.setColor(VGA_WHITE);elsemyGLCD.setColor(colorlist[col]);if (bsize==1)myGLCD.drawPixel(myGLCD.getDisplayXSize()-15, 177);elsemyGLCD.fillCircle(myGLCD.getDisplayXSize()-15, 177, bsize);myGLCD.setColor(colorlist[col]);}void setup(){myGLCD.InitLCD();myGLCD.clrScr();myGLCD.setFont(BigFont);myTouch.InitTouch();myTouch.setPrecision(PREC_HI);myGLCD.setColor(VGA_WHITE);myGLCD.drawLine(32,0,32,myGLCD.getDisplayYSize()-1);myGLCD.drawLine(myGLCD.getDisplayXSize()-32,0,myGLCD.getDisplayXSize()-32,myGLCD.getDisplayYSize()-1);myGLCD.print("C", myGLCD.getDisplayXSize()-24, 8);myGLCD.print("L", myGLCD.getDisplayXSize()-24, 24);myGLCD.print("E", myGLCD.getDisplayXSize()-24, 40);myGLCD.print("A", myGLCD.getDisplayXSize()-24, 56);myGLCD.print("R", myGLCD.getDisplayXSize()-24, 72);myGLCD.print("+", myGLCD.getDisplayXSize()-24, 136);myGLCD.print("-", myGLCD.getDisplayXSize()-24, 200);myGLCD.fillRect(myGLCD.getDisplayXSize()-32,96,myGLCD.getDisplayXSize()-1,128);myGLCD.drawLine(myGLCD.getDisplayXSize()-32,160,myGLCD.getDisplayXSize()-1,160);myGLCD.drawLine(myGLCD.getDisplayXSize()-32,192,myGLCD.getDisplayXSize()-1,192);myGLCD.drawLine(myGLCD.getDisplayXSize()-32,224,myGLCD.getDisplayXSize()-1,224);for (int i=0; i<8; i++){myGLCD.setColor(colorlist[i]);myGLCD.fillRect(0, (i*30), 24, (((i+1)*30)-1));}drawColorMarkerAndBrushSize(color);}void loop(){long x, y;while (myTouch.dataAvailable() == true){myTouch.read();x = myTouch.getX();y = myTouch.getY();if ((x!=-1) and (y!=-1)){if (x>(31+bsize) and (x<myGLCD.getDisplayXSize()-(31+bsize))){if (bsize==1)myGLCD.drawPixel(x, y);elsemyGLCD.fillCircle(x, y, bsize);}else{if (x<(30+bsize)){if (y<240){color = y / 30;drawColorMarkerAndBrushSize(color);while (myTouch.dataAvailable()) {};delay(50);}}else{if (y<96){myGLCD.setColor(VGA_BLACK);myGLCD.fillRect(33, 0, myGLCD.getDisplayXSize()-33, myGLCD.getDisplayYSize()-1);myGLCD.setColor(colorlist[color]);}if ((y>128) and (y<160)){if (bsize<7){bsize++;drawColorMarkerAndBrushSize(color);while (myTouch.dataAvailable()) {};delay(50);}}if ((y>160) and (y<192)){bsize=4;drawColorMarkerAndBrushSize(color);while (myTouch.dataAvailable()) {};delay(50);}if ((y>192) and (y<224)){if (bsize>1){bsize--;drawColorMarkerAndBrushSize(color);while (myTouch.dataAvailable()) {};delay(50);}}}}}}} |
*** การเลือกซื้อบอร์ดต้องให้แน่ใจนะครับว่ามี Library และคำแนะนำของผู้ขายประกอบนะครับ ถ้าให้ดีควรซื้อกับร้านที่มีการทดลองแล้วว่าใช้งานคู่กับ Library ที่ให้มาได้ 100 % การใช้งานสลับกัน หรือ Library ไม่ถูกต้องอาจจะทำให้จอไม่ทำงานหรือทำงานผิดปรกติได้ครับ ***
ถ้าเสร็จแล้วจะเห็นว่าจอจะแสดงแบบนี้ (ลองเขียนดูนะครับ)
ข้อมูลที่สำคัญสำหรับผู้อ่าน
บทความที่เขียนด้านบนนั้นใช้สำหรับ TFT LCD + Touch Screen ในรุ่น 3.2" TFT Touch screen รุ่นที่ร้านเราจำหน่ายนะครับ การใช้งานในแบบอื่นๆ ถึงแม้จะมีขนาดเท่ากันก็ต้องใช้ Library ที่ผู้ผลิตให้มานะครับ
2.4" TFT LCD Module Display + Touch Screen รุ่น 240*320 V1.3
สำหรับการใช้งานกับ 2.4" TFT LCD Module Display + Touch Screen รุ่น 240*320 V1.3 ขอให้ใช้ Library ตามนี้นะครับ ตัวอย่างการใช้งาน Touch Screen ก็ตามนี้ครับ (ผมทดสอบกับ ARDUINO UNO R3 นะครับ)
ให้ทดสอบตัวอย่างด้านล่างด้วย Arduino IDE version ที่ต่ำกว่า 1.0 นะครับ ผมต้องกลับไปใช้ Arduino-0022 แทน เพราะ Function บางอย่าง ได้ยกเลิกไปในเวอร์ชั่นใหม่ๆ แล้ว
Library ก็ Download ตามนี้นะครับ
/*================================================================This demo code shows how to use the touch screen in TFT01The LCD connection is the same as that in “8 Bit Pant Demo“by Elecfreaks================================================================*/#define LCD_RS 19#define LCD_WR 18#define LCD_CS 17#define LCD_REST 16#define DCLK 15#define DIN 14#define CS 8#define DOUT 9//#define IRQ 8unsigned int TP_X,TP_Y;unsigned int TouchCount=0;int pacy=0;void spistar() //SPI Start{digitalWrite(CS,LOW);digitalWrite(DCLK,HIGH);digitalWrite(DIN,HIGH);digitalWrite(DCLK,HIGH);}//**********************************************************void WriteCharTo7843(unsigned char num) //SPI Write Data{unsigned char count=0;unsigned char temp;unsigned nop;temp=num;digitalWrite(DCLK,LOW);for(count=0;count<8;count++){if(temp&0x80)digitalWrite(DIN,HIGH);elsedigitalWrite(DIN,LOW);temp=temp<<1;digitalWrite(DCLK,LOW);nop++;nop++;digitalWrite(DCLK,HIGH);nop++;nop++;}}//**********************************************************unsigned int ReadFromCharFrom7843() //SPI Read Data{unsigned nop;unsigned char count=0;unsigned int Num=0;for(count=0;count<12;count++){Num<<=1;digitalWrite(DCLK,HIGH);//DCLK=1; _nop_();_nop_();_nop_();nop++;digitalWrite(DCLK,LOW);//DCLK=0; _nop_();_nop_();_nop_();nop++;if(digitalRead(DOUT)) Num++;}return(Num);}void LCD_Writ_Bus(char VH,char VL){PORTD = VH;digitalWrite(LCD_WR,LOW);digitalWrite(LCD_WR,HIGH);PORTD = VL;digitalWrite(LCD_WR,LOW);digitalWrite(LCD_WR,HIGH);}void LCD_Write_COM(char VH,char VL){digitalWrite(LCD_RS,LOW);LCD_Writ_Bus(VH,VL);}void LCD_Write_DATA(char VH,char VL){digitalWrite(LCD_RS,HIGH);LCD_Writ_Bus(VH,VL);}void Lcd_Write_Com_Data(int com,int val) //发送数据命令{LCD_Write_COM(com>>8,com);LCD_Write_DATA(val>>8,val);}void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2){LCD_Write_COM(0x00,0x46);LCD_Write_DATA(x2,x1);LCD_Write_COM(0x00,0x47);LCD_Write_DATA(y2>>8,y2);LCD_Write_COM(0x00,0x48);LCD_Write_DATA(y1>>8,y1);LCD_Write_COM(0x00,0x20);LCD_Write_DATA(x1>>8,x1);LCD_Write_COM(0x00,0x21);LCD_Write_DATA(y1>>8,y1);LCD_Write_COM(0x00,0x22);}void LCD_Init(void){digitalWrite(LCD_REST,HIGH);delay(5);digitalWrite(LCD_REST,LOW);delay(5);digitalWrite(LCD_REST,HIGH);delay(5);digitalWrite(LCD_CS,LOW);Lcd_Write_Com_Data(0x11,0x2004);Lcd_Write_Com_Data(0x13,0xCC00);Lcd_Write_Com_Data(0x15,0x2600);Lcd_Write_Com_Data(0x14,0x252A);Lcd_Write_Com_Data(0x12,0x0033);Lcd_Write_Com_Data(0x13,0xCC04);delay(1);Lcd_Write_Com_Data(0x13,0xCC06);delay(1);Lcd_Write_Com_Data(0x13,0xCC4F);delay(1);Lcd_Write_Com_Data(0x13,0x674F);Lcd_Write_Com_Data(0x11,0x2003);delay(1);Lcd_Write_Com_Data(0x30,0x2609);Lcd_Write_Com_Data(0x31,0x242C);Lcd_Write_Com_Data(0x32,0x1F23);Lcd_Write_Com_Data(0x33,0x2425);Lcd_Write_Com_Data(0x34,0x2226);Lcd_Write_Com_Data(0x35,0x2523);Lcd_Write_Com_Data(0x36,0x1C1A);Lcd_Write_Com_Data(0x37,0x131D);Lcd_Write_Com_Data(0x38,0x0B11);Lcd_Write_Com_Data(0x39,0x1210);Lcd_Write_Com_Data(0x3A,0x1315);Lcd_Write_Com_Data(0x3B,0x3619);Lcd_Write_Com_Data(0x3C,0x0D00);Lcd_Write_Com_Data(0x3D,0x000D);Lcd_Write_Com_Data(0x16,0x0007);Lcd_Write_Com_Data(0x02,0x0013);Lcd_Write_Com_Data(0x03,0x0003);Lcd_Write_Com_Data(0x01,0x0127);delay(1);Lcd_Write_Com_Data(0x08,0x0303);Lcd_Write_Com_Data(0x0A,0x000B);Lcd_Write_Com_Data(0x0B,0x0003);Lcd_Write_Com_Data(0x0C,0x0000);Lcd_Write_Com_Data(0x41,0x0000);Lcd_Write_Com_Data(0x50,0x0000);Lcd_Write_Com_Data(0x60,0x0005);Lcd_Write_Com_Data(0x70,0x000B);Lcd_Write_Com_Data(0x71,0x0000);Lcd_Write_Com_Data(0x78,0x0000);Lcd_Write_Com_Data(0x7A,0x0000);Lcd_Write_Com_Data(0x79,0x0007);Lcd_Write_Com_Data(0x07,0x0051);delay(1);Lcd_Write_Com_Data(0x07,0x0053);Lcd_Write_Com_Data(0x79,0x0000);LCD_Write_COM(0x00,0x22);digitalWrite(LCD_CS,HIGH);}void Pant(char VH,char VL){int i,j;digitalWrite(LCD_CS,LOW);Address_set(0,0,240,320);for(i=0;i<=320;i++){for (j=0;j<=240;j++){LCD_Write_DATA(VH,VL);}}digitalWrite(LCD_CS,HIGH);}void AD7843(void){digitalWrite(CS,LOW);WriteCharTo7843(0x90);digitalWrite(DCLK,HIGH);digitalWrite(DCLK,LOW);TP_Y=ReadFromCharFrom7843();WriteCharTo7843(0xD0);digitalWrite(DCLK,HIGH);digitalWrite(DCLK,LOW);TP_X=ReadFromCharFrom7843();digitalWrite(CS,HIGH);}void setup(){unsigned char p;int i,j,k;for(p=0;p<20;p++){pinMode(p,OUTPUT);}pinMode(DOUT,INPUT);// pinMode(IRQ,INPUT);LCD_Init();Pant(0x00,0x00);}void loop(){ TouchCount++;unsigned char flag;unsigned char ss[6];unsigned int lx,ly;spistar();if(TouchCount==200){pacy=random(0, 7);TouchCount=0;}// while(digitalRead(IRQ)==0)// {digitalWrite(LCD_CS,LOW);AD7843();lx=240-((TP_X-220)/16);ly=320-((TP_Y-400)/11);Address_set(lx,ly,lx+2,ly+2);switch(pacy){case 0: for(int i=0; i<5; i++) LCD_Write_DATA(0xF8,0x00); break; //Redcase 1: for(int i=0; i<5; i++) LCD_Write_DATA(0xFF,0xE0); break; //Yellowcase 2: for(int i=0; i<5; i++) LCD_Write_DATA(0xFF,0xFF); break; //Whitecase 3: for(int i=0; i<5; i++) LCD_Write_DATA(0x05,0x1F); break; //Bluecase 4: for(int i=0; i<5; i++) LCD_Write_DATA(0x00,0x1F); break; //Blue-2case 5: for(int i=0; i<5; i++) LCD_Write_DATA(0xF8,0x1F); break; //Magentacase 6: for(int i=0; i<5; i++) LCD_Write_DATA(0x07,0xE0); break; //Greencase 7: for(int i=0; i<5; i++) LCD_Write_DATA(0x7F,0xFF); break; //Cyandefoult:for(int i=0; i<5; i++) LCD_Write_DATA(0x00,0x00); break; //Black}digitalWrite(LCD_CS,HIGH);// }} |
Link ที่น่าสนใจ
UTFT Manual
https://www.robotics.org.za/datasheet/UTFT_library_ref.pdf
Library
http://www.henningkarlsen.com/electronics/library.php?id=51
Schematics
http://www.elecfreaks.com/wiki/index.php?title=2.4%22_TFT_LCD:_TFT01-2.4#8_bit_Show_Picture_Demo
TFT by Elecfreaks
http://www.elecfreaks.com/1249.html
UTOUCH
http://www.henningkarlsen.com/electronics/library.php?id=55
อ่านบทความตอนที่ 1
Introduction to TFT + Touch Screen with Arduino Boards
อ่านบทความแล้วมีข้อสงสัย หรือมีข้อแนะนำ ก็ติดต่อมาได้นะครับ
โดย Mountain A
หน้านี้เป็นสารบัญของบทความที่ปรากฏในเว็บของ Arduitronics.com นะครับ จะขอแบ่งออกเป็นหัวข้อตามกลุ่มของสินค้าในร้านดังต่อไปนี้
หน้าที่เข้าชม | 15,375,832 ครั้ง |
ผู้ชมทั้งหมด | 5,878,910 ครั้ง |
เปิดร้าน | 21 พ.ค. 2556 |
ร้านค้าอัพเดท | 6 ก.ย. 2568 |