Looking for some simple tips on resistive touch panel on an LCD - Page 1
Forum section: electronics / general

author: peter-h
author_rank: Super Contributor
timestamp: August 20, 2025, 04:36:44 pm
content: There seems very little clear stuff out there on how this works.This is the displayhttps://www.buydisplay.com/serial-spi-3-5-inch-tft-lcd-module-in-320x480-optl-touchscreen-ili9488and this is the DS, which says almost nothing about ithttps://www.buydisplay.com/download/manual/ER-TFT035-6_Datasheet.pdfYou can have a resistive one or a capacitive one. The latter is implemented with a controller chip which lives on the flat cable (or so it looks) and that is I2C which I can't readily use, so I am looking at the former.There seem to be X+ X- Y+ Y- signals. These seem to be analog. The LCD and its controller is powered from +3.3V and my guess is that the resistive surface somehow connects across GND and 3.3V.They have code examples but not for the resistive touch panel.OTOH, reading about resistive touch panels, they seem to be regarded as crapPoor durability, poor contrast, etc.All I am interested in doing is implementing several virtual buttons. No multi finger gestures. Alternatively I can obviously implement physical buttons which can then be properly robust, and I can read them via SPI with just a PISO shift register. The display is already running very well (non touch version) via output-only 10MHz SPI (was a lot of work).Thank you in advance for any input and some simple usage tips

author: langwadt
author_rank: Super Contributor
timestamp: August 20, 2025, 04:52:30 pm
content: it's like an X/Y grid,first you supply vref to X+ and gnd to X-, then on Y+ (or Y-) you can measure the voltage that is the result of the resistive divider, left/right of the touch point.then you supply vref to Y+ and gnd to Y-, then on X+ (or X-) you can measure the voltage that is the result of the resistive divider, above/below of the touch pointand they are usually kinda crap both visually and functionally

author: peter-h
author_rank: Super Contributor
timestamp: August 20, 2025, 04:54:58 pm
content: So you continually alternate the application of Vref to the two pins, and sample the returns?I might stick to normal switchesEspecially as I don't have unlimited power to turn up the backlight, which at the 50mA or so is bright enough but not sunlight readable by any means.

author: wraper
author_rank: Unknown
timestamp: August 20, 2025, 04:57:26 pm
content: It acts like two potentiometers with wipers connected together through a switch.

author: peter-h
author_rank: Super Contributor
timestamp: August 20, 2025, 08:24:07 pm
content: The above diagram suggests that the voltage versus x/y position is nonlinear, because the bottom of say RV2 will be loading up the output of the wiper of RV1, so Y+ will be attenuated, and vice versa.

author: langwadt
author_rank: Super Contributor
timestamp: August 20, 2025, 08:42:47 pm
content: Quote from: peter-h on August 20, 2025, 08:24:07 pmX+ = high, X- = low, Y+ = tristate, Y- = senseY+ = high, Y- = low, X+ = tristate, X- = sensethere are other combinations

author: wraper
author_rank: Unknown
timestamp: August 20, 2025, 09:13:58 pm
content: Quote from: peter-h on August 20, 2025, 08:24:07 pmAs already said, you power only half of it at the time (one potentiometer) and read the voltage from either terminal of another half. Nothing loads anything.

author: peter-h
author_rank: Super Contributor
timestamp: August 20, 2025, 10:16:07 pm
content: OK; that's cunningSo I would need some analog switches.Funny the data sheet doesn't give the typical resistance. A quick search suggests it is around 300 ohms. So you don't want to put too much voltage across it...

author: langwadt
author_rank: Super Contributor
timestamp: August 20, 2025, 10:43:38 pm
content: Quote from: peter-h on August 20, 2025, 10:16:07 pmyou could probably get away with 4 GPIOs, two of them capable of being an ADC input. If you think the current is too high you could some series resistance to one end of each string, it needs to be calibrated anyway

author: wraper
author_rank: Unknown
timestamp: August 20, 2025, 10:56:49 pm
content: Quote from: peter-h on August 20, 2025, 10:16:07 pmAnalog switches for what? MCU GPIO of themselves may be enough, or a few small mosfets for power switching and two ADC inputs directly connected to the touch screen.https://ww1.microchip.com/downloads/en/appnotes/doc8091.pdf

