Go Down

Topic: New graphics library for NodeMCU (ESP8266), ESP32 and SPI based TFT displays (Read 15041 times) previous topic - next topic

bodmer

Dec 23, 2016, 04:22 pm Last Edit: May 20, 2017, 03:20 am by bodmer Reason: Added ESP32 support
UPDATE on 22/2/17: The TFT_ILI9341_ESP library has now morphed into a new library that supports multiple display drivers. The new library TFT_eSPI can be found here. See also post #63. The library currently supports the ILI9341, ILI9163, ST7735 and S6D02A1 based TFT displays with SPI interface.


I have ported my TFT_ILI9341 graphics library to the NodeMCU.  A copy can be found on GitHub.


The library support use of the hardware SPI interface, example connections for a NodeMCU board with a 2.2" 320x240 display are:

Display SDO/MISO to NodeMCU pin D6
Display LED      to NodeMCU pin VIN (5V)
Display SCK      to NodeMCU pin D5
Display SDI/MOSI to NodeMCU pin D7
Display DC       to NodeMCU pin D3
Display RESET    to NodeMCU pin D4
Display CS        to NodeMCU pin D8
Display GND      to NodeMCU pin GND (0V)
Display VCC      to NodeMCU pin VIN (5V)

Performance is quite reasonable with a 40MHz SPI clock when running the graphicstest sketch:

Benchmark                Time (microseconds)
Screen fill              161973
Text                     49593
Lines                    320578
Horiz/Vert Lines         17827
Rectangles (outline)     13985
Rectangles (filled)      333103
Circles (filled)         187493
Circles (outline)        210565
Triangles (outline)      70579
Triangles (filled)       212988
Rounded rects (outline)  88425
Rounded rects (filled)   429151
Done!

The library is based on (but does not use) the Adafruit_GFX library. Extra fonts have been added that are encoded for fast rendering. Text and numbers can also be right/left/centre justified to assist in creating neat displays.

Examples are included which show how to use the features.

Report any bugs here.

Formerly Rowboteer (now a broken user profile!)

bodmer

Amazingly the the ILI9341 based display I have seems to work OK with a 160MHz SPI clock (not recommended though!) ...

If you want to try this change the CPU frequency in the IDE to 160MHz and set the SPI frequency in the library's User_Setup as follows:

 #define SPI_FREQUENCY 160000000


Results then are that the ported UTFT_demo completes in 1.2s and graphicstest completes in 1.12s:

Benchmark                Time (microseconds)
Screen fill              81895
Text                     28177
Lines                    180730
Horiz/Vert Lines         9173
Rectangles (outline)     7297
Rectangles (filled)      168457
Circles (filled)         101677
Circles (outline)        121312
Triangles (outline)      39352
Triangles (filled)       111733
Rounded rects (outline)  50062
Rounded rects (filled)   219447
Done! Total = 1118586


Formerly Rowboteer (now a broken user profile!)

david_prentice

Ah-ha.   I generally find that ARM M3 or M4 go faster than the TFT on 8-bit parallel interface.

Are you really going at SCK = 80MHz?
One byte is going to take 100ns.   

Quote
18.3.4 Display Serial Interface Timing Characteristics (4-line SPI system)
TFT Instruction write cycles are 100ns.  Read cycles 150ns.

Quote
18.3.1 Display Parallel 18/16/9/8-bit Interface Timing Characteristics (8080-Ⅰ system)
Write cycle = 66ns.  Read cycle is 450ns.

In practice,  I have found that read cycles are often slower than the datasheet suggests.   Yes,  ILI9341 is a lot faster than some "other" models.

David.

bodmer

@david_prentice

Yes, it dawned on me that the SPI frequency is set to 80MHz even though the CPU clock has been upped to 160MHz.

So the results in post#1 are with 160MHz CPU and 80MHz SPI clock. Trying to set the SPI clock to 160MHz actually only sets it to 80MHz.

