PDA

View Full Version : 4 Wire resistive touch screen, Need help



Megahertz
- 21st January 2012, 03:02
Hi, I have been trying to figure out the 4 wire resistive touch screen concept from last few days. Though I have kind of understood the basics of how it operates, but need some jump start on the PBP code side of it. I am struggling to understand on what to do exactly to get the X,Y co-ordinates, how to turn an analog input pin to provide full 5V? may be there is a separate circuit to it or not. A brief idea of the code to start with will be a great help, I have few 16f676 to play with and will try them to get the ball rolling. Thanks

rsocor01
- 22nd January 2012, 03:14
Hmmmm :confused:, I am trying to post some code but when I go back to the editing window all I see is the following, everything after "TRISA =" is missing.

START:
'################ START READING AVERAGE PRESSURE VALUE ################
TRISA =

Demon
- 22nd January 2012, 03:48
1. Click on GO ADVANCED at bottom right.

2. Click on the leftmost icon, it is two A; it will say SWITCH EDITOR TO SOURCE MODE when you mouse over.

3. Click on the CODE icon at far right in the middle row.

4. Paste your code within those tags.

WYSIWYG mode gives unpredictable results when you paste code, always switch to source mode first.

Robert
:)

rsocor01
- 22nd January 2012, 03:57
Well, I tried in a second computer and it didn't work either. Somehow when I copy-paste the code from MCS into the editor window and press the button "Go Advanced" all the code after "TRISA =" is missing in my editor window and the window kind of freezes up. Is this some kind of bug, because I tried it in two different computers? So, I will attach the code as a txt file.

Megahertz,

I wrote a program a while back to control a 4-wire touchscreen in a 320x240 color GLCD. The program worked great. I used a PIC18F4550. The wiring that I used was

PortA.0, AN0 ---> X+
PortA.1, AN1 ---> X-
PortA.2, AN2 ---> Y+
PortA.3, AN4 ---> Y-

First, you need to "monitor" the touchscreen to find out if it has been touched. Then if it has been touched you find the coordinates for the point were the screen was touched.

Also, in this program I had a calibration routine. I displayed in the screen two crosses, one at the upper left corner and the other one at the lower right corner. The user had to touch one cross first and then the other cross to save the optimum parameters for the touchscreen.

The program is attached as a txt file. Review the program and if you have any questions let me know.

6231

Robert

rsocor01
- 22nd January 2012, 04:01
1. Click on GO ADVANCED at bottom right.

2. Click on the leftmost icon, it is two A; it will say SWITCH EDITOR TO SOURCE MODE when you mouse over.

3. Click on the CODE icon at far right in the middle row.

4. Paste your code within those tags.

WYSIWYG mode gives unpredictable results when you paste code, always switch to source mode first.

Robert
:)

Wow, that fixed it. It was driving me nuts :nightmare:. Thank you.

Demon
- 22nd January 2012, 04:32
Wow, that fixed it. It was driving me nuts :nightmare:. Thank you.


1. Click on SETTINGS at top right.

2. Click on General Settings at left.

3. Scroll down to Miscellaneous Options.

4. Select Standard Editor.

You will now be in SOURCE mode by default when you post and not have to worry about code.

Robert
:)

Demon
- 22nd January 2012, 04:34
...
The program is attached as a txt file. Review the program and if you have any questions let me know.
...

Tadaa!



'************************************************* ***************
'* MAIN PROGRAM *
'************************************************* ***************

START:

'################ START READING AVERAGE PRESSURE VALUE ################

TRISA = %00001001 ' Set Y+ (portA.2, AN2) and X- (portA.1, AN1) as outputs
' and Y- (portA.3, AN3) and X+ (portA.0, AN0) as inputs

low PORTA.1 ' Set X- = 0V
high PORTA.2 ' Set Y+ = 5V
ADCON0 = %00000001 ' Bits(5-2): 0000=AN0. Start sampling at X+
pauseus 10
ADCON0.1 = 1 ' Stops or continues sampling depending on ADCON2 bits(5-3),
' then begins conversion

