Touch screen displays are common choice in many microcontroller projects. Touch capability won’t take additional space – it sits on top of LCD where you can directly interact with objects you see on screen. In order to get this working touch screen coordinates must match screen coordinates. So could be sure when you touch the point on screen you point where you want.
Touch screen is analog device. It is made of two flexible resistive sheets with gap between. When screen is touched, a connection between sheets is made and thus measurement of voltage drop is taken. Normally resistive touch screen has four wire configuration. And normally there is a specialized IC used to take measurements and send data to MCU for processing. In our case we are dealing with ADS7843 touch screen controller, but in other systems this works pretty same way.
The fact is that touch screen controller reads screen ADC values and simply passes them via SPI interface. So all you get is raw ADC readings that are not lined up with LCD coordinates. As you know LCD screens can be different resolution, different orientation, so data gathered from resistive touch screen must be scaled down to match all those circumstances. And this is done in different ways. One of the method I tried before was simple mathematical-empirical approach, when you know the ADC readings on screen edges. Then you can calculate what is ADC value per pixel size and thus calculate the coordinates using simple formula:
where Xread is ADC value read from touch screen. Xoff is ADC value at X=0 screen coordinate and Xpix – ADC value per pixel size. I saw this method in many hobbyist projects and libraries. They work fine and can be used as far as you know display parameters. If you plug different screen even if it is same resolution readings of touch screen may differ and you will need to find those constants again. This doesn’t sound attractive. Another problem may occur with negative values that appear due to different rotation. I think this is more dirty method that way to do this. Better approach is to use calibration algorithm which automatically aligns screen by asking user to give few points on screen.
We recommend EasyEDA for circuit design and PCB prototype
So where to start. First of all of course you need to get LCD working and be able to read ADC values from touch screen controller. After these are set up. Then you need to chose what type of calibration you will run. 2, 3, 5 or 9 point calibration. I’ve chosen 5 point calibration scheme the main reason is that algorithm is already implemented by ST and is used in their GUI lib. So I used it as starting point in to getting my screen calibrated. It uses a 5 point scheme as in this picture
The algorithm simply draws a point and you need to touch it. You have to be sure you touch exactly there it is indicated, otherwise calibration won’t be correct. We are not going in to math, just look at how it works. When you need to calibrate screen you call function TS_Calibration(); it asks to enter 5 points one by one. Once you do so, it calculates six constants that are used to calculate real screen coordinates from ADC readings you get from touch screen controller. These constants are A, B, C, D, E and F. Having those constants coordinates are calculated by applying simple formulas:
If don’t want to calibrate your screen every time you power the device you can store calibration constants so some non volatile memory. It can be internal flash memory or if there is EEPROM then this is the best place to store. Next time when you turn device, just check if there is already calibration available then load and use them. In my example I cheated a bit. I set up a function which would display constants when calibration was done. Then I wrote those values down and added to source code as constant values. When I implement EEPROM read/write functions, they will be placed here. If you want to test how it works, here is the source code [STM32Touch.zip]. It is still messy, so don’t judge it very much.
Here is a short video taken with phone. Sorry for crappy quality.