author: peter-h
author_rank: Super Contributor
timestamp: August 21, 2025, 06:54:04 am
content: Thanks for that appnote. It's very good. Yes, four mosfets would do it. I don't have enough GPIO but that's another issue.So they use ITO coating on the glass... I used that a few years ago to make an ice-protected aircraft movie camera faceplate, heated to +8C with a controller, and yes you do lose some light transmission. And they need two layers, not one.I should investigate the capacitive option. This is I2C only which one can bit-bang, or maybe even run over SPI (?).Yes I know the 32F4 USARTs can do both but in this case it is shared.I will buy some of each and test them.

author: fchk
author_rank: Frequent Contributor
timestamp: August 21, 2025, 09:34:19 am
content: I'd use a small PIC to handle the touch, decode positions and send it back via slave spi.

author: xvr
author_rank: Frequent Contributor
timestamp: August 21, 2025, 10:40:11 am
content: QuoteYes. So it is best not to apply constant voltage to them. In standby mode, you can connect X+ and X- to Vdd, leave Y+ floating, and connect Y- to the microcontroller input (with a weak pull-down). This configuration will not consume power, but will notify about touches to the panel. Then you can switch to the normal process of scanning the touch panel (while the user continues to touch the panel).

author: wraper
author_rank: Unknown
timestamp: August 21, 2025, 10:46:32 am
content: Quote from: xvr on August 21, 2025, 10:40:11 amThere is no need to connect both terminals to VDD, and especially use any additional parts on having such capability. Also it can be VSS + pull-up which are way more commonly buil-in in MCUs.

author: peter-h
author_rank: Super Contributor
timestamp: August 21, 2025, 10:59:48 am
content: This is interesting. Another strategy is what one does with PT100 sensors and such: power them up with a low duty cycle, say only 1%.Looking at that Microchip appnote, it may be less work to build an I2C to SPI converterIf there is a protocol spec, I sure have not found it yetBut I would expect the capacitive controller to just tell you the exact finger coordinates, otherwise what is the point? I would hope the data is just output-only, so no need to interrogate it.

author: langwadt
author_rank: Super Contributor
timestamp: August 21, 2025, 11:50:54 am
content: Quote from: peter-h on August 21, 2025, 10:59:48 amwhy not I2C? it is only 2 pins and easily bit bangedand there are capaitive touch controllers with spi, e.g.https://www.hpinfotech.ro/FT5206.pdf

author: peter-h
author_rank: Super Contributor
timestamp: August 21, 2025, 01:28:16 pm
content: OK; the issue here is that I am using "cheap but very good" Chinese LCDs like thishttps://www.buydisplay.com/serial-spi-3-5-inch-tft-lcd-module-in-320x480-optl-touchscreen-ili9488and the capacitive option on that uses its own controllerWhen choosing displays one has a complex matrix of display size, pixel size, the controller it uses (whether you have software for it) and now this extra dimension.https://www.buydisplay.com/download/manual/ER-TPC035-6_Drawing.pdfI found the 6236 controller DShttps://www.buydisplay.com/download/ic/FT6236-FT6336-FT6436L-FT6436_Datasheet.pdfIt doesn't output by itself; you have to send it an address and other stuff.Fairly obviously using this feature could be a future trap...

author: langwadt
author_rank: Super Contributor
timestamp: August 21, 2025, 01:51:26 pm
content: Quote from: peter-h on August 21, 2025, 01:28:16 pmthose controller are usually fairly similar; an optional interrup when touched, read a register to see how many points, and then one by on read out the x and y coordinate for each point

author: peter-h
author_rank: Super Contributor
timestamp: August 21, 2025, 02:21:35 pm
content: OK it does look like capacitive is the way to go, especially if it has a lesser impact on the LCD readability than resistive.I am just being a lazy bastardI have a totally proven SPI expansion interface, mutexed and working with loads of devices, under RTOS, rock solid, each with different clock speed and mode etc, and I am trying to avoid bit banging I2C. I did it some years ago on an H8/323 (ADS7828) and it took a few days to get it to work. Looking up the way I2C works, I can't see any way to drive the 9 bit I2C from an SPI Master. But this is all doable of course... I am just very short of GPIO pins.But there are convertershttps://www.nxp.com/products/interfaces/ic-spi-i3c-interface-devices/bridges/spi-to-ic-bus-bridge:SC18IS604