GOSUB CONVERSION_ROUTINE ' Obtain value for A/D conversion resolution
PRESSURE_XP = RESOLUTION ' Obtain PRESSURE_XP from X+ sampling, X- = 0V, and Y+ = 5V

ADCON0 = %00001101 ' Bits(5-2): 0011=AN3. Start sampling at Y-
pauseus 10
ADCON0.1 = 1 ' Stops or continues sampling depending on ADCON2 bits(5-3),
' then begins conversion

GOSUB CONVERSION_ROUTINE ' Obtain value for A/D conversion resolution
PRESSURE_YM = RESOLUTION ' Obtain PRESSURE_YM from Y- sampling, X- = 0V, and Y+ = 5V

IF (PRESSURE_XP > 24) AND (PRESSURE_YM < 1000) THEN ' THE TOUCHSCREEN HAVE BEEN TOUCHED
GOSUB READ_COORDINATES
gosub CALIBRATE_TOUCHSCREEN
ENDIF

LCDOUT $FE, 1 ' Clear LCD
LCDOUT $FE,2,"X=",DEC5 X_VALUE,", Y=",DEC5 Y_VALUE ' DISPLAYS A/D CONVERSION VALUES
LCDOUT $FE,$C0,"P1=",DEC4 PRESSURE_XP,", P2=",DEC4 PRESSURE_YM

GOTO START


'************************************************* ***************
'* READ X AND Y VALUES SUBROUTINE *
'************************************************* ***************
READ_COORDINATES:
' PORTA.0 (AN0) -> X+
' PORTA.1 (AN1) -> X-
' PORTA.2 (AN2) -> Y+
' PORTA.3 (AN3) -> Y-

'################ READ AVERAGE X-VALUE ################

TRISA = %00000011 ' Set X+ (portA.0, AN0) and X- (portA.1, AN1) as inputs
' and Y+ (portA.2, AN2) and Y- (portA.3, AN3) as outputs

low PORTA.3 ' Set Y- = 0V
high PORTA.2 ' Set Y+ = 5V
ADCON0 = %00000001 ' Bits(5-2): 0000=AN0. Start sampling at X+
pauseus 10
ADCON0.1 = 1 ' Stops or continues sampling depending on ADCON2 bits(5-3),
' then begins conversion
GOSUB CONVERSION_ROUTINE ' Obtain value for A/D conversion resolution
X_VALUE = RESOLUTION ' Obtain X_VALUE from X+ sampling, Y- = 0V, and Y+ = 5V

ADCON0 = %00000101 ' Bits(5-2): 0001=AN1. Start sampling at X-
pauseus 10
ADCON0.1 = 1 ' Stops or continues sampling depending on ADCON2 bits(5-3),
' then begins conversion
GOSUB CONVERSION_ROUTINE ' Obtain value for A/D conversion resolution
X_VALUE = (X_VALUE + RESOLUTION) ' Obtain X_VALUE from X- sampling, Y- = 0V, and Y+ = 5V

'################ READ AVERAGE Y-VALUE ################

TRISA = %00001100 ' Set X+ (portA.0, AN0) and X- (portA.1, AN1) as outputs
' and Y+ (portA.2, AN2) and Y- (portA.3, AN3) as inputs

low PORTA.1 ' Set X- = 0V
high PORTA.0 ' Set X+ = 5V
ADCON0 = %00001001 ' Bits(5-2): 0010=AN2. Start sampling at Y+
pauseus 10
ADCON0.1 = 1 ' Stops or continues sampling depending on ADCON2 bits(5-3),
' then begins conversion
GOSUB CONVERSION_ROUTINE ' Obtain value for A/D conversion resolution
Y_VALUE = RESOLUTION ' Obtain Y_VALUE from Y+ sampling, X- = 0V, and X+ = 5V

