ESP32 TFT display library

User avatar
loboris
Posts: 514
Joined: Wed Dec 21, 2016 7:40 pm

Re: ESP32 TFT display library

Postby loboris » Sat Dec 09, 2017 12:34 pm

@Vader_Mester

I'm planning to implement the capacitive touch driver for a long time. I have the same ER-TFTM035-6 with capacitive touch, just never had a time to do it. I'll try to add it this month.

I have plans to implement a kind of simple transparency for images where you could define a color which is considered as "transparent".
It will require reading the background display data, so all operation will need twice the time to complete.

I'm also working on a special kind of images (sprites) limited to 64x64 pixels which will be the raw RGB bitmaps with transparency.
They will be buffered in memory (or you can have them included in Flash as constant data) and the drawing will be much faster than bmp or jpeg. The functions for moving the sprites will also be implemented.
I think it will satisfy your need for icons with rounded corners.

I don't know why I haven't included the TFT_dispOff/TFT_dispOn functions, I'll do it in next update.

As @kearins mentioned, it is probably better to have the display always on. If you are concerned about "Burn-in and ghosting effects", you could easily add a kind of screensaver (fill screen with random color or objects) combined with some motion detection sensor like HC-SR501, HC-SR505 or AM312.

@kearins
In one of my applications I have light and proximity sensors controlling the display. It is easy to implement, I'm not shure if it would be usefull to have it in this library.
I'll probably add the TFT_backlight(uint8_t val) function which will use PWM to controll the brightness.

User avatar
Vader_Mester
Posts: 300
Joined: Tue Dec 05, 2017 8:28 pm
Location: Hungary
Contact:

Re: ESP32 TFT display library

Postby Vader_Mester » Sun Dec 10, 2017 8:16 pm

Thanks for the answers.

@loboris
Looking forward for the support! I really appreciate the work you've put into this library :)
Reading the pixel data can be done only once... so if you read the color and store it, you can automatically use it every next time without pixel reading...at least I guess.
:roll:
I was thinking about using a VCNL4200, which is a proxy-ALS sensor. I want the display backlight to follow room lighting conditions, like on a smart phone (at night a brighly glowing screen on the wall can be quite anoying).
Also the VCNL4200 is a proxy sensor that can reach up to 1,5m :shock: So if you stand at least that close, the screen should come to life, so you can read it, without touching it, so the touch event Interrupt can be reserved for toggling the room light by touching the screen after a long idle.

Screensaver is the same problem as turning off the screen... with screensaver, you don't see the data on it :lol:

Code: Select all

task_t coffeeTask()
{
	while(atWork){
		if(!xStreamBufferIsEmpty(mug)){
			coffeeDrink(mug);
		} else {
			xTaskCreate(sBrew, "brew", 9000, &mug, 1, NULL);
			xSemaphoreTake(sCoffeeRdy, portMAX_DELAY);
		}
	}
	vTaskDelete(NULL);
}

User avatar
Vader_Mester
Posts: 300
Joined: Tue Dec 05, 2017 8:28 pm
Location: Hungary
Contact:

Re: ESP32 TFT display library

Postby Vader_Mester » Wed Dec 20, 2017 8:57 am

@loboris

I took a deep dive in the code, and some components, on how the fonts and other stuff are being generated, so I came up with some ideas - for now theoretical solutions - to implement transparent icons into the code.

1) It's possible to create an ICON font, and creating the icons as font C-code source files, with associated caraters assigned to them. This will enable us to use icons without backgrounds, as transparent fonts.
I'm trying to make some kind of excel sheet, to get create the HEX data of in icon and manually put together a C-source file for my icons.

