gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Touchscreen accuracy... again

#65475 - MatLeOuf - Tue Jan 03, 2006 4:00 pm

Hi all!

my first post will concern the recurrent problem seen on this forum (and others) : the DS touchscreen accuracy with homebrew.
At home we've got two DS, bought at the same time, when they were released in France. On mine, the homebrew games using touchscreen are mostly unusable because of a very unaccurate touchscreen coordinates (particularly on the borders), whereas on my brother one everything works perfectly.
Some facts first : both DS have the same screen protector, both works perfectly in commercial games, mine is flashed with V5, the other one isn't flashed at all.

I've decided to search what can be the cause, and I've found something interesting : the PersonalData->calX1, X2, Y1, Y2 are really not the same on the 2 DS, whereas PersonalData->calX1px,... are exactly the same. The figures follow:
Code:
on my DS           : X1,Y1 = 624,720 | X2,Y2 = 3360,3212
on my brother's DS : X1,Y1 = 688,832 | X2,Y2 = 3352,3328

I've tried to put manually the "good" figures in the arm7/touch.c code of libnds, but it didn't do anything (I used the code of the TouchTest example for my purpose)...

I'm really new to DS programming (but not new to programming in general), so I've a lot of others things to learn, but this touchscreen problem is really annoying and I'd like very much to see a solution for it.
If anyone got ideas, I've got both "good" and "bad" DS at home to try things!

#65481 - Maverick - Tue Jan 03, 2006 5:10 pm


_________________
http://downtou.ne1.net/

#65499 - MatLeOuf - Tue Jan 03, 2006 6:14 pm

#65604 - Maverick - Wed Jan 04, 2006 9:28 am

Thats strange, it works perfectly on my GBAMP, and through wifime, i havent tried it on a flash cart.

What exactly happens?
_________________
http://downtou.ne1.net/

#65615 - pepsiman - Wed Jan 04, 2006 12:07 pm

MatLeOuf wrote:
I would be glad to do that, but this soft don't work on my M3...

This NDS file doesn't have a built in loader, so you'll need to add one.

#65616 - MatLeOuf - Wed Jan 04, 2006 12:09 pm

Maverick wrote:
Thats strange, it works perfectly on my GBAMP, and through wifime, i havent tried it on a flash cart.

What exactly happens?
Nothing at all :) Just 2 black screens. But it happens regularly with homebrew, I think there's something to add when you want your soft to work on M3 (in the arm9 code):
Code:
powerON(POWER_ALL);
(http://forum.gbadev.org/viewtopic.php?t=7723).

#65662 - Maverick - Wed Jan 04, 2006 9:48 pm

If it displays one white screen, one black, then that is what it is meant to do
_________________
http://downtou.ne1.net/

#65753 - MatLeOuf - Thu Jan 05, 2006 2:20 pm

No, it's really just two black screens, it needs to be recompiled with powerON(POWER_ALL); in the arm9 code (something you don't do on the other sources I've seen on your site) to work on the M3.
If you send me the source code I can do it, it's no problem :)

#65785 - pepsiman - Thu Jan 05, 2006 6:39 pm

MatLeOuf wrote:
No, it's really just two black screens, it needs to be recompiled with powerON(POWER_ALL); in the arm9 code (something you don't do on the other sources I've seen on your site) to work on the M3.
If you send me the source code I can do it, it's no problem :)

It does have powerON() - it works on my G6.
It doesn't have a built in NDS loader - YOU need to add one.

#65793 - MatLeOuf - Thu Jan 05, 2006 7:54 pm

Thanks for the loader tip, I didn't know that some homebrew needed one to function, still a newbie in that field :)
Anyway, the soft works now, and I've been able to take pictures of it on both DS :
My brother DS
My DS
I tried to do the same thing on both and, as you can see, the result on my DS is really strange, and it explains why I'm mainly unable to use touchscreen only homebrew on it...
And I'm probably not the only one with this problem out there!

#65815 - dovoto - Thu Jan 05, 2006 9:57 pm

I got this from someone and I wont have time to investigate it for the next few days. It is code created by stepping through an official DS game (meteos i think). If someone has time to verify it and clean it up maybe we can figure out why our code is accurate for some but not for otheres.
http://www.drunkencoders.com/demos/DS/TouchTest4.rar
_________________
www.drunkencoders.com

#65818 - MatLeOuf - Thu Jan 05, 2006 10:43 pm

I didn't look at the code yet (just compiled it), but the touchpad result isn't accurate for me. It seems to be better, but I still can't go nowhere near the top left corner...

#65819 - dovoto - Thu Jan 05, 2006 10:57 pm

but does it work accuratly for you on official games?
_________________
www.drunkencoders.com

#65823 - tepples - Thu Jan 05, 2006 11:19 pm

Do official games go near the corners?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#65826 - Alex Atkin UK - Thu Jan 05, 2006 11:28 pm

Quote:
Some facts first : both DS have the same screen protector, both works perfectly in commercial games, mine is flashed with V5, the other one isn't flashed at all.

_________________
[Images not permitted - Click here to view it]

[Images not permitted - Click here to view it]

#65834 - MatLeOuf - Fri Jan 06, 2006 12:34 am

Thanks Alex Atkin, I can add that I play Meteos with no touchscreen accuracy problem at all (it might suffice to prove it ;)).
Both DS have originally a NDSv2 firmware (viewed vith FlashMe V6).
I looked quickly at the TouchTest4 code and I don't think I'll be able to clean it up myself, way too complicated for me, but I'm ready to do all the needed tests to end up with a correctly calibrated touchscreen on homebrews...

#65845 - wintermute - Fri Jan 06, 2006 2:59 am

tepples wrote:
Do official games go near the corners?


The only one I've seen so far which makes use of the entire touchscreen is Pac Pix. It works well on both of my DSes but then, so does the homebrew code :/

#65847 - Sintax - Fri Jan 06, 2006 3:30 am

Animal Crossing has a button in the extreme upper right which opens/closes the menu. So I figured they don't have problems with screen touches not registering at the edges if they put such an important button there.

#65848 - majincline - Fri Jan 06, 2006 3:32 am

Ok....I've known something was funky about my touch screen but i didnt know it was this serious....this test program really helps see what data is being used by the homebrew.

My problem:
Every time te screen is touched the first parts that register are grossly wrong....they are shifted to the bottom-left corner but then return to the place they should be...this also occurs when letting go and that causes problems. It's like theres something pressing on the screen down there but it only happens in homebrew. I have a video of this behavior because I figure it cant hurt to give a bit too much info. I have also noticed that the top is dificult to press(just the fist couple millimeters) but thats no biggie, and I think comercial games do it to me too.

Finally uploaded: I really hope these touchscreen problems can be solved, they've plagued homebrew long enough
http://media.putfile.com/touchscreen18


Last edited by majincline on Fri Jan 06, 2006 8:56 pm; edited 1 time in total

#65873 - MatLeOuf - Fri Jan 06, 2006 11:39 am

For your information, here are the values I obtain with the TouchTest4 soft:
(min_px,min_py) = (24,6)
(min_x,min_y) = (512,232) (those values changes with each launch of the program but not much)
(max_x,max_y) = (3424,3736) (same thing, values changing a bit)
(max_px,max_py) = (228,186)

Hope this can help...
I also made a little video of the app running, so you can see the "disaster" ;)
The video.

#65914 - duencil - Fri Jan 06, 2006 8:21 pm

I've always had problems with readings around the edges of my touchscreen too. I've been playing with the test app dovoto posted - from what I've seen its built from decompiling the meteos arm9 executable, doing the touchscreen coordinates conversion to pixel coordinates on that processor instead of on the arm7 as we have it in libnds, and using a fairly cryptic algorithm which gives results very similar ( I think at most a pixel off ) from those using the method natrium posted here some months ago, and the method wintermute impliments in current libnds.

For my DS at least the problem was always in the original touchscreen coordinate readings, that would be off around the corners, rather than in the pixel coordinate conversion. I think I've managed to solve that problem now. It seems that just before taking a reading with TSC_MEASURE_X or TSC_MEASURE_Y, the hardware should be prepared calling touchRead(TSC_MEASURE_X | 1) or touchRead(TSC_MEASURE_Y | 1) repectively, ignoring the return value.
If you've downloaded dovoto's touchscreen app, change the following lines in arm7.cpp:
Code:
x = touchRead(TSC_MEASURE_X | 1);//tempPos.x;
y = touchRead(TSC_MEASURE_Y | 1);//tempPos.y;

for
Code:
touchRead(TSC_MEASURE_X|1);
x = touchRead(TSC_MEASURE_X);
touchRead(TSC_MEASURE_Y|1);
y = touchRead(TSC_MEASURE_Y);

Personally I'd prefer to call the libnds touchReadXY() function, and impliment the changes in the reading there, and just use the pixel cooordinate conversion performed there unless we see a reason to follow the meteos method. In that function there is already an average of the median readings performed which should also help prevent the kind of spurious contact readings majincline mentions.

So for making the equivalent change in libnds in touch.c I modify the lines:
Code:
for ( i=0; i<3; i++) {
   x[i] =  touchRead(TSC_MEASURE_X | 1);
   y[i] =  touchRead(TSC_MEASURE_Y | 1);
}
   
x[3] =  touchRead(TSC_MEASURE_X);
y[3] =  touchRead(TSC_MEASURE_Y);

with:
Code:
for ( i=0; i<4; i++) {
   touchRead(TSC_MEASURE_X | 1);
   x[i] = touchRead(TSC_MEASURE_X);
   touchRead(TSC_MEASURE_Y | 1);
   y[i] = touchRead(TSC_MEASURE_Y);
}


Hope that helps.

#66003 - MatLeOuf - Sat Jan 07, 2006 2:41 pm

Whoa! This is MUCH better! Still not perfect ((min_px,min_py) = (7,7), (max_px,max_py) = (249,189)), but at least the ball follows my stylus!
I've just been able to make the changes in the source of the app, when I looked into libnds source (the latest libnds 20052812), there was no such line in arm7/touch.c
Anyway, the modified software works a lot better on my DS, and works still flawlessly on the other. So I think someone should modify the libnds to take into account this modifcation (that I've been unable to apply to the latest version, but I'm no expert in that field :)).

#66004 - wintermute - Sat Jan 07, 2006 2:51 pm

you sure you looked at arm7/touch.c & not arm9/touch.c ?

did this modification fix that bendiness you had?

#66005 - MatLeOuf - Sat Jan 07, 2006 3:06 pm

Yup, looked in arm7/touch.c, here's the source I've got :
Code:
touchPosition touchReadXY() {

   touchPosition touchPos;

   if ( !touchInit ) {

      xscale = ((PersonalData->calX2px - PersonalData->calX1px) << 16) / ((PersonalData->calX2 & -8) - (PersonalData->calX1 & -8));
      yscale = ((PersonalData->calY2px - PersonalData->calY1px) << 16) / ((PersonalData->calY2 & -8) - (PersonalData->calY1 & -8));

      xoffset = (PersonalData->calX1 & -8) * xscale - (PersonalData->calX1px << 16);
      yoffset = (PersonalData->calY1 & -8) * yscale - (PersonalData->calY1px << 16);
      
      touchInit = true;

   }

   touchPos.x = touchRead(TSC_MEASURE_X) & -8;
   touchPos.y = touchRead(TSC_MEASURE_Y) & -8;

   s16 px = ( touchPos.x * xscale - xoffset + xscale/2 ) >>16;
   s16 py = ( touchPos.y * yscale - yoffset + yscale/2 ) >>16;

   if ( px < 0) px = 0;
   if ( py < 0) py = 0;
   if ( px > (SCREEN_WIDTH -1)) px = SCREEN_WIDTH -1;
   if ( py > (SCREEN_HEIGHT -1)) px = SCREEN_HEIGHT -1;

   touchPos.px = px;
   touchPos.py = py;

   return touchPos;

}