author: mino-fm
author_rank: Regular Contributor
timestamp: August 22, 2025, 03:43:25 pm
content: A RP2040 PicoTerm version for 4.3" resistive TFT:http://mino-elektronik.de/TFT-direct-drive/TFT-direct-drive.htm#tft-6Source code is for Segger IDE.

author: peter-h
author_rank: Super Contributor
timestamp: August 27, 2025, 01:38:39 pm
content: This is the 320x480 display above but with the capacitive touch screen controller chipIt is I2C not SPI so it will take me a while to test it, but I should be able to test the display quality of the three versions sooner.This is the resistive touch panel version

author: SiliconWizard
author_rank: Super Contributor
timestamp: August 27, 2025, 03:54:27 pm
content: Yes, just use a touch controller, I wouldn't bother implementing that manually unless as a challenge.If using a resistive touch panel, the XPT2046 is a very common controller in chinese products, TI has equivalents with the TSC2046E, ADS7843, TSC2006.But yes, capacitive feels nicer and the capacitive touch panels usually have less light attenuation too. The one thing going for a resistive touchscreen is that it requires intentional user action - while with capacitive, any accidental light touch could have unintended consequences.

author: peter-h
author_rank: Super Contributor
timestamp: September 17, 2025, 08:20:08 pm
content: I've done the PCB for this stuff now.The display uses the FT6236 capacitive controller. The code for that is a right PITA to work out, not least because the device DS is poor. I got some code from Claude which kind of hangs together and will try that.The extra complication is that the FT6236 is I2C and I have just SPI, so I am talking to it via the SC18IS604 SPI to I2C converter chip. Fortunately the SC18IS604 has five GPIOs and I am using them to read four buttons (the standard Omron tactile pushbuttons) as an alternative to the touch screen; probably will be more robust too.

author: peter-h
author_rank: Super Contributor
timestamp: October 14, 2025, 10:02:10 am
content: Has anyone here actually used the FT6236?I have it more or less working (via the NXP SC18IS604 SPI to I2C bridge, whose DS is the biggest load of BS I have seen in years) but I am finding that some of the initialisation commands need a huge time gap before the next one can be sent - example:Code:// Config FT6236. This is done blindly; if the chip is dead then nothing we can dobuf = 0x86;// CTRL = 0buf = 0x00;// keep the Active mode when there is no touchingspi2i2c_out(buf,2,0x70);osDelay(100);// This needs ~70ms!buf = 0xa4;// G_MODE = A4buf = 0x00;// Select interrupt polling (INT drops on a valid touch)spi2i2c_out(buf,2,0x70);osDelay(100);// 10ms is OK if no more commands follow

