TFT 3.5" display (320x480) ILI9488 or HXD8357D?

KurtE

Senior Member+
I know some of us have played around some with the 9488, which has twice as many pixels as the ILI9341, but takes 3 times as many bytes to be transferred over SPI to update the display.

SO I was curious about the Adafruit display: https://www.adafruit.com/product/2050
Which uses the HXD8357D, which at least from the Adafruit description sounds like we can still do 16 bit pixels... So I ordered one...

Actually one from Amazon: https://smile.amazon.com/320x480-Touchscreen-Breakout-MicroSD-Socket/dp/B00TIYUWNY

Wonder if anyone else has played with these? Who knows may have to make a version of our ..._t3 library work with these to see how well they work out.

For now this thread is probably a place holder until I receive it early next week.
 
Yes, I have one of these in a project using a Teensy 3.5

I'm actually using the Adafruit_ili9341 library with it, modifying the Adafruit_ILI9341.h file to the proper resolution... it actually works despite the ili9341 specific code...

If I recall correctly,I read this was possible somewhere in this forum, despite protest that it couldn't possibly work... the "proper" library wouldn't compile. This was several TD versions ago that I last flashed the firmware in that device. E52EB853-133C-4C6B-A2A2-CC9D6E346B91.jpeg
 
The graphicstest sketch compiles for me for teensy 3.5. I'll try this library next time I do any thing to the device.
 
There looks like a few different starting points to play with :D

@mjs513 (and others) - I am trying to decide on one of three different courses of action.
a) It's own library, again probably based off of one of our others.
b) Add it as a sub-class of my(our) ILI9341_t3n library
c) Add it as a sub-class of our ILI9488_t3 library.

Actually I am trying do decide to start from b) or c)... Can always decide to split off.

Looking at the Adafruit code, it looks like there is not a lot of diff difference in their code versus the ILI9341... Yes a couple of constants for Width and Height. Plus some difference in the bytes that send for Init...

Whereas our differences to ILI9488_t3 is a little more as the ILI9488 code deals with 18 bit pixels where we need to send 3 bytes instead of 2... But again not difficult Could make one or a couple of methods to be virtual, so the
output 16 bit pixel code would be different.

Also of course the DMA code would be different, for similar reasons. That is the 9488 code during DMA translates the Frame buffer contents into the 3 byte pixels... So again in some ways easier to start with 9341 code, BUT another interesting aspect of the 9488 code is that we allowed for the Frame buffer to be 8 bits per pixel (with a palette) which allowed us to also have Frame buffer on T3.5/3.6...

So again wondering which way to go.

Also while hacking on some of this code, may again look at how hard it would be to keep a rough estimate of the areas of the frame buffer that changed since the last updateScreen and have the option to say only update the bounding rectangle area of areas that the data changed... Sort of like what I manually did for the faster RPM gauge code... Wonder if it would be worth it.

And if so maybe add the code for the one shot DMA update to be able to constrained as well to either the dirty area or the clip rectangle...

As always too many distractions :D
 
@KurtE

Was thinking about using your b) or c) options. In post #7 looks like @Slapstick starts with something that looks like the code from ILI9341_t3. One of the things I want to check was if the ILI9341_t3n or the ili9488 code would run without mods more out of curiosity. One on the posts said that ILI9341 would run - almost like the 9488 code does run on the 9341 display. Going over the datasheet looks like it would support 18bit pixels as well.

Bounding box sounds like fun - it should work. One of the graphics programs I ported uses bounding boxes to update screen areas. :)

Should get mine tomorrow afternoon and going to check a few things out. Will let you know.
 
@mjs513 - Will be fun to try out the stuff when the Adafruit display arrives...

In the Mean time, I spent some time discussing SPI versus buss output in another thread, and mentioned some about maybe using the scroll region support in some (most) of the display chips...

And sort of remember I played some with this a few years ago, as I found up on the Adafruit forum: https://forums.adafruit.com/viewtopic.php?f=47&t=56039

So I thought I would try it out on the ILI9488 and 9341 display...

So I hacked up a sketch to setup the region with a couple lines of text on top and a few on the bottom...

I sub-classed the display drivers to get access to the protected members...

Sort of fun playing, but shows some usage of scrolling...

Note: It was sort of setup originally for 9341... But currently setup for 9488... Also I have the code slowed down to delay(100) between text line outputs. WIthout it, it just shows up as a blur :)