So I see nothing near what duencil modifies.

Concerning the bending, I can still see it on the sides, but I've got to look at the coordonates figures. I'll say the x coordinates on the left side goes from 7 to 13, 13 being attained near the center of the left side. But anyway it's, as I said, MUCH better than before that modifcation!

#67409 - Nphinity - Tue Jan 17, 2006 8:29 pm

MatLeOuf wrote:

Code:
   touchPos.x = touchRead(TSC_MEASURE_X) & -8;
   touchPos.y = touchRead(TSC_MEASURE_Y) & -8;

So I see nothing near what duencil modifies.


Ookay I have not even compiled a single NDS or GBA app ever, however, due to the buggyness I've noticed in coord on homebrew, I was intrested in the thread.

Anyway, despite my lack of knowledge on the subjuct, I beleive the above lines of code(taken from the code MatLeOuf posted) are the particular lines of code to change, likely should end up looking something like:

Code:
   touchRead(TSC_MEASURE_X | 1);
   touchPos.x = touchRead(TSC_MEASURE_X) & -8;
   touchRead(TSC_MEASURE_Y | 1);
   touchPos.y = touchRead(TSC_MEASURE_Y) & -8;


Though, I don't know why the code you two are looking at would be soo different.


I also find the origional code in touch.c that duencil had posted to be very highly suspicious.

Code:
for ( i=0; i<3; i++) {
   x[i] =  touchRead(TSC_MEASURE_X | 1);
   y[i] =  touchRead(TSC_MEASURE_Y | 1);
}
   
x[3] =  touchRead(TSC_MEASURE_X);
y[3] =  touchRead(TSC_MEASURE_Y);


What this code does is fill the first 3 results with the | 1 version of the read. And the final 4th result with a normal read.

One would assume these numbers are later averaged, and it is no wonder that this would produce inaccurate results, as its averaging two different types of numbers.

Obviously that can't be right.

But the question for me is, what is actually right about the replaced code that duencil provided.

His code fills all 4 results in the array with normal read values. But also before each read, an | 1 is executed.

I am curious as to what would happen if you didn't execute the | 1 first. Since the origional code was comparing apples and oranges, if you just filled all the results with oranges, that may be what fixes the problem.

Then again, I really dunno this stuff. Cause it may very well be the | 1 does as is said here, and prepares for a proper read.

Anyway it goes, hopefully you can get wintermute in on the conversation, ask why he did the 3 | 1's followed by the normal read, he may have had some reason, and of course share your finding.

I really hope to see a fix implemented in libnds and all the homebrew recompiled(especially WinDS) to use it.

#67453 - HyperHacker - Wed Jan 18, 2006 6:28 am

I've noticed a similar problem in both my programs and others. The touch screen works but every now and then you get some random hit way off from where you touched. For example when using an onscreen keyboard, you hit one key (or even a part of the screen without any keyboard on it) and it registers as hitting some other key. Also when simply drawing a pixel at each touched point occasionally a pixel will appear far from where the screen is being touched. This seems to be most common if you just tap really quick (never seen it while dragging), and I have yet to see it in a commercial game.

#67520 - Sausage Boy - Wed Jan 18, 2006 8:29 pm

Do you use any form of screen protection? I used to have similar issues with homebrew, but removing the plastic from the screen fixed it. Not a nice solution of course, since it works with commercial games we're obviously doing something wrong, but it's nice to be able to enjoy the homebrew properly.
_________________
"no offense, but this is the gayest game ever"

#67540 - Snuk the Great - Wed Jan 18, 2006 10:01 pm

Hmm, I was quite interested to see how the 'commercial positioning' worked on my DS and I found that the positioning left/right is oke. But top/bottom is not. It seems that if I am hiting my ds with my styles with a 90degree angle (thats including my eye position :P) it is off about 2mm.

Now I wonder. If this info is stored in your firmware isn't it possible to make a nds app that can redifine these settings? Just by simply asking for users to give input from the upper right position of their touch screen and then let them give input from there lower left side of the screen. Maybe add a visual aspect like 'touch the red square'.

#67590 - HyperHacker - Thu Jan 19, 2006 5:34 am

Possible, yes, but then wouldn't that interfere with commercial games?
Sausage Boy wrote:
Do you use any form of screen protection?
Nope.

#67654 - Snuk the Great - Thu Jan 19, 2006 8:09 pm

Hmm, oke this is kind of odd. I figured something else today. I found that the positioning on WinDS is accurate while my Advanced Wars DS (European version) is not. The 2mm off was with AW.

*booting DS testing other stuff*

Oke lol, there is a callibration tool build in in the DS firmware already :P. Just used it and I will test AW with it again, so hang in there :P

Oke, AW is accurate now as well, now I wonder if WinDS is still accurate...

Oke, I dont get it every app responds differently when it comes to the onscrean possitioning. Atleast the homebrew does... Isnt there just one lib you guys use?

#67694 - Tobin - Thu Jan 19, 2006 10:54 pm

HyperHacker wrote:
I've noticed a similar problem in both my programs and others. The touch screen works but every now and then you get some random hit way off from where you touched. For example when using an onscreen keyboard, you hit one key (or even a part of the screen without any keyboard on it) and it registers as hitting some other key. Also when simply drawing a pixel at each touched point occasionally a pixel will appear far from where the screen is being touched. This seems to be most common if you just tap really quick (never seen it while dragging), and I have yet to see it in a commercial game.

