Arduino – Interfacing with a capacitive touch screen – pt2

Previously – an overview of the particular screen I’m using

In this post, I’m going over how to interface with the capacitive touch functionality. As previously mentioned, you have to interface with SD, Display, and Touch separately

For this, I will be using an arduino mega compatible device. But any arduino with IIC support should work just fine.

 

Interrupt pins


It is extremely important that if you are using interrupt based touches, that you tie the CTP_INT pin to an interruptible pin on the arduino.

Initially I didn’t remember that only certain pins can be used for interrupts, and so I picked a pin at random that couldn’t be used. This lead to me going down a rabbit hole learning how oscilloscopes work, and thinking that the internal pullup resistor must be too low of resistance and that the touchscreen was actually wanting 3.3v and that I would have to use a logic level shifter to get it to work. Use the right pins.

The documentation has a list of which pins can be used on which arduino

This is a copy of the table 11/24/2025. The documentation is the source of truth, but this is for prevention of dead links

Board Digital Pins Usable For Interrupts Notes
UNO R3, Nano, Mini, other 328-based 2, 3
UNO R4 Minima, UNO R4 WiFi 2, 3
UNO WiFi Rev2, Nano Every All digital pins
Mega, Mega 2560, Mega ADK 2, 3, 18, 19, 20, 21 pins 20 & 21 are not available to use for interrupts while they are used for I2C communication; they also have external pull-ups that cannot be disabled
Micro, Leonardo 0, 1, 2, 3, 7
Zero 0-3, 5-13, A0-A5 Pin 4 cannot be used as an interrupt.
MKR Family boards 0, 1, 4, 5, 6, 7, 8, 9, A1, A2
Nano 33 IoT 2, 3, 9, 10, 11, 13, A1, A5, A7
Nano 33 BLE, Nano 33 BLE Sense (Rev 1 & 2) all pins
Nano RP2040 Connect 0-13, A0-A5
Nano ESP32 all pins
GIGA R1 WiFi all pins
Due all digital pins
101 all digital pins Only pins 2, 5, 7, 8, 10, 11, 12, 13 work with CHANGE.

Wiring


The example code I followed uses the interrupt pin, and doesn’t do anything special about the reset.

So we will be wiring the CTP_INT to pin 2. We’ll hook up the SDA and SCL pins to their respective positions.

For CTP_RST it can be used for resetting the touchscreen. It needs to be held high for the touchscreen to be usable. Generally it can just be tied to 5v, but if you run into problems, you could pull it to ground then back to 5v to reset it.

 

Code


The code is pretty basic. Because this is just a sample sketch to understand how the touchscreen works, I created this with Arduino IDE instead of doing something complicated like a PlatformIO project.

Start by installing the library in the library manager – RAK14014-FT6336U by RAKWireless

Once installed, there is an example project, but it didn’t compile for me. So this is the code I ended up with.

The driver library has some methods for weights, but they don’t seem to be supported with this screen.

The driver also has some methods like touch 1 id, and touch 1 event. But looking into them, they’re just doing some bit shifting of the x/y coordinates. There’s nothing I’ve read in the datasheet that leaves me to believe there are any ids or event ids. And other libraries I’ve looked at don’t have the functions. So I’ve decided to ignore them.

The driver says it supports gesture recognition, but I haven’t found any evidence of them being supported. And I don’t have any specific usage planned for gestures, so I haven’t looked too closely.

Also of note is write_time_period_enter_monitor(int seconds) which can be used to indicate a number of seconds without input for the screen to go into monitor mode. This reduces the number of checks per second it makes for touches, and makes it start ignoring commands on the i2c bus, which will reduce the power consumption.

 

For my purposes, I intend to just have a simple UI with some buttons to tap.

The screen supports 2 touches at a time. If the first touch ends, then the second touch moves to being the first touch, and the number of touches decreases. Additionally the second touch x,y is now 4095.

So for button pressing, you could do something as simple as if the button press lasts too long, or if the x/y coordinates move too far from their starting point, then cancel the press. Otherwise when the number of touches decreases, then decide if your x/y coordinate matches any of your UI elements.

If you want to just ignore multi-touch, then if the number of touches ever goes to 2, just cancel the touch.

 

For dragging, you would want to use the start of a touch (number of touches goes from 0 to 1) to determine what UI element is being touched, and then make changes to that element until the number of touches goes down (or up if you’re ignoring multi touch, which on a screen this size is easy to do)

 

Unfortunately as I cover later, unless you’re using a 32 bit microcontroller to use something like TFT_eSPI/LVGL you have to roll your own UI. draw some rectangles, put some text on them, and know what the coordinates are.

I feel like there’s probably some room for making a really simple UI library that just has some button classes with draw and hit test methods, that could make things a little simpler, but its hard to commit to anything when 32 bit microcontrollers are so inexpensive, and someone’s done the hard work there

Leave a Comment

Your email address will not be published. Required fields are marked *