Some time along with coming up with being able to use fonts, it would be nice if we could have a set of defines for colors.

Something like: COLOR565_RED or TFT565_RED ... Which would be common to all of the ones who use the 565 color scheme... And would make converting from one to another easier...
 

Attachments

  • Scroll_Test_ILI9341_t3n-200209a.zip
    1.4 KB · Views: 95
@KurtE

Cool have to try it on the HX8357 just out of curiosity but I promise I wont tell you - let you have the fun on Monday. :)

You are right about all the displays using the same colors would be good just to have one set. Do we really need to use Color56_xxxx though can't we just use the color. Which ever display we are using should take care of 565 or other format change that that library uses. From what I remember aren't all the displays using 565 except for maybe the KeDei which I don't really want to spend any time on :)
 
For Color defines etc feel free to use any part of my code that might help you. I’ve done a lot of work on displays and graphics library stuff (most of it not on github yet). Colours based on standard set of web colours. Includes a python script for generating your own color sets in whatever format you need:

https://github.com/projectitis/tilemap/blob/master/Bitmap.h

Part of tilemap library: https://github.com/projectitis/tilemap

P.s. a whole lot more than just color defines there - methods for fast blending, converting between color formats etc :)

My own libraries mostly use 888 colour format (or 8888) and convert silently to whatever underlying format the display uses (user doesn’t care). I’m working on support for a whole bunch of different displays (I own 7 and have 2 more on the way).
 
Last edited:
Thanks Projectis...

Long term, I think adding all of that would be great. Right now just playing with the basics. Each of the current drivers like ILI9341_t3, ILI9488_t3, ST7735_t3/ST7789_t3, RA8875, all have some real basic defines for colors, like:
BLACK, WHITE, RED, GREEN, BLUE, YELLOW... And they all have them prefixed by their library names, like: ILI9341_WHITE, ST7735_WHITE, ILI9488_WHITE which have the same value...

So for all of our simple sketches that we are playing with to get more compatibility between them or the like, it is sort of pain. Could probably reduce this if I changed some of the example code to do stuff like:
tft.color565(0xff, 0, 0) for RED... but...

Again just sort of playing around. My HX... Adafruit display should maybe arrive later today, so I am curious about how well it will perform as compared to the ILI9448 display, especially using SPI... I expect the full screen updates will be about 1.5 times faster as will only be transferring 2 bytes per pixel instead of 3... But there are always details like do they both support the same SPI speeds...

Nice thing about the ILI9488 displays is you can buy some of them cheap on EBAY (maybe about $15-$25 shipped to US)... Probably less if you buy multiple and it combines shipping costs. And so far I have only found the Adafruit one of the HX... Which is considerably more expensive.
 
@Projectitis
Thanks for the link really cool stuff - gives me ideas.

KurtE said:
So for all of our simple sketches that we are playing with to get more compatibility between them or the like, it is sort of pain. Could probably reduce this if I changed some of the example code to do stuff like:
tft.color565(0xff, 0, 0) for RED... but...
Been playing around with opengl on the Teensy so been learning about how colors are specified:
1. glColor3ub(255,0,0) for RED, which is basically what we have for CL(……..) function
2. glColor3f(1.0, 0,0) for RED (really not a fan of this seems GPUs like it), also for me not intuitive with our displays
3. saw someplace by name but can't find the right format now.

Guess the call to tft.color565(xx,xx,xx) would return the color value that we would use for drawing primitives etc?

Was also thinking about that we could use the ILI9341_fonts.h file to include a standard set of color defines that we currently use but with the display name attached?

Just thinking out loud now :)
 
I have an ILI9341_fonts equivalent called “PackedBDF” that attempts to remove itself from specific displays. It’s the exact format as the original font, but I’ve added support for smooth fonts (blended pixels). Feel free to take a look at that, too :)

For drawing primitives, I do something like:
tft.setLineColor(255,0,0);
tft.setFillColor(128,64,0);
tft.drawRect(10,10, 50,30);

Colours specified in 888, but converted internally to whatever the TFT uses. This way you (as the dev, or artist) are always working with RGB, and the code handles conversion.
 
No reason to be sorry - you know how many times I've played the catch-up game - always wind up lost :)
 