I am wondering why this problem is not solved already. A few weeks ago I posted my touchscreen code that I use for DSChess (http://forum.gbadev.org/viewtopic.php?t=7256). Maybe it is not the best solution, but for me it really works very well.
The trick is, not to take the first one or two inputs after the pen hits or leaves the key. Then you have no problems with jumping positions.

Hope we can find a good working solution soon.

#67759 - HyperHacker - Fri Jan 20, 2006 3:33 am

Actually, that makes quite a bit of sense. You had to do the same with the original Game Boy, as the first few reads from the button status registers were unpredictable due to contact bounce. (As you press the button and the two contacts come closer together, electricity will sometimes jump between them and not other times, so until the button is fully depressed, you would get erratic results.) You'd generally just do something like this (in Z80 ASM):
Code:
ld a,(REG_KEYS)
ld a,(REG_KEYS)
ld a,(REG_KEYS)
ld a,(REG_KEYS)
ld a,(REG_KEYS)
ld (KeyStatus),a


The same sort of problem is probably present here. I've noticed similar with the temperature (with mine, if it's ~20?C, it'll constantly jump between 19 and 21), and that's related to the touch screen, so it's probably the same problem.

My own code, using NDSlib, actually seems to work almost perfect if I just call touchReadXY() on ARM7, then wait for vblank, in a loop. I discard the very first read each time the screen is touched, as I use my own button-reading code which (like NDSLib's) has one variable for buttons that were just pressed this frame, and one for those that have been held for at least 2 frames. Since the code that handles touching (on ARM9) only checks the touch bit in the 'keys held' variable, it ignores the first touch (where the bit would be set in 'keys pressed' instead), and gives very accurate results, but on very rare occasions it will read some arbitrary other position when I just poke it quickly. If I don't discard the first read, this happens slightly more often. (I haven't tried it on any other DS though.) However, other people's programs such as Moonshell and TxtWriter suffer quite a bit from this. In Moonshell, window dragging often wigs out (the windows jump around), and TxtWriter seems to have the same occasional-incorrect-position bug as mine (when I don't discard the first input) but also, about 30 pixels on the left never register as touched. All commercial games seem to work fine, though.

#67788 - agentq - Fri Jan 20, 2006 11:07 am

ScummVM also ignores the pen inputs for the first frame it's pressed, and this corrects the jumping around problem nearly completely. It seems the way you touch the screen makes a major difference, if you touch the screen really lightly it's more likely to happen, while if you make firm contact with the screeen it happens less. The James Bond FPS game on the DS suffers from this problem a lot.

However, there is still an accuracy issue separate to this.

#67815 - ghazi - Fri Jan 20, 2006 5:07 pm

Quote:
Do you use any form of screen protection? I used to have similar issues with homebrew, but removing the plastic from the screen fixed it. Not a nice solution of course, since it works with commercial games we're obviously doing something wrong, but it's nice to be able to enjoy the homebrew properly.


Similar to this, my brother's DS performs significantly worse than mine where homebrew is concerned as well (mine doesn't work perfectly around the edges either, but his is much worse).

What I noticed was that the plastic lip that goes around the touch screen was deformed to the point that it made contact with the screen. Until I ran homebrew on it, I thought the only problem with it was that you had to press a bit harder with the stylus.

Anyway, it may or may not be entirely related, and I don't know how common it is, but I thought maybe I should throw that out.

#68254 - agentq - Mon Jan 23, 2006 10:18 am

Yes, I have also noticed that if I get any grit under the little gap around the screen, it makes the touch screen work badly. This isn't the cause of the homebrew issues though.

#68327 - chava - Mon Jan 23, 2006 8:50 pm

Hi!

I've got the same problem, do you know if this can be solved?

I've tested Win2DS, and there's a shot of what the mouse pointer drawed when I slided the stylus over the four edges of my touchscreen (using Win2DS):

http://img72.imageshack.us/img72/2319/touchscreen1ab.jpg

It works great on commercial games, but not with homebrew...

EDIT: I know there are some posts about similar things, but the screen is well calibrated and it's not because of the protector.

#68338 - Sintax - Mon Jan 23, 2006 9:44 pm

The touchscreen is a tricky thing. I have a feeling on newer DS's they work slightly different, as I've heard that for some people the mouse pointer resets to the middle of the screen, and now your problem (about Win2DS).

#68350 - duencil - Mon Jan 23, 2006 10:40 pm

Sintax:
Could you try the solution I suggested (on the 2nd page of this thread). THat removed pretty much all the bendiness around the touchscreen edges for me. If you're getting touchscreen coordinates using the touchReadXY() function in libnds, the current version in cvs now incorporates thee changes.

#68900 - knight0fdragon - Fri Jan 27, 2006 7:49 am

Is the calibration affected in anyway with this, plus what is up with the touch screen having coordingates of 3000+, is there anyway to set it up to go from 0 to 255 and 0 to 191, that would make the world a lot easier, since i cant access inbetween the pixels anyway. I was reading through touch.h and it says that that touchread returns both touch and screen coordinates, how do i enable this to return the screen coordinates anyway



nevermind, got screen coords, now just need the calibration i guess


i must say i love how my top left corner is reading as 50,5ish and my bottem left is reading 5 , 190ish

I am trying to build a generic card drawing class for some games id like to make, heres a test of it if people want to test on there hardware and see if they are getting weird results also

on the top screen
line 1 is the current XY of the touch
line 2 is the min X and min Y the touch had found
line 3 is the max X and max Y the touch had found

http://www.free-webster.com/users/knight0fdragon/TouchTest.zip
_________________
http://www.myspace.com/knight0fdragonds

MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206

#68930 - Xtreme - Fri Jan 27, 2006 1:07 pm

In G6 flash menu (I use the latest "G6 Flash 3 Loader V3.1 24-1-2006") the touch screen also does not function right. It is impossible to use it. I looks like it randomly chooses different location than what I'm pointing at.
I have tested with all different commercial games and they seem to be very sharp and accurate even when touching on the edges (animal crossing for example).

I have European DS with FlashMe v6 (ex N-FW3).

Has anyone discovered what is causing this? It is very annoying and I'm not able to use homebrew programs/games. :(

EDIT: I have re-readed all the posts and come to the conclusion that new DS firmwares does fix touch screen proplems.. also prevents homebrew.. heh not working.
_________________
My Theme
DS Lite (FM_V8a) ** R4 Revolution (2GB Transcend) ** SuperCard Lite (2x 2GB Transcend)

#69003 - HyperHacker - Fri Jan 27, 2006 10:31 pm

I have V1 firmware and mine works fine aside from occasionally reading the wrong spot when I first touch the screen, which I suggest is just me not reading right. I do notice some problems with the edges (Moonshell's window dragging tends to freak out, especially near the edges, and Txtwriter just plain ignores touches too far near the edge) but I suspect this is due to outdated ndslib code (Txtwriter hasn't been updated in a few months) and/or the first problem (Moonshell's window dragging still acts up near the center, and I haven't seen anyone else report this problem).

knightOfdragon: ipc->touchXpx and ipc->touchYpx. :-)

#69009 - knight0fdragon - Fri Jan 27, 2006 11:26 pm

yea i figured that part out, but for some reason my numbers are off, I updated my program to display the calibration numbers also, mine are (0,0) , (14652,128), perhaps theres a problem with the calibration formula in the touch.c, or perhaps its something with supercard. I loadned my XG2 lite to a friend till he got his SC so i will have him test out my app also to see if he gets the top left and bottem right corners totally warped
_________________
http://www.myspace.com/knight0fdragonds

MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206

#69021 - duencil - Sat Jan 28, 2006 12:34 am

knight0fdragon wrote:
perhaps theres a problem with the calibration formula in the touch.c, or perhaps its something with supercard.

Have you tried the latest version of touch.c from cvs. It was modified just recently to fix problems with warping around the corners -- maybe you can recompile the lib with that change and see if it helps.

http://cvs.sourceforge.net/viewcvs.py/devkitpro/libnds/source/arm7/

#69045 - knight0fdragon - Sat Jan 28, 2006 3:42 am

yes i have, and i dont think it solved the problem as of yet

what i am going to do now is write my own calibration formula that is applied to the coordinates of what the screen gives me and just work off that till there is a real solution or something
_________________
http://www.myspace.com/knight0fdragonds

MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206

#69111 - OnWarmerMusic - Sat Jan 28, 2006 3:11 pm

duencil wrote:
knight0fdragon wrote:
perhaps theres a problem with the calibration formula in the touch.c, or perhaps its something with supercard.

Have you tried the latest version of touch.c from cvs. It was modified just recently to fix problems with warping around the corners -- maybe you can recompile the lib with that change and see if it helps.

http://cvs.sourceforge.net/viewcvs.py/devkitpro/libnds/source/arm7/


I was having the "bending" problem around the edges (first run DS, FlashMe v5, w/ screen protector no less) and rebuilding with the new touch.c fixed it brilliantly. The reading still comes up a few pixels short around the edges, but it's a huge improvement.

Thanks for pointing this out, duencil :).

#69116 - knight0fdragon - Sat Jan 28, 2006 4:09 pm

the problem occurs all over the screen, its just tighter in the middle then on the edges, which is probablywhy i get concave lines on the edges, and it seems like its not accurately reading the right points if u look at it in actual numbers, but i do not believe this is the case. perhaps the registers are still being initialized and read wrong, who knows. would be nice to know what nintendos thing does to read it accurately
_________________
http://www.myspace.com/knight0fdragonds

MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206

#69304 - knight0fdragon - Sun Jan 29, 2006 9:58 pm

Here are my changed done to touch.c It gives more accuracy to the touchpad now and reduces a lot of warping. Unfortunatly, i still get the weird rhombus type shape, so hopefully something else can be done

Code:

/*---------------------------------------------------------------------------------
   $Id: touch.c,v 1.13 2006/01/12 11:13:55 wntrmute Exp $

   Touch screen control for the ARM7

   Copyright (C) 2005
      Michael Noland (joat)
      Jason Rogers (dovoto)
      Dave Murphy (WinterMute)

   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any
   damages arising from the use of this software.

   Permission is granted to anyone to use this software for any
   purpose, including commercial applications, and to alter it and
   redistribute it freely, subject to the following restrictions:

   1.   The origin of this software must not be misrepresented; you
         must not claim that you wrote the original software. If you use
         this software in a product, an acknowledgment in the product
         documentation would be appreciated but is not required.
   2.   Altered source versions must be plainly marked as such, and
         must not be misrepresented as being the original software.
   3.   This notice may not be removed or altered from any source
         distribution.

   $Log: touch.c,v $
   Revision 1.13  2006/01/12 11:13:55  wntrmute
   modified touch reading code from suggesrions found here -> http://forum.gbadev.org/viewtopic.php?t=7980

   Revision 1.12  2005/12/17 01:03:05  wntrmute
   corrected typos
   changed to median values
   
   Revision 1.11  2005/12/11 22:49:53  wntrmute
   use con for console device name
   
   Revision 1.10  2005/10/17 15:35:56  wntrmute
   use weighted averaging
   
   Revision 1.9  2005/10/03 21:19:34  wntrmute
   use ratiometric mode
   lock touchscreen on and average several readings
   
   Revision 1.8  2005/09/12 06:51:58  wntrmute
   tidied touch code
   
   Revision 1.7  2005/09/07 18:05:37  wntrmute
   use macros for device settings

   Revision 1.6  2005/08/23 17:06:10  wntrmute
   converted all endings to unix

   Revision 1.5  2005/08/01 23:12:17  wntrmute
   extended touchReadXY to return touchscreen co-ordinates as well as screen co-ordinates

   Revision 1.4  2005/07/29 00:57:40  wntrmute
   updated file headers
   added touchReadXY function
   made header C++ compatible

   Revision 1.3  2005/07/12 17:32:20  wntrmute
   updated file header

   Revision 1.2  2005/07/11 23:12:15  wntrmute
   *** empty log message ***

---------------------------------------------------------------------------------*/

#include <nds/jtypes.h>
#include <nds/system.h>
#include <nds/arm7/touch.h>


//---------------------------------------------------------------------------------
uint16 touchRead(uint32 command) {
//---------------------------------------------------------------------------------
   uint16 result;
   SerialWaitBusy();

   // Write the command and wait for it to complete
   REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS; //0x0A01;
   REG_SPIDATA = command;
   SerialWaitBusy();

   // Write the second command and clock in part of the data
   REG_SPIDATA = 0;
   SerialWaitBusy();
   result = REG_SPIDATA;

   // Clock in the rest of the data (last transfer)
   REG_SPICNT = SPI_ENABLE | 0x201;
   REG_SPIDATA = 0;
   SerialWaitBusy();

   // Return the result
   return ((result & 0x7F) << 5) | (REG_SPIDATA >> 3);
}


//---------------------------------------------------------------------------------
uint32 touchReadTemperature(int * t1, int * t2) {
//---------------------------------------------------------------------------------
   *t1 = touchRead(TSC_MEASURE_TEMP1);
   *t2 = touchRead(TSC_MEASURE_TEMP2);
   return 8490 * (*t2 - *t1) - 273*4096;
}



static bool touchInit = false;
static s32 xscale, yscale;
static s32 xoffset, yoffset;

// reading pixel position:
//---------------------------------------------------------------------------------
touchPosition touchReadXY() {
//---------------------------------------------------------------------------------


   touchPosition touchPos;


   if ( !touchInit ) {


      xscale = ((PersonalData->calX2px - PersonalData->calX1px) << 19) / ((PersonalData->calX2) - (PersonalData->calX1));
      yscale = ((PersonalData->calY2px - PersonalData->calY1px) << 19) / ((PersonalData->calY2) - (PersonalData->calY1));

//      xoffset = (PersonalData->calX1) * xscale - (PersonalData->calX1px << 19);
//      yoffset = (PersonalData->calY1) * yscale - (PersonalData->calY1px << 19);


      xoffset = ((PersonalData->calX1 + PersonalData->calX2) * xscale  - ((PersonalData->calX1px + PersonalData->calX2px) << 19) ) / 2;
      yoffset = ((PersonalData->calY1 + PersonalData->calY2) * yscale  - ((PersonalData->calY1px + PersonalData->calY2px) << 19) ) / 2;
      touchInit = true;

   }
//New changes start here
   s32 x[5],y[5];
   
   int i;
   
    //First weed out some garbage reads
   for ( i=0; i<5; i++) {
      touchRead(TSC_MEASURE_X | 1);
      x[i] =  touchRead(TSC_MEASURE_X);
      touchRead(TSC_MEASURE_Y | 1);
      y[i] =  touchRead(TSC_MEASURE_Y);
   }
   //grab some more accurate reads now
   for ( i=0; i<5; i++) {
      touchRead(TSC_MEASURE_X | 1);
      x[i] =  touchRead(TSC_MEASURE_X);
      touchRead(TSC_MEASURE_Y | 1);
      y[i] =  touchRead(TSC_MEASURE_Y);
   }

   s32 temp;
   
   for ( i=1; i<4; i++ ) {
      temp = x[i];

      if ( temp > x[4] ) { x[i] = x[4]; x[4] = temp; temp = x[i]; }
      if ( temp < x[0] ) { x[i] = x[0]; x[0] = temp; }

      temp = y[i];

      if ( temp > y[4] ) { y[i] = y[4]; y[4] = temp; temp = y[i]; }
      if ( temp < y[0] ) { y[i] = y[0]; y[0] = temp; }
   }

   touchPos.x = x[2];
   touchPos.y = y[2];
//New changes end here
   s16 px = ( touchPos.x * xscale - xoffset + xscale/2 ) >>19;
   s16 py = ( touchPos.y * yscale - yoffset + yscale/2 ) >>19;

   if ( px < 0) px = 0;
   if ( py < 0) py = 0;
   if ( px > (SCREEN_WIDTH -1)) px = SCREEN_WIDTH -1;
   if ( py > (SCREEN_HEIGHT -1)) py = SCREEN_HEIGHT -1;

   touchPos.px = px;
   touchPos.py = py;

   return touchPos;

}


_________________
http://www.myspace.com/knight0fdragonds

MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206

#69323 - duencil - Mon Jan 30, 2006 1:14 am

If you want to take the median of your readings, you'll need to do a more thorough sort. All your loop does now is guarantee that the minimums will be in position 0 and the maximums in position 4.
Interesting that you discard your first 5 readings as garbage, though. Have you confirmed that the second set of 5 readings are more accurate?

#69338 - knight0fdragon - Mon Jan 30, 2006 3:27 am

i have tested it by sending the output to the arm 9, and usually its the first couple of readings that would give me warped results, but anything after the 4th usually gave me desired results for my DS, as for this median.... I did the same thing as the old touch screen code, but i just added 1 more number to the mix so that i am not averageing 2 results together, which is probably why i was getting an X min of 35 instead of now 12 in the top left corner, but still getting 5 for the bottem left, my other friends are going to use my lib revision tonight on there code and see if it gives them better results
_________________
http://www.myspace.com/knight0fdragonds

MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206

#69339 - chishm - Mon Jan 30, 2006 3:35 am

Are any of these techniques checking to see how much pressure is being applied to the screen? The most inaccurate readings are made when the screen is only lightly touched.
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com

#69340 - tepples - Mon Jan 30, 2006 3:41 am

Unfortunately, we don't have solid data as to what constitutes a "light" touch. There is a register that's sensitive to resistance, which is inversely proportional to touch area or "pressure". However, the baseline for a resistance measure varies by at least a factor of 3 from unit to unit.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#69417 - wintermute - Mon Jan 30, 2006 6:12 pm

For those having trouble with bendy edges, give this a try

http://devkitpro.sourceforge.net/touch_test.zip

#69423 - MatLeOuf - Mon Jan 30, 2006 6:53 pm

wintermute wrote:
For those having trouble with bendy edges, give this a try

http://devkitpro.sourceforge.net/touch_test.zip

I tested it, the continuous mode is MUCH better, in fact there's just the right side where I can still see some light bending. But the single shot mode is much more problematic and not very accurate. It seems logic with the method used (median of 5 values) but I prefer to say it ;)

Anyway, thanks a lot for all your efforts, and keep up the good work!

#69430 - knight0fdragon - Mon Jan 30, 2006 7:26 pm

what did u do to have it do that???
_________________
http://www.myspace.com/knight0fdragonds

MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206

#69433 - wintermute - Mon Jan 30, 2006 7:34 pm

knight0fdragon wrote:
what did u do to have it do that???


I take it this means the new code works better for you?

#69434 - knight0fdragon - Mon Jan 30, 2006 7:36 pm

new codes beautiful left stays at 3, right stays at 251, only prob is that it jumps from time to time, probably a bad read
_________________
http://www.myspace.com/knight0fdragonds

MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206

#69435 - wintermute - Mon Jan 30, 2006 7:44 pm

MatLeOuf wrote:
wintermute wrote:
For those having trouble with bendy edges, give this a try

http://devkitpro.sourceforge.net/touch_test.zip

I tested it, the continuous mode is MUCH better, in fact there's just the right side where I can still see some light bending. But the single shot mode is much more problematic and not very accurate. It seems logic with the method used (median of 5 values) but I prefer to say it ;)

Anyway, thanks a lot for all your efforts, and keep up the good work!


I got rid of the median code and used a slightly different method of reading the touch values which attempts to get a stable reading instead.

The single shot mode is probably showing up the "light touch" issue which I'm not quite sure how to deal with at present. It sounds like your touchscreen is a lot more sensitive than mine and previous attempts to discard low pressure touches resulted in the code ignoring the stylus completely on some units.

#69438 - knight0fdragon - Mon Jan 30, 2006 7:52 pm

would you mind sharing the method then?
_________________
http://www.myspace.com/knight0fdragonds

MK DS FC: Dragon 330772 075464
AC WW FC: Anthony SamsClub 1933-3433-9458
MPFH: Dragon 0215 4231 1206

#69447 - tepples - Mon Jan 30, 2006 8:52 pm

If single jabs are unreliable, then just ignore the touch screen for the first frame that the pen is down.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#69456 - YopYop - Mon Jan 30, 2006 9:23 pm

We maybe have to read 5 times the touchscreen in continuous mode and make the average of the 3 closer points of the middle of the square that contains these points.

yopyop

#69463 - Haiken - Mon Jan 30, 2006 10:34 pm

Did someone try to follow some classical formulas, such as those described here.
They request 3 calibration points, but although the NDSTechWiki describes only 2 points, my DS asks for 3 of them...

#69472 - Xtreme - Tue Jan 31, 2006 12:06 am

wintermute wrote:
For those having trouble with bendy edges, give this a try touch_test.zip
Ok. That test is great indeed! Thank you that you take the "inaccure situation" seriously!

I have played with that test many minutes to see if anything changes..
Center = Very accurate (...*...)
Right corner = Ball a bit too much left from stylus (....*..)
Left corner = Very accurate (...*...)

Top corner = Very accurate X,Y
Lower corner = Very accurate X,Y

Do want to see some on-screen pics?
_________________
My Theme
DS Lite (FM_V8a) ** R4 Revolution (2GB Transcend) ** SuperCard Lite (2x 2GB Transcend)

#69483 - wintermute - Tue Jan 31, 2006 12:53 am

Haiken wrote:
Did someone try to follow some classical formulas, such as those described here.
They request 3 calibration points, but although the NDSTechWiki describes only 2 points, my DS asks for 3 of them...


The third point isn't stored anywhere.

Using our own calibration functions would mean that all homebrew would need to be calibrated individually for each use.

Thankfully we seem to be getting somewhere with the touch code and the standard calibration settings.

#69484 - wintermute - Tue Jan 31, 2006 12:58 am

knight0fdragon wrote:
would you mind sharing the method then?


I'd like to get another couple of positive tests from people who were having problems then I'll commit it to CVS.

#69485 - duencil - Tue Jan 31, 2006 1:29 am

works well on my unit too, wintermute

#69488 - wonderworld - Tue Jan 31, 2006 1:34 am

Hey, the first thing that worked for me.
Can't say if it's really accurate, because the ball is a bit to large, but
i had VERY BAD problems with other apps, like scumm and win2ds.

THis is a screeny i made using win2ds and tapping "1"

http://img210.imageshack.us/my.php?image=img03141om.jpg

would be a great thing, if this imporved code would make it into apps because every hombrew-app that used the touchscreen was unusable for me till now as you can imagine checking the screenshot..

#69492 - LuXo - Tue Jan 31, 2006 1:54 am

wintermute wrote:
I'd like to get another couple of positive tests from people who were having problems then I'll commit it to CVS.


Its almost perfect for me, its not very accurate in the borders (just a few pixels) but its by far the best touch_test ive tried :)