Very aggressive tests indicate that 80MHz SPI clock is marginal and pixels etc can get "lost" at that frequency, so 40MHz SPI is the highest my setup works reliably in this situation.
Formerly Rowboteer (now a broken user profile!)

ZinggJM

First I got a Christmas Tree, now I get even a BIG Christmas Present! Thank you.

Would it be easy to adapt it to support 9 bit SPI transfer? There seem to be quite a few TFTs without C/D pin.

Merry Christmas and a Happy New Year to all of you.

Jean-Marc
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

ZinggJM

I don't understand how and where the member variable:

SPIClass *_SPI;

gets initialized.

Somehow it works, and it works extremely well, speed is impressive.

I tried to enhance the SPI class of the ESP8266 package. But adding additional member values does not work, I got exceptions on access to these member variables. So I created a new class SPI9Class, and modified a copy of TFT_ILI9341_ESP to use this class:

SPI9Class * _SPI9;

but it looks like the pointer gets set to the standard SPI instance of SPIClass.

Strange.
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

bperrybap

The library needs a license file.
The code says it is a derivative work from the adafruit code. If so, then it must retain the original copyrights and license of that code.
I'd recommend putting the removed license file back in the repository as well as the source code file copyright and license information back at the top of the source modules.
Even better would be to do a fork from the original adafruit code and then apply your changes to your repo.
That way everything is properly tracked back to the original work.
It also might create the potential to do pull requests or merges back to the original adafruit code.

--- bill

ZinggJM

The library needs a license file.
The code says it is a derivative work from the adafruit code. If so, then it must retain the original copyrights and license of that code.
I'd recommend putting the removed license file back in the repository as well as the source code file copyright and license information back at the top of the source modules.
Even better would be to do a fork from the original adafruit code and then apply your changes to your repo.
That way everything is properly tracked back to the original work.
It also might create the potential to do pull requests or merges back to the original adafruit code.

--- bill
That's why I like the concept of "Help Yourself Software", that I try to introduce.

It is more open than Open Software, but with its true meaning, give away and take, without obligations.

Jean-Marc Zingg, 27.12.2016
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

bodmer

@bperrybap
Here's a link to the Adafruit library that this is derived from, no license file has been removed.  The original Adafruit MIT licence text has been retained in the main .cpp and .h files, see header for location.
Formerly Rowboteer (now a broken user profile!)

bperrybap

It appears to me that this library is a mushing together of two adafruit libraries (Adafruit-GFX-Library and Adafruit_ILI9341) with some tweaks & modifications to create a single library that does not depend on either original library.
If so, it makes it a derivation subject to both library's copyrights and licenses.

Your original post says:
Quote
The library is based on (but does not use) the Adafruit_GFX library.
but given the similarity of the code and and a few of the comments in the .cpp and .h files
like:
Quote
This library has been derived from the Adafruit_GFX
  library and the associated driver library. See text
  at the end of this file
and
Quote
// Fill a triangle - original Adafruit function works well and code footprint is small
it appears that it is based on (as in uses code from Adafruit_GFX library) but then does not depend on that library.

Was any code taken from Adafruit-GFX-Libary ? (It does look like it)

If so, the library is missing the required copyright notice from the Adafruit-GFX-Library .cpp file.
It would also be helpful to provide links back to the repositories for the original code.

Regardless of the library's heritage, it is always best to have a clear license file included in the top level directory.
Adafruit-GFX has one, but Adafruit_ILI9341 doesn't (I'll go file a bug to get LadyAda to correct that).

--- bill





ZinggJM

Uff, this is ugly. I don't give credit to Bjarne Stroustrup for every line of C++ code I produce, or have copied from somewhere.

I thought the whole Arduino World is based on Open Software. This openness is what makes it live and evolve, so rapidly.

Lets continue in this attitude.

Jean-Marc Zingg
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

bperrybap

I don't think it is getting ugly at all. s/w is considered private copyrighted work that is protect against copying unless otherwise noted; so, some sort of copyright and licensing must be stated and granted if it is to be shared and used by others.

