Touch screen displays are a common choice in many microcontroller projects. Touch capability won’t take additional space – it sits on top of LCD to directly interact with objects you see on screen. 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.
The touch screen is an analog device. It is made of two flexible resistive sheets with a gap between them. When the screen is touched, a connection between sheets is made, and thus a measurement of voltage drop is taken. Normally resistive touch screen has a four-wire configuration. And normally, a specialized IC is used to take measurements and send data to MCU for processing. In our case, we are dealing with the ADS7843 touch screen controller, but in other systems, this works the pretty the same way.
The fact is that the touch screen controller reads screen ADC values and passes them via the 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 of different resolutions, different orientations, so data gathered from resistive touch screens must be scaled down to match all those circumstances. And this is done in different ways. One of the methods I tried before was the 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 a simple formula:
The Xread is an ADC value read from the 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 a separate screen, even if it is the exact resolution, readings of the 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 rotations. I think this is a more dirty method that way to do this. A better approach is to use a calibration algorithm that automatically aligns the screen by asking the user to give a few points on the net.
So where to start. First of all, you need to get the LCD working and read ADC values from the 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 a starting point in getting my screen calibrated. It uses a 5 point scheme as in this picture
The algorithm draws a point, and you need to touch it. You have to be sure you touch exactly where it is indicated. Otherwise, calibration won’t be correct. We are not going into math; look at how it works. When you need to calibrate the screen, you call function TS_Calibration(); it asks to enter 5 points one by one. Once you do so, it calculates six constants used to calculate actual screen coordinates from ADC readings you get from the touch screen controller. These constants are A, B, C, D, E, and F. Having those constants coordinates are calculated by applying simple formulas:
If you 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 it. When you turn the device, check if there is already calibration available, then load and use them. In my example, I cheated a bit. I set up a function that would display constants when calibration was done. Then I wrote those values down and added them to the 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.