author: peter-h
author_rank: Super Contributor
timestamp: October 14, 2025, 07:43:17 pm
content: OK here we goDue to the crappy data sheets for SC18IS604 and the FT6236, and an amazing lack of example source code (I found some but it looked like half finished garbage) it took a full week to get the touch screen working. The chips need a lot of delays after/between e.g. register loads, and are generally badly described. And driving the latter through the former added to the work, even though the SPI and the I2C were visible on a scopeThis is the typical timing in reading out the touch screen x,y values. I config the 6236 to hold /INT down though the whole touch, and poll that signal via one of the five GPIOs of the SC18IS604. That poll is the first portion of the SPI burst. It is not exactly efficient (it is intended for an interrupt) but it is fine, running under the RTOS as a low priority task, every 100ms. Then when I see /INT=0 I do a burst read of five of the 6236 registers and that is the second portion of the SPI burst.Ignore the ringing on the waveforms. I often don't bother to ground probes properly when just looking whether a signal even existsThe codeCode:// Set or clear the chip select for the SC18IS604// cs=0 to select, cs=1 to deselect the devicestatic void spi2i2c_cs(uint8_t cs){HAL_GPIO_WritePin(ADS1118_AN_PULLUP_EXTERNAL_GPIO_PORT, ADS1118_AN_PULLUP_EXTERNAL_PIN, cs ? GPIO_PIN_SET : GPIO_PIN_RESET);}// Write the buffer, length numbytes, to the SC18IS604.// Returned data goes back into the buffer. Buffer must not be in CCM.// Returns true unless SPI3_DMA_TransmitReceive() returned false.static bool spi2i2c_write_read(uint8_t *buffer, uint16_t numBytes){spi2i2c_cs(0);retcode = SPI3_DMA_TransmitReceive(buffer, buffer, numBytes, false, false, false);spi2i2c_cs(1);return (retcode);}// Read GPIO. Returns 1 byte.// 5 bits, 4 of them are push buttons and 5th is LCD /IRQ// This differs from the crappy NXP DS which contains this// https://peter-ftp.co.uk/screenshots/20251013517655316.jpg// but actually it is this// https://peter-ftp.co.uk/screenshots/202510131619345819.jpg// Exec time 60us, plus the mutex stuff.static uint8_t spi2i2c_read_gpio(void){static uint8_t buf;// Must not be in CCMbuf = 0x21;// read reg commandbuf = 0x01;// select reg 1buf = 0xFF;// dummy valuebuf = 0xFF;// dummy value - gets replaced with the GPIO bytespi2i2c_cs(0);hang_around_us(5);// DS suggests 0.4us min (not actually specced)SPI3_DMA_TransmitReceive(buf, buf, 4, false, false, false);hang_around_us(5);// DS states 0.4us minspi2i2c_cs(1);return buf;}// Write I2C command. Write N bytes to I2C-bus target device.// This uses the SC18IS604 SPI to I2C converter chip.// This function can be used to write any reg in the FT6236: src is the reg #, src is the value.// Len is the actual number of data bytes.// Some huge delay is required after writing some registers.static void spi2i2c_out(uint8_t *src, uint8_t len, uint8_t i2caddr){static uint8_t buf;// Must not be in CCMbuf = 0x00;// read reg commandbuf = len;// select reg 1buf = i2caddr;// i2c address (LS bit is ignored)spi2i2c_cs(0);hang_around_us(5);// DS suggests 0.4us min (not actually specced)SPI3_DMA_TransmitReceive(buf, buf, 3, false, false, false);// send 0x00 & len & addrSPI3_DMA_TransmitReceive(src, NULL, len, true, false, false);// send the datahang_around_us(5);// DS states 0.4us minspi2i2c_cs(1);}// Read I2C command. This is I2C-bus read after write i.e. you make a request and then get the data.// dst: destination buffer// reg: FT6236 register number// len: # of bytes to read back// i2caddr: i2c addressstatic void spi2i2c_read_reg(uint8_t *dst, uint8_t reg, uint8_t len, uint8_t i2caddr){// This part transmits the request *through* the SC18IS604static uint8_t buf;// Must not be in CCM// Send I2C read commandbuf = 0x02;// I2C write and read commandbuf = 2;// number of write bytesbuf = len;// number of read bytesbuf = i2caddr;buf = reg;buf = 0x00;// dummy bytebuf = i2caddr;spi2i2c_cs(0);hang_around_us(5);SPI3_DMA_TransmitReceive(buf, NULL, 7, true, false, false);hang_around_us(5);spi2i2c_cs(1);// Wait for I2C transaction to complete and for the data to arrive in the SC18IS604.// Min delay required is 200us and that is for 1 byte read back.osDelay(2+((len*500)/1000));// Min 2 tick delay, adding 500us per byte// This part reads the data out of the buffer in the SC18IS604buf = 0x06;// SC18IS604 Read Buffer commandspi2i2c_write_read(buf, len+2);// Since the read-back data is at buf+2 onwards, shuffle it backfor (int i=0; i<len; i++){dst = buf[i+2];}}// Check for presence of SC18IS604 chip - used for touch screen LCD. This also sets g_lcd_touch.// If found, initialise it and also do the FT6236 behind it.static void spi2i2c_init(void){g_lcd_touch=false;static uint8_t buf = {0};// 2+16 actually needed, and must not be in CCM// Apply hardware reset pulse to SC18IS604HAL_GPIO_WritePin(STLED316S_DISPLAY_CURRENT_GPIO_PORT, STLED316S_DISPLAY_CURRENT_PIN, GPIO_PIN_SET);// just in caseosDelay(10);HAL_GPIO_WritePin(STLED316S_DISPLAY_CURRENT_GPIO_PORT, STLED316S_DISPLAY_CURRENT_PIN, GPIO_PIN_RESET);hang_around_us(1);// min 125nsHAL_GPIO_WritePin(STLED316S_DISPLAY_CURRENT_GPIO_PORT, STLED316S_DISPLAY_CURRENT_PIN, GPIO_PIN_SET);osDelay(10);// 10ms just in case (data sheet says nothing about this)// Issue Read version function ID and get the ID string into the bufferbuf = 0xFE;// read device ID commandspi2i2c_write_read(buf, 1);osDelay(2);// actually measured: 10us is enough and here we use 1-2msbuf = 0x06;// read buffer commandspi2i2c_write_read(buf, 16);printf("\n%s",&buf);if (strncmp((char*)&buf,"SC18IS604",9)==0)// the "2" offset is a mystery{g_lcd_touch=true;}else{return;// Forget config if ID check fails}// Configure the five GPIOs. Set all four to inputs (power-up default)// The delays are needed! 100us tested.buf = 0x20;// write regbuf = 0x00;// reg 0buf = 0x00;// value 0spi2i2c_write_read(buf, 3);osDelay(2);// Configure bus clock rates register (I2CClk) - 375kHzbuf = 0x20;// write regbuf = 0x02;// reg 2buf = 0x05;// value 5 (max freq)spi2i2c_write_read(buf, 3);osDelay(100); // needs ages for the clock config to stabilise (70ms)// Config FT6236. This is done blindly; if the chip is dead then nothing we can dobuf = 0x86;// CTRL = 0buf = 0x00;// keep the Active mode when there is no touchingspi2i2c_out(buf,2,I2CADDR);// This sends stuff onto the I2C busosDelay(100);// This needs ~70ms!buf = 0xa4;// G_MODE = A4buf = 0x00;// Select interrupt polling (INT drops on a valid touch)spi2i2c_out(buf,2,I2CADDR);// This sends stuff onto the I2C busosDelay(100);// 10ms is OK if no more commands follow// Get and check FT6236 device IDspi2i2c_read_reg(buf, 0xa8, 1, I2CADDR);if (buf!=0x11) return;}// =============== TEST CODEuint8_t touchint = spi2i2c_read_gpio();if ((touchint&0x10)==0)// Check for /INT=0{uint8_t numt;uint16_t xt,yt;uint8_t buf;spi2i2c_read_reg(buf, 0x02, 5, I2CADDR);numt=buf;if (numt==1)// check there is only one touch point active{xt=buf+(256*(buf&0x0f));// collect the x,y as they are spread across two regsyt=buf+(256*(buf&0x0f));debug_thread_printf("touch %3d %3d %3d",numt,xt,yt);gsetcolorf (COL);uint16_t truex, truey;truex=480-yt;// transpose touch controller coordinates to the system actually usedtruey=xt;gcircle(truex, truey, 20, 1U);// draw a filled blob at the touch point}}

