ili9486 tft display arduino library bodmer brands
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:
If you report the results from each 320x480 with 16-bit interface, I can probably give a guess as to which controller you actually have. UTFT only has ILI9481, ILI9486, R61581 to test.
Make notes of the results. Report back. Please use controller names and not model names. i.e. say ILI9486, ILI9481, ... Do not use the Itead or Coldtears brand name
MCUFRIEND_kbv works out of the box with every "Mcufriend style" parallel Shield on a Nucleo. i.e. it supports more controllers than TFT_eSPI. But TFT_eSPI is more sophisticated and probably faster.
As I said. I don"t have the Waveshare Shield. It is definitely convenient to plug a Shield into a Nucleo. I would expect it to run pretty fast with TFT_eSPI. So I am wondering what you have done in your User_Setup.
It is unfortunate that I do not want to buy a Waveshare. I can probably test most other display types. (on AVR, Due, Nucleo, Teensy, ESP8266, ESP32, RPi Pico, ... targets)
Regarding Red SPI displays and Shields. I mount headers and solder wire routeing on a custom ProtoShield. This means that I can run different displays on different targets.
You will see that most of the Display contributors have similar arrangements. i.e. Protoboard or ProtoShields that receive the popular TFT, OLED, GLCD, ...
I started with an Arduino DUE board that I"ve added WiFi and SD breakout modules to. I have a 2.8" TFT display that works fine using this GitHub - marekburiak/ILI9341_due: Arduino Due and AVR (Uno, Mega, Nano, Pro Mini,...) library for interfacing with ILI9341 SPI TFTs and JPEGDecoder. Unfortunately, this display has bad color distortion at various viewing angles so I"d like to replace it with slightly larger 3.5" 320x480 displays.
I have a WaveShare 3.5" that supposedly uses ILI9486 and appears a bit better at various viewing angles, but I"ve only gotten it working using ILI9488 from GitHub - jaretburkett/ILI9488: Arduino Library for the ILI9488 TFT controller for 4 wire SPI - mostly because I can"t find a ILI9486_DUE type of library...I believe that HX8357 can work, but I ran into trouble using it. While I can use Bodmer"s TFT_HX8357_Due version, it"s missing the ILI9486 driver that got merged into the regular TFT_HX8357 version. I can"t use the regular TFT_HX8357 since I"m on a due. (Should I be trying to merge these two?) The sample code provided with the display isn"t for due either (https://www.waveshare.com/wiki/3.5inch_TFT_Touch_Shield) but I"d rather work with something closer to what I"m used to if I can also.
The WaveShare mostly works for me; I am able to draw background colors, write text, and so on using the ILI9488 driver. This is the code that"s specifically giving me trouble with ILI9488 and the JPEGDecoder library:
I"ve tried both of the methods above and the first line (pushColor) produces distorted grey blocks with a slight resemblance of the original JPG, whereas the latter (pushColors) simply produces no output to the TFT for me.
This is all probably pretty vague, but I"m hoping someone a bit more familiar with this sort of thing can help steer me in the right direction... Should I be trying to modify the pushColor/pushColors functionality of the ILI9488 driver, or should I be using a different driver? Should I try merging the ILI9486 driver from TFT_HX8357 into TFT_HX8357_DUE? Should I be trying to use the ILI9341_DUE driver that I had working with the 2.8" display but adapting it to these WaveShare 3.5" displays?
This display can be mounted on an Arduino Mega or Due. It has a fairly high resolution of 320*480 pixels and is also quite large with 3.5 inch LCD size.
This new library is a standalone library that contains the TFT driver as well as the graphics functions and fonts that were in the GFX library. This library has significant performance improvements when used with an UNO (or ATmega328 based Arduino) and MEGA.
Examples are included with the library, including graphics test programs. The example sketch TFT_Rainbow_one shows different ways of using the font support functions. This library now supports the "print" library so the formatting features of the "print" library can be used, for example to print to the TFT in Hexadecimal, for example:
To use the F_AS_T performance option the ILI9341 based display must be connected to an MEGA as follows:MEGA +5V to display pin 1 (VCC) and pin 8 (LED) UNO 0V (GND) to display pin 2 (GND)
In the library Font 0 (GLCD font), 2, 4, 6 and 8 are enabled. Edit the Load_fonts.h file within the library folder to enable/disable fonts to save space.
TFT_ILI9341 library updated on 1st July 2015 to version 12, this latest version is attached here to step 8:Minor bug when rendering letter "T" in font 4 without background fixed
Graphics user interfaces often require much more programming effort than the ‘actual code’ that does the important functions of the project. To be able to concentrate on the essential aspects of the project, ready-made solutions or the use of ready-made libraries for the graphical output of information are becoming more popular and important. Well-known names are µGFX, emWin or TouchGFX for STM32 boards, to name just a few. They all have advantages and disadvantages, such as commercial licensing or the connection to certain controller manufacturers. Of course, you could also develop a library yourself, but that"s a huge amount of work and presents many pitfalls, not to mention the many bugs in the homebrew, extensive code.
Things look better with a library like LittlevGL by Gábor Kiss-Vámosi because it comes with a very project-friendly MIT license. A GUI developed with it is well suited for touchscreens, but can also be operated with a mouse, keyboard or some buttons. The code runs on popular 16-, 32- and 64-bit microcontrollers. The minimum criteria to meet are 16 MHz, 64 kB Flash and 16 kB RAM. Thus, the library fits perfectly to small boards such as the ESP32 or ESP8266 and has now been included by Espressif in their IDF. Below you’ll find support for getting started and putting together test hardware. LittlevGL also offers the opportunity to develop and test GUIs on the PC, which is not to be sniffed at. The code created on the PC for a GUI can be transferred to the target microcontroller without major adjustments.
You learn most when you try something hands-on. Therefore, the use of the library within Elektor’s Weather Station is demonstrated here. The goal is a GUI suitable for touch operation. We will even realize a multi-page display for data. But this requires hardware.
An ESP32 module is easily available. You can use modules like an ESP32 PICO D4, an ESP32 DevKitC, or a derivate board. The display offers a selection between a serial interface and parallel control, which then uses almost all IOs of the ESP32. Since the price also plays a role, a common 3.5" LCD for the Raspberry Pi is used. Most cheap displays like the 3.5" JOY-iT are connected via SPI and work with 3.3-V levels on the signal lines. They are therefore perfectly suited for a pin-saving link to an EPS32 board. In addition, they already have an integrated touch controller that can be connected via SPI.
The SPI displays intended for RPi, however, are limited in terms of speed at which data can be transferred to the display. Anyone who has ever experienced such a display in action on an RPi already feels the slightly sluggish screen update.
Note: LittlevGL does not provide display drivers, only ‘higher’ functions for drawing objects. It is up to the creator to develop the appropriate hardware-related routines. But even that doesn’t require reinventing the wheel, since most display controllers benefit from ready-made libraries. Here the Arduino TFT_eSPI library is used, which also supports 3.5" displays for the RPi.
The required software is also orderly. In addition to the compulsory Arduino IDE and board support for the ESP32, the Arduino versions of the LittlevGL and TFT_eSPI libraries are needed.
In order to install and manage both libraries comfortably, the following two address lines must be entered in the Arduino IDE under Preferences Additional Boards Manager URLs:
These allow searching and installing LittlevGL and TFT_eSPI via the Library Manager. Then check if the Arduino library folder contains ‘TFT_eSPI’ and ‘LittlevGL’.
As already mentioned, both libraries are needed. LittlevGL takes care of the UI, i.e. the animation and arrangement of objects, the management of several scenes, and the rendering of the displayed graphics. The result is a bitmap. This data is then transferred from TFT_eSPI to the display hardware in a suitable way. These libraries therefore abstract from the actual display used.
TFT_eSPI not only supports SPI displays for the RPi, but others too based on the following controllers: ILI9341, ST7735, ILI9163, S6D02A1, HX8357D, ILI9481, ILI9486, ILI9488, ST7789, and R61581.
This supports many common colour displays. If a RAiO-based controller such as the RA8875 is used, the RA8875 library from Adafruit can be used instead. Adjustments are necessary to connect LittlevGL. In addition to colour displays, monochrome types can also be used in conjunction with the u8g2 library . However, the following text refers to the common 3.5" SPI LCDs for RPi.
If you are using a display with a controller lacking Arduino driver support, you need to know what functions need to be provided. This knowledge is also helpful for porting and linking.
Basically, it is sufficient to write your own driver capable of setting individual pixels on the display in a defined colour. LittlvGL expects a function like this:
This function is passed to LittlevGL as a function pointer. For parameters it receives the start and end coordinates of the drawing area to be filled as well as a pointer to the image data. The actual setting of the pixels depends on the driver for the respective display. However, it can happen that the colours desired by LittlevGL have to be converted for the display (e.g. from RGB to BGR). That’s as far as the abilities of the drawing routine have to go. On the other hand, there are solutions for hardware acceleration, such as the DMA2D engine of some STM32 controllers.
This should clarify how a graphic is displayed on the screen. What’s missing is the processing of the data from the touch controller. For that, we have a LittlevGL function which reads and processes the coordinates of a possible touch depending on the device. RPi displays are usually equipped with an XPT2046 touch controller, which is connected to the SPI bus as an additional slave. Unfortunately, this cannot be read with a clock rate higher than 2.5 MHz. Since the display and its controller run at a clock rate of 20 MHz (at room temperature, up to 26 MHz), the bus clock rate needs adjusting during access and then get reset to the original clock rate. The TFT_eSPI library also helps here, because it not only offers XPT2064 support, but also automatically takes care of the necessary clock switching.
First, a word about the strengths of LittlevGL: it is advantageous that the source code is also available. This facilitates the debugging of your own code. In addition, the library is well documented and developed out actively. Even beginners can use the examples to quickly achieve their first sense of achievement and design interfaces. From simple labels, buttons and tables to dropdown lists and gauges — a wide range of controls is provided. Windows and note boxes as well as themes for the appearance are also provided in order to be able to adapt the GUI even better to one"s needs. The documentation describes all elements in detail. At [1], functions of the library and their interaction are demonstrated. LittlevGL does not yet offer any basic functions for setting pixels or drawing lines. That’s due to the type of image generation: If an element changes, the new screen area to be drawn can be determined and the buffer prepared in the internal RAM. The image is then sent to the display. Consequently, not just a line needs to be present as an object, but even individual pixels. This restriction makes it much easier to redraw areas on the screen.
The technical details of image generation and display are now available: If you want flicker-free and interference-free animations or screen updates, you could first prepare the complete image in the RAM of the controller and then transfer this data to the display. In this case, we would be dealing with 307 kB of data. You could also transfer all elements directly to the display and use less RAM. The latter complicates a flicker-free display and hinders effects like antialiasing, transparency and shadows.
A compromise is to mirror a part of the screen in RAM. With only a little more than 10% of the memory required for the entire image, you get all the features mentioned. For a display with 480 × 320 pixels at 16-bit colour depth that would be ‘only’ 30.7 kB of RAM — for an ESP32 that"s a lot, but it can handle it.
In the current version 6 of the library, the memory area is not communicated by a #define, but instead has to be provided by code. This procedure is especially useful if additional external RAM is available and is to be used.
With other microcontrollers the possibilities and priorities need to be considered, because many devices either have considerably less RAM available, or would have to address external RAM through a bag of tricks. In addition to the available RAM, other aspects such as the available computing power or multi-threading are also relevant. LittlevGL unfortunately does not allow multi-threading, so all access must be from the same thread as the lv_task_handler() function. The required computing power depends on how much interaction and drawing takes place on the display and whether and how animations are used. Thanks to its two processor cores, an ESP32 has enough computing power for a GUI.
If you want to experiment now, be wary of the pitfalls. A setup example is described below for easy-peasy commissioning. An ESP32 D4 PICO board occasionally has slight startup problems due to the additional load of a display. An additional 10-µF capacitor between 3.3 V and GND delays booting until the voltages are within a defined range.
The connection of a display to an ESP32 board should follow the allocation in Table 1. This would prepare the hardware. Now the configuration and the software testing follow. First, we deal with the library TFT_eSPI as the actual display driver and then with the configuration of LittlevGL.
Concerning the display driver, to be able to adapt the file User_Setup.h to the display used, you have to look for the folder TFT_eSPI in the library directory of the Arduino IDE. The following #defines have to be present for the display used:
Meaning: the GPIOs used are defined and a 20-MHz SPI clock serves as safe initial value for the display. 2.5 MHz is suitable for the touch controller. For testing we use an example (selection: TFT_eSPI 480x320 Rainbow480), which outputs the rainbow colours once. If everything is compiled and connected correctly, the display should look like Figure 2. At this point, we have the hardware basically ready for use.
The next step is linking LittlevGL to the display driver and creating its own HMI (Human Machine Interface). In order to use LittlevGl, the configuration should be adapted first. To do this, look for the littlevGL folder in the Arduino library directory. In the file lv_config.h, adaptations to the display used are made and the available elements of the library are set. At the start of the file you will find the settings for the memory management.
So much for the basic setting. For first tests, the remaining settings remain untouched; the changes are saved. In the Arduino IDE you can now select the example ESP32_TFT_eSPI under LittlevGL and upload it to the ESP32 board. If everything is configured correctly, “Hello Arduino!” should show up on a white background on the display.
So, the driver and LittlvGL cooperate well. However, the touch controller of the display has not yet been read and this data has not been transferred to the library. The following are the basic code parts allowing you to can create a basic framework for your own application. For this purpose, the example ESP32_TFT_eSPI from the LittlevGL library, which just got loaded into the ESP32, is examined more closely.
In the setup() function, after the initialization of the library in line 63 using lv_init() and the TFT in lines 69 and 70 with tft.begin() and tft.setRotation(1), lines 73 and 74 with the initialization of the structure lv_disp_drv_t follow. This structure is given a function pointer for writing to the display, and is subsequently registered in the library.
A similar procedure can be found in the dummy touch driver in lines 80–84. The last step is to provide a time base for the library using "Tickers". Here, a function is called in the specified interval of 20 ms. Each time, a timer is increased by 20 ms. Finally, a button will be created and assigned the text “Hello Arduino!” (lines 90–92).
To avoid having to start from scratch with every project, the author has created a basic project in which the settings for the display of JOY-iT and its touch controller as well as the initialization of the components are made. In line 139 of the sketch, the orientation of the display is set with tft.setRotation(3). The image is thus rotated 270° from the starting position. If another display needs e.g. a rotation of 180°, the parameter should be set to 1.
Since we’re talking about a weather station, a simple surface with three tabs is created for the display of the weather data. To keep the Arduino sketch clear, the functions and the creation of the GUI elements are stored in a separate file.
Let’s start with the barometer: three values for humidity, temperature and air pressure should be displayed here. For humidity and temperature, lv_lmeter and label are used, indicating the value and name of the measured variable. For the humidity, lv_gauge is used. Conveniently, you can still influence the look of the elements at runtime by styles and so individualize each element.
The Autofit function of the library must be taken into account when arranging elements. Consequently, you should arrange the elements appropriately or disable Autofit. Elements can be positioned from several original coordinates — an overview can be found here. The individual elements can have parents, i.e. objects on which their position depends. This results in elegant dependencies of the positions, which also realigns all children during a parent shift. In the code, the created elements cannot be accessed directly later. For LMeter and Gauges we therefore use pointers that can be accessed globally. In the example code
it is noticeable that functions like lv_ L-meter create only return pointers. The question now is where memory is reserved. This is buried a bit deeper in the library. The expression:
creates a fixed storage pool for the graphic elements. Each time a Create function is called, some memory is taken from the pool and reserved for the graphic object. The result of the operation is a pointer to the memory address, which is used to change the properties of the object. If the memory runs out at some point — this can happen with dynamic surfaces — an error is triggered in the library and an endless loop is created. The ESP32 stops completely.
Through Pointer, you can then write new values to the displays. One example is the UpdateTemperature function. The display element Lmeter expects a value between 0 and 100, but the size has a value range of ±50°. The temperature must therefore be offset by 50. 0° then corresponds to a Lmeter value of 50. In addition, the current temperature is displayed as text. This is done by snprintf and a small local buffer, which is written as new text into the text field. If the text length changes, the text is not automatically realigned. The alignment must be done again after setting the text. To do this, lv_obj_align is called again with the parameters for the label. Humidity and air pressure are treated very similarly. Figure 5 shows a screenshot of the finished tab and Figure 6 shows what it ’really‘ looks on the LCD.
The first tab is now filled with content. The second tab is similar, but the wind direction display as a compass dial requires a little more effort. Here a Gauge acts as Parent for four labels. In the code, a Gauge with 0–359° is created first. This is followed by four labels, which are forwarded to the compass as a Parent. The labels are defined in relation to the centre of the compass. This results in the four points of the compass. The pointer points in the direction from which the wind comes. With the Gauge, 0° does not result from the value 0, but from 180. For the display of the wind speed, again an Lmeter with similar structure is used as with the barometer. Notice that processes are repeated for the creation of the elements. First, a style is created for the object, then the object is created, and finally its properties get assigned to it. The finished result can be seen in the screenshot of Figure 7.
In the case of rain or precipitation, the values are displayed differently. Here the values are represented in text form as well as in a diagram, from which the temporal process results. The texts are realized as described before: First, styles and objects are created — then the values are assigned. For the course of the rain volume a line diagram is suitable, which requires no more tricks to label the axes since version 6. To update the values, it is not necessary to move each data point individually, because lv_chart_set_next does this. A new value is passed to the diagram once per hour. The update of the precipitation volumes is done just as with other texts as well as by an internal function. Figure 8 shows a screenshot with pseudo data of the progression and the precipitation values.
For the data connection of the display, code from the Monster LED Clock project got recycled, since data already coming from a broker via MQTT is processed here. The code expects the broker to send a JSON string containing the values for humidity, temperature, air pressure, wind direction, wind speed and precipitation. When new data comes from the broker, it is entered into the corresponding elements. However, you need to make sure that this does not happen through different threads. With the configuration, there are no big differences to the LED Clock project except for the missing time setting. WLAN and MQTT settings were simply adopted; only the weather station and the display have to be set to the same topic. From then on, the values are displayed directly on the screen. An exception at this point is the rain quantity, because here only the current rain quantity of the weather station is output. The calculation of hourly values and the trend are unfortunately not yet implemented with the weather station. As soon as this has materialized, however, these values are also updated on the display.
If you like the simplicity of using this library, you might want to try LittlevGL in your own projects. After all, an EPS32 module in combination with a touch display is a platform that can be used quite universally and offers a lot of performance for little money.
Hello everyone to my new tutorial in which we are going to program arduino for tft lcd shield of 3.5" with ILI9486 driver, 8 bit. I found it important to write this tutorial as if we see we find tutorial for 1.44, 1.8, 2.0, 2.4, 2.8 inch shields however there are no or less tutorials available for 3.5" shield as its completely different from other smaller tft lcd shields -adafruit tft lcd library doesn"t even support ILI9486 driver in 3.5" tft lcd, it supports drivers of tft shields lesser then 3.5"
Go through the above link to know better, lets start with our tutorial however if we can"t use Adafruit_TFTLCD library which library will we use ?, there"s a simple answer to this that"s MCUFRIEND_kbv library which helps to use 3.5" tft lcd shield, if you see this library makes it much more easier to program arduino for tft lcd shield than adafruit as we have to simply create a tft object in MCUFRIEND_kbv library and then using that we can control the tft lcd shield however in Adafruit_TFTLCD library we will have to create the object and also define connections which makes it a very long task.
Once added, create the tft object using library name and a name for object, you can also define some color codes for text which we are going to type, using the define function and giving color code. This all is to be done before setup.#include
Its time to now start our tft lcd screen and change the background, this is to be done by using some simple functions by obtaining the tft ID and changing the background bytft.fillScreen("color_name");void}
Now we will be programming in loop for printing text on TFT LCD shield, for that we will be using a number of functions such as -tft.setCursor("x","y");x means the position from the x axis on screen and y means position from the y axis on screen of tft lcd shield.tft.setTextSize("number");number here refers to text size which take parameter as number you can give any number from 1 according to your requirements.tft.setTextColor("color");color here means to give the color name we had defined before setup, this makes the text color as whatever you give.tft.print("value");value is nothing but what you want to print, whatever you give as value must be in double quotes.void loop() {// put your main code here, to run repeatedly:tft.setCursor(0,0);tft.setTextSize(3);tft.setTextColor(WHITE);tft.print("my first project with tft -");tft.setCursor(0,70);tft.setTextSize(2);tft.setTextColor(RED);tft.print("welcome to the world of arduino and display , myself I love arduino and game programming very much. This is why I have my own youtube channel in which I share my arduino projects and games made by me , isn"t it amazing !");}
Graphics which we see in our phone is combination of square, rectangle, circle, triangle, lines. This is why here we will learning how to draw the following shapes.tft.drawRect(x,y,width,height,color);x means the position from the x axis of the screen, y means the position from y axis of the screen, width refers to set the width of rectangle, height refers to set the height of the rectangle and color means the color of rectangle you want it to be. You can use this same function by simply keeping the height and width same.tft.drawCircle(x,y,radius,color);x means the position from the x axis of the screen, y means the position from y axis of the screen, radius is a para to set the radius of circle and color means the color of circle you want it to be.tft.drawTriangle(x1,y1,x2,y2,x3,y3,color);x1, y1, x2 etc. are to set the position of triangle"s three points from which lines are drawn.tft.drawLine(x1,y1,x2,y2,color);x1 and y1 are to set point 1 from which line is made to point 2 which is set by x2 and y2.
I have shown we can draw text and shapes by which we can make various graphics, you can also refer to code given by me, one is for text and other is for graphics display.