TFTTouch
TFT Touch Screen Module
This is a module that I have put together to work with the Firewing Color TFT Library, the module has only been tested with the 2.4" TFT Display Shield from IteadStudio, the same one that was used on the Firewing Color TFT Library, See here for more information: TFT Library article.
I have also put together a simple Calibration programme that you can use to set the calibration values into the Touch module to suit your display.
I will include download links at the bottom to make it easier to download.
Module Touch ' Touch Data In pin... #option T_DIN = A0 #if IsOption(T_DIN) And Not IsValidPortPin(T_DIN) #error T_DIN, "Invalid option. Touch T_DIN must be a valid pin." #endif ' Touch Clock pin... #option T_CLK = A1 #if IsOption(T_CLK) And Not IsValidPortPin(T_CLK) #error T_CLK, "Invalid option. Touch T_CLK must be a valid pin." #endif ' Touch Data Out pin... #option T_DOUT = D8 #if IsOption(T_DOUT) And Not IsValidPortPin(T_DOUT) #error T_DOUT, "Invalid option. Touch T_DOUT must be a valid pin." #endif ' Touch Pen Interrupt pin... #option T_IRQ = D9 #if IsOption(TFT_EN) And Not IsValidPortPin(T_IRQ) #error T_IRQ, "Invalid option. Touch T_IRQ must be a valid pin." #endif ' Bring pin options into the Module... private _din As T_DIN.T_DIN@ ' Data In pin private _clk As T_CLK.T_CLK@ ' Clock pin private _dout As T_DOUT.T_DOUT@ ' Data Out pin private _irq As T_IRQ.T_IRQ@ ' Touch Interrupt pin ' Calibration Structure... private Structure TCalibration dim X_TopLeft As integer dim X_BottomRight as integer dim Y_TopLeft As integer dim Y_BottomRight as integer End Structure ' Public variables... public Calibrate As TCalibration public dispX as ushort = 320 public dispY as ushort = 240 public TPos_X as integer = 0 public TPos_Y as integer = 0 '****************************************************************************** '* Name : SendCommand * '* Purpose : Send command to touch (MSB first) * '****************************************************************************** private sub SendCommand(byval data as byte) low(_clk) delayus(1) for i as byte = 7 to 0 step -1 if data.bits(i) = 1 then high(_din) else Low(_din) end if low(_clk) delayus(5) high(_clk) delayus(5) next end sub '****************************************************************************** '* Name : ReadData * '* Purpose : Reads the touch data * '****************************************************************************** private function ReadData() as ushort dim data as ushort = 0 for count as byte = 12 to 0 step - 1 if _dout = 1 then data.bits(count) = 1 else data.bits(count) = 0 end if high(_clk) delayus(25) low(_clk) delayus(25) next return data end function '****************************************************************************** '* Name : Read * '* Purpose : Initialise a read sequence to get new touch data * '****************************************************************************** public sub Read() dim x as uinteger = 0 dim y as uinteger = 0 for i as byte = 1 to 9 SendCommand(&H90) high(_clk) delayus(20) low(_clk) delayus(20) y += ReadData() delayus(20) SendCommand(&HD0) high(_clk) delayus(20) low(_clk) delayus(20) x += ReadData() next TPos_X = x / 9 TPos_Y = y / 9 end sub '****************************************************************************** '* Name : Available * '* Purpose : Check to see if there is touch data * '****************************************************************************** ' Available Touch Data (Returns True/False)... public function Available() as Boolean return (_irq = 0) end function '****************************************************************************** '* Name : GetXPos * '* Purpose : Get touch X position * '****************************************************************************** public function GetXPos() as ushort dim x as ushort = Cal(TPos_Y,Calibrate.X_TopLeft,Calibrate.X_BottomRight,0,dispX-1) if x >= (dispX-1) then x = (dispX-1) end if if x <= 0 then x = 0 end if return x end function '****************************************************************************** '* Name : GetYPos * '* Purpose : Get touch Y position * '****************************************************************************** public function GetYPos() as ushort dim y as ushort = Cal(TPos_X,Calibrate.Y_TopLeft,Calibrate.Y_BottomRight,0,dispY-1) if y >= (dispY-1) then y = (dispY-1) end if if y <= 0 then y = 0 end if return y end function '****************************************************************************** '* Name : Cal * '* Purpose : Calculate touch calibration * '****************************************************************************** Private Function Cal(val as ushort, inMin as ushort, inMax as ushort, outMin as ushort, outMax as ushort) as ushort return (val - inMin) * (outMax - outMin) / (inMax - inMin) + outMin end function '****************************************************************************** '* Name : SetDefaultCal * '* Purpose : Set default calibration values * '* Note : Edit these values to suit your tft touch screen calibration, * '* : Obtain calibration values by running the touch calibration prog * '****************************************************************************** private sub SetDefaultCal() Calibrate.X_TopLeft = 406 Calibrate.X_BottomRight = 3831 Calibrate.Y_TopLeft = 370 Calibrate.Y_BottomRight = 3765 end sub '****************************************************************************** '* Name : Main * '* Purpose : Configure the touch screen module before use * '****************************************************************************** private Sub Main() input(_dout) input(_irq) high(_clk) high(_din) SetDefaultCal() End Sub End Module
CalibrationProg
This is a simple calibration programme which you can use to obtain the calibration values for your tft display, you will then need to edit the Touch module to suit your display, see "SetDefaultCal" subroutine in the Touch module. The calibration procedure is pretty much self explanatory, just follow what it says on the tft display.
Note: you will also need to download the Font module which I have used with the Calibration programme, just put the font file and touch module into your User Library.
Example Prog Images
The image to the right shows a screen with cross hairs, this is the screen that you will see after the Calibration is complete, you can test your calibration values by holding a stylus in the centre of the cross hairs, the X/Y text will automatically update on the screen.
The values expected should be close to (X=50,Y=50), (X=100,Y=100) and (X=200,Y=200).
Calibration Prog Code
'***************************************************************************** '* Name : CalibrateProg.bas * '* Author : Gavin Wiggett * '* Notice : Copyright (c) 2013 Bitfogav * '* : All Rights Reserved * '* Date : 17/07/2013 * '* Version : 1.1 Changed PPS pins configuration see (Onstartup) sub. * '* Version : 1.0 * '* Notes : Record the Calibration values and edit the values under, * '* : SetDefaultCal() in the tft Touch module. * '***************************************************************************** ' set high speed clock and import modules... clock = 80 imports Tft imports TftGraphic imports ComicSansMS imports TftTouch ' program entry point... Sub Main() WriteInstr() CalibrateScreen(1) ' Top Left CalibrateScreen(2) ' Bottom Right DisplayCalValues() ' display cal values do ' wait for user to touch screen loop until Touch.Available() DrawMarkers() dim x,y as ushort while true if Touch.Available() then Tft.Clear DrawMarkers() Touch.Read() x = Touch.GetXPos() y = Touch.GetYPos() Tft.WriteAt(150,20, "X="+str(x)+" Y="+str(y)) delayms(800) end if end while End Sub ' Display Cal values... sub DisplayCalValues() Tft.Clear Tft.WriteAt(15, 5, "*Calibration Values*") Tft.WriteAt(15, 20, "X_TopLeft..........= "+ str(Calibrate.X_TopLeft)) Tft.WriteAt(15, 32, "X_BottomRight....= "+str(Calibrate.X_BottomRight)) Tft.WriteAt(15, 44, "Y_TopLeft..........= "+str(Calibrate.Y_TopLeft)) Tft.WriteAt(15, 56, "Y_BottomRight....= "+str(Calibrate.Y_BottomRight)) Tft.WriteAt(15, 76, "Calibration is complete.") Tft.WriteAt(15, 88, "Record values and edit TftTouch Module.") Tft.WriteAt(15, 108,"Tap screen to continue to test.") end sub ' testmarkers... sub DrawMarkers() CrossHair(50,50) CrossHair(100,100) CrossHair(200,200) CornerMarker(1,0,0) CornerMarker(2,dispX-1,dispY-1) end sub ' Calibrate Touch Screen... sub CalibrateScreen(n as byte) dim counter as ushort = 0 Tft.Clear select case n case 1 : CornerMarker(1,0,0) case 2 : CornerMarker(2,dispX-1,dispY-1) end select Tft.WriteAt((dispX/2)-15,(dispY/2)-10, "PRESS") do ' wait for user to touch screen loop until Touch.Available() Tft.Clear select case n case 1 : CornerMarker(1,0,0) case 2 : CornerMarker(2,dispX-1,dispY-1) end select Tft.WriteAt((dispX/2)-10,(dispY/2)-10, "HOLD") do Touch.Read() ' keep reading touch screen values counter += 1 loop until counter = 60 select case n case 1 : Calibrate.X_TopLeft = TPos_Y : Calibrate.Y_TopLeft = TPos_X case 2 : Calibrate.X_BottomRight = TPos_Y : Calibrate.Y_BottomRight = TPos_X end select Tft.Clear select case n case 1 : CornerMarker(1,0,0) case 2 : CornerMarker(2,dispX-1,dispY-1) end select Tft.WriteAt((dispX/2)-20,(dispY/2)-10, "RELEASE") do ' wait for user to release loop until not Touch.Available() delayms(500) end sub ' Write Instructions on start screen... sub WriteInstr() Tft.Clear Tft.Brush.Style = BrushStyle.IsClear Tft.SetFont(ComicSansMS) Tft.WriteAt(25,50,"Use a stylus or something similar to touch as close") Tft.WriteAt(25,65,"to the corner of the selected corner marker as possible.") Tft.WriteAt(25,85,"Keep as still as possible and keep holding") Tft.WriteAt(25,100,"until told to release!.") Tft.WriteAt(25,120,"Repeat for both Top/Bottom.") Tft.WriteAt(25,140,"Do NOT use your finger as a calibration.") Tft.WriteAt(25,160,"Tap screen to continue.") Tft.WriteAt((dispX/2)-60,(dispY)-15,"*TFT Touch Calibration*") do ' wait for user to touch screen loop until Touch.Available() do ' wait for user to release loop until not Touch.Available() delayms(500) end sub ' Cross Hairs... sub CrossHair(x as ushort, y as ushort) Tft.Rect(x-10, y-10, x+10, y+10) Tft.Line(x-5, y, x+5, y) Tft.Line(x, y-5, x, y+5) end sub ' Corner Markers... sub CornerMarker(n as byte, x as ushort, y as ushort) select case n case 1 ' Top Tft.Line(x, y, x+10, y+10) Tft.Line(x, y, x+10, y) Tft.Line(x, y, x, y+10) case 2 ' Bottom Tft.Line(x, y, x-10, y-10) Tft.Line(x, y, x-10, y) Tft.Line(x, y, x, y-10) end select end sub ' disable UART1 on pins D0 and D1... sub OnStartup() Handles PIC.OnStartup RPINR18 = RPINR18 or &H001F RPOR2 = RPOR2 and &HE0FF end sub
Download Files
*TftTouch.zip - TFT Touch Module.
*CalibrateProgV1_1.zip - Calibration Prog.
*ComicSansMS.zip - Font File.