ADCON0 = %00001101 ' Bits(5-2): 0011=AN3. Start sampling at Y-
pauseus 10
ADCON0.1 = 1 ' Stops or continues sampling depending on ADCON2 bits(5-3),
' then begins conversion
GOSUB CONVERSION_ROUTINE ' Obtain value for A/D conversion resolution
Y_VALUE = (Y_VALUE + RESOLUTION) ' Obtain Y_VALUE from Y- sampling, X- = 0V, and X+ = 5V


RETURN

'************************************************* ***************
'* CONVERSION SUBROUTINE *
'************************************************* ***************
CONVERSION_ROUTINE:
REPEAT ' Wait until conversion is finished. When finished ADCON0.1 will be =0
PAUSEUS 10
CONV_STATUS = ADCON0.1
UNTIL CONV_STATUS = 0

RESOLUTION.BYTE0 = ADRESL : RESOLUTION.BYTE1 = ADRESH ' READ A/D CONVERSION VALUE

RETURN


'************************************************* ***************
'* CALIBRATION SUBROUTINE *
'************************************************* ***************
CALIBRATE_TOUCHSCREEN:

IF X_VALUE < 250 THEN
X_VALUE = 0
ELSE
X_VALUE = (X_VALUE - 250) * 22
ENDIF

IF Y_VALUE < 250 THEN
Y_VALUE = 0
ELSE
Y_VALUE = (Y_VALUE - 250) * 25
ENDIF

IF X_VALUE > 32750 THEN X_VALUE = 32750
IF Y_VALUE > 32750 THEN Y_VALUE = 32750

X_VALUE = ABS (X_VALUE - 32750)
'Y_VALUE = ABS (Y_VALUE - 32750)

RETURN



end


Robert
:)

Megahertz
- 29th January 2012, 23:49
Thanks a lot. I am sorry for not replying upto now, I just got my touch screen today (4wire), will study the whole code tonight and update the progress in couple of days. Thanks again for the code.

Megahertz
- 30th January 2012, 18:09
Okkkk, I have read the code and tried to digest it. Few questions:
1) Can you please explain how is "Start reading average pressure value" routine is working. Upto now I have only encountered putting 5v on y+ or x+ and corresponding y- or x- to be 0v. What is 5v @ y+ and 0v and x- doing?
2) Any ideas on how to change the circuit to add an interrupt on RA2 when touchscreen is pressed, unlike monitoring it continuesly?
3) Please explain the calibrate routine, this is the hardest bit of the code which I am failing to understand.
Many Thanks

rsocor01
- 31st January 2012, 00:43
Hi,

I got the theory for this program from a technical paper that I downloaded from the internet and that I can't find right now. I will keep looking for it and posted when I find it. In response to your questions,

1) The "start reading average pressure value" is a procedure to check if the screen has been touched. You monitor the two values for X and Y pressure and if they go outside a given range then that means that the screen has been touched. If you constantly output these two values to a LCD display you'll see what I mean.

2) No, that I know of. The method I used in my program to detect if the screen has been touched is the only method I could find in the internet.

3) I am not in front of my PC right now, and I can't answer that question from the top of my head. I'll get back to you later with this question.

Ioannis
- 31st January 2012, 07:22
Interesting thread.

About point 2).
Since it is an analog signal, I cannot see a way of diect interrupt. Only regular interrupts to start analog conversion and check.

Ioannis

rsocor01
- 6th February 2012, 06:34
Megahertz,

That code I posted above I wrote it some time ago. It was part of a program that sent the touchscreen coordinates to my PC through the USB port to move the mouse cursor. I modified the USBMouse program that came with PBP to send the 4-wire resistive touchscreen coordinates to the PC.

The sub routine "CALIBRATE_TOUCHSCREEN" was actually a way of "converting" the 10-bit ADC reading comming out of the PIC ADC port to the proper pixel coordinates I needed to make the mouse cursor move accross the PC screen. These values were found experimentally, pretty much trial and error. Now, for my 320x240 LCD display with touchscreen I wrote a calibration routine which is a lot more involved than the code that you have above. If you need the code, let me know.

Robert

