IPS Capacitive LCD on an ESP32 (DIY Generator Part 8)

After a long wait, I finally have received a 3.5-inch LCD Display with a capacitive touch panel. The LCD with a touch interface is probably the last thing which needs to be done before whole generator’s project could be brought to the last phase of designing and building a finished tool.

Links to project’s all posts

  1. VCA822 Gain Amplifier Circuit
  2. LM7171 Offset Circuit
  3. Gain and Offset Control Filter Circuit
  4. Dual 5V Power Supply
  5. Dual 12V TPS65131 Power Supply
  6. Battery Charging Circuit with BQ24295
  7. Basic WEB Interface
  8. IPS Capacitive LCD on an ESP32 (this post)
  9. IPS LCD, ESP32 with eSPI library and Touch screen
  10. Final PCB Design for the DIY Waveform Generator
  11. Custom Design PCBs and How To Get Them Manufactured
  12. Soldering the PCB
  13. AD9833 Library and Further Output Noise Reduction
  14. Arduino BQ24295 Battery Charger Library
  15. LCD GUI with LVGL on ESP-32
  16. 3D Printed Enclosure
  17. Finished DIY generator


This screen was bought from AliExpress. The main reason why I have chosen this LCD is that it by default has capacitive touch. In my opinion, capacitive is better than resistive touch. Furthermore, the capacitive panel is symmetric, and extends a bit over LCD area, so it could be easily integrated into a device’s enclosure or it even could be mounted flush with the enclosure’s surface.

IPS LCD D3.5LG07-3V TL35024-02 with Capacitive touch back side

According to the seller, the LCD has IPS panel, which has great viewing angles. Also, it has resolution of 480×320 which might be a bit of a problem when used with not so powerful MCU such as ESP32. It has 8080 (MIPI-DBI Type B) interface for sending image data to the LCD. It also should have an SPI connection, but I haven’t tried it, and what is more, according to the LCD driver’s datasheet, it doesn’t support sending image data through the SPI (only commands for setting up the display).

As mentioned in the description it can be interfaced by 8 or 16 data bit lanes and because ESP32 has a few available pins, 8-bit interface was used. Through this interface you can send 16, 18 or 24 bits per pixel which means that you can get up to 16M of colors from this LCD (provided you have enough of the MCU resources).

The back of the LCD you can find two lines of markings: D3.5LG07-3V and JL35024-02:

IPS LCD D3.5LG07-3V with Capacitive touch back side

Driver and features

The LCD has integrated R61529 driver. This driver has its own frame buffer for 480×320(x24bit) pixels. This means that you don’t have to constantly write pixel data to keep image on the LCD. It is enough to write the data once, and the driver will refresh the pixels on the LCD with ~60 Hz rate. Of course, you will have to write data when you want to change the image shown 😀

Although, I still haven’t tried, but the driver supports writing image data to the selected part of frame buffer. This means, that it should be possible to update only small frame parts when needed instead of writing full frame which might take a lot of MCU time.

The Pinout

The LCD pinout is shown below. It is table take from the sellers page, with some added information from the R61529 datasheet:

Pin No.Pin Name (as seller provided)Description (as seller provided)I/OPin name (as in R61529 datasheet)
8FMARKTearing effect output pin to synchronize MPU to frame writing, activated by S/W commandOTE
9CS/SPI CSChip select inpu pin (“Low” enable)ICSX
10RS/A0(4 WIRE)This pin is used to select “Data or Command” in the parallel interface or 4-wire 8-bit serial data interface)IDCX
11WR/SPI CSL/SCK)-8080 system (WRX): Serves as write signal and writes at the rising edge
-4 line system (D/CX): serves as command or parameter select
12RD8080 system (RDX): Serves as a read signal and MCU read data at the rising edgeIRDX
13SPI SDI/SDAWhen IM[3]: Low, Serial in/out signal
When IM[3]:High, Serial input signal
14SPI SDOSerial output signalO
15RESETThis signal will reset the device and must be applied to properly initialize the chipIRESX
17-32DB0-DB15Data busI/ODATA
38IM0Interface select PinIIM0
39IM1Interface select PinIIM1
40IM2Interface select PinIIM2

Note, the LCD’s connector doesn’t have IM3 pin. I believe it is set as 0.

Connection to the ESP32

DIY LCD 40pin adapter breakout board

For initial testing the ESP32 development board was connected to the LCD (through a DIY 40pin break-out board using UV method) as follows:

LCD Pin No. Pin Name (as seller provided) ESP pin
1 XL Not connected
2 YU Not connected
3 XR Not connected
4 YD Not connected
6 IOVCC(1.8/2.8V) 3.3V(2.8V)
7 VCI(2.8V) 3.3V(2.8V)
8 FMARK Not Connected
10 RS/A0(4 WIRE) GPIO33
12 RD GPIO27
13 SPI SDI/SDA Not connected
14 SPI SDO Not connected
17 D0 GPIO16
18 D1 GPIO17
19 D2 GPIO18
20 D3 GPIO19
21 D4 GPIO21
22 D5 GPIO22
23 D6 GPIO23
24 D7 GPIO25
25-32 D8-D15 Not connected
33 A 3.3V(2.8V)
34 K GND
35 K GND
36 K GND
38 IM0 GND
39 IM1 GND
40 IM2 3.3V(2.8V)

Please note, that ESP32 was powered from 2.8 volts, so all 3.3V pins on the development board were actually 2.8V. This voltage (2.8V) was used because it is the recommended power supply voltage for the LCD, but it also can be powered with up to 3.3 volts.

Speed Problems

LCD display connected to the ESP32 development board

So, first thing to do after connecting LCD to the ESP32 was to write a small code sketch with Arduino core. The code can be found at GitHub. This snippet should work with any Arduino device as it uses standard Arduino functions. Just the speed with slower devices might be an issue as it was with the ESP32.

There you can find a long LCD initialization sequence. It was taken from a file given by the seller. Without it, I think, it would have been a lot of work to even start up the device 🙂

Using standard Arduino functions such as digitalWrite() to manipulate data on the GPIOs, I have managed to get around 700 kHz of write speed. As I was writing 24 bits per pixel of data, the frequency of 700 kHz translates to approx. 1 Hz of screen refresh speed. Which is clearly noticeable as the frame data is updated from the first to the last pixel:

Direct register access

A better result can be achieved by using GPIO registers directly. In this case the code won’t be suitable for other MCUs. By using GPIO_OUT_W1TS_REG to write 1s to GPIO and GPIO_OUT_W1TC_REG register to clear GPIOs (set 0), I have managed to get around 3.3 MHz of write speed. Moreover, the function which writes data to the GPIOs need does some logical data manipulation before physically setting up the GPIOs. So, if all pixels need to be in the same color, it is possible to set the data bits with precalculated value (instead of doing the calculations before each data write) thus speeding writing up to around 10 MHz (as was measured with a multimeter). But this write solution is convenient only when all data bytes are the same and if not – only slower writes are possible (at least at the time of writing this post).

The code with direct register writes is also available on GitHub

The third option to try is I2S interface. As it is written in ESPs datasheet, I2S interface can be set up as LCD interface. In such case the write speed should be even higher, but this testing is left for another time.


To sum up, this little LCD is great addition to the DIY generators project. Even now, with direct GPIO data writes, it is useable for the project, although I will still try to tweak the data write speeds. Also, the LCD need a nice graphical user interface and of course, I still need to test out the touch panel.


Universal Arduino .cpp code: HERE

ESP32 specific, faster solution: HERE

A tutorial for LVGL.

Subscribe to a newsletter!

Was this page helpful?