author: peter-h
author_rank: Super Contributor
timestamp: October 15, 2025, 08:15:43 pm
content: Does anyone know how to get the FT6236 to stop auto repeat?I can do it in software, by disregarding touches within same or similar x,y as the last one.

author: peter-h
author_rank: Super Contributor
timestamp: October 16, 2025, 09:23:23 pm
content: I solved it with the usual keyboard debounce method.I was wondering about a suitable simple API for the touch screen. The normal ones are hugely complicated, event driven etc. So I just check the controller /INT from a 10Hz RTOS task, and upon the initial touch will load a "touch" flag followed by the two x,y values into an array. The touch flag is an atomic boolean so another RTOS task can poll it, and if found True, can fetch the x,y and clear the flag. Obviously this will work with just one task consuming the touch data, but that's ok, and avoids a mutex.The FT6236 is a funny chip. The "number of touches" can be 0,1,2 for any one touchSo I just retrieve the first touch point x,y and that is super reliable. In my application, nobody is likely to be looking for gestures...Got this email from them:Hi Peter,Honestly many of the registers in focaltech datasheet are useless, Some of them might be wrong, You don't need them for operating and they are not important, You could ignore that.Warm Regards-----Sales EngineerEastRising Technology Co., Ltd.Room 6G Floor 6,Building A1,Zhujiang Square ZhongxinCheng, Longgang District,Shenzhen, 518172, ChinaAt least they are honest