ili9486 tft display arduino library bodmer manufacturer
I am trying to use TFT LCD Display ILI9486/ILI9488 480x320 with Arduino Due. The display is showing blank white screen. My test program compiles and uploads without any error. However, LCD display remains blank with white screen.
An Arduino IDE compatible graphics and fonts library for Mega with a drivers for the HX8357B, HX8357C, ILI9481 and ILI9486 based TFT displays with a 16 bit parallel interface. This library will not run on an UNO and it does not support 8 bit UNO shields.
The library contains proportional fonts, different sizes can be enabled/disabled at compile time to optimise the use of FLASH memory. The library has been tested with the Mega.
In addition to the default fonts (1, 2, 4, 6, 7 and 8) the library includes and supports the encoded Free Fonts from the new Adafruit_GFX library. Unlike the Adafruit_GFX library these fonts can be automatically rendered with background and padding to over-write and erase old text, see the examples.
The library is based on the Adafruit GFX library and the aim is to retain compatibility. Significant additions have been made to the library to boost the speed for the Mega processor and to add new features. The new graphics functions include different size proportional fonts and formatting features. There are a significant number of example sketches to demonstrate the different features.
Configuration of the library font selections and other features is made by editting the User_Setup.h file in the library folder. Fonts and features can easily be disabled by commenting out lines.
This HX8357B based display does appear to have a bug in the silicon of the driver chip as it sometimes generates spurious pixels on the display. The only way around this is to redraw the whole screen occasionally to wipe out the duff ones, this is most noticeable for intensive updates in small screen areas (e.g. in ring meter sketch). So my suggestion is to go for the next revision driver, the HX8357C with 3" TFT which does not exhibit the same problem:
TFT LCDs are the most popular color displays – the displays in smartphones, tablets, and laptops are actually the TFT LCDs only. There are TFT LCD shields available for Arduino in a variety of sizes like 1.44″, 1.8″, 2.0″, 2.4″, and 2.8″. Arduino is quite a humble machine whenever it comes to process or control graphics. After all, it is a microcontroller platform, and graphical applications usually require much greater processing resources. Still, Arduino is capable enough to control small display units. TFT LCDs are colorful display screens that can host beautiful user interfaces.
Most of the smaller TFT LCD shields can be controlled using the Adafruit TFT LCD library. There is also a larger TFT LCD shield of 3.5 inches, with an ILI9486 8-bit driver.
The Adafruit library does not support the ILI9486 driver. Actually, the Adafruit library is written to control only TFT displays smaller than 3.5 inches. To control the 3.5 inch TFT LCD touch screen, we need another library. This is MCUFRIEND_kbv. The MCUFRIEND_kbv library is, in fact, even easier to use in comparison to the Adafruit TFT LCD library. This library only requires instantiating a TFT object and even does not require specifying pin connections.
TFT LCDs for ArduinoUser interfaces are an essential part of any embedded application. The user interface enables any interaction with the end-user and makes possible the ultimate use of the device. The user interfaces are hosted using a number of devices like seven-segments, character LCDs, graphical LCDs, and full-color TFT LCDs. Out of all these devices, only full-color TFT displays are capable of hosting sophisticated interfaces. A sophisticated user interface may have many data fields to display or may need to host menus and sub-menus or host interactive graphics. A TFT LCD is an active matrix LCD capable of hosting high-quality images.
Arduino operates at low frequency. That is why it is not possible to render high-definition images or videos with Arduino. However, Arduino can control a small TFT display screen rendering graphically enriched data and commands. By interfacing a TFT LCD touch screen with Arduino, it is possible to render interactive graphics, menus, charts, graphs, and user panels.
Some of the popular full-color TFT LCDs available for Arduino include 3.5″ 480×320 display, 2.8″ 400×200 display, 2.4″ 320×240 display and 1.8″ 220×176 display. A TFT screen of appropriate size and resolution can be selected as per a given application.
If the user interface has only graphical data and commands, Atmega328 Arduino boards can control the display. If the user interface is a large program hosting several menus and/or submenus, Arduino Mega2560 should be preferred to control the TFT display. If the user interface needs to host high-resolution images and motions, ARM core Arduino boards like the DUE should be used to control the TFT display.
MCUFRIEND_kbv libraryAdafruit TFT LCD library supports only small TFT displays. For large TFT display shields like 3.5-inch, 3.6-inch, 3.95-inch, including 2.4-inch and 2.8-inch TFT LCDs, MCUFRIEND_kbv library is useful. This library has been designed to control 28-pin TFT LCD shields for Arduino UNO. It also works with Arduino Mega2560. Apart from UNO and Mega2560, the library also supports LEONARDO, DUE, ZERO, and M0-PRO. It also runs on NUCLEO-F103 and TEENSY3.2 with Sparkfun Adapter. The Mcufriend-style shields tend to have a resistive TouchScreen on A1, 7, A2, 6 but are not always in the same direction rotation. The MCUFRIEND_kbv library can be included in an Arduino sketch from the library manager.
The 3.5-inch TFT LCD shield needs to be plugged atop the Arduino board. The Mcufriend-style shields are designed to fit into all the above-mentioned Arduino boards. The shields have a TFT touch screen that can display colorful images and interfaces and a micro SD card reader to save images and other data. A 3.5-inch TFT LCD touch screen has the following pin diagram.
How project worksThe code fills a rectangle, then draws a rectangle within which text “EEWORLDONLINE” is displayed. Then, lines, circles, rectangles, and squares are drawn on the screen. The project ends with a greeting and a message.
Anyway now I commented that line, beacuse I am not interested in speed right now. But now the problem seems to be the programation code. the error message is as follows: ( I am using Arduino 1.8.7)
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:101:37: warning: ISO C++ forbids converting a string constant to "char*" [-Wwrite-strings]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:106:42: warning: ISO C++ forbids converting a string constant to "char*" [-Wwrite-strings]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:118:39: warning: ISO C++ forbids converting a string constant to "char*" [-Wwrite-strings]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:121:42: warning: ISO C++ forbids converting a string constant to "char*" [-Wwrite-strings]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:151:40: warning: ISO C++ forbids converting a string constant to "char*" [-Wwrite-strings]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:163:39: warning: ISO C++ forbids converting a string constant to "char*" [-Wwrite-strings]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:176:37: warning: ISO C++ forbids converting a string constant to "char*" [-Wwrite-strings]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:183:38: warning: ISO C++ forbids converting a string constant to "char*" [-Wwrite-strings]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:188:38: warning: ISO C++ forbids converting a string constant to "char*" [-Wwrite-strings]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:193:38: warning: ISO C++ forbids converting a string constant to "char*" [-Wwrite-strings]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:198:38: warning: ISO C++ forbids converting a string constant to "char*" [-Wwrite-strings]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:205:39: warning: ISO C++ forbids converting a string constant to "char*" [-Wwrite-strings]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:210:39: warning: ISO C++ forbids converting a string constant to "char*" [-Wwrite-strings]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:215:39: warning: ISO C++ forbids converting a string constant to "char*" [-Wwrite-strings]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:220:39: warning: ISO C++ forbids converting a string constant to "char*" [-Wwrite-strings]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino: In function "void drawBMP(char*, int, int, boolean)":
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:267:40: warning: converting to non-pointer type "int" from NULL [-Wconversion-null]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino: In function "void drawRAW(char*, int16_t, int16_t, int16_t, int16_t)":
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2\ILI9341_draw_bitmap_v2.ino:377:40: warning: converting to non-pointer type "int" from NULL [-Wconversion-null]
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2/ILI9341_draw_bitmap_v2.ino:355: undefined reference to `FatFile::close()"
C:\Users\ADMIRAL\Videos\arduino\Libraries\Adafruit_ILI9341_AS\examples\ILI9341_draw_bitmap_v2/ILI9341_draw_bitmap_v2.ino:338: undefined reference to `FatFile::read(void*, unsigned int)"
In my searches for an appropriate board I realized that Arduino compatible 2.4 inch touch TFTs with SPI interface have almost the same price as 3.5 inch 480×320 touch TFT display modules for RPi. I decided to buy one of these.
Also, the nature of the ILI9341 SPI commands e.g to set individual pixels by sending address then value, is very inefficient, especially as the default Adafruit library does not buffer these transfers into one larger SPI transfer.
Most TFT controllers can be configured for 8-bit SPI. The minimum write-cycle is marginally faster with 8080 parallel-interface. The minimum read-cycle is faster with SPI than parallel. OTOH, SPI is easily controlled with DMA.
As far as I know, RPi drives the display as “frame buffer”. It means, it has a complete image buffer in RAM and writes it as a whole frame always all over again with high speed to the display. So it does not need to change the window coordinates, no switch between command and data select. That’s why it can really work with DMA.
I have a custom made PCB I am using for these tests, which has a maple mini on one side and the ILI9341 display on the other, so that the wires (pcb tracks) are quite short ( approx 3 cm)
Using double buffering would allow the best use of DMA ( if we had a completion callback) as calculation of line, pixel and text drawing must be taking almost as much time as the SPI data transfer to the display
I was having a look at those numbers, and I’m surprised too at getting the same speed with DMA and without, but I also noticed you can’t run the display at the max SPI speed.
A while back when porting the sd-fat library I did some tests with and without DMA at slower SPI speeds, and noticed pretty much the same, up to a certain point DMA was not faster than normal.
If I remember right, I did some test with the ILI library where it would only use DMA if the line to draw was longer than N pixels, and use the normal transfer for smaller lines, and found the minimum number of pixels for DMA to make a difference. Still the gains over using DMA all the time at full speed were not significant, but did show that normal transfers were faster if under a number of bytes.
Victor, the tests ran at 36 MHz, but the display was partially corrupted. Before any optimization, the corruption was not that significant that after. If I speed-optimize the register writing, than i have more problems, randomly.
It looks a lot like they may be salvaged from old mobile phones, I had similar issues with the Nokia 5110 displays from eBay as a lot of them are not actually “new” (as advertised), they are salvaged and are often not even cleaned so were covered in whatever grime was in the mobile phone form years of use
Your comparison makes only sense if you compare same graphicstest software running on the same controller board (MM or blue pill) controlling same display controller (ILI9341?), driving same display resolution (320×240) in two different modes (parallel and serial at maximum possible speed).
stevestrong wrote:If you look on the scope screenshot (second blue/cyan block), you will observe that the SPI stream is continuous, no need for the controller to generate extra WR strobe between consecutive pixel data. This is managed by the hardware serial->parallel circuit on the display board.
This would provide a “sprite” transfer capability, cut out from a single source containing image and transferred through DMA to the display at the desired destination position. With little modifications, this could be used for fixed/variable font rendering too.
The ILI9486 specifies a WR cycle time of 50 ns min. (twc in datasheet, page 212), thus you are limited to 20 MHz on the 8080 interface side. The limit will be the HCT chips at the given VCC.
From fbtft sources, the RPi looks like it is driving this display @ 32 MHz, but this is using a full continuously refreshed frame buffer, so a glitch won’t be as noticeable as it will be redrawn on next frame anyway.
That’s interesting! I wonder which other ILI controllers have the same. That could make for really fast display drivers even with small buffers, and minimal cpu usage.
Just had a look at the ILI9341 datasheet, and supports a mode without D/C line, I guess there is some track cutting and soldering involved to reconfigure the display. Looks like the serial mode without DC line in the ILI9341 is serial 9bit, which complicates things in other ways
Yes, because of this, fast TFT screen circuits are using 8 or 16-bit parallel modes, since the controller built-in 3 or 4-wire SPI modes are getting roughly the same toggling speed, you get transfer performance divided by 8 or 16.
And although the RaspPi is driving the SPI @ 32 MHz which is above the guaranteed maximum frequency, it is still in the typical achievable ones, and as again the Pi is using a full frame buffer with continuous refresh, a glitch will get unnoticed, whereas the way the Arduino TFT library uses it is completely different, and pushing the transfer frequency to the limits will result in corrupted displays (if in data mode) or may hang the controller (if in register mode).
So my first guess is that Bodmer’s library is using the SPI library. And the SPI library limits SCK frequency to 40MHz. Edit. Bodmer’s User_Setup.h file specifies maximum 40MHz for SCK
The AVR SPI peripheral always has “gaps”. The AVR USART_MSPI peripheral can achieve full speed with no gaps. Of course you need a good Arduino SPI library to get the best out of the hardware.
Bodmers said that he gets occasional glitches with SCK=80MHz. I was running my standard “graphictest_kbv.ino” sketch through a GLUE class. I did not observe any glitches. I am familiar with where gliches can occur from my parallel targets.
The current SPI lib of Arduino_STM32 is already “gap-less” in non-DMA mode. That’s why all graphic test (except one) without DMA performs equal or better than with DMA, due to lacking DMA overhead.
I cannot see how any RPi would work correctly with this display at 40MHz, without any HW hacks. I saw blogs where rather 16MHz was suggested to be used, this sounds a lot more realistic. Also, there are several versions of such boards, maybe there are others with better characteristics/controllers.
Otherwise I see myself forced to remove the HC chips from the display board and drive the display with 16 bits parallel directly from BP (using PB0..15).
An “unreadable” display does not really interest me. However, it would be interesting to see just how fast your shift registers will work. After all, the 16-bit parallel could be driven up to 10x faster.
David, my original intention was just to have one display which is SPI driven. I have already one 240×320 display which is 8 bit parallel driven, and, of course, is much faster than this one. Here, I am limited by the serial->parallel converter.
Sorry. tDST is the data setup time before the active edge of /WR in the 8080 parallel interface. (ST7789 nomenclature. The ILI9486 datasheet might use a different acronym)
As far as I can see, a stock HC4040 is going to produce the WR signal before the HC4094 has loaded the shift register. i.e. it will be wrong for the ILI9486 and also wrong for the HC4094 to latch the shift register.
Still, there is one clock period delay at 36MHz between WR and data. That means, the color data is sampled as being is shifted one bit left. For example, if I want a red color (0x8000), the display controller will get 0x0001 sampled because of this one clock period propagation delay of WR edge relative to the parallel shifted data.
The chip works >150MHz internally, when routed you can mess with counters, shift registers and whatever logic you want at 80-90Mhz sure. The logic guys need is about 10 lines of verilog, or, with schematic capture the same schematics as above, as the library includes dozens components like those the guys use now for the tft (almost all ttl/cmos standard chips people mess with).
The trick is when you want to change something in the schematics – wiring or add a component or invert a signal, or fully change your design, you do it on the screen and then just flash – the same process as with arduino. The XC9536XL family has got flash memory for the wiring, programmble via jtag.The dev cycle is about 1-2minutes to change and run. And the chip is 100% routable so you can connect your tft to whatever pins you want – it always fits your new design/schematics to existing pin layout on the pcb (or in other words – your design can be always routed to any i/o pin setup you want).
Here is a 32bit freqmeter/periodmeter/counter in an XC9572XL I did 5y back for arduino forum as an example. It includes 2x16bit counters and 2x16bit shift registers and some logic (arduino had read the freq measured off the chip serially, only 7 pins used). The ring oscillator (3 invertors in loop) there did 150MHz freq.
I am still thinking where should the SPI initialization take place: outside the ILI9486 driver, in setup phase, before or within the driver begin() function?
I am still thinking where should the SPI initialization take place: outside the ILI9486 driver, in setup phase, before or within the driver begin() function?
Compiling the code from github produces some errors (not a problem), but one of them is the following – which is an apparent mismatch with SPI.cpp in hardware\Arduino_STM32\STM32F1\libraries\SPI\src.
The core of the issue (apart from my mis-paste from the core SPI library) seems to be that I was using the SPI library from Roger’s master repo, rather than Steve’s amended one.
I have used the SPI example in the STM32 library to test the SPI communication and the display responds always with the pattern 0x55, does it mean the communication is OK? I have disconnected it and I have got 0xFF!!! Looked fine to me!!
Well! Afterwards I could run the ILI9486 example program and got the run times statistic quite similar to the one in beginning of this post (see below!)
The problem is, that the display is just flashing white synchronously to the test sequences. After doing some debugging with Atollic , I could not detect any error.
I have followed all the hints above, but I could not run any demo on this display. The device I have bought looks exactly the same as yours at the beginning of this post. I have tried your example with no positive results. Obviously there is a serial parallel converter on the board, that why it is a write only device. I have tried ILI9481 and ILI9486 . If the controller is not ILI9486, what might it be?
It looks as if your display was made by WaveShare. So there is probably a schematic. So it should be easy to guess how the hardware needs to be driven.
Most 320×480 controllers are MIPI compliant. And probably start up by themselves. Just Reset, Display Off, Wake up, Display On. (with some pauses)
Finally I have got it done! I have found out the right initialisation sequence. The SPI frequency is crucial. The display works only in the range between 12MHz and 32MHz only. Any frequency out of this range lead to white flashing on the screen!
Hi. After spending a lot of time and seeing that the pin connection was correct, I decided to change the 5v power supply of the display and then the sketch of REG_ID showed that “reg (0x0000) 45 35” (though the remaining registers were all like 00 00).
There are several versions of Adafruit_TFTLCD library that have been hacked for an LGDP4535. There are probably some original ones too. As far as I know, they will only run on a Uno or Mega.
Anyway, I have one of these generic 3.5inch RPi LCDs. The above library works perfectly for running the LCD. The XPT_2046 library also works perfectly for driving the touch panel. BUT the two do not work together. Display calls break the touch panel, and vice-versa.
Did you enabled DMA? With DMA I have some artefacts with the graphic tests (not only with this display) It’s on my todo list to investigate the problem (maybe too much speed for the controller).
I do not own/use diff tools, because I don’t need them regularly (I just use notepad++ with the compare plugin on windows or XCode on OSX for such things (private)). It’s always better to post the whole code/library as *.zip or *.rar file as Attachments otherwise many people will cry “How to use this?” -especially under windows (there is no “patch” without further installing something)
The teensy library is MUCH slower – maybe the errors caused by to high speed (SPI or low level pin manipulations) – It should be not to difficult to find the problem as we have two – almost same – libraries