2) Implementing the Alpha channels:
I came across this handy little tool to convert images to C source, and essentially preserving Alpha channel data, in A8R8G8B8 formats. (it needs some fiddling in the converter settings though.
Link to the converter tool
This is also able to handle fonts, but not tested it yet.
(in this case, proper 32bit words can be used, for easier reading of pixel data from flash).

Implementing the Alpha channels can be done with this formula:

Code: Select all

r = new Color();
r.A = 1 - (1 - fg.A) * (1 - bg.A);
if (r.A < 1.0e-6) return r; // Fully transparent -- R,G,B not important
r.R = fg.R * fg.A / r.A + bg.R * bg.A * (1 - fg.A) / r.A;
r.G = fg.G * fg.A / r.A + bg.G * bg.A * (1 - fg.A) / r.A;
r.B = fg.B * fg.A / r.A + bg.B * bg.A * (1 - fg.A) / r.A;
fg is the icon color, bg is the background. r is the resulting color. 1.0e-6 is just a really small number, to compensate for rounding errors.
These of course must be multiplied with 255 to get the RGB values. And the actual RGB values can be used as well in the above code.

Since the bacground is never transparent, bg.A and therefore r.A which is the resulting transparency will aways be 1,0 (255).
So the above code will look like this (a bit simpler)

Code: Select all

r = new Color();

r.R = fg.R * fg.A + bg.R * (1 - fg.A);
r.G = fg.G * fg.A + bg.G * (1 - fg.A);
r.B = fg.B * fg.A + bg.B * (1 - fg.A);
Of course. As you can see, if the icon has fully transparent pixels, the result will be the same color as background.
I tested this formula manually doing some painting in GIMP with different transparency values, and this formula actually works.

So before outputting the actual image with transparency, first the color data on the screen where the icon will be must be read, and stored into a buffer (or to occupy less space, probalby it could be done line-by-line), and then pixel the pixel-by-pixel operations of the above formula must be performeed with the image to be output and this will be output to the screen resulting in a nice transparent look, with any background.
(this of course is much easyier if the background is not a picture, but a solid color, so reading the color data from the LCD is not that necessary, as well as if you can read the background image pixels from the flash, that will result in a less occupied SPI bus).

This above is just theory, I did not have time to write any piece of code, but I hope it's interesting.

Vader

Code: Select all

task_t coffeeTask()
{
	while(atWork){
		if(!xStreamBufferIsEmpty(mug)){
			coffeeDrink(mug);
		} else {
			xTaskCreate(sBrew, "brew", 9000, &mug, 1, NULL);
			xSemaphoreTake(sCoffeeRdy, portMAX_DELAY);
		}
	}
	vTaskDelete(NULL);
}

User avatar
loboris
Posts: 514
Joined: Wed Dec 21, 2016 7:40 pm

Re: ESP32 TFT display library

Postby loboris » Wed Dec 20, 2017 7:52 pm

@Vader_Mester

Thank you for the suggestions.

Icons as font can be easily implemented, but the problem is that the fonts are only 1-bit bitmaps, so the icon would be in one color only.
Also, drawing it transparently would be relatively slow as it has to be drawn pixel by pixel.

I'm now testing the following approach:
- icons are defined as raw RGB(A) bitmaps (as Flash constants or read from file)
- TFT driver works with icon structures of position (x,y), global transparency, raw icon buffer pointer and pointer to the icon background buffer allocated on first transparent/alpha write
- when icon is drawn, display RAM area at icon position is read in one dma transaction into icon background buffer, icon content and alpha channel is combined with the background buffer and written to the display in one dma transaction
- icon can be moved on the display, icon background buffer is first drawn at icon current position, then the icon is drawn at new position

It is quite fast (1-3 ms for 32x32 icon), and RAM usage is not to high, 3K for 32x32 icons or 12K for 64x64.

I'm quite bussy lately, I don't think I'll be able to push the working example to GitHub before 2nd or 3rd week of January.

User avatar
Vader_Mester
Posts: 300
Joined: Tue Dec 05, 2017 8:28 pm
Location: Hungary
Contact:

Re: ESP32 TFT display library

Postby Vader_Mester » Wed Dec 20, 2017 8:57 pm

Dude, you are at some great works.
I'm really up for this, and consider this a better option compared to Nextion :)

Code: Select all

task_t coffeeTask()
{
	while(atWork){
		if(!xStreamBufferIsEmpty(mug)){
			coffeeDrink(mug);
		} else {
			xTaskCreate(sBrew, "brew", 9000, &mug, 1, NULL);
			xSemaphoreTake(sCoffeeRdy, portMAX_DELAY);
		}
	}
	vTaskDelete(NULL);
}

fanhuanji
Posts: 9
Joined: Tue Feb 13, 2018 6:55 am

Re: ESP32 TFT display library

Postby fanhuanji » Tue Feb 13, 2018 7:13 am

Very well, this library is easy to use, but i'm now tring to drive a 3-wire spi IPS LCD, and it has to use 9-bit spi(it doesn't have D/C line, and i don't want to use DBI Type B Parallel Interface due to that needs to much I/O ports).
as there has to be a leading bit to indicate D/C(data or command).
but i didn't find a fast way to use the HW-spi to transfer data.and i tried to find some solution.
esp32 idf provids a spi-master lib to use spi, but it can't transfer each byte with its leading bit, if i want to do that. i need to transfer one byte per transcation? it doesn't have the function to trans a byte array with leading bit before each byte? or i did not found it?
if you have some suggestions, thanks.

User avatar
loboris
Posts: 514
Joined: Wed Dec 21, 2016 7:40 pm

Re: ESP32 TFT display library

Postby loboris » Wed Feb 14, 2018 8:43 am

I have some plans to update the library to be able to use 3-wire SPI displays, probably early next month.
At the moment, it is not possible.

fanhuanji
Posts: 9
Joined: Tue Feb 13, 2018 6:55 am

Re: ESP32 TFT display library

Postby fanhuanji » Mon Feb 19, 2018 9:32 am

loboris wrote:I have some plans to update the library to be able to use 3-wire SPI displays, probably early next month.
At the moment, it is not possible.
thanks, but i really want to know how to do that? is
in my former reply i mentioned a ips lcd, that needs me to transfer at least 1'229'760bytes pixel data per second. if i transfer one byte per transcation, it is obviously not fast enough, and if i use 80M or 40M spi , i can theoretically transmit (80M/9bit*8bit=71'111'104bytes) or (40M/9bit*8bit=35'555'552bytes)per second, which fairly enough. so the problem is i have no idea to transmit byte array with the leading bit.
so if you have some idea to do that transmission faster ,please tell me if convenient,thank you :)