rsocor01
- 6th February 2012, 08:14
1) Can you please explain how is "Start reading average pressure value" routine is working. Upto now I have only encountered putting 5v on y+ or x+ and corresponding y- or x- to be 0v. What is 5v @ y+ and 0v and x- doing?


This application note will help you understand better what is going on.
http://www.eetasia.com/ARTICLES/2004DEC/A/2004DEC06_MSD_AN02.PDF?SOURCES=DOWNLOAD

Before you start reading the touchscreen coordinates, you need to know if the screen has been touched. By having 5V at Y+ and 0V at X- you monitor if the screen was touched. The setup is as follows

6254

And the code is


START:

'################ START READING AVERAGE PRESSURE VALUE ################

TRISA = %00001001 ' Set Y+ (portA.2, AN2) and X- (portA.1, AN1) as outputs
' and Y- (portA.3, AN3) and X+ (portA.0, AN0) as inputs

low PORTA.1 ' Set X- = 0V
high PORTA.2 ' Set Y+ = 5V
ADCON0 = %00000001 ' Bits(5-2): 0000=AN0. Start sampling at X+
pauseus 10
ADCON0.1 = 1 ' Stops or continues sampling depending on ADCON2 bits(5-3),
' then begins conversion

GOSUB CONVERSION_ROUTINE ' Obtain value for A/D conversion resolution
PRESSURE_XP = RESOLUTION ' Obtain PRESSURE_XP from X+ sampling, X- = 0V, and Y+ = 5V

ADCON0 = %00001101 ' Bits(5-2): 0011=AN3. Start sampling at Y-
pauseus 10
ADCON0.1 = 1 ' Stops or continues sampling depending on ADCON2 bits(5-3),
' then begins conversion

GOSUB CONVERSION_ROUTINE ' Obtain value for A/D conversion resolution
PRESSURE_YM = RESOLUTION ' Obtain PRESSURE_YM from Y- sampling, X- = 0V, and Y+ = 5V

IF (PRESSURE_XP > 24) AND (PRESSURE_YM < 1000) THEN ' THE TOUCHSCREEN HAVE BEEN TOUCHED
GOSUB READ_COORDINATES
gosub CONVERT_TO_PIXELS
ENDIF

LCDOUT $FE, 1 ' Clear LCD
LCDOUT $FE,2,"X=",DEC5 X_VALUE,", Y=",DEC5 Y_VALUE ' DISPLAYS A/D CONVERSION VALUES
LCDOUT $FE,$C0,"P1=",DEC4 PRESSURE_XP,", P2=",DEC4 PRESSURE_YM

GOTO START



If the screen is not touched then the reading for PRESSURE_XP is going to be very close to zero and the reading for PRESSURE_YM is going to be very close to 1024, remember it is a 10-bit ADC. The screen has been touched when the following condition has been met


IF (PRESSURE_XP > 24) AND (PRESSURE_YM < 1000) THEN ' THE TOUCHSCREEN HAVE BEEN TOUCHED

To read the X,Y coordinates you need the following setup.

6255

And the code is


'************************************************* ***************
'* READ X AND Y VALUES SUBROUTINE *
'************************************************* ***************
READ_COORDINATES:
' PORTA.0 (AN0) -> X+
' PORTA.1 (AN1) -> X-
' PORTA.2 (AN2) -> Y+
' PORTA.3 (AN3) -> Y-

'################ READ AVERAGE X-VALUE ################

TRISA = %00000011 ' Set X+ (portA.0, AN0) and X- (portA.1, AN1) as inputs
' and Y+ (portA.2, AN2) and Y- (portA.3, AN3) as outputs

low PORTA.3 ' Set Y- = 0V
high PORTA.2 ' Set Y+ = 5V
ADCON0 = %00000001 ' Bits(5-2): 0000=AN0. Start sampling at X+
pauseus 10
ADCON0.1 = 1 ' Stops or continues sampling depending on ADCON2 bits(5-3),
' then begins conversion
GOSUB CONVERSION_ROUTINE ' Obtain value for A/D conversion resolution
X_VALUE = RESOLUTION ' Obtain X_VALUE from X+ sampling, Y- = 0V, and Y+ = 5V