#69533 - HyperHacker - Tue Jan 31, 2006 9:33 am

Is that keyboard in your screenshot public domain or some such? It's used in TxtWriter as well. I asked the author of the program about it but he never replied. I want to use it in my own programs, it's pretty sweet.

As for pressure, couldn't there be some sort of homebrew pressure calibration? You have the player press some spot light, then another spot hard, and do this a few times to get a good reading, then store it in some unused part of the firmware.

#69540 - Sintax - Tue Jan 31, 2006 10:04 am

HyperHacker wrote:
Is that keyboard in your screenshot public domain or some such? It's used in TxtWriter as well. I asked the author of the program about it but he never replied. I want to use it in my own programs, it's pretty sweet.

As for pressure, couldn't there be some sort of homebrew pressure calibration? You have the player press some spot light, then another spot hard, and do this a few times to get a good reading, then store it in some unused part of the firmware.
Keyboard: http://headkaze.webpal.info/

As for a pressure calibration, it's not a real bad idea, it'd just be nice to have code that works for everything. For my first program, I used some pressure code (I think by natrium) and it worked perfectly for me, but other DS's had settings that were way different (it was a drawing program so that was important). The pressure code seemed to work perfectly for me, but it could be like everything else with the touch screen- that it's different for different DS's.

#69577 - chava - Tue Jan 31, 2006 4:46 pm

wintermute wrote:
For those having trouble with bendy edges, give this a try

http://devkitpro.sourceforge.net/touch_test.zip


Hey! This is the first homnebrew app that works correctly for my DS! Touch screen is now accurate!
(See what happened to me in win2ds when moving the stylus over the edges of the screen-> http://img72.imageshack.us/img72/2319/touchscreen1ab.jpg)

Please, release the source, so others can use this code in their apps.

Thanx!

#69580 - wintermute - Tue Jan 31, 2006 4:54 pm

source is now in CVS, I'll look at doing a libnds stable release over the next couple of days

#69584 - chava - Tue Jan 31, 2006 5:21 pm

wintermute wrote:
source is now in CVS, I'll look at doing a libnds stable release over the next couple of days


Thanx! Hope Moonshell will include this ^^

#69617 - chava - Tue Jan 31, 2006 9:03 pm

Weeeee!!!
It's already on new MoonShell! Thanx to moonsheel and wintermute! Hope the rest of homebrew apps will use this soon

#69646 - Snuk the Great - Tue Jan 31, 2006 10:43 pm

Hmm, I also tested the http://devkitpro.sourceforge.net/touch_test.zip. It works better then most things I tested, though it seems like my screen is not the right size... I seem to miss 5 pixels at the left and right side of the screen. Adding to that the upper left and lower left differ 2 pixels, oddly enough that are the only ones that differ.
Anyway, good work on the tests! I love testing this stuff :P!
[EDIT]
I reconfigured my DS in the DS menu and now it works perfectly! The only thing that I still find pretty odd is the is the difference of 2 pixels at the upper left and bottom left side of my screen...
[/EDIT]

#69648 - wonderworld - Tue Jan 31, 2006 10:51 pm

I tried out the new moonshell.
It works fine now for me....
This solved nearly all my touchscreen problems, very nice.

Hope others will start using this improved code soon, because i can't wait to try out all those apps that weren't working before for me :)

#69704 - duencil - Wed Feb 01, 2006 11:13 am

Actually, Moonshell is using the previous revision of touch.c, version 1.13, that came about from my suggestions in page 2 of the thread, rather than wintermute's latest revision.

#69707 - chava - Wed Feb 01, 2006 12:45 pm

duencil wrote:
Actually, Moonshell is using the previous revision of touch.c, version 1.13, that came about from my suggestions in page 2 of the thread, rather than wintermute's latest revision.


Well, so thanx to anyone involved.

#69708 - duencil - Wed Feb 01, 2006 1:03 pm

Oh hell I wasn?t being petty & seeking credit - I thought people were giving feedback on the latest code based on observations with Moonshell, and I was wondering if MoonLight had found a problem with the latest iteration, or just hadn't got around to testing it yet. As I said, for me it works very well.

#69747 - Xtreme - Wed Feb 01, 2006 5:24 pm

Is the fixed source available to homebrew community?
_________________
My Theme
DS Lite (FM_V8a) ** R4 Revolution (2GB Transcend) ** SuperCard Lite (2x 2GB Transcend)

#69792 - tepples - Wed Feb 01, 2006 10:54 pm

The improved version of touch.c should be in libnds CVS repository and should show up in the next release of libnds.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#69995 - Lino - Fri Feb 03, 2006 5:50 pm

Snuk the Great wrote:
Hmm, I also tested the http://devkitpro.sourceforge.net/touch_test.zip.


Where is the source code?

#70000 - melw - Fri Feb 03, 2006 6:00 pm

http://www.devkitpro.org/

Quote:
libnds 20060201

improved touch code
...


It's been there for couple days already.

#70194 - WhyKlef - Sat Feb 04, 2006 11:15 pm

Anyone?!? How do i apply touch.c to my actual firmware? Any program to change it or anything? Sorry for my n00beness

#70258 - HyperHacker - Sun Feb 05, 2006 4:21 am

It's just a replacement for the touch.c in LibNDS. It doesn't involve firmware.

#78179 - josath - Wed Apr 05, 2006 8:00 pm

I'm using latest touch code from latest CVS libnds, It doesn't solve the 'jumping lines' problem at all.

I've tried using some of the other mentioned code, taking multiple reads, taking the median, throwing out first 3 & last 3 readings....they all help a bit, but nothing really solves it completely. the problem is still there.

