Highly optimized ILI9341 (320x240 TFT color display) library

@Paul, any chance to adopt my changes ?


Droid-Fonts:

https://github.com/FrankBoesing/ILI_9341_Fonts_DROID




https://github.com/FrankBoesing/ILI9341_Fonts_Digital-7
digital-7.regular.png
digital-7.mono.png
digital-7.italic.png

(no commercial use)
 
Last edited:
That's perfectly ok. It's clear to me that you can't include that font.
Users can find it in my repro..

If someone wants to have a special font, I can convert it if the license allows. It requires Linux for conversion - not everyone has a Linux.
 
Last edited:
It requires Linux for conversion - not everyone has a Linux.

In theory, the C code could be compiled for Mac or Windows. It uses only C stdio functions, so it should be portable to any system.

Likewise, the Perl script should be able to work on any system with Perl. It doesn't use/require any Perl libs, just standard built-in features.
 
Google Open Source Fonts

I was looking to see if Arial Rounded Bold MT (my favorite font) was open source (it isn't) and stumbled onto Google Fonts.

Google has 706 open source fonts. Many of them are really nice.

Here's a link to a visual catalog: https://www.google.com/fonts#

Here's a link to GitHub where the TTF files can be downloaded: https://github.com/google/fonts/tree/master/ofl

Nunito-Bold.ttf is the closest to Arial Rounded Bold that I could see.
Paul or Frank... Next time you're converting fonts, It would be great to have this one available. Thanx

Terms of use from the Google Fonts page:
Open Source Fonts
All of the fonts are Open Source. This means that you are free to share your favorites with friends and colleagues. You can even customize them for your own use, or collaborate with the original designer to improve them. And you can use them in every way you want, privately or commercially
 
Very nice link Wozzy, thanks! Maybe lots of people knew about that but I didn't. Thumbs up.
 
Google has 706 open source fonts. Many of them are really nice.

Here's a link to a visual catalog: https://www.google.com/fonts#

Here's a link to GitHub where the TTF files can be downloaded: https://github.com/google/fonts/tree/master/ofl
I converted ALL* of them :)
https://github.com/FrankBoesing/fonts