ADCON0 = %00000101 ' Bits(5-2): 0001=AN1. Start sampling at X-
pauseus 10
ADCON0.1 = 1 ' Stops or continues sampling depending on ADCON2 bits(5-3),
' then begins conversion
GOSUB CONVERSION_ROUTINE ' Obtain value for A/D conversion resolution
X_VALUE = (X_VALUE + RESOLUTION) ' Obtain X_VALUE from X- sampling, Y- = 0V, and Y+ = 5V

'################ READ AVERAGE Y-VALUE ################

TRISA = %00001100 ' Set X+ (portA.0, AN0) and X- (portA.1, AN1) as outputs
' and Y+ (portA.2, AN2) and Y- (portA.3, AN3) as inputs

low PORTA.1 ' Set X- = 0V
high PORTA.0 ' Set X+ = 5V
ADCON0 = %00001001 ' Bits(5-2): 0010=AN2. Start sampling at Y+
pauseus 10
ADCON0.1 = 1 ' Stops or continues sampling depending on ADCON2 bits(5-3),
' then begins conversion
GOSUB CONVERSION_ROUTINE ' Obtain value for A/D conversion resolution
Y_VALUE = RESOLUTION ' Obtain Y_VALUE from Y+ sampling, X- = 0V, and X+ = 5V

ADCON0 = %00001101 ' Bits(5-2): 0011=AN3. Start sampling at Y-
pauseus 10
ADCON0.1 = 1 ' Stops or continues sampling depending on ADCON2 bits(5-3),
' then begins conversion
GOSUB CONVERSION_ROUTINE ' Obtain value for A/D conversion resolution
Y_VALUE = (Y_VALUE + RESOLUTION) ' Obtain Y_VALUE from Y- sampling, X- = 0V, and X+ = 5V


RETURN

'************************************************* ***************
'* CONVERSION SUBROUTINE *
'************************************************* ***************
CONVERSION_ROUTINE:
REPEAT ' Wait until conversion is finished. When finished ADCON0.1 will be =0
PAUSEUS 10
CONV_STATUS = ADCON0.1
UNTIL CONV_STATUS = 0

RESOLUTION.BYTE0 = ADRESL : RESOLUTION.BYTE1 = ADRESH ' READ A/D CONVERSION VALUE

RETURN


For the final routine "CONVERT_TO_PIXELS" the constants Ax, Bx, Ay, and By should be found experimentally. They will vary depending on the resolution of the LCD screen. One thing to remember is that the relation of the 4-wire touchscreen readings and the corresponding LCD pixels behaves almost linearly.


'************************************************* ***************
'* CONVERT_TO_PIXELS ROUTINE *
'************************************************* ***************
CONVERT_TO_PIXELS:

'Ax, Bx, Ay, and By should be found experimentally
X_VALUE = Ax * X_VALUE + Bx
Y_VALUE = Ay * Y_VALUE + By
RETURN

Demon
- 7th February 2012, 01:23
nevermind, read code few more times...

Robert

Megahertz
- 11th February 2012, 00:39
Makes much more sense now. Thanks a lot for all the info.

Art
- 16th February 2012, 15:59
I can't see why you'd use an interrupt for a touch screen,
and if there is a valid reason I'd like to know what it is.

Why not follow the way 2D games work?

1) Draw current frame to screen,

2) Check for user input,

3) act on user input, and apply any movement/calculations for next frame,

4) goto step one.

It would seem if you're using an interrupt, and your program is in the middle of step 3
while receiving new input you are complicating things.

rsocor01
- 16th February 2012, 17:28
I can't see why you'd use an interrupt for a touch screen,
and if there is a valid reason I'd like to know what it is.

Why not follow the way 2D games work?

1) Draw current frame to screen,

2) Check for user input,

3) act on user input, and apply any movement/calculations for next frame,

4) goto step one.

It would seem if you're using an interrupt, and your program is in the middle of step 3
while receiving new input you are complicating things.

No, there is no interrupt in the program I posted.

Robert