Colours specified in 888, but converted internally to whatever the TFT uses. This way you (as the dev, or artist) are always working with RGB, and the code handles conversion.
That also makes porting (between displays) easier.

For example, if one wants to use ILI9341/ILI9488 in 9-bit parallel mode (for 18-bit color, or 6 bits per component), one can use the non-contiguous AD_B1_00-11 pins on Teensy 4.0. Each 8 or 16-bit source color is mapped to two 16-bit words, with the bit order matching GPIO6 bits 16..31. A 1k look-up table can be used to map 15/16-bit color to 18-bit color in the funky GPIO6 bit order; or a 256k LUT (65536-entry palette) if you want to use some other colorspace in your 16-bit framebuffer.

It gets pretty wonky at the low level, but the high-level interface is basically the same as the one you showed.

For palette modes, allocating/setting palette entries should use that also; i.e. color = palette.allocate(R,G,B) etc. In some cases, it might be useful to allow color definition via YCbCr (via transformation to 24-bit RGB first) -- I'm thinking of things like procedurally generated colors; YCbCr is much easier to generate good color sets in.
(Personally, I do prefer the single 24/32-bit parameter form -- 0xOORRGGBB, but that's just because I used to do a lot of HTML and CSS stuff, where colors are defined using #RGB or #RRGGBB in hexadecimal also. For YCbCr, on Teensy 4.0, I'd probably use a float interface: Y from 0.0f to 1.0f, and Cb and Cr from -1.0f to +1.0f. Again, that would make procedural color selection easier, that's all.)

Similarly, artwork masters should be in whatever editor format (GIMP, Photoshop) in multilayer form, then converted to 24-bpp PNG images (true alpha even for transparent pixels, lossless), and then packed/converted for use by each particular display/microcontroller combination. I use NetPBM tools on Linux to script this, but lots of other toolkits work here too.
For scalable vector graphics, SVG is an excellent format. I personally use Inkscape masters, export optimized, and fine-tune them by hand. Of course, SVG is easy to convert to 24-bpp PNG images, to use the same pipeline, if you use the SVG masters to generate pixmap images.
 
This all sounds great... But not sure exactly where all to take this. That is most all of our stuff has a common ancestry with the Adafruit drivers. The big exception is the RA8875.. Mainly some of us got into that one to get it to work on T4.

So again only talking for myself, I mainly have been just trying to keep compatibility with the existing library and make some opportune changes that make them more compatible with each other....

Our ILI9488_t3 still just uses 16 bit colors, which we then upshift to 18 due to SPI limitations on this device. We did add a simple Palette mode for the frame buffer as we were trying to port code over from my ILI9341_t3n including frame buffer and did not have enough memory for T4B1, so added an 8 bit Frame buffer. The code is sort of hacked up to when you output a color it sees if it is already in the 256 entry Palette if not adds it and then stuffs out the index into frame buffer. There is a way to short cut some of this and say I am writing out the index so you don't have to translate... Now with released T4 we can and think we turned off palette and have 16 bit values in Frame buffer... But I think we left in the 8 bit mode as well as to allow it to work on T3.5 and 6...

There are many different ways to go with this. But then there are already several different sets of display libraries out there like GFX, Sparkfun has theirs, ...

Will be interesting, to see what everyone ends up doing.
 
Some great points. I'm a big fan of abstracting the hardware layer so that the developer can just use the colour set (s)he is used to. And yep, it means porting to different displays does not generally require any changes to the actual project code :)

With regard to setting colours in YCbCr or other modes (HSV), it's usually easy enough to use a helper to convert to RGB first, so no problem there.

Palette's a are little tricky. Allocating colours to a palette is fine, but I think the user needs to be aware of palette colour mode when they are painting/drawing. Even a robust algorithm to match any RGB colour to the closest palette entry is going to be costly in terms of CPU, so the user needs to paint directly with palette indexes in my view. So you wouldn't use this with palette mode:
tft.setLineColor(255,0,0);
tft.setFillColor(128,64,0);
tft.drawRect(10,10, 50,30);

You'd use something like what you have above:

lineColor = tft.palette.allocate(255,0,0);
fillColor = tft.palette.allocate(128,64,0);
tft.setLineColor(lineColor);
tft.setFillColor(fillColor);
tft.drawRect(10,10, 50,30);

But I think we're hijacking KurtE's thread :)
 
Back
Top