Usage:
You can find the the needed *.c and *.h files inside the font subdirectories inside /ofl/*
Copy them (including the licence, pls) to your local fonts directory.

*two did not work
 
I refreshed my Arduino/Teensyduino installation and finally got a chance to try out the new font library.

I'll say that the new fonts look really nice, and the display is very responsive.

I noticed two small issues while playing around with the library.
One is that the text background color feature is not working.
The other is that on my installation, tft.println() doesn't seem to send a line feed. I need to set the cursor position to avoid overprinting the previous line of text.

Here's some info on my setup.
OS: Windows 8.1
Arduino_1.6.5_R5
Teensyduino_1.25


I'm seeing this also... Same setup
Does anyone know why tft.println() doesn't provide a linefeed with the new fonts? Does anyone else using the new fonts see this as well?
 
It does handle newline, but not all the fonts have line spacing info. The BDF format isn't clear on this point (or perhaps it is and I just don't understand). So I had to guess a bit from other info, and when that info isn't present the font gets zero for line spacing.

Each size within each font has 2 parameters, line_space and cap_height. They're the last 2 numbers:

Code:
const ILI9341_t3_font_t AwesomeF000_8 = {
	AwesomeF000_8_index,
	0,
	AwesomeF000_8_data,
	1,
	0,
	0,
	127,
	0,
	0,
	11,
	4,
	4,
	2,
	3,
	4,
	10,   // line_space
	10    // cap_height
};

line_space is used for the distance between lines when you wrap around the right edge, or print a newline character.

cap_height is used as an offset from the current cursor position, which is the top left corner due to following the convention from Adafruit's GFX library, to the bottom of a "normal" capital letter. Some letters like 'y' or 'g' or 'O' or 'J' descend below this point, and some can reach above the current drawing position. cap_height is used to know the height of ordinary capital letters without special ascent above or descent below so we can have a sane default that's sort-of a drop in replacement for Adafruit GFX.

If you find a font with wrong numbers in either of these fields, please report is as an issue or pull request on github.

https://github.com/PaulStoffregen/ILI9341_fonts

Ideally you'd figure out the correct numbers for all the sizes in that font, but even one or two is more helpful than none.
 
I'm still not seeing println work with a line feed. I tried adjusting the values you referenced with no obvious changes.

Here's some simple code using 3 couriernew fonts vs default With the default you see 2 lines, with courier new you see one line with the underline at the end.

If there is something else I should be doing please let me know.

Cheers Kb

O.k. with a little more testing I found if the text 'wraps' to the next line then newline seems to behave like a CR, i.e. takes you to the first position of the current line.

I am testing with the color display.
 

Attachments

  • fontTestingSimple.zip
    9.4 KB · Views: 136
Last edited:
Is it possible to add some type of background clearing to the font drawing? Unfortuantely the drawFontBits is a bit elusive to me.

I managed to get a quick and dirty solution using this. Forgive the slightly "non-standard" code as I had to port your library to C in order to make it work with my LPC1769 (horrible memory constraints).



Code:
        int l=0;
	for(l=0; l<xoffset; l++) {
		drawFastVLine(display, origin_x+l-1, display->cursor_y, height, 0x00);
	}
	for(l=display->cursor_x; l>origin_x+xoffset+width; l--) {
		drawFastVLine(display, l, display->cursor_y, height, 0x00);
	}
It's definitely not perfect as there's visible flickering when redrawing identical text, but it looks much better than having overlapping numbers.

This will draw a vertical line in the blank space between created by the "xoffset" as well as the offset between the final cursor position and "xoffset+width". But I can't help to think it would be faster to instead draw the individual pixels rather than switching windows umpteen times.
 
Last edited:
If you write "XXX" at a spot in a foreground color you see it
If you write "XXX" at a spot in a background color you don't see it

Rewrite the prior text in background color to restore the pixels you wrote before with minimal data transfer.

Alternatively rather than a series of lines - send over appropriate rectangles to restore the background.
 
I tried clearing a rectangular area behind the text before drawing but this resulted in very noticable flickering. Unfortunately when the ILI9341 is in SPI mode there is no blanking period so anything that is transferred to the screen is seen immediately. Regardless of how fast you can draw it. I'm currently using the DMA controller in my LPC1769 at 40Mhz to fill rects, so speed definitely isn't the issue there either.

I'll try inverting the characters as you first suggested. I thought of this too but assumed that it would result in the same issue as the background blanking. If the character is drawn all in one rect with the blanking happening at the same time as the font pixels it results in a much smoother transition.

Edit: Inverting the characters worked much better than blanking the entire label at once. Though there is still a lot of flicker. Is the font format documented anywhere in more detail or is it a custom format?
 
Last edited:
Yeah, there's not much to be done about the flicker, given the limits of this low-cost hardware.

I believe the ILI9341 chip does have a pad which can indicate the blanking interval. So far, I've not seen any low cost display boards which bring that signal to the outside world.

The font format is *very* custom. The only documentation is the source code!
 
Yeah, there's not much to be done about the flicker, given the limits of this low-cost hardware.

I believe the ILI9341 chip does have a pad which can indicate the blanking interval. So far, I've not seen any low cost display boards which bring that signal to the outside world.

The font format is *very* custom. The only documentation is the source code!

(Disclaimer: I don't work for these guys. I've just yet to find another company that has the same quality, selection, and price)
The displays at buydisplay.com allow you to select which configuration you would like (3/4 wire SPI, 8080 or 6800 interface). As well as expose all of the necessary pins. (42 in total I believe). They're fairly priced too IMO though the 3 week shipping is pretty terrible. If you have the right parts laying around (SMD resistors and capacitors) you can actually change the configuration of the screen yourself. Though this requires you to add/remove some capacitors/resistors as well as change the solder jumper. I've yet to try this myself. Don't make the same mistake as me and pay for the font chip. While the font chip is a nice idea it's far too slow to use directly, as you have to copy the characters into memory first anyway. It seems like it's more useful for eastern languages/fonts.

http://www.buydisplay.com/default/q...-shield-320x240-serial-module-display-ili9341

I tried extensively to get the blanking period interrupts to work but there is in fact a section of the datasheet which implies they are only functional in RGB mode.

I understand the refresh on these screens in SPI mode is terrible but as I said if the background and foreground pixels are written in the same window it doesn't appear to flicker, instead if just appears as if that character is redrawn. The flicker is specifically because there is a period of time where the framebuffer is in fact blank before the character is drawn. That should eliminate the issue entirely.
 
Last edited:
How about a function to update one character given the old character, the new character, the foreground color, the background color, and location?

This would minimize the flicker because each pixel would be changed to its final value with no intermediate states.

For variable pitch fonts, multiple sizes, etc, the complexity quickly gets out of hand, but for numeric fields, I believe this would work at a cost of 2x the drawing time of a character at most.
 
Last edited:
What I did was to compare the previous value with the updated values and if they needed to change I would. The flicker is very noticeable if you update characters that don't change. It's very strange since the off time is fairly short.

I also attempted to break up the values and only blank characters that changed but my limited skill at c caused a few issues and I gave up, I had some success but it seemed hit or miss at times.

When I get home I can dig it up if anyone wants to play with it, I did 4 char values with a movable decimal, which I think the decimal part broke it sometimes.
 
Back
Top