DS Touchscreen Calibration/Reading

I'm having trouble getting accurate readings on my resistive touchscreen. I'm using a DS touchscreen from Sparkfun and the breakout board for the connector also from Sparkfun. I'm using an old Bare Bones Board from Modern Device with a 168.

I know I'm driving the screen correctly. I'm getting somewhat accurate readings but it seems that I don't get full resolution. The lowest coordinates I can see are about 70,123 (x,y respectively) while the highest I can see are about 900,850. I have y1 connected to digital pin 14, x2 to digital pin 15, y2 to digital pin 16, and x1 to digital pin 17. I have weak pulldowns of 39K on each pin. Don't ask me why I'm doing this. In my mind, this would seem to create a voltage divider on the inputs when doing an analogRead of the screen but it seems to increase my resolution when I do it (does that mean my high impedance inputs aren't as high impedance as I need them to be?) I saw an example somewhere that used 10K resistors but I only have three of those right now so I went for something a bit weaker that I had more of.

I'm trying to get the full 0-1023 range from this screen. What am I doing wrong?

Here's the part of my code relevant to reading the screen:

//define touchscreen pins
#define y1          14 //A0
#define x2          15 //A1
#define y2          16 //A2
#define x1          17 //A3
#define xRead       A2
#define yRead       A3

unsigned int posX = 0;
unsigned int posY = 0;

inline void touchCheck()
{ 
  
 //read X coord 
  pinMode(x1, OUTPUT);
  pinMode(x2, OUTPUT);
  digitalWrite(x1, LOW);
  digitalWrite(x2, HIGH);
 
  pinMode(y1, INPUT);
  pinMode(y2, INPUT);
  digitalWrite(y1, LOW);
  digitalWrite(y2, LOW);
  
  delay(5);
  
  posX = analogRead(xRead);
  
  delay(5);
  
  //read Y coord
  
  pinMode(x1, INPUT);
  pinMode(x2, INPUT);
  digitalWrite(x1, LOW);
  digitalWrite(x1, LOW);
  
  pinMode(y1, OUTPUT);
  pinMode(y2, OUTPUT);
  digitalWrite(y1, HIGH);
  digitalWrite(y2, LOW);
  
  delay(5);
  
  posY = analogRead(yRead);
  
  delay(5);
  
}

void loop()
{
  
  touchCheck();
 
  Serial.print(posX);   
  Serial.print(",");     
  Serial.println(posY); 
  
}

I'm inclined to believe this is a hardware problem, not a software one but, based on what I've seen in other examples, what I have SHOULD work.

Any help would be much appreciated.

I'm inclined to believe this is a hardware problem, not a software one but, based on what I've seen in other examples, what I have SHOULD work.

It is a hardware problem. You still get a bit of resistance from the touch screen even when you are touching the limits. Not sure quite how to get a full 0-1023 range from it.

Mowcius

I'm trying to get the full 0-1023 range from this screen. What am I doing wrong?

trying to get the full 0-1023 range from this screen

Can't be done. :slight_smile:

Can't be done.

Hmm well if you decreased the gnd connection to -v and increased the vcc connection to just over 5v you could then get the full range. It'd take rather a lot of work :stuck_out_tongue:

I'm sure there's some other way you could do it. Perhaps by increasing the voltage of the input slightly and then shifting the analog signal before it goes into the ADC.

Mowcius

I know I'm reaching for straws when I say I want the full 10-bit resolution but I feel like the numbers I'm getting are pretty bad. I've only previously worked with matrix capacitive touchscreens (not with arduino, I was using a PSoC at the time) and while you expect the numbers to be less accurate around the edges, I didn't expect this bad.

So I guess it's just an issue of the arduino not driving a good 5V or gnd? I did some probing last night and ground looked pretty good. 5V looked more like 4.9 but that's not too bad either. Should I be looking into getting a logic buffer between the arduino and the screen... or some sort of switch/mux solution?

The less calibration I have to do in code or the more resolution I can get out of the hardware, the better.

I tried feeding the analog values back into a PWM output just to see what kind of voltages I was getting and I saw some weird stuff. It would hit 6 volts near the middle of the screen (which doesn't make sense at all unless there was some charge pump action going on inside my DMM :-?) and then dropped to 0 after that (somewhere around 850 on the Y axis).

I feel like I'm missing something obvious.

So I guess it's just an issue of the arduino not driving a good 5V or gnd?

No, it's most likely an issue with not completely isolating either 5v or ground on each 'end' of the touch screen. Touch screen issue... I would probably not say that for the accuracy of this touch screen is good enough for the full 10 bit but I may be wrong.

Mowcius

So I guess it's just an issue of the arduino not driving a good 5V or gnd

No.
The problem is that the touch screen acts as a variable resistance, you need another resistor to turn this into a voltage you can measure on the arduino. By definition this means you can't pull the full range of 0 to 5v because of this fixed resistor. Unless as mowcius says you feed it with over and under voltages. However, that requires circuits for switching those voltages so the whole thing gets very messy very quickly.

I tried feeding the analog values back into a PWM output

That makes little sense, care to explain exactly what you did? You can't do what you said you did.

By definition this means you can't pull the full range of 0 to 5v because of this fixed resistor.

Yes, I understand it acts as a resistor divider but that also means that if I touch at the edge of one the screen, I should be getting close to a 5V or gnd because the "wiper" would be shorted to that location. I think?

That makes little sense, care to explain exactly what you did? You can't do what you said you did.

After the analogRead, I sent the values back out in an analogWrite to pin 11.

I should be getting close to a 5V or gnd because the "wiper" would be shorted to that location.

Well like I said, there is still some resistance. The touch screen does not act as a perfect potentiometer and it does not 'short' to 5v or ground completely.

Basically, the touch screen is not going to change, that's how it is! You're not doing anything wrong.

Then we just have to ask how complicated you want to get to get 0-1023. We can suggest some ways (under and over voltage supply) but they are not simple and probably not worth it due to (as I said), the innacuracies in the touch screen.

Mowcius

I should be getting close to a 5V or gnd because the "wiper" would be shorted to that location

Getting close to only one of them, the other you get close to the resistor junction, so you can't get the full range.

After the analogRead, I sent the values back out in an analogWrite to pin 11.

Two things spring to mind:-

  1. Did you scale the readings. Analogue read returns 0 to 1023 analogue write takes numbers 0 to 255 (anything over that wraps round).
  2. How did you measure the voltage from the PWM, if it just a voltmeter then the readings will be meaningless because of the nature of the waveform.

mowcius:

I thought you were talking about the resistance of the touchable part of the screen. I completely forgot to take into account the resistance of the traces. Still, I don't get any real values until I get about an eighth to a quarter inch into the touchable part of the screen. Surely this isn't how the screen is supposed to work. I'm losing almost 25% of the total area of the screen.

Grumpy_Mike:

I forgot about the 8 bit limit of analogWrite.

Still, I don't get any real values until I get about an eighth to a quarter inch into the touchable part of the screen. Surely this isn't how the screen is supposed to work. I'm losing almost 25% of the total area of the screen.

Well as far as I can remember, my DS touch screen is similar, maybe not that far in but it's a cheap touch screen. Is it a DS replacement screen (made by someone for nintendo) or a 'compatible' touch screen?

Anyway the answer is still that there is nothing that you can do in software to change this!