Open source is not the same as FreeWare.
Open source usually comes with copyright and licensing requirements/restrictions that allows it to be copied and shared and often does not allow it to be used in certain ways.
So you can't just copy open source software and use it anyway you want.
That is the price you pay for being able to start with someone else's s/w code vs having to start from scratch.
People have different views on the s/w that they create and the license they choose allows them to choose how their s/w can or cannot be used by others.

In this case it looks like it might be easy to clean things up by adding some missing notices and copyrights.
The tricky part will be if the the library is using code from both GFX and and ILI9341 since they have different licenses.
It may be that the combined work will have to become BSD vs MIT since I think BSD is a bit more restrictive, assuming the MIT licensing actually allows that.
(Although I just created an issue in the Adafruit ILI9314 library asking them to clarify the licensing)

btw, I faced a some licensing & copyright issue when I created my arduino hd44780 library.
This was mainly because the Arduino team (Including Adafruit) was so sloppy with their licensing and copyrights.
This was particularly an issue on the LiquidCrystal library. I pushed hard on both Arduino and Adafruit to clean up their copyrights and licensing on their code & libraries and for the most part they have.
In my case I was having to dance around a bit since they originally didn't have any licensing or copyright notices for LiquidCrystal when I started hd44780.
They had a very vague and general license file for Arduino code but that license file was never included with the Arduino IDE distribution - it was only in the repository - so nobody that had the IDE would ever be able to see it - which does not comply with the GPL/LGPL requirements.
My eventual solution was to look at their intent and went with that until they updated their licensing.
I now also include a licenseInfo.txt file that provides a detailed description of the licensing and the history of the licensing of the original sources.
You can see in my repo here: https://github.com/duinoWitchery/hd44780

I am a big believer in s/w copyrights and licensing and believe that ALL s/w should be very clear as to its licensing and the lineage of the code, including arduino libraries and sketches.

One of the worst licenses of all is Creative Commons CC-BY-SA 3.0 as that license is not compatible with anything but itself. It was never intended to be used on a work that is piece of something else. So legally you can't ever create a public/shared project that uses it in something like an adrduino project (even if the CC-BY-SA 3.0 work is just a library) since CC-BY-SA 3.0 is not compatible with other licenses like GPL/LGPL code due to some of the attributions required by CC-BY-SA 3.0 that are forbidden by GPL/LGPL.
CC-BY-SA 4.0 was created to work around this by allowing the work to be re-licensed as GPL/LGPL.

--- bill

bodmer

@bperrybap

Ah! Missed the BSD reference, it seems that Adafruit have different license and license versions sprinkled through their various libraries.

I've have updated the repository.
Formerly Rowboteer (now a broken user profile!)

bodmer

The NodeMCU has an ESP8266 at heart which makes a networked sketch for the library a must, so here is a starter sketch that will (after some more tweaks) find it's way into the examples

If anyone has some cool ideas for another networking sketch that needs a TFT then post on this thread.

Work on this library will cease now for a while until I can persuade Alexa (i.e.and Amazon Echo) to talk to and read some networked sensors, that may take some time as she is proving to be a bit obstinate :-)
Formerly Rowboteer (now a broken user profile!)

bperrybap

Ah! Missed the BSD reference, it seems that Adafruit have different license and license versions sprinkled through their various libraries.
They have been and continue be sloppy with their licenses. And in some past cases they have violated licenses and copyrights by claiming a different license for their derivative work that is simply not allowed.
It has gotten better in recent times, but as you have seen, there are still some "gotchyas".


The NodeMCU has an ESP8266 at heart which makes a networked sketch for the library a must, so here is a starter sketch that will (after some more tweaks) find it's way into the examples
Have you seen the WifiManager? It is really cool.
You might consider adding the WifiManager to the code so that it is usable "out of the box".
i.e. users attached to it to set the ssid & password rather than have to hard code them in to the sketch code.
But that does add more complexity and the addition of another library so you may not want to go that route. - but is very cool.

--- bill

Go Up