Arduino一直幫助輕松構建項目并使它們看起來更具吸引力。使用觸摸屏選項對LCD屏幕進行編程可能聽起來是一項復雜的任務,但Arduino庫和擴展板使它變得非常容易。在這個項目中,我們將使用2.4英寸Arduino TFT LCD屏幕來構建我們自己的Arduino觸摸屏計算器,該計算器可以執行所有基本計算,如加法,減法,除法和乘法。
所需材料:
- Arduino Uno
- 2.4“ TFT 液晶顯示器屏蔽
- 9V電池。
了解TFT液晶屏模塊:
在我們真正深入研究該項目之前,重要的是要了解這個 2.4 英寸 TFT LCD 模塊的工作原理以及其中存在的類型。讓我們來看看這款2.4英寸TFT液晶屏模塊的引腳排列。
如您所見,有28個引腳可以完美地適合任何Arduino Uno / Arduino Mega Board。下表給出了這些引腳的一小部分分類。
如您所見,引腳可以分為四個主要類別,例如LCD命令引腳, LCD數據引腳,SD卡引腳和電源引腳, 我們不需要了解這些引腳的詳細工作,因為它們將由我們的Arduino庫負責。
您還可以在上面顯示的模塊底部找到一個SD卡插槽,可用于加載帶有bmp圖像文件的SD卡,這些圖像可以使用Arduino程序顯示在我們的TFT LCD屏幕中。
另一個需要注意的重要事項是 接口IC 。市場上有許多類型的TFT模塊,從原始的Adafruit TFT LCD模塊到廉價的中國克隆。一個非常適合你的Adafruit盾牌的程序可能不適用于中國的分線板。因此,了解您手中拿著哪種類型的LCD顯示器非常重要。此詳細信息必須從供應商處獲得。如果你有一個像我這樣的廉價克隆,那么它很可能使用的是**ili9341驅動程序IC。 **您可以按照此TFT LCD與Arduino接口教程嘗試一些基本的示例程序并熟悉LCD屏幕。
校準觸摸屏的TFT液晶屏:
如果您打算使用TFT LCD模塊的觸摸屏功能,則必須對其進行校準以使其正常工作。未經校準的LCD屏幕可能不太可能工作,例如,您可能會在一個地方觸摸,而TFT可能會在其他地方響應觸摸。這些校準結果對于所有電路板來說并不相似,因此您可以自己做這件事。
校準的最佳方法是使用校準示例程序(庫隨附)或使用串行監視器來檢測錯誤。但是對于這個項目,由于按鈕的大小很大,校準應該不是一個大問題,我還將在下面的編程部分下解釋如何校準屏幕。
TFT LCD 與 Arduino 連接:
2.4英寸TFT LCD屏幕是一個完美的Arduino Shield。您可以直接將LCD屏幕推到Arduino Uno的頂部,它將與引腳完美匹配并滑入。但是,出于安全考慮,用小絕緣膠帶覆蓋Arduino UNO的編程端子,以防終端與TFT LCD屏幕接觸。在UNO上組裝的LCD如下所示。
為 TFT LCD 編程您的 Arduino:
我們正在使用 SPFD5408 庫來使這個 arduino 計算器代碼正常工作。這是一個經過修改的 Adafruit 庫,可以與我們的 LCD TFT 模塊無縫協作。
** 注意: 在Arduino IDE或此程序中安裝此庫以編譯而不會出現任何錯誤非常重要。**
要安裝此庫,您只需單擊上面的鏈接,該鏈接將帶您進入Github頁面。在那里單擊克隆或下載并選擇“下載ZIP”。將下載一個 zip 文件。
現在,打開Arduino IDE并選擇Sketch -> Include Librarey -> Add .ZIP library。 瀏覽器窗口將打開,導航到ZIP文件,然后單擊“確定”。如果成功,您應該注意到Arduino左下角的“庫已添加到您的庫中”。
現在,您可以在Arduino IDE中使用以下代碼,并將其上傳到Arduino UNO,以便觸摸屏計算器正常工作。再往下,我將代碼解釋為小段。
我們需要三個庫才能使該程序工作;所有這三個庫都在您從上面提供的鏈接下載的 ZIP 文件中給出。我只是將它們包含在代碼中,如下所示。
#include // Core graphics library
#include // Hardware-specific library
#include
如前所述,我們需要校準LCD屏幕以使其按預期工作,但不要擔心此處給出的值幾乎是通用的。變量TS_MINX、TS_MINY、TS_MAXX和TS_MAXY決定屏幕的校準。如果您覺得校準不令人滿意,您可以玩弄它們。
#define TS_MINX 125
#define TS_MINY 85
#define TS_MAXX 965
#define TS_MAXY 905
眾所周知,TFT LCD屏幕可以顯示很多顏色,所有這些顏色都必須以十六進制值輸入。為了使它更易于閱讀,我們將這些值分配給一個變量,如下所示。
注: 僅當屏幕旋轉 2 時,這些值才為 true。這是為了編程方便。
#define WHITE 0x0000 //Black->White
#define YELLOW 0x001F //Blue->Yellow
#define CYAN 0xF800 //Red->Cyan
#define PINK 0x07E0 //Green-> Pink
#define RED 0x07FF //Cyan -> Red
#define GREEN 0xF81F //Pink -> Green
#define BLUE 0xFFE0 //Yellow->Blue
#define BLACK 0xFFFF //White-> Black
好了,現在我們可以進入編程部分了。 該程序涉及三個部分 。一種是創建帶有按鈕和顯示器的計算器的 UI。然后,根據用戶的觸摸檢測按鈕,最后計算結果并顯示它們。讓我們一一解決它們。
1. 創建計算器的用戶界面:
在這里,您可以使用大量創造力來 設計計算器的用戶界面 。我只是簡單地制作了一個帶有 16 個按鈕和一個顯示單元的計算器的基本布局。你必須構建設計,就像你在MS油漆上畫東西一樣。添加的庫將允許您繪制線條,矩形,圓形,字符,字符串以及更多任何首選顏色。
我使用線條和框繪圖功能來設計一個看起來與 90 年代計算器非常相似的 UI。每個框的寬度和高度分別為 60 像素。
//Draw the Result Box
tft.fillRect(0, 0, 240, 80, CYAN);
//Draw First Column
tft.fillRect (0,260,60,60,RED);
tft.fillRect (0,200,60,60,BLACK);
tft.fillRect (0,140,60,60,BLACK);
tft.fillRect (0,80,60,60,BLACK);
//Draw Third Column
tft.fillRect (120,260,60,60,GREEN);
tft.fillRect (120,200,60,60,BLACK);
tft.fillRect (120,140,60,60,BLACK);
tft.fillRect (120,80,60,60,BLACK);
//Draw Secound & Fourth Column
for (int b=260; b>=80; b-=60)
{ tft.fillRect (180,b,60,60,BLUE);
tft.fillRect (60,b,60,60,BLACK);}
//Draw Horizontal Lines
for (int h=80; h<=320; h+=60)
tft.drawFastHLine(0, h, 240, WHITE);
//Draw Vertical Lines
for (int v=0; v<=240; v+=60)
tft.drawFastVLine(v, 80, 240, WHITE);
//Display keypad lables
for (int j=0;j<4;j++) {
for (int i=0;i<4;i++) {
tft.setCursor(22 + (60*i), 100 + (60*j));
tft.setTextSize(3);
tft.setTextColor(WHITE);
tft.println(symbol[j][i]);
2. 檢測按鈕:
另一項具有挑戰性的任務是 檢測用戶觸摸 。每次用戶觸摸某個地方時,我們就能知道他觸摸的像素的 X 和 Y 位置。可以使用 println 在串行監視器上顯示此值,如下所示。
TSPoint p = waitTouch();
X = p.y; Y = p.x;
Serial.print(X); Serial.print(','); Serial.println(Y);// + " " + Y);
由于我們設計的框的寬度和高度分別為 60 像素,并且有四行和從 (0,0) 開始的列。每個盒子的位置可以預測,如下圖所示。
但在實際情況下,結果并非如此。由于校準問題,預期值和實際值之間會有很大的差異。
因此,要預測盒子的確切位置,您必須單擊該行并在串行監視器上檢查其相應的位置。這可能不是最專業的方式,但它仍然可以完美地工作。我測量了所有線條的位置并獲得了以下值。
現在,因為我們知道所有盒子的位置。當用戶觸摸任何地方時,我們可以通過將他的 (X,Y) 值與每個框的值進行比較來預測他觸摸過的位置,如下所示。
if (X<105 && X>50) //Detecting Buttons on Column 2
{
if (Y>0 && Y<85)
{Serial.println ("Button 0"); //Button 0 is Pressed
if (Number==0)
Number=0;
else
Number = (Number*10) + 0; //Pressed twice
}
if (Y>85 && Y<140)
{Serial.println ("Button 2");
if (Number==0)
Number=2;
else
Number = (Number*10) + 2; //Pressed twice
}
3. 顯示數字并計算結果:
最后一步是計算結果并將其顯示在TFT液晶屏上。這個arduino計算器只能對2個數字進行操作。這兩個數字被命名為變量“Num1”和“Num2”。變量“Number”給出并從Num1和Num2中獲取值,并且還承擔結果。
當用戶按下按鈕時,數字將添加一個數字。當按下另一個按鈕時,前一個數字乘以 10,并隨之添加新數字。例如,如果我們按 8,然后按 5,然后按 7。然后首先變量將保持 8,然后 (810)+5=85,然后 (8510)+7 = 857。因此,最終變量的值為 857。
if (Y>192 && Y<245)
{Serial.println ("Button 8");
if (Number==0)
Number=8;
else
Number = (Number*10) + 8; //Pressed again
}
當我們執行任何操作(如加法)時,當用戶按下加法按鈕時,來自 Number 的值將被傳輸到 Num1 ,然后 Number 將變為零,以便它準備好接受第二個數字的輸入。
當按下等于時,數字中的值將被發送到 Num2 ,然后進行相應的計算(在本例中為加法),結果將再次存儲在變量“數字”中。
最后,此值將顯示在LCD屏幕中。
加工:
這個Arduino觸摸屏計算器的工作很簡單。您必須在Arduino上上傳以下給定的代碼并啟動它。計算器顯示在LCD屏幕上。
現在,您可以輸入任何數字并執行計算。它目前僅限于兩個操作數和唯一的運算符。但是,您可以調整代碼以使其有很多選擇。
每次執行計算后,您必須按“C”以清除屏幕上的值。希望您了解該項目并喜歡構建類似的東西。
/*______Import Libraries_______*/
#include // Core graphics library
#include // Hardware-specific library
#include
/*______End of Libraries_______*/
/*______Define LCD pins (I have asigned the default values)_______*/
#define YP A1 // must be an analog pin, use "An" notation!
#define XM A2 // must be an analog pin, use "An" notation!
#define YM 7 // can be a digital pin
#define XP 6 // can be a digital pin
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4
/*_______End of defanitions______*/
/*______Assign names to colors and pressure_______*/
#define WHITE 0x0000 //Black->White
#define YELLOW 0x001F //Blue->Yellow
#define CYAN 0xF800 //Red->Cyan
#define PINK 0x07E0 //Green-> Pink
#define RED 0x07FF //Cyan -> Red
#define GREEN 0xF81F //Pink -> Green
#define BLUE 0xFFE0 //Yellow->Blue
#define BLACK 0xFFFF //White-> Black
#define MINPRESSURE 10
#define MAXPRESSURE 1000
/*_______Assigned______*/
/*____Calibrate TFT LCD_____*/
#define TS_MINX 125
#define TS_MINY 85
#define TS_MAXX 965
#define TS_MAXY 905
/*______End of Calibration______*/
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); //300 is the sensitivity
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); //Start communication with LCD
String symbol[4][4] = {
{ "7", "8", "9", "/" },
{ "4", "5", "6", "*" },
{ "1", "2", "3", "-" },
{ "C", "0", "=", "+" }
};
int X,Y;
long Num1,Num2,Number;
char action;
boolean result = false;
void setup() {
Serial.begin(9600); //Use serial monitor for debugging
tft.reset(); //Always reset at start
tft.begin(0x9341); // My LCD uses LIL9341 Interface driver IC
tft.setRotation(2); // I just roated so that the power jack faces up - optional
tft.fillScreen(WHITE);
IntroScreen();
draw_BoxNButtons();
}
void loop() {
TSPoint p = waitTouch();
X = p.y; Y = p.x;
// Serial.print(X); Serial.print(','); Serial.println(Y);// + " " + Y);
DetectButtons();
if (result==true)
CalculateResult();
DisplayResult();
delay(300);
}
TSPoint waitTouch() {
TSPoint p;
do {
p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
} while((p.z < MINPRESSURE )|| (p.z > MAXPRESSURE));
p.x = map(p.x, TS_MINX, TS_MAXX, 0, 320);
p.y = map(p.y, TS_MINY, TS_MAXY, 0, 240);;
return p;
}
void DetectButtons()
{
if (X<50 && X>0) //Detecting Buttons on Column 1
{
if (Y>0 && Y<85) //If cancel Button is pressed
{Serial.println ("Button Cancel"); Number=Num1=Num2=0; result=false;}
if (Y>85 && Y<140) //If Button 1 is pressed
{Serial.println ("Button 1");
if (Number==0)
Number=1;
else
Number = (Number*10) + 1; //Pressed twice
}
if (Y>140 && Y<192) //If Button 4 is pressed
{Serial.println ("Button 4");
if (Number==0)
Number=4;
else
Number = (Number*10) + 4; //Pressed twice
}
if (Y>192 && Y<245) //If Button 7 is pressed
{Serial.println ("Button 7");
if (Number==0)
Number=7;
else
Number = (Number*10) + 7; //Pressed twice
}
}
if (X<105 && X>50) //Detecting Buttons on Column 2
{
if (Y>0 && Y<85)
{Serial.println ("Button 0"); //Button 0 is Pressed
if (Number==0)
Number=0;
else
Number = (Number*10) + 0; //Pressed twice
}
if (Y>85 && Y<140)
{Serial.println ("Button 2");
if (Number==0)
Number=2;
else
Number = (Number*10) + 2; //Pressed twice
}
if (Y>140 && Y<192)
{Serial.println ("Button 5");
if (Number==0)
Number=5;
else
Number = (Number*10) + 5; //Pressed twic
}
if (Y>192 && Y<245)
{Serial.println ("Button 8");
if (Number==0)
Number=8;
else
Number = (Number*10) + 8; //Pressed twic
}
}
if (X<165 && X>105) //Detecting Buttons on Column 3
{
if (Y>0 && Y<85)
{Serial.println ("Button Equal");
Num2=Number;
result = true;
}
if (Y>85 && Y<140)
{Serial.println ("Button 3");
if (Number==0)
Number=3;
else
Number = (Number*10) + 3; //Pressed twice
}
if (Y>140 && Y<192)
{Serial.println ("Button 6");
if (Number==0)
Number=6;
else
Number = (Number*10) + 6; //Pressed twice
}
if (Y>192 && Y<245)
{Serial.println ("Button 9");
if (Number==0)
Number=9;
else
Number = (Number*10) + 9; //Pressed twice
}
}
if (X<213 && X>165) //Detecting Buttons on Column 3
{
Num1 = Number;
Number =0;
tft.setCursor(200, 20);
tft.setTextColor(RED);
if (Y>0 && Y<85)
{Serial.println ("Addition"); action = 1; tft.println('+');}
if (Y>85 && Y<140)
{Serial.println ("Subtraction"); action = 2; tft.println('-');}
if (Y>140 && Y<192)
{Serial.println ("Multiplication"); action = 3; tft.println('*');}
if (Y>192 && Y<245)
{Serial.println ("Devesion"); action = 4; tft.println('/');}
delay(300);
}
}
void CalculateResult()
{
if (action==1)
Number = Num1+Num2;
if (action==2)
Number = Num1-Num2;
if (action==3)
Number = Num1*Num2;
if (action==4)
Number = Num1/Num2;
}
void DisplayResult()
{
tft.fillRect(0, 0, 240, 80, CYAN); //clear result box
tft.setCursor(10, 20);
tft.setTextSize(4);
tft.setTextColor(BLACK);
tft.println(Number); //update new value
}
void IntroScreen()
{
tft.setCursor (55, 120);
tft.setTextSize (3);
tft.setTextColor(RED);
tft.println("ARDUINO");
tft.setCursor (30, 160);
tft.println("CALCULATOR");
tft.setCursor (30, 220);
tft.setTextSize (2);
tft.setTextColor(BLUE);
tft.println("-Circut Digest");
delay(1800);
}
void draw_BoxNButtons()
{
//Draw the Result Box
tft.fillRect(0, 0, 240, 80, CYAN);
//Draw First Column
tft.fillRect (0,260,60,60,RED);
tft.fillRect (0,200,60,60,BLACK);
tft.fillRect (0,140,60,60,BLACK);
tft.fillRect (0,80,60,60,BLACK);
//Draw Third Column
tft.fillRect (120,260,60,60,GREEN);
tft.fillRect (120,200,60,60,BLACK);
tft.fillRect (120,140,60,60,BLACK);
tft.fillRect (120,80,60,60,BLACK);
//Draw Secound & Fourth Column
for (int b=260; b>=80; b-=60)
{ tft.fillRect (180,b,60,60,BLUE);
tft.fillRect (60,b,60,60,BLACK);}
//Draw Horizontal Lines
for (int h=80; h<=320; h+=60)
tft.drawFastHLine(0, h, 240, WHITE);
//Draw Vertical Lines
for (int v=0; v<=240; v+=60)
tft.drawFastVLine(v, 80, 240, WHITE);
//Display keypad lables
for (int j=0;j<4;j++) {
for (int i=0;i<4;i++) {
tft.setCursor(22 + (60*i), 100 + (60*j));
tft.setTextSize(3);
tft.setTextColor(WHITE);
tft.println(symbol[j][i]);
}
}
}
-
lcd
+關注
關注
34文章
4424瀏覽量
167410 -
TFT
+關注
關注
10文章
385瀏覽量
111063 -
計算器
+關注
關注
16文章
437瀏覽量
37327 -
Arduino
+關注
關注
188文章
6468瀏覽量
186958
發布評論請先 登錄
相關推薦
評論