It's not a big deal for most apps, but I'm trying to make a drawing app, and it's really frustrating to have lines drawn where you don't want them (especially since I don't have an 'undo' yet heh).

Has there been any progress with this? I have a feeling that all the people who have the ability to solve this, have a DS with a more accurate touchscreen and it's hard for them to fix.

EDIT: One more thing I tried, was throwing out all touchscreen readings where dx > 30 || dy > 30. This solves about 90% of the jumps, there are still the occasional small one, so it's not perfect. But it has the downside of ignoring valid user input where the user is sweeping the stylus really fast across the screen. Still not a 100% solution.

#78186 - tepples - Wed Apr 05, 2006 8:58 pm

To detect impossible jumps in the position, you might want to try taking the second derivative of the position stream with respect to time: (d^2x(t)/dt^2, d^2y(t)/dt^2). The second derivative is proportional to the force that the user is using to move his or her fingers/hand/wrist to move the stylus. To find appropriate thresholds, try making a program that graphs the magnitude of this second derivative, and examine the peaks from rapid scratching vs. the peaks from true discontinuities.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#90330 - qw3rty - Thu Jun 29, 2006 7:12 pm

The iteration algorithm for this isn't overly hard :

you only need to remember the past two frame's touchpositions (and of course you'll need the touchposition of this frame)
the acceleration is :

acceleration_x = (touchPos_2framesago.px - 2* touchPos_1framesago.px + touchPos_0framesago.px) / (dt^2);
absolute_acceleration = sqr( acceleration_x^2 + acceleration_y^2 );

dt := time difference from frame to frame.

P.S. : The concept seems to work - it gets rid of most of the jumps....it's not (yet) perfect however....

