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
- VCA822 Gain Amplifier Circuit
- LM7171 Offset Circuit
- Gain and Offset Control Filter Circuit
- Dual 5V Power Supply
- Dual 12V TPS65131 Power Supply
- Battery Charging Circuit with BQ24295
- Basic WEB Interface
- IPS Capacitive LCD on an ESP32 (this post)
- IPS LCD, ESP32 with eSPI library and Touch screen
- Final PCB Design for the DIY Waveform Generator
- Custom Design PCBs and How To Get Them Manufactured
- Soldering the PCB
- AD9833 Library and Further Output Noise Reduction
- Arduino BQ24295 Battery Charger Library
- LCD GUI with LVGL on ESP-32
- 3D Printed Enclosure
- Finished DIY generator
The LCD
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.
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:
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/O | Pin name (as in R61529 datasheet) |
1 | XL | TOUCH PIN | I/O | |
2 | YU | TOUCH PIN | I/O | |
3 | XR | TOUCH PIN | I/O | |
4 | YD | TOUCH PIN | I/O | |
5 | GND | GROUND | GROUND | |
6 | IOVCC(1.8/2.8V) | POWER SUPPLY | POWER | |
7 | VCI(2.8V) | POWER SUPPLY | POWER | |
8 | FMARK | Tearing effect output pin to synchronize MPU to frame writing, activated by S/W command | O | TE |
9 | CS/SPI CS | Chip select inpu pin (“Low” enable) | I | CSX |
10 | RS/A0(4 WIRE) | This pin is used to select “Data or Command” in the parallel interface or 4-wire 8-bit serial data interface) | I | DCX |
11 | WR/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 | I | WRX |
12 | RD | 8080 system (RDX): Serves as a read signal and MCU read data at the rising edge | I | RDX |
13 | SPI SDI/SDA | When IM[3]: Low, Serial in/out signal When IM[3]:High, Serial input signal | I/O | |
14 | SPI SDO | Serial output signal | O | |
15 | RESET | This signal will reset the device and must be applied to properly initialize the chip | I | RESX |
16 | GND | GROUND | GROUND | |
17-32 | DB0-DB15 | Data bus | I/O | DATA |
33 | A | LED ANODE | I | |
34 | K | LED CATHODE | I | |
35 | K | LED CATHODE | I | |
36 | K | LED CATHODE | I | |
37 | GND | GROUND | GROUND | |
38 | IM0 | Interface select Pin | I | IM0 |
39 | IM1 | Interface select Pin | I | IM1 |
40 | IM2 | Interface select Pin | I | IM2 |
Note, the LCD’s connector doesn’t have IM3 pin. I believe it is set as 0.
Connection to the ESP32
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 |
5 | GND | GND |
6 | IOVCC(1.8/2.8V) | 3.3V(2.8V) |
7 | VCI(2.8V) | 3.3V(2.8V) |
8 | FMARK | Not Connected |
9 | CS/SPI CS | GPIO13 |
10 | RS/A0(4 WIRE) | GPIO33 |
11 | WR/SPI CSL/SCK) | GPIO32 |
12 | RD | GPIO27 |
13 | SPI SDI/SDA | Not connected |
14 | SPI SDO | Not connected |
15 | RESET | GPIO |
16 | GND | GND |
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 |
37 | GND | 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
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.
Summary
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.
LINKS
Universal Arduino .cpp code: HERE
ESP32 specific, faster solution: HERE