Arduino XPT2046 Touchscreen Calibration and Coding - ILI9341 LCD with XPT2046 Touch screen

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
if you've got a touchscreen for your arduino you're going to need to know how to calibrate it and then how to turn this values into screen pixel coordinates so let's see how it's done [Music] hi and welcome to bytes and bits we've been doing quite a bit of work with our lcd touch screen panel and today we're gonna have a look at how we can actually set up the touch part of it so we're gonna have a look at how we calibrate our resistive touch screen and get that all set up so let's start by having a think about how the resistive touch screen works and how we're going to then calibrate that a resistive touch screen is made from two layers of conductive material and these are separated by a very thin layer of non-conducting material either sort of a gas or a liquid and basically when you press your stylus against the screen you make the two layers touch because the layers only have to touch that this is why you can use whatever you want to activate your touchscreen so it doesn't have to be a finger it can be a stylus or whatever but it also then means that you have to press slightly harder on a resistive touchscreen than on a capacitive touchscreen so once the layers have touched the system is basically able to form a potential divider between opposite edges of the screen so looking at that horizontally we can see that we have a touch point and then a potential divider which lets us measure in effect a voltage at where we touched it and then we can repeat that process for the vertical direction and we'll get then two values for the point at which we touched because the touch screen and the lcd circuitry aren't connected in any way we now have to translate the values we're getting back from our touch screen and match those up with the pixel dimensions on our lcd screen so this is the this is what we call the process of calibration now because the touch screen's zero position won't necessarily and actually it won't match up with the zero position on our screen we can't just do one point we have to take multiple points now the most accurate way is to take three points because this lets you both calibrate the position of your point on the touch screen but also lets you calibrate the misalignment of the touchscreen so the the way in which the two layers are put together both the lcd screen and the touch screen they might not exactly line up um horizontally or vertically so taking three points lets you um factor that value in as well but it does involve quite complex mathematics and on these small screens the actual alignment error is going to be rather small and in effect the the error where you're touching your point on the screen is probably going to give a bigger error than the alignment so i'm going to just use two points that which lets us then actually work out the the mathematics ourselves without without too much bother so we can actually do our own calibration code um if you do want to do full three-point calibration code you're probably best bet is to download a a package which lets you do that and some of the touch screen packages then have that built in but we'll say we're going to do this by ourselves so we can learn both a bit more about coding and about how more how these things work so we'll just use a simple two points as shown on the screen so in fact we're going to end up then at the end of our calibration routine we will have two points where we know what the pixel dimensions of that point were and then we will have measured the touch screen resistive values for that as well so we now need to work out a way of mapping the values we get back from our touch screen with the pixel dimensions on our lcd screen and really what we can do here is we can assume that we have a linear relationship so if we were to plot these on a graph so let's think about our x coordinates we're going to have to do our x coordinates and our y coordinates separately so if we were plotting a graph we could put a graph of the actual pixel value on our vertical axis and then the value returned from our touchscreen on the horizontal axis and we're going to plot two points that we've measured so far so our top left point and our bottom right point and that will then give us two points on our graph and we can then put a straight line between these and we'll see that the line doesn't go through the origin of our graph so it shows then that the zero position in our pixel lcd screen won't necessarily match up with the zero position in our touch screen values so we need to model this then as a straight line so we think about our normal straight line equation so our y value here is actually our x pixel value so that's going to be equal to some gradient of this line times our x value coming out of our touch screen plus this constant c which again signifies the y axis crossing point so what we have to do now is really just get some formulas which will let us work out these values for m and c and that would then give us our straight line equation for this particular x axis we can then repeat the whole process for our y-axis and that will end up then giving us two equations which will let us then translate the values we get back from our touch screen into pixel dimensions on our lcd screen so let's go and have a look at actually coding that and see if it works so this arduino sketch will take us through the calibration function and then allow us to check that out by letting us move a little block around the screen so as we touch the screen this block will follow us around so to begin with then we're very much using the same basic setup that we've been using in the previous animation tutorial and the setup tutorial so if you haven't been through the setup tutorial please do go and have a look at that which will show you how to get the screen all connected up so that we can both draw on the lcd and read from the touch screen so we're using the same sort of libraries so again we're using the adafruit graphics libraries and lcd screen driver and then this xpt 2046 touch screen and driver which will let us then talk to the little chip so my touch screen my resistive touchscreen uses this xpt 2046 um chip so once you've got all that set up so we've got set up here and if i scroll down the bottom here you'll see that in our setup function again this is exactly the same as we do with our normal work for the animation and so on the only um addition here is that we at the end of our setup function after we've turned it black instead of rotation and and initialized our various variables um that just simply calls the calibrate touch screen function which we're going to have a look at in a second so um we also then um once we get past the calibration then we have a bit of code in here which will let us then just simply check if it's being touched and let us draw a block but again we'll come to that in a second so let's first of all have a look at this calibration function so this is called at the end of our setup so at this point we now have our lcd screen set up and our touchscreen setup and we create up here we create two global variables so tft is an instance of the adafruit ili 9341 driver object so again that's what we use to connect and talk to the lcd screen and then ts is an instance of this touch screen object and again that's what lets us talk to the actual touch screen socket um circuitry so once we calibrate we know that we're trying to find out um values which let us calibrate the x and y values so we've seen that we need to just model those as linear equations so we need to have both an x gradient and a y gradient and an x y axis crossing point and a y y axis crossing point so we're going to store the values of those two modeling lines inside these variables and again i'm making them float so that we can just get a little bit of that extra accuracy on those and some variables here i'm defining which you're going to be doing with the displaying of the blocks is the block size and block position i'm then going to just use a little bit of extra code to make it easier for us to work with our screen coordinates and so on so um we know the screen coordinates are made up of x and y values so i'm just creating a little class here called a screen point which just wraps up those x and y values inside little object and that makes it easier for us to handle them and when we get on to creating our breakout clone game which will be in the next video lesson then that makes the whole process easier so um we do have function here which will try and do the actual translation at the very end so we'll come back to that after we've done the calibration so in our calibration function then we're going to need to be able to talk to the touch screen and get back the position of the current touch so when we touch it we'll be able to sense that and we'll then be able to ask the touchscreen give me back those potential divider values from that particular touch point and then we're going to need to store those values so it returns back two integer values so an x integer value and a y integer value and we're going to do that for two points so we'll end up with our x1 y1 x2 y2 as our two touch points that come from our calibration function so we'll start by just blanking the screen by just filling it black then the person might be touching the screen as they turn on the arduino so we'll do a little loop here so we're saying here so if the touch screen is currently being touched then we'll just stay inside this loop until it's stopped being touched and that saves us getting a false reading at the very beginning of our calibration code so once we've detected that nobody is touching the screen then we're going to draw a little red cross and that red cross is going to be centered at pixel coordinates 20 20. we then sit there so that that tells the person where they need to touch and we're then going to wait until the screen is touched so while it's not being touched sit in this loop we're then going to do a little slight delay here and what what you find is when you first bring the stylus down to touch the screen the the very first touch that is recognized by the screen those coordinates are slightly different from when the actual person has finished pressing it against the screen so it's almost like as it touches it sort of half touches and gets a slightly erroneous value now that when we get through to actually using the touch screen that's not such an issue but when we're calibrating it it can throw out our calibrations so i've just put in a little 50 millisecond delay here to make sure that the stylus is firmly pressed against the the actual screen so once we've got the stylus in the right position we're then going to call this func this method so team member ts is the object that is linked to our library software for the touch screen and that then has a method called getpoint so that will return us back one of this with one of these ts point objects so again i'm capturing that in my variable p remember we made that into one of the ts point variables so that will then give us back so p dot x and p dot y those will be the two raw readings from our touch screen and you can see there we're just simply saving them into x one and y one we're then going to draw or overdraw that red cross to take it off the screen we're then waiting for half a second and we're waiting for the person to then lift the stylus off the screen so again we're so at the moment so just in here this is where the person has touched on that first x we've then removed the x and we're now going to wait for them to lift the stylus off so while our touch screen is touched we just simply sit here so once we break out of that loop that means that nobody's touching the screen anymore so we're going to draw another red cross and that's going to be centered 20 pixels in and 20 pixels up from the bottom right hand corner of our screen so again we're using our tft.width function here so that will tell us how many pixels wide the screen is how many pixels high the screen is and we'll just draw a little red cross centered 20 pixels in and 20 pixels up and then we just simply repeat that same sort of process so we wait until um the screen is touched then we let that touch settle down to get an accurate reading and we then make a log of those two x and y coordinates then we delete our black or our our little red cross and then we go into the actual calculation portion of our code so we saw from our initial discussion that we need to calculate a gradient and a y-axis crossing point for both our x values and our values so this is where we're just sort of calculating that so we need to know are the difference between our two x pixel positions so in our x direction that's really just the width of the screen minus 40 pixels and then our y direction that's the height of the screen minus 40 pixels and then to calculate our gradient then we use this pixel value difference divided by our touch screen x values difference and that will then give us our gradient and then we can substitute those values into one of the points that we measure so i'm substituting it into our x1 point here and you can see how we're calculating then this c so we have an m and a c then for our x coordinate and then we do the same again then for our y coordinate so we end up with an m and a c for our y coordinates and those inners are stored so this x cal m x calc and so on those are global variables that are defined up the top of the sc of the um code here and they'll then be used in the actual calculations and all that's happening here is i i was just doing some debugging where that's going to put out in the serial channel so we can see what the calculations came up with so that is the calibration stuff so we now have an x model and a y model to translate the raw values coming from our touch screen into actual pixel dimensions and i've created a little function up here so once we've run the calibrate touch screen function are our x cal m and so on those are now loaded with the correct values to model this and really all we're doing is we are sending in an x and a y value and those are going to be values which we've read straight from the touch screen using that library software and this bit of code then is simply going to take that you can see here that it's using our um our x times so mx plus c and our our mx c here as well so we're doing the calculation and we're then rounding it to the nearest whole pixel value um and that then gives us an idea of where we are and then just a little bit of error checking here so if our if if the values that we calculate are less than zero well we can't have a pixel value less than zero so we're just limiting it to zero and same with the other side there it can't be more than the um width of the screen minus one pixel so we just limit those two values just in case something went off the edge of the screen and then we return one of these screen point um objects so we create a screen point object load it with the x and y coordinates so those are again those are now the pixel coordinates and return that back to our function so um down here then we'll see where that's actually used okay so we have this here so in our main loop we're looping around here 50 times a a second again we're using this frame timer stuff here and again have a look in the previous animation tutorial to see why we need that and how we do that i'm basically saying if somebody is touching the screen then we're going to move the block and that's really going to move the block to where that screen is being touched so inside here then we're basically setting things up we're just rechecking that it is actually a touch we're then reading the values from the touch screen we're then getting hold of those values and passing it across to our little function that will translate the touch screen values remember so these two values here are the touch screen values and this function get screen chords we'll translate those into screen coordinates and return them back as one of these screen point objects and once we've got that we can then simply just work out where we need to draw our rectangle so we do that so again we're doing this here so we're saying the new position of the rectangle we calculate all of that we have a look to see if the rectangle is actually moved from its previous position and if it has then we delete the old copy of the rectangle and then draw the new copy of the rectangle and that will just simply then give us our our rectangle moving on the screen with our with our um stylus so that's really the code then i'll say that the main part of it is this calibration function so we come through here we do our calibration we calculate our our our gradient and our crossing points for both x and y and then we embed those into a little function and you can see here it's a very simple function really and it just uses that straight line equation to translate touch screen values to pixel values so let's upload that code then to our arduino and see if we can get this calibration software um running so that's our first x position then so if we then touch that it should then move across to our second exposition if we touch that we should now be able to move the square around the screen and you can see there but it's actually following our our stylus quite well you can see there's a little bit of glitchiness as regards the readings and again that's just part of the way that the screen's working again these are quite cheap screens so um you know we're not going to get absolute precision with these ones but you can see there that now that we've calibrated that you can see that our our translation code between my stylus position and the screen xy coordinates is is pretty good okay so that all seems to be working okay so let's come back across then to our code now that we've got our lcd screen working and our touchscreen working we can start to create various user interfaces using this touch screen idea so i've got some code here which will just generate a simple button and we can then detect whether we've clicked the button or not so again you could use this to control various projects and so on and again when we write the um breakout game we'll say that we're using that to control both buttons and then the the bat itself so really what i've done and this is just an expansion of the code we just saw before but i've created a little button class now there actually is a button class built into the adafruit library so please do have a look at that to see how that works but i'm just really creating a very simple one here so we can see the general idea of what you need to do so the button itself has got obviously an x y position on the screen a width and a height and then some text on the button itself if you're not familiar with you working with text in the arduino or the c-plus plus system again you you need to have a look at how that's done using character arrays and of course then um getting into the deal of c plus plus pointers um but again that that that is another topic to be honest um so we are just creating here some simple methods within this so we have initialize our button so we're setting up this position and passing that in then and that then really just sets up the button and then a render function which will actually draw the button on screen and i'm really just drawing a green rectangle with some white text inside it we then have a an is clicked method and this is going to return true or false so i'm going to use one of these screen point objects which we set up in the in the last block of code so that really just encapsulates an x and y pixel um coordinate so really just checking if if that supplied x and y coordinate is actually inside our button area then we're going to return back a true otherwise we're going to return back a false so that will let us know whether when we've detected a touch um point that whether it's actually inside this button and whether the button has been clicked or not so the rest of it really then is exactly the same as we had in the calibration function that's all the calibration stuff there we're then creating a a global variable to hold our button and then inside the setup function we are initialize our initializing the button to be a this size and with just the words click me inside it so inside our main loop then so again we're going to do the actual touching bit inside the loop so we're creating a screen point object here to capture that um screen point values so we're checking then so if the touch screen is touched so we're not gonna so if so if it's not being touched we're just simply in effect writing over where we're going to be putting up a message but if the touchscreen is touched then we're getting hold of that touch point converting it to a screen coordinates within checking so we're asking that button object have you been clicked so again we're saying calling it is clicked method and passing in the screen coordinates so if it has been clicked we're going to write little message saying clicked otherwise we're going to overdraw where that message would appear so basically what what we'll do then is when we run it if we touch the screen and we're not inside the button we'll just simply get nothing appear on screen if we touch inside the button we'll get our message clicked so let's upload that into the arduino and see what we get okay so that's uploaded and we're now running our calibration function so if i just calibrate the screen and now we have our button appearing and again we can play around with making that prettier and aligning things properly but if i touch over here now nothing happens and then of course if i click on the button we get our click event being being seen so that then gives us a way of producing some nice user interfaces for our arduino projects where we can put up buttons and little sliders and so on and again it's just a matter now of using this touch screen function and monitoring clicks and then writing little code to produce our user interface items and as i say we'll be doing that a bit more when we come to do the breakout program which i think will be the very next video so we can now use the touchscreen as an input device for our arduino um so we've really got everything we need now in place to start writing a bit more software um and perhaps a game so if you've been following through on this series you'll notice that i've been using a uh and breakout or arkanoid clone um as a bit of a demo program and that's really what we're going to tackle then in the very next program so we're going to bring together all of our graphics our touch screen and a bit of c plus programming and bring that game back to life again so look forward to seeing you in the very next video have fun making and i will see you soon don't forget to visit the course pages for this project there you'll be able to download the code for this lesson and get lots of extra hints and tips you'll also get access to all my other programming electronics and gaming projects all the links are in the description below for more games programming electronics projects and retro gaming please make sure you like this video subscribe to my youtube channel and visit my website
Info
Channel: Bytes N Bits
Views: 26,642
Rating: undefined out of 5
Keywords: arduino, touchscreen, calibration, user interface
Id: QZbgPHvLfGw
Channel Id: undefined
Length: 27min 6sec (1626 seconds)
Published: Wed Dec 02 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.