P.P.S. : you can also use dt = 1 to make things less complicated (IF your game / touchroutine runs at a CONSTANT speed (e.g. 60 Hz)

#90354 - josath - Thu Jun 29, 2006 9:07 pm

qw3rty wrote:
.it's not (yet) perfect however....


good work, let us know if you make any more progress. perfect touchscreen readings are necessary for a drawing app to work well (like what I've been writing). those evil jumps are quite annoying when i'm trying to draw something :(

#90464 - qw3rty - Fri Jun 30, 2006 9:40 am

This is one possibility for the beginning of your main loop :
Code:

#define PEN_ACCELERATION_MAX 75 //values from 50 .... 150 make sense in a 60Hz loop-speed
swiWaitForVBlank();
touchPosition touchPosCurrentFrame;
touchPosCurrentFrame = touchReadXY();
static touchPosition touchPosLast[2]; //this is to remember the last two readings - touchPosLast[0] will be 2 frames ago, [1] 1 frame ago
int acc_x,acc_y,acceleration;
acc_x = touchPosLast[0].px - 2* touchPosLast[1].px + touchPos.px;
acc_y = touchPosLast[0].py - 2* touchPosLast[1].py + touchPos.py;
acceleration = (acc_x*acc_x + acc_y*acc_y); //this is acceleration^2 - if you want the "real" acceleration, take the squareroot but you'll loose accuracy

touchPosLast[0] = touchPosLast[1];
touchPosLast[1] = touchPosCurrentFrame;
if (acceleration > PEN_ACCELERATION_MAX)
{
   //DISCARD THE READING !
   .
   .
   .
}
.
.
.
//YOUR CODE
.
.
.


P.S. : I didn't include the time into the formula - if you call this code on a constant basis (e.g. every 1/60th second) it doesn't matter.

#91502 - wintermute - Fri Jul 07, 2006 4:01 pm

I've been experimenting with multiple sampling per frame in the arm7 code which seems to help quite a bit.

new arm7 code

It might be worth extending this a bit to "smooth" the pen input rather than jjust discarding the erroneous values.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#91521 - masscat - Fri Jul 07, 2006 6:56 pm

The jumpy pointer problem appears to happen when the touch screen is gently touched.
Using the Z1 and Z2 touch screen readings it is possible to ignore light touches. Here is some changes to the while loop of the TouchTest code:

Code:
#define RESISTANCE_SHIFT 16
uint32 min_resistance = 0x7fffffff;

while(1) {
  uint32 z1, z2, resistance;
  ...
  ...
  z1 = IPC->touchZ1;
  z2 = IPC->touchZ2;
  z2 <<= RESISTANCE_SHIFT;

  resistance = touch.x;
  resistance *= z2/z1 - ( 1 << RESISTANCE_SHIFT);
  resistance >>= RESISTANCE_SHIFT;

  if ( resistance < min_resistance)
    min_resistance = resistance;

  if ( resistance < (min_resistance + 3000)) {
    /* Use the non-gentle touch */
    ...
    ...
    ...
  }
}

The resistance calculation is taken from the data on no$gba. The 3000 in the min_resistance + 3000 check is just a value that works on my DS.

#91536 - wintermute - Fri Jul 07, 2006 8:16 pm

This is something that's been tried before. The resistance appears to differ quite markedly between different units and we ended up with some units being totally jump free while others were unable to read the touchscreen at all.

The two z values are now contained in the touch position structure

Code:

typedef struct touchPosition {
   int16   x;
   int16   y;
   int16   px;
   int16   py;
   int16   z1;
   int16   z2;
} touchPosition;


I'm still in two minds whether to discard the IPC structure completely and use the hardware mailbox for communication between the processors. Some things make more sense to be maintained in a shared area of main memory, others would be better with the more immediate transfer offered by the registers.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#91542 - masscat - Fri Jul 07, 2006 9:17 pm

wintermute wrote:
This is something that's been tried before. The resistance appears to differ quite markedly between different units and we ended up with some units being totally jump free while others were unable to read the touchscreen at all.

The two z values are now contained in the touch position structure

The minimum and maximum resistance value can be computed at runtime (as the minimum in my example) and then a threshold calculated from these two values. I am assuming that the response of the touchscreen is the same on all DSs even if the values given for the same pressure vary so if this is not the case then it would not work.

I could not see the ARM9 libnds function that copies them in, hence directly accessing the IPC structure.

#91592 - wintermute - Sat Jul 08, 2006 2:18 am

masscat wrote:

The minimum and maximum resistance value can be computed at runtime (as the minimum in my example) and then a threshold calculated from these two values. I am assuming that the response of the touchscreen is the same on all DSs even if the values given for the same pressure vary so if this is not the case then it would not work.


Interesting theory, we should come up with some code to test this & see how well it works across a range of systems. The major problem we've had with touch screen reading so far is that none of the people contributing to libnds have had access to particularly problematic units. Reading through most of the feedback regarding touch code in the forums it would seem that most of the trouble with erratic and inaccurate touch screens has been with end users rather than developers.

Quote:

I could not see the ARM9 libnds function that copies them in, hence directly accessing the IPC structure.


Currently they're read from the IPC structure but this may ( or may not ) change at some point in the future. I've been considering implementing a proper FIFO based command system for some time but some aspects may be better left as they are.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#91596 - HyperHacker - Sat Jul 08, 2006 3:19 am

FYI, I noticed that while many apps have jumping problems on my DS, DSBASIC, which I used quite extensively on vacation last week, didn't do it once that I can recall.
_________________
I'm a PSP hacker now, but I still <3 DS.

#91600 - wintermute - Sat Jul 08, 2006 4:13 am

Anyone know what method DS basic is using for touch screen reading?
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#91652 - zzo38computer - Sat Jul 08, 2006 4:12 pm

wintermute wrote:
Anyone know what method DS basic is using for touch screen reading?


I made DS BASIC, it uses just a simple one, read 2 reading and if they don't match, then try again. I don't know if it may be inaccurate sometimes... It doesn't seem to be inaccurate on DS BASIC, but DS Multigam uses the same methods and it does jump sometimes, I will see what wrong
_________________
Important: Please send messages about FWNITRO to the public forum, not privately to me.

#91698 - HyperHacker - Sat Jul 08, 2006 9:53 pm

Well with DSBASIC you're not drawing lines or anything like that, so it might not show up there.
_________________
I'm a PSP hacker now, but I still <3 DS.

#91775 - masscat - Sun Jul 09, 2006 1:47 pm

With regard to using the Z too filter out gentle touches:
The Z values vary with what you use to touch the screen (pen, finger, double touch) so I do not think this is a feasible method. Having read the datasheet for the touchscreen it suggests you can use the Z for determining a pen touch from a finger touch.

Replacing the TouchTest arm7 code (i.e. the default arm7 code used by ndstool) with the arm7 code from the libnds examples templates directory resulted in almost no pointer jumping for me.

#91781 - tepples - Sun Jul 09, 2006 2:58 pm

masscat wrote:
With regard to using the Z too filter out gentle touches:
The Z values vary with what you use to touch the screen (pen, finger, double touch)

True, but the values that cause jumping with a stylus might also cause jumping with a finger and vice versa.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#98073 - PadrinatoR - Sun Aug 13, 2006 2:03 am

Hi! I'm trying to do a drawing app and I'm having these troubles you're talking about... is there any way to minimize that annoying trouble?

If I set a minimum pressure, my app doesn't detect the right border of the screen because it senses less pressure than the rest of the screen... O_o

#98080 - tepples - Sun Aug 13, 2006 2:42 am

Try looking at the acceleration (second differential) of position readings.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#98110 - qw3rty - Sun Aug 13, 2006 8:50 am

PadrinatoR wrote:
Hi! I'm trying to do a drawing app and I'm having these troubles you're talking about... is there any way to minimize that annoying trouble?

If I set a minimum pressure, my app doesn't detect the right border of the screen because it senses less pressure than the rest of the screen... O_o


The pressure seems to be proportional to the distance from the lower right border.

min_pressure = C0 + C* sqrt((256 - x)^2 + (192 - y)^2)

I have no idea which values C0 and C have. My observation may even be false :)

I didn't look further into pressure reading, after implementing acceleration-limiting, as tepples suggested, because it's easy and gives good results.
Maybe combing pressure reading and acceleration limiting would give perfect readings....(allow more acceleration, if pen is pressed harder)

#98116 - masscat - Sun Aug 13, 2006 10:06 am

Here is a link to the touchscreen controller's product page:

http://focus.ti.com/docs/prod/folders/print/tsc2046.html

The datasheet is useful when experimenting with touchscreen reading and interpretation.

#98462 - PadrinatoR - Tue Aug 15, 2006 12:17 pm

Hi!
I don't know if it is an error nor if it can help to improve touchscreen accuracy:

s32 readTouchValue(int measure, int retry , int range) {
//---------------------------------------------------------------------------------
int i;
s32 this_value=0, this_range;

s32 last_value = touchRead(measure | 1);

for ( i=0; i < retry; i++) {
this_value = touchRead(measure | 1);
this_range = abs(last_value - this_value);
if (this_range <= range) break;
}

if ( i == range) this_value = 0;
return this_value;

}


Due to these declarations:

Code:
static int _MaxRetry = 5;
static int _MaxRange = 30;


i==range will be always false.

#98651 - PadrinatoR - Wed Aug 16, 2006 7:38 pm

Well... I've read TSC2046 datasheet and I suppose that this is the problem:
Quote:
TOUCH SCREEN SETTLING

In some applications, external capacitors may be required
across the touch screen for filtering noise picked up by the
touch screen (e.g., noise generated by the LCD panel or
backlight circuitry). These capacitors provide a low-pass
filter to reduce the noise, but cause a settling time
requirement when the panel is touched that typically
shows up as a gain error. There are several methods for
minimizing or eliminating this issue. The problem is that
the input and/or reference has not settled to the final
steady-state value prior to the ADC sampling the input(s)
and providing the digital output. Additionally, the reference
voltage may still be changing during the measurement
cycle.


And these are the possible solutions:
Quote:
Option 1 is to stop or slow down the TSC2046 DCLK
for the required touch screen settling time. This allows the
input and reference to have stable values for the Acquire
period (3 clock cycles of the TSC2046; see Figure 9). This
works for both the single-ended and the differential modes.





Option 2 is to operate the TSC2046 in the differential mode
only for the touch screen measurements and command
the TSC2046 to remain on (touch screen drivers ON) and
not go into power-down (PD0 = 1). Several conversions
are made depending on the settling time required and the
TSC2046 data rate. Once the required number of
conversions have been made, the processor commands
the TSC2046 to go into its power-down state on the last
measurement. This process is required for X-Position,
Y-Position, and Z-Position measurements.





Option 3 is to operate in the 15 Clock-per-Conversion mode, which
overlaps the analog-to-digital conversions and maintains
the touch screen drivers on until commanded to stop by the
processor (see Figure 13).


According to http://nocash.emubase.de/gbatek.htm#dstouchscreencontrollertsc, differential mode doesn't allow to measure the temperature and other things except X, Y, Z1 and Z2... and there are no commercial games that measure the temperature and so on, so... may Nintendo chose option 2 to avoid this problem??

#98683 - masscat - Wed Aug 16, 2006 11:13 pm

I noticed the same thing and tried out a test where the ADC is left powered up whilst the pen is down, bit 0 is set to 1 in the command byte (arm7 code here). There is still jumping when gently touched.

Having just looked at the code again I notice that I never power the ADC down.

#98691 - HyperHacker - Thu Aug 17, 2006 12:05 am

PadrinatoR wrote:
According to http://nocash.emubase.de/gbatek.htm#dstouchscreencontrollertsc, differential mode doesn't allow to measure the temperature and other things except X, Y, Z1 and Z2.

Could we not switch to one mode to read the temperature, then back when we're done?
_________________
I'm a PSP hacker now, but I still <3 DS.

#98693 - PadrinatoR - Thu Aug 17, 2006 12:12 am

HyperHacker wrote:
PadrinatoR wrote:
According to http://nocash.emubase.de/gbatek.htm#dstouchscreencontrollertsc, differential mode doesn't allow to measure the temperature and other things except X, Y, Z1 and Z2.

Could we not switch to one mode to read the temperature, then back when we're done?


I think it can generate more problems, but it may be possible. I don't know so much about hardware :S

#98758 - masscat - Thu Aug 17, 2006 10:50 am

PadrinatoR wrote:
HyperHacker wrote:
PadrinatoR wrote:
According to http://nocash.emubase.de/gbatek.htm#dstouchscreencontrollertsc, differential mode doesn't allow to measure the temperature and other things except X, Y, Z1 and Z2.

Could we not switch to one mode to read the temperature, then back when we're done?


I think it can generate more problems, but it may be possible. I don't know so much about hardware :S

In my example code, you could only read the temperature and battery values when the pen is up. If the pen is down then just use a repeat of the last reading. Somebody using a DS does not leave the pen touching the screen for long enough for this to cause a problem.
But, again, the powered up ADC does not solve the gentle touch problem.

#98759 - PadrinatoR - Thu Aug 17, 2006 10:55 am

Ok! And what about the other 2 options?

#98796 - masscat - Thu Aug 17, 2006 5:29 pm

There were a couple of faults in my last example.
When the ADC is powered up the PENIRQ signal is disabled and not good for touchscreen touch detecting. Therefore I now power down the touchscreen after the pen release is detected thus re-enabling the PENIRQ signal.
Since the touchscreen values and the touchscreen button event are read seperately on the arm9 there is a change that the button could be read as down but the touchscreen value be wrong. I am not sure this happens but to keep things in sync I pass the touch data using the fifo.

Still some jumping on my DS but I think it is less (although this could be rose tinting on my behalf). If people want to have a play and see what they think grab the .nds file and code.

As for option 1 - I am not sure when it needs the slow/stopped clock. If it is after the touchscreen has received the channel select bits of the command byte but before the aquire period (the last three bit of the command byte) then this would have to be done in hardware and therefore no good to us.
As for option 3 - this would have to be done at the hardware level so no good to us.

#98815 - PadrinatoR - Thu Aug 17, 2006 7:30 pm

Yehaaa!! I think I've solved the jumping problem :D This solution is not based on pressure or any other possible variable that depends of the DS.

First, I'm using this:
- devKitPro 1.3.2
- libnds 21/06/2006
- PAlib 29/06/2006

I've modified libnds and added one thing to PAlib.
Here you can download the modified libnds, PAlib and the alpha version of my drawing app (source and binary): http://www.ftp.nu/files/5291/

Ok! I've made the next changes:
- Added to IPC struct a field:
include/nds/ipc.h
Code:
u8 touchError

- Added to touchPosition struct a field:
include/nds/jtypes.h
Code:
u8 error


This field will let us know if data readed from touchscreen is valid. Then... how to know if data is valid? I've modified ReadTouchValue and touchReadXY:

source/arm7/touch.c
Code:
s32 readTouchValue(int measure, int retry , int range, u8 *bError) {
//---------------------------------------------------------------------------------
   int i;
   s32 this_value=0, this_range;

   *bError=false;
   s32 last_value = touchRead(measure | 1);

   for ( i=0; i < retry; i++) {
      this_value = touchRead(measure | 1);
      this_range = abs(last_value - this_value);
      if (this_range > range) break;
   }
   
   if ( i != retry) {this_value = 0; *bError=true; }
   return this_value;

}


As you can see, I've added a new boolean argument called error. The new struct of this function gets 'retry' values from the touchscreen and, if all of them are in the 'range', returns the last obtained value. In other case, it returns 0 and sets bError to true.

source/arm7/touch.c
Code:
touchPosition touchReadXY() {
//---------------------------------------------------------------------------------

   touchPosition touchPos;
   u8 error;

   touchPos.error=false;

   if ( !touchInit ) {

      xscale = ((PersonalData->calX2px - PersonalData->calX1px) << 19) / ((PersonalData->calX2) - (PersonalData->calX1));
      yscale = ((PersonalData->calY2px - PersonalData->calY1px) << 19) / ((PersonalData->calY2) - (PersonalData->calY1));

      xoffset = ((PersonalData->calX1 + PersonalData->calX2) * xscale  - ((PersonalData->calX1px + PersonalData->calX2px) << 19) ) / 2;
      yoffset = ((PersonalData->calY1 + PersonalData->calY2) * yscale  - ((PersonalData->calY1px + PersonalData->calY2px) << 19) ) / 2;
      touchInit = true;
   }

   touchPos.x = readTouchValue(TSC_MEASURE_X, _MaxRetry, _MaxRange, &error);
   if(error){
      touchPos.error=true;
      return touchPos;
   }
   touchPos.y = readTouchValue(TSC_MEASURE_Y, _MaxRetry, _MaxRange, &error);
   if(error){
      touchPos.error=true;
      return touchPos;
   }

   s16 px = ( touchPos.x * xscale - xoffset + xscale/2 ) >>19;
   s16 py = ( touchPos.y * yscale - yoffset + yscale/2 ) >>19;
   
   touchPos.z1 = readTouchValue( TSC_MEASURE_Z1, _MaxRetry, _MaxRange, &error);
   touchPos.z2 = readTouchValue( TSC_MEASURE_Z2, _MaxRetry, _MaxRange, &error);

   if ( px < 0) px = 0;
   if ( py < 0) py = 0;
   if ( px > (SCREEN_WIDTH -1)) px = SCREEN_WIDTH -1;
   if ( py > (SCREEN_HEIGHT -1)) py = SCREEN_HEIGHT -1;

   touchPos.px = px;
   touchPos.py = py;

   return touchPos;

}


Here it checks if there was an error reading X and Y values. If there was, it sets touchPos.error to true and goes out.

That's all. Then if you want to know if touchscreen is being touched you must do two things: first check IPC->buttons (or REG_KEYXY) and check if there wasn't any error reading data.

Changes in PAlib:

lib/arm7/PA.c
Code:
void PA_UpdateStylus(void){
//---------------------------------------------------------------------------------

   touchPosition tempPos = touchReadXY();

   IPC->touchError   = tempPos.error;
   
   IPC->touchX    = tempPos.x;
    IPC->touchY    = tempPos.y;
    IPC->touchXpx  = tempPos.px;
    IPC->touchYpx  = tempPos.py;   
   
   IPC->touchZ1 = tempPos.z1;//touchRead(TSC_MEASURE_Z2);
   IPC->touchZ2 = tempPos.z2;//touchRead(TSC_MEASURE_Z2);
}


I added a line that gets the possible data reading error (the two last lines have been modified too, but that only corrects a little bug :P It doesn't matter)

And finally:

lib/arm9/PA/PA_Keys.c
Code:
void PA_UpdateStylus(void) {
//u8 temp = (((~IPC->buttons) << 6) & (1<<12));
u8 temp = (((~IPC->buttons) >> 6) & 1) && !IPC->touchError;

   Stylus.Pressure = (((IPC->touchXpx * IPC->touchZ2) >> 6) / IPC->touchZ1) - (IPC->touchXpx >> 6);
   //if (Stylus.Pressure > 10) temp = 0; // limit to good pressures


   
   Stylus.Released = ((!temp) & Stylus.Held);
   Stylus.Newpress = temp & (!Stylus.Held);
   Stylus.Held = temp;

   if (Stylus.Held) { // On en met ? jour que si on touche l'?cran, histoire de pas avoir un truc fauss?
      Stylus.altX =  ((IPC->touchX - 0x0113) / 14);
      Stylus.altY =  ((IPC->touchY - 0x00E0) / 19);
   
      if(Stylus.Newpress){
         Stylus.X =  IPC->touchXpx;
         Stylus.Y =  IPC->touchYpx;
         Stylus.Vx = Stylus.oldVx = 0;
         Stylus.Vy = Stylus.oldVy = 0;
      }
      else if (PA_Distance (Stylus.oldVx, Stylus.oldVy, Stylus.Vx, Stylus.Vy) < 2500){ // Limit speed change
         Stylus.oldVx = Stylus.Vx;
         Stylus.oldVy = Stylus.Vy;   
         Stylus.Vx = IPC->touchXpx - Stylus.X;
         Stylus.Vy = IPC->touchYpx - Stylus.Y;               
         Stylus.X = IPC->touchXpx;
         Stylus.Y = IPC->touchYpx;
      }
      else {
         Stylus.Vx = Stylus.oldVx;
         Stylus.Vy = Stylus.oldVy;
      }
   }
      
   
}


The modified line is this:
u8 temp = (((~IPC->buttons) >> 6) & 1) && !IPC->touchError;

As you can see, it avoids to detect a real screen touch that caused an error when arm7 readed data.

I've tested for 15min touching gently and I haven't noticed any 'jumping fail', but I've only tested it in 2 DS Lite. Test it and comment your results :D

PS: Sorry, I'm Spaniard and my English isn't very good :P

#98830 - masscat - Thu Aug 17, 2006 9:11 pm

PadrinatoR wrote:
Yehaaa!! I think I've solved the jumping problem :D This solution is not based on pressure or any other possible variable that depends of the DS.

Works nicely on my DS.

I am still curious why the touchscreen is returning bad readings in the first place. Is this normal for a touchscreen?

#98836 - PadrinatoR - Thu Aug 17, 2006 9:35 pm

masscat wrote:
PadrinatoR wrote:
Yehaaa!! I think I've solved the jumping problem :D This solution is not based on pressure or any other possible variable that depends of the DS.

Works nicely on my DS.

I am still curious why the touchscreen is returning bad readings in the first place. Is this normal for a touchscreen?


^^ Well when you doesn't touch firmly the screen, the touchscreen might not be capable to detect what point was touched.

I don't know XD This is the first touchscreen I've used (I haven't got PDAs or something similar).

#98890 - qw3rty - Fri Aug 18, 2006 9:13 am

PadrinatoR wrote:


Code:
s32 readTouchValue(int measure, int retry , int range, u8 *bError) {
//---------------------------------------------------------------------------------
   int i;
   s32 this_value=0, this_range;

   *bError=false;
   s32 last_value = touchRead(measure | 1);

   for ( i=0; i < retry; i++) {
      this_value = touchRead(measure | 1);
      this_range = abs(last_value - this_value);
      if (this_range > range) break;
   }
   
   if ( i != retry) {this_value = 0; *bError=true; }
   return this_value;

}




If I understood your code right, when you set error = true, readTouchValue() returns 0 anyway !
So, where's the difference ? (if the function returns 0, the position isn't read obviously !)

BUT I have tested you little draw APP, and it seems to actually WORK !
there's absolutely NO jumping :O

The only difference I can think of, is that you discard the reading if ANY reading goes wrong (x,y,z1 or z2) - but shouldn't libnds do this anyway ?

#98909 - PadrinatoR - Fri Aug 18, 2006 1:32 pm

qw3rty wrote:
PadrinatoR wrote:


Code:
s32 readTouchValue(int measure, int retry , int range, u8 *bError) {
//---------------------------------------------------------------------------------
   int i;
   s32 this_value=0, this_range;

   *bError=false;
   s32 last_value = touchRead(measure | 1);

   for ( i=0; i < retry; i++) {
      this_value = touchRead(measure | 1);
      this_range = abs(last_value - this_value);
      if (this_range > range) break;
   }
   
   if ( i != retry) {this_value = 0; *bError=true; }
   return this_value;

}




If I understood your code right, when you set error = true, readTouchValue() returns 0 anyway !
So, where's the difference ? (if the function returns 0, the position isn't read obviously !)

BUT I have tested you little draw APP, and it seems to actually WORK !
there's absolutely NO jumping :O

The only difference I can think of, is that you discard the reading if ANY reading goes wrong (x,y,z1 or z2) - but shouldn't libnds do this anyway ?


There are a few differences:
- 0 is a valid value, so you don't know when that 0 is returned because there was an error or because it's the correct value. Then if error is set to true, it doesn't matter what the function returns because those values won't be taken into account (as you can see in the modification of PA_Keys.c).

- Previous code only read 2 times the position, if all of them is in the range, the function returns that value, and if after 'retry' retries it hasn't got any value are the range, it discards all readed data and returns 0 (anyway it wasn't working well because the line before 'return this_value' was if ( i == range) this_value = 0; and it should be retry.

However, the modified code checks the touchscreen 'retry' times and if all times the obtained data is in the specified range around 'last_value', it's accepted. In other case it returns an error.

I hope these annoying jumps have dissapeared :D

#98913 - wintermute - Fri Aug 18, 2006 2:12 pm

I was about to say the same thing, the error flag is redundant. In theory the touch screen readings run from 0 to 4097, in practice the extreme values will never be seen so 0 was used as an error value. The original code does not report a pen down if either touchscreen co-ordinate is zero.

Interestingly Padrinator's code suggests that the range part of this code was the important part, rather than the number of retries. What I was attempting to acheive here was a settled value by repeated reading until all values were within a certain range. Being honest I'd assumed the "bendy" touchscreen readings were caused by not waiting for the value to settle but perhaps reading 2 or 3 times would suffice.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#98914 - wintermute - Fri Aug 18, 2006 2:21 pm

PadrinatoR wrote:

There are a few differences:
- 0 is a valid value, so you don't know when that 0 is returned because there was an error or because it's the correct value. Then if error is set to true, it doesn't matter what the function returns because those values won't be taken into account (as you can see in the modification of PA_Keys.c).


0 is actually not a valid value. In practice it's very rare to find values at the extremes of a range for any analog signal and, when you do, it usually indicates that the device has failed in some way.

Quote:

- Previous code only read 2 times the position, if all of them is in the range, the function returns that value, and if after 'retry' retries it hasn't got any value are the range, it discards all readed data and returns 0 (anyway it wasn't working well because the line before 'return this_value' was if ( i == range) this_value = 0; and it should be retry.


Your results seem to indicate that if any of the values are in error then all of them are. It might be sufficient to read 2 values and check the range.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog


Last edited by wintermute on Fri Aug 18, 2006 2:33 pm; edited 1 time in total

#98915 - PadrinatoR - Fri Aug 18, 2006 2:22 pm

wintermute wrote:
I was about to say the same thing, the error flag is redundant. In theory the touch screen readings run from 0 to 4097, in practice the extreme values will never be seen so 0 was used as an error value. The original code does not report a pen down if either touchscreen co-ordinate is zero.


I think I obtained a negative value from the touchscreen coordinates (before they were converted to pixel coordinates) when I was investigating what caused these jumps. But I may be wrong... that's the reason why I preferred to use an extra variable. Anyway, this method to control errors and pen touches can be improved a lot.

I think it was better to have a variable in IPC and touchPosition, called something like 'touched', whose value was determined by:
(((~IPC->buttons) >> 6) & 1) && !IPC->touchError

(yes, like 'temp' variable in PA_UpdateStylus from PAlib)

With this you can forget REG_KEYXY and errors reading data independence, and we'll have all of it in only one variable.

Well, I've sent to drunken coders a modified version of libnds, until this changes are included in the official package more efficiently :)

#98917 - PadrinatoR - Fri Aug 18, 2006 2:30 pm

wintermute wrote:

0 is actually not a valid value. In practice it's very rare to find values at the extremes of a range for any analog signal and, when you do, it usually indicates that the device has failed in some way.


Ok, as I said I remember to had obtained a negative value, so I considered 0 as a possible value.

wintermute wrote:
Your results seem to indicate that if any of the values are in error then all of them are. It might be sufficient to read 2 values and check the range.

it seems to me that


I think you're right because I've changed _MaxRetry to 3 and there is no jumpings :)

#98934 - wintermute - Fri Aug 18, 2006 4:35 pm

well, considering the value obtained from the touchscreen is 12bits it's kind of impossible to get a negative value there. I've seen the pixel co-ordinates go negative which is why they're clamped. The touchscreen test example displays the range of values at the edges, try it and see what you get.

If nothing else, doing a little research on the construction of resistive touch panels will show you that it's physically impossible to obtain values across the entire theoretical range.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#99129 - PadrinatoR - Sat Aug 19, 2006 6:07 pm

wintermute wrote:
well, considering the value obtained from the touchscreen is 12bits it's kind of impossible to get a negative value there. I've seen the pixel co-ordinates go negative which is why they're clamped. The touchscreen test example displays the range of values at the edges, try it and see what you get.

If nothing else, doing a little research on the construction of resistive touch panels will show you that it's physically impossible to obtain values across the entire theoretical range.


Yes, you're right, I may not remember it well or something hehehe :P

Well I've been testing the drawing app and I had to change '_MaxRange' value because when you touch the border of the screen, it seems that values are less stables and always fall out of range.

With this values it seems to be solved (in my DS Lite):

static int _MaxRetry = 5;
static int _MaxRange = 170;

If I reduce _MaxRetry using that range, there are jumps.

#99484 - PadrinatoR - Tue Aug 22, 2006 12:57 am

PadrinatoR wrote:
With this values it seems to be solved (in my DS Lite):

static int _MaxRetry = 5;
static int _MaxRange = 170;


I tested my app with this values in another DSLite and there are jumpings :( So it's needed to decrease _MaxRange :S

#99595 - laurens - Tue Aug 22, 2006 4:27 pm

The code that PadrinatoR posted doesn't work for me!
either the drawit by padrinator and the draw3 by davr (that both uses the code) give me the same problem.
The problem is that only a small area of my touchscreen is actually registered. so i can only touch, and thus paint, at only a very small spot.
This is quite bad because i love drawing on my DS.
to show what area i only can draw, i have saved an image using davr's Draw app.

these are the images (please notice that these are twice the size of the DS touchscreen).


The first is made using the Brush tool.
[Images not permitted - Click here to view it]

and the second is made by filling the background with black and using the eraser tool to make the white dot.
[Images not permitted - Click here to view it]


Hope you can help me.

#99599 - PadrinatoR - Tue Aug 22, 2006 4:52 pm

O_o

I assume that you haven't a screen protector on your touchscreen, commercial games run fine in your DS, and you have calibrated your touchscreen right.

#99603 - PadrinatoR - Tue Aug 22, 2006 5:29 pm

Please, check if this gives you the same results:

http://www.ftp.nu/files/5410/

I've seen that if I only take into account the FIRST obtained value and then try to draw at the borders, I get something like this:

[Images not permitted - Click here to view it]

And the SECOND value is almost perfect (it depends of pressure, as you know) and lets me draw the borders almost perfect. Then, the code of "readTouchValue" function as I modified it, doesn't return a valid value when I touch the borders because the distance between the FIRST value and the SECOND value is more than 'range' so the function doesn't take into account this touch.

How to avoid this? I've ignored the FIRST value and taken the SECOND value to check if the next values are in the range:

Code:
   s32 last_value = touchRead(measure | 1); //Dump
   last_value = touchRead(measure | 1); //Reference value

   for ( i=0; i < retry; i++) {
      this_value = touchRead(measure | 1);
      this_range = abs(last_value - this_value);
      if (this_range > range) break;
   }



That's the reason that forced me to increase _MaxRange, but with this change, I can use the initial values: _MaxRetry=5 and _MaxRange=30 and it work's perfectly (in my DS Lite).

#99607 - laurens - Tue Aug 22, 2006 5:39 pm

I do have a screen protector (a brando one, works fine, never had problems with it).
Games work fine with the touchscreen.
I just tried to calibrate my DS to see if it work after doing that, but it still doesn't.

#99608 - josath - Tue Aug 22, 2006 5:47 pm

Some info on laurens' problem:
laurens wrote:

Ive used the program before to, but im quite concerned now, as i can't use it probably anymore. i can only use a small portion of the screen to touch, ive saved a png of what i was able to draw, and i couldn't draw outside this black dot i managed to create. so i don't know whats the problem now, but its quite sad it didn't work.

see the attachments for the pictures, the first one is done with a brush, the second one is used by using the paint bucket tool with black and using the eraser i made a white part.

Here are his example images, showing where he can draw on the screen:
http://davr.org/ds2/laurens1.png
http://davr.org/ds2/laurens2.png

Hopefully this problem can be sorted out, as otherwise this new code seems good.

EDIT: Whoops, didn't notice the other posts above, somehow I didn't reload, or I'm just blind :P


Last edited by josath on Tue Aug 22, 2006 5:55 pm; edited 1 time in total

#99609 - laurens - Tue Aug 22, 2006 5:50 pm

josath wrote:
Some info on laurens' problem:
laurens wrote:

Ive used the program before to, but im quite concerned now, as i can't use it probably anymore. i can only use a small portion of the screen to touch, ive saved a png of what i was able to draw, and i couldn't draw outside this black dot i managed to create. so i don't know whats the problem now, but its quite sad it didn't work.

see the attachments for the pictures, the first one is done with a brush, the second one is used by using the paint bucket tool with black and using the eraser i made a white part.

Here are his example images, showing where he can draw on the screen:
http://davr.org/ds2/laurens1.png
http://davr.org/ds2/laurens2.png

Hopefully this problem can be sorted out, as otherwise this new code seems good.

Thanks for helping me out now, but as you told me in a previous PM, i already asked about this in the topic and showed the images, i also send a pm to PadrinatoR.
Still thanks that you are actually putting effort in this for me =D

#99616 - wintermute - Tue Aug 22, 2006 6:38 pm

laurens: What boot method are you using to run these applications?
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#99617 - laurens - Tue Aug 22, 2006 6:38 pm

Ok, the problem is solved now!
We now find a more accurate way to measure the touch screen and jumping lines, and padrinator is going to post his new fixed code v?ry soon now!
be sure to update your homebrew when you've used it!

It had something to do with the first read data and the second read data. PadrinatoR was using the first read data as a reference point, but it seems that the second read data is much more accurate.
He didn't post his new code yet, because he wasn't sure if it worked better at all. Then he gave his beta to me, and it seemed to work perfectly, very smooth and no weird jumping lines. Suddenly the answers all started to come up and he knew what was wrong and stuff. so hes updating the code a little now and is going to post it soon.

#99620 - PadrinatoR - Tue Aug 22, 2006 6:53 pm

Yeah, it seems that all I've talked about in my last post does work for laurens :)

I hope these changes can help to improve libnds :D

#99638 - Sausage Boy - Tue Aug 22, 2006 9:20 pm

WOOO!
_________________
"no offense, but this is the gayest game ever"

#99651 - PadrinatoR - Tue Aug 22, 2006 10:58 pm

Please, test this file and tell me if you notice some of these things:

- Stylus jumping (you must touch gently the touchscreen)
- You can't draw in some parts of the screen even if you touch hardly.

URL: http://www.ftp.nu/files/5419/

I've included the modified version of touch.c of libnds (libnds/source/arm7). The other changes are the same that I explained in:

http://forum.gbadev.org/viewtopic.php?p=98815#98815

#99658 - tepples - Wed Aug 23, 2006 12:37 am

PadrinatoR's tech demo works perfectly on my silver DS classic, came with FW2)
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#99714 - laurens - Wed Aug 23, 2006 3:34 pm

Again, this one works absolutly perfect for me!

#99885 - PadrinatoR - Thu Aug 24, 2006 3:52 pm

Thank you for answering. It seems that no one wants to fix this problem O_o

Anyway, I've been investigating a bit more.

Last code generates jumps in some DS where it's better to use the FIRST read data as reference value instead of the second one.

However I think I've found a solution for this problem, it's not perfect but very accurate. I suggest to use it with a Pressure limitation (a big interval, like 0-170 seems to be enough). Here you have a new test version which uses Pressure limitation and the new solution:

LINK: http://www.ftp.nu/files/5434/

As far as I know, this new method needs to avoid reading any measure that needs Single-Ended Mode (temperature, battery and aux inputs) because they seems to unstabilize the rest of measures (x, y and pressure), so I removed temp, battery and aux measures and changed z1 and z2 measures to differential mode. I think Nintendo may do it in this way... at least I've not seen any game that measures temperature or battery (there is a special byte which tell us how charged is our battery, so we needn't to measure it from the touchscreen, isn't it??).

Well, test these last files and tell me if you can draw in the whole screen and if you notice annoying jumps. This is the most accurate and compatible version I've written, I've combined the new solution with pressure limitation (0-170) so it should work on any DS with only a few little (very very little) jumps and let you draw in the whole screen. Thanks in advance!

#99952 - josath - Thu Aug 24, 2006 10:24 pm

This works pretty good for me, except I have to press more firmly on the screen to get it to register. My comparison is always pictochat - with it, I don't have to press so hard and it draws fine. It's not a big problem, just a minor annoyance. It's not like I'm stabbing the screen or anything, just have to press harder than usual.

EDIT: One other issue...I can't draw to the top or left edges, theres about a 5 pixel border I cant draw into.

#99957 - PadrinatoR - Thu Aug 24, 2006 10:37 pm

Thanks for answering :D

It may be the pressure limit... I'm trying other posibilities... I'm beginning to hate the touchscreen hahaha

It would be great to get PictoChat code and disassemble it to see how does it manage the touchscreen, but I'm not able to get it from firmware :@

#99964 - josath - Thu Aug 24, 2006 10:51 pm

well, we know that touchscreen can only be accessed by arm7, and also that most commercial nds apps use the same arm7 code, so if you want to disassemble, you could probably look at the arm7 bins from one of the official wifi demos.

#99965 - PadrinatoR - Thu Aug 24, 2006 11:02 pm

Yes I'm trying to study commercial games' source, but I think PictoChat's code is shorter and more simple than, for example, Polarium's one.

But... what do you mean when you say 'wifi official demos'?? What are those demos??

#99968 - josath - Thu Aug 24, 2006 11:31 pm

http://wiki.akkit.org/Downloadable_DS_Demos

#100008 - PadrinatoR - Fri Aug 25, 2006 11:01 am

I've disassembled Polarium Trial Version and I've found touchscreen code. I'm studying it now. I suppose that no one has disassembled a commercial game before in order to know how is the touchscreen managed, isn't it?

#100075 - tepples - Fri Aug 25, 2006 10:49 pm

PadrinatoR wrote:
I suppose that no one has disassembled a commercial game before in order to know how is the touchscreen managed, isn't it?

Unsurprising. If more people on this board had disassembly skills and were willing to use them, we would have WiFiMe2 by now.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#100080 - zzo38computer - Fri Aug 25, 2006 11:08 pm

If someone knows how to make it to work correctly without jumping, then I will add a calibration feature to FWNITRO
_________________
Important: Please send messages about FWNITRO to the public forum, not privately to me.

#100082 - PadrinatoR - Fri Aug 25, 2006 11:13 pm

zzo38computer wrote:
If someone knows how to make it to work correctly without jumping, then I will add a calibration feature to FWNITRO

I'm invistigating that, and I've got a very accurate method to do this, but I must study more Brain Training's source.

Have you got Pictochat's source (ie, the source of the program loaded when you switch on your NDS)?? It may be a very little file with the needed algorithm, so it should be easy to analize.

tepples, I thought that libnds, no$gba and other emus would be made by disassemble and study commercial games.

#100214 - HyperHacker - Sat Aug 26, 2006 9:47 pm

tepples wrote:
PadrinatoR wrote:
I suppose that no one has disassembled a commercial game before in order to know how is the touchscreen managed, isn't it?

Unsurprising. If more people on this board had disassembly skills and were willing to use them, we would have WiFiMe2 by now.

Assuming any loaders are exploitable.
_________________
I'm a PSP hacker now, but I still <3 DS.

#100215 - tepples - Sat Aug 26, 2006 9:51 pm

But if some member of this board had actually tried this and found a loader to be more than likely not exploitable, he or she would have posted the info to the board (including a description of what kind of code authentication the subsequent stages of loading use), and we would have known about it by now.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#158522 - ritz - Thu Jun 12, 2008 9:14 pm

Sorry to bring up an old thread, but I was wondering if this (or similar) code for alleviating the gentle-touch-jumping issue, as discussed earlier, has made it into libnds. If not, is it because each DS could possibly be too different in this regard for the code to be used in a common library?

#158524 - josath - Thu Jun 12, 2008 9:19 pm

Have you updated to the latest libnds and tried it? I thought this sort of thing was fixed a long long time ago (notice this thread is almost 2 years old)

#158530 - ritz - Thu Jun 12, 2008 11:20 pm

I'm using devARM 23b with "libnds 20071023" from sourceforge. I'm also using the new default ARM7 code from sourceforge "default am7 20080416". I thought I'd ask as I get funny/wild jumping on very gentle pen touches/movement in my DS app.
I'll review my sources/installation when I get home to confirm these versions, etc. It is very possible I botched something up some day in the past and never noticed :)

Thanks for your reply.

#158532 - josath - Thu Jun 12, 2008 11:40 pm

very gentle touches is likely gonna cause problems, but if you draw with normal pressure does it work ok?

#158543 - ritz - Fri Jun 13, 2008 4:42 am

Yea, all my libs and source match what I said earlier. Must be as you said, josath, just too gentle. Regular pressing seems to work the majority of the time. It's just annoying when stuff flies all over the place instantly :)

#158544 - josath - Fri Jun 13, 2008 5:48 am

Most apps it doesn't matter, but if you're doing something like drawing, some clever filtering on your part can get rid of the jumps. No need to use special pressure sensors or anything like that, just do things like:

1. Disregard the first one or two frames of data when the pen is put down, if the points are too far apart, and:
2. Disregard the last one or two frames of data before the pen is picked up, if the points are too far apart.

I think that should solve most problems.

#158547 - TwentySeven - Fri Jun 13, 2008 6:10 am

What you probably want to use is a SMA or WMA

see: http://en.wikipedia.org/wiki/Moving_average

think of it as input filtering

X= (X0+X1+X2+..+Xn)/n;
Y= (Y0+Y1+Y2+..+Yn}/n;

#158562 - ritz - Fri Jun 13, 2008 2:26 pm

Thanks for the tips, I'll try them out.

#158617 - josath - Sat Jun 14, 2008 10:29 pm

I don't know about averaging...the main problem is not noisy data, but a few outliers, that usually come at the very beginning and very end of a touch. I think averaging will give inaccurate results.

#158619 - silent_code - Sat Jun 14, 2008 11:39 pm

You could try the newest release (1.3.0) of my VSdemo (go to my WWW), which has a rather smooth touch implementation. The only problem is, that it has a slight tendency to "drift" towards smaller values. I will hopfully fix that very soon. :^)
_________________
July 5th 08: "Volumetric Shadow Demo" 1.6.0 (final) source released
June 5th 08: "Zombie NDS" WIP released!
It's all on my page, just click WWW below.

#159139 - Funky Gibbon - Wed Jun 25, 2008 11:57 pm

There is a Faulty Batch of DS's, i had one, it would'nt calibrate properly, i did'nt realise it was a fault until someone told me about it, luckily the shop knew about the fault and exchanged my DS even a year after i bought it

#167129 - mbmax - Mon Mar 02, 2009 7:35 pm

I have seen some people in this thread saying that moonshell works better with last modification made in touch library.
It seems that the nightmare is here again on some DSL.
I have opened this thread last year on unofficial ez forum to collect as much as possible information before posting here.
If someone has a clue on what's going on and perhaps a way to fix that, i will be glad to read it. :)

Thanks.


Last edited by mbmax on Tue Mar 03, 2009 11:58 am; edited 1 time in total

#167136 - Vague Rant - Tue Mar 03, 2009 5:57 am

It's probably not a good idea to link to that board from here, I would recommend just quoting some important information.
_________________
I've got nothing to say, but it's OK.

#167138 - qw3rty - Tue Mar 03, 2009 8:55 am

Filtering out readings with too high accelerations worked quite well for me.
(I talk about two year old libnds, but it should still hold true)

#167142 - mbmax - Tue Mar 03, 2009 11:55 am

Vague Rant wrote:
It's probably not a good idea to link to that board from here, I would recommend just quoting some important information.

There is so much informations inside that i really don't know what to quote.
qw3rty wrote:
Filtering out readings with too high accelerations worked quite well for me.
(I talk about two year old libnds, but it should still hold true)

Thanks for your answer qw3rty. If i can reach moonlight again, i will inform him about this. ;)