User avatar
Vader_Mester
Posts: 300
Joined: Tue Dec 05, 2017 8:28 pm
Location: Hungary
Contact:

Re: ESP32 TFT display library

Postby Vader_Mester » Wed Feb 21, 2018 8:04 am

The limitation to SPI clock is the LCD controller itself. Normally the maximum SPI clock is 40Mhz, 80Mhz is too much and will not meet the timing requirements of the LCD controllers.

You can use DMA with the SPI.
I'm currently trying to figure that one out. I'm gonna need 4 DMA buffers, 2 small buffers for the command part, and 2 larger buffers to the image data.
(You need 2 buffers for each, so that when one buffer is being written or being read from the other buffer can be manipulated.)
Once you fill both command and data buffers, then a simple SPI transaction should initiate the send, with minimum CPU load, just the DMA doing the data transfer.

Normally it is not the transfer speed that's the problem, it's more like the induvidual transactions that takes time, and data processing calculations in the CPU slowing the thing down.

Vader[BEN]

Code: Select all

task_t coffeeTask()
{
	while(atWork){
		if(!xStreamBufferIsEmpty(mug)){
			coffeeDrink(mug);
		} else {
			xTaskCreate(sBrew, "brew", 9000, &mug, 1, NULL);
			xSemaphoreTake(sCoffeeRdy, portMAX_DELAY);
		}
	}
	vTaskDelete(NULL);
}

User avatar
loboris
Posts: 514
Joined: Wed Dec 21, 2016 7:40 pm

Re: ESP32 TFT display library

Postby loboris » Wed Feb 21, 2018 9:06 am

fanhuanji wrote:
loboris wrote:I have some plans to update the library to be able to use 3-wire SPI displays, probably early next month.
At the moment, it is not possible.
thanks, but i really want to know how to do that?
It shouldn't be difficult, I've did some tests and it should work. Basically, only the 9-bit spi transfer has to be enabled.
Unfortunately, at the moment, I don't have the 3-wire spi display to fully test it.
In my library, I'm using non-transactional approach to transfer the data to the display, so the transfer occurs at the full spi speed.

Who is online

Users browsing this forum: No registered users and 8 guests