tft lcd st7735s 16 bit free sample
This is a graphics library for the family of small colour TFT displays based on the ST7735 and ST7789 driver chips. These are really nice displays; bright, colourful, available in a variety of useful sizes, and available at low cost from suppliers like Adafruit, AliExpress, or Banggood:
Unlike most other TFT display libraries this one doesn"t require a memory buffer, allowing it to be run on any processor down to an ATtiny85. The displays are SPI and require four pins to drive the display, leaving one pin free on an ATtiny85 to interface to another device, such as a temperature sensor. If you need more pins choose a larger chip, such as the ATtiny84; see Using the library with other AVR chips at the end of the article for information about how to convert the code for different chips.
I"ve published a library for a colour OLED display in a previous article: Colour Graphics Library. The main difference between the colour TFT displays and the colour OLED displays is that the TFT displays are not self-illuminating, and so need a backlight; they therefore have a slightly higher power consumption. However, they are exceedingly cheap, and they are available in larger sizes than the colour OLED displays.
This library will work with displays based on the ST7735 which supports a maximum display size of 132 (H) x 162 (V), or the similar ST7789 which supports a maximum display size of 240 (H) x 320 (V).
The ATtiny85 and other AVR processors supports toggling of one or more bits in a port, so provided you set all the pins to their disabled state at startup, for speed the display access routines can simply toggle the appropriate pins to enable or disable them.
The display memory stores 18 bits per pixel: 6 bits per colour. However, you can write to the display in three alternative modes, with 12, 16, or 18 bits per pixel. I chose the 16 bit mode, which assigns 5 bits to red, 6 bits to green, and 5 bits blue. It"s the most convenient one to work with as you simply send two bytes to define the colour of each pixel.
To clear the display the ClearDisplay() routine sends the appropriate number of zero bytes. The routine temporarily switches to 12-bit colour mode, which reduces the time to clear the display by 25%:
The library includes basic graphics routines for plotting points and drawing lines. These work on a conventional coordinate system with the origin at lower left. For example, on the 80x160 display:
14th January 2020: Tested the program with the Adafruit 1.3" 240x240 TFT display, and updated the program to correct a problem when rotating the image on that display.
Hi guys, welcome to today’s tutorial. Today, we will look on how to use the 1.8″ ST7735 colored TFT display with Arduino. The past few tutorials have been focused on how to use the Nokia 5110 LCD display extensively but there will be a time when we will need to use a colored display or something bigger with additional features, that’s where the 1.8″ ST7735 TFT display comes in.
The ST7735 TFT display is a 1.8″ display with a resolution of 128×160 pixels and can display a wide range of colors ( full 18-bit color, 262,144 shades!). The display uses the SPI protocol for communication and has its own pixel-addressable frame buffer which means it can be used with all kinds of microcontroller and you only need 4 i/o pins. To complement the display, it also comes with an SD card slot on which colored bitmaps can be loaded and easily displayed on the screen.
Due to variation in display pin out from different manufacturers and for clarity, the pin connection between the Arduino and the TFT display is mapped out below:
We will use two libraries from Adafruit to help us easily communicate with the LCD. The libraries include the Adafruit GFX library which can be downloaded here and the Adafruit ST7735 Library which can be downloaded here.
We will use two example sketches to demonstrate the use of the ST7735 TFT display. The first example is the lightweight TFT Display text example sketch from the Adafruit TFT examples. It can be accessed by going to examples -> TFT -> Arduino -> TFTDisplaytext. This example displays the analog value of pin A0 on the display. It is one of the easiest examples that can be used to demonstrate the ability of this display.
The first thing, as usual, is to include the libraries to be used after which we declare the pins on the Arduino to which our LCD pins are connected to. We also make a slight change to the code setting reset pin as pin 8 and DC pin as pin 9 to match our schematics.
Next, we create an object of the library with the pins to which the LCD is connected on the Arduino as parameters. There are two options for this, feel free to choose the most preferred.
testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", ST7735_WHITE);
The ST7735 display is a TFT LCD that is controlled by the ST7735/ST7735S/ST7735B micro-chip driver, which acts as a bridge between the display matrix and the microcontroller. These colorful displays are cheap, easy to connect and control. Therefore, they spread widely in the Arduino world and their popularity gave rise to many breakout board variations.
At the moment, the library allows to work only with displays with a resolution of 128x160 pixels, 16-bit color depth, and connected via hardware SPI bus.
ST7735 breakout boards can differ from each other and require different initialization methods. Therefore, the xod-dev/st7735-display library contains 4 quickstart nodes at once - st7735-128x160-b, st7735-128x160-g, st7735-128x160-rg, and st7735-128x160-rr. Each of these nodes works with a display of a certain type conventionally named “B”, “G”, “RG”, and “RR”. To find out which type your specific display belongs to, try each of these nodes until it works.
Here is a simple example of using quickstart nodes. For example, We use an ST7735 128x160 SPI display of a “G” type. Connect it to a microcontroller according to the wiring scheme.
Put the quickstart node st7735-128x160-g onto the patch and fill in ports values CS, DC, and RST according to the wiring scheme. Using the XOD graphics library, create a new canvas with the size of a display screen. The width W of the canvas is 128 and the height H is 160. The background color BG is set to black (#000000) and the foreground color FG to pink (#FF00FF).
If the quickstart nodes doesn’t suit your task try to operate some developer nodes from the xod-dev/st7735-display library. Initializie your display using the device nodes from the library - st7735-128x160-b-device, st7735-128x160-g-device, st7735-128x160-rg-device, and st7735-128x160-rr-device.
While in theory an Arduino can run any LCD, we believe that some LCDs are particularly suited to being an Arduino LCD display. We"ve currated this list of LCD displays that will make any Arduino-based project shine.
Which brings us to the second factor in choosing an Arduino display: the number of pixels. We typically recommend a display with a resolution of 320x240 or less for use with Arduino. Take for example a 320x240 24-bit display. Such a display takes 230,400 bytes *(8 + 2) = 2,304,000 bits for a single frame. Divide that by 8,000,000 (Arduino SPI speed of 8MHZ) = 0.288 seconds per frame or 3.5 frames per second. 3.5 fps is fast enough for many applications, but is not particularly quick. Using fewer bits-per-pixel or a display with fewer pixels will result in higher frame rates. Use the calculator below to calculate the frame rate for a display using SPI with an Arduino.
An excellent new compatible library is available which can render TrueType fonts on a TFT screen (or into a sprite). This has been developed by takkaO and is available here. I have been reluctant to support yet another font format but this is an amazing library which is very easy to use. It provides access to compact font files, with fully scaleable anti-aliased glyphs. Left, middle and right justified text can also be printed to the screen. I have added TFT_eSPI specific examples to the OpenFontRender library and tested on RP2040 and ESP32 processors, however the ESP8266 does not have sufficient RAM. Here is a demo screen where a single 12kbyte font file binary was used to render fully anti-aliased glyphs of gradually increasing size on a 320x480 TFT screen:
The TFT configuration (user setup) can now be included inside an Arduino IDE sketch providing the instructions in the example Generic->Sketch_with_tft_setup are followed. See ReadMe tab in that sketch for the instructions. If the setup is not in the sketch then the library settings will be used. This means that "per project" configurations are possible without modifying the library setup files. Please note that ALL the other examples in the library will use the library settings unless they are adapted and the "tft_setup.h" header file included. Note: there are issues with this approach, #2007 proposes an alternative method.
Support has been added in v2.4.70 for the RP2040 with 16 bit parallel displays. This has been tested and the screen update performance is very good (4ms to clear 320 x 480 screen with HC8357C). The use of the RP2040 PIO makes it easy to change the write cycle timing for different displays. DMA with 16 bit transfers is also supported.
Smooth fonts can now be rendered direct to the TFT with very little flicker for quickly changing values. This is achieved by a line-by-line and block-by-block update of the glyph area without drawing pixels twice. This is a "breaking" change for some sketches because a new true/false parameter is needed to render the background. The default is false if the parameter is missing, Examples:
Frank Boesing has created an extension library for TFT_eSPI that allows a large range of ready-built fonts to be used. Frank"s library (adapted to permit rendering in sprites as well as TFT) can be downloaded here. More than 3300 additional Fonts are available here. The TFT_eSPI_ext library contains examples that demonstrate the use of the fonts.
Users of PowerPoint experienced with running macros may be interested in the pptm sketch generator here, this converts graphics and tables drawn in PowerPoint slides into an Arduino sketch that renders the graphics on a 480x320 TFT. This is based on VB macros created by Kris Kasprzak here.
The RP2040 8 bit parallel interface uses the PIO. The PIO now manages the "setWindow" and "block fill" actions, releasing the processor for other tasks when areas of the screen are being filled with a colour. The PIO can optionally be used for SPI interface displays if #define RP2040_PIO_SPI is put in the setup file. Touch screens and pixel read operations are not supported when the PIO interface is used.
DMA can now be used with the Raspberry Pi Pico (RP2040) when used with both 8 bit parallel and 16 bit colour SPI displays. See "Bouncy_Circles" sketch.
The library now provides a "viewport" capability. See "Viewport_Demo" and "Viewport_graphicstest" examples. When a viewport is defined graphics will only appear within that window. The coordinate datum by default moves to the top left corner of the viewport, but can optionally remain at top left corner of TFT. The GUIslice library will make use of this feature to speed up the rendering of GUI objects (see #769).
An Arduino IDE compatible graphics and fonts library for 32 bit processors. The library is targeted at 32 bit processors, it has been performance optimised for STM32, ESP8266 and ESP32 types. The library can be loaded using the Arduino IDE"s Library Manager. Direct Memory Access (DMA) can be used with the ESP32, RP2040 and STM32 processors with SPI interface displays to improve rendering performance. DMA with a parallel interface is only supported with the RP2040.
"Four wire" SPI and 8 bit parallel interfaces are supported. Due to lack of GPIO pins the 8 bit parallel interface is NOT supported on the ESP8266. 8 bit parallel interface TFTs (e.g. UNO format mcufriend shields) can used with the STM32 Nucleo 64/144 range or the UNO format ESP32 (see below for ESP32).
The library supports some TFT displays designed for the Raspberry Pi (RPi) that are based on a ILI9486 or ST7796 driver chip with a 480 x 320 pixel screen. The ILI9486 RPi display must be of the Waveshare design and use a 16 bit serial interface based on the 74HC04, 74HC4040 and 2 x 74HC4094 logic chips. Note that due to design variations between these displays not all RPi displays will work with this library, so purchasing a RPi display of these types solely for use with this library is not recommended.
Some displays permit the internal TFT screen RAM to be read, a few of the examples use this feature. The TFT_Screen_Capture example allows full screens to be captured and sent to a PC, this is handy to create program documentation.
The library includes a "Sprite" class, this enables flicker free updates of complex graphics. Direct writes to the TFT with graphics functions are still available, so existing sketches do not need to be changed.
A Sprite is notionally an invisible graphics screen that is kept in the processors RAM. Graphics can be drawn into the Sprite just as they can be drawn directly to the screen. Once the Sprite is completed it can be plotted onto the screen in any position. If there is sufficient RAM then the Sprite can be the same size as the screen and used as a frame buffer. Sprites by default use 16 bit colours, the bit depth can be set to 8 bits (256 colours) , or 1 bit (any 2 colours) to reduce the RAM needed. On an ESP8266 the largest 16 bit colour Sprite that can be created is about 160x128 pixels, this consumes 40Kbytes of RAM. On an ESP32 the workspace RAM is more limited than the datasheet implies so a 16 bit colour Sprite is limited to about 200x200 pixels (~80Kbytes), an 8 bit sprite to 320x240 pixels (~76kbytes). A 1 bit per pixel Sprite requires only 9600 bytes for a full 320 x 240 screen buffer, this is ideal for supporting use with 2 colour bitmap fonts.
One or more sprites can be created, a sprite can be any pixel width and height, limited only by available RAM. The RAM needed for a 16 bit colour depth Sprite is (2 x width x height) bytes, for a Sprite with 8 bit colour depth the RAM needed is (width x height) bytes. Sprites can be created and deleted dynamically as needed in the sketch, this means RAM can be freed up after the Sprite has been plotted on the screen, more RAM intensive WiFi based code can then be run and normal graphics operations still work.
Drawing graphics into a sprite is very fast, for those familiar with the Adafruit "graphicstest" example, this whole test completes in 18ms in a 160x128 sprite. Examples of sprite use can be found in the "examples/Sprite" folder.
If an ESP32 board has SPIRAM (i.e. PSRAM) fitted then Sprites will use the PSRAM memory and large full screen buffer Sprites can be created. Full screen Sprites take longer to render (~45ms for a 320 x 240 16 bit Sprite), so bear that in mind.
The "Animated_dial" example shows how dials can be created using a rotated Sprite for the needle. To run this example the TFT interface must support reading from the screen RAM (not all do). The dial rim and scale is a jpeg image, created using a paint program.
The XPT2046 touch screen controller is supported for SPI based displays only. The SPI bus for the touch controller is shared with the TFT and only an additional chip select line is needed. This support will eventually be deprecated when a suitable touch screen library is available.
The library supports SPI overlap on the ESP8266 so the TFT screen can share MOSI, MISO and SCLK pins with the program FLASH, this frees up GPIO pins for other uses. Only one SPI device can be connected to the FLASH pins and the chips select for the TFT must be on pin D3 (GPIO0).
The library contains proportional fonts, different sizes can be enabled/disabled at compile time to optimise the use of FLASH memory. Anti-aliased (smooth) font files in vlw format stored in SPIFFS are supported. Any 16 bit Unicode character can be included and rendered, this means many language specific characters can be rendered to the screen.
Configuration of the library font selections, pins used to interface with the TFT and other features is made by editing the User_Setup.h file in the library folder, or by selecting your own configuration in the "User_Setup_Selet,h" file. Fonts and features can easily be enabled/disabled by commenting out lines.
Anti-aliased (smooth) font files in "vlw" format are generated by the free Processing IDE using a sketch included in the library Tools folder. This sketch with the Processing IDE can be used to generate font files from your computer"s font set or any TrueType (.ttf) font, the font file can include any combination of 16 bit Unicode characters. This means Greek, Japanese and any other UCS-2 glyphs can be used. Character arrays and Strings in UTF-8 format are supported.
It would be possible to compress the vlw font files but the rendering performance to a TFT is still good when storing the font file(s) in SPIFFS, LittleFS or FLASH arrays.
Anti-aliased fonts can also be drawn over a gradient background with a callback to fetch the background colour of each pixel. This pixel colour can be set by the gradient algorithm or by reading back the TFT screen memory (if reading the display is supported).
The common 8 bit "Mcufriend" shields are supported for the STM Nucleo 64/144 boards and ESP32 UNO style board. The STM32 "Blue/Black Pill" boards can also be used with 8 bit parallel displays.
Unfortunately the typical UNO/mcufriend TFT display board maps LCD_RD, LCD_CS and LCD_RST signals to the ESP32 analogue pins 35, 34 and 36 which are input only. To solve this I linked in the 3 spare pins IO15, IO33 and IO32 by adding wires to the bottom of the board as follows:
If you load a new copy of TFT_eSPI then it will overwrite your setups if they are kept within the TFT_eSPI folder. One way around this is to create a new folder in your Arduino library folder called "TFT_eSPI_Setups". You then place your custom setup.h files in there. After an upgrade simply edit the User_Setup_Select.h file to point to your custom setup file e.g.:
The library was intended to support only TFT displays but using a Sprite as a 1 bit per pixel screen buffer permits support for the Waveshare 2 and 3 colour SPI ePaper displays. This addition to the library is experimental and only one example is provided. Further examples will be added.
In these videos, the SPI (GPIO) bus is referred to being the bottleneck. SPI based displays update over a serial data bus, transmitting one bit per clock cycle on the bus. A 320x240x16bpp display hence requires a SPI bus clock rate of 73.728MHz to achieve a full 60fps refresh frequency. Not many SPI LCD controllers can communicate this fast in practice, but are constrained to e.g. a 16-50MHz SPI bus clock speed, capping the maximum update rate significantly. Can we do anything about this?
The fbcp-ili9341 project started out as a display driver for the Adafruit 2.8" 320x240 TFT w/ Touch screen for Raspberry Pi display that utilizes the ILI9341 controller. On that display, fbcp-ili9341 can achieve a 60fps update rate, depending on the content that is being displayed. Check out these videos for examples of the driver in action:
This driver does not utilize the notro/fbtft framebuffer driver, so that needs to be disabled if active. That is, if your /boot/config.txt file has lines that look something like dtoverlay=pitft28r, ..., dtoverlay=waveshare32b, ... or dtoverlay=flexfb, ..., those should be removed.
-DPIRATE_AUDIO_ST7789_HAT=ON: If specified, targets a Pirate Audio 240x240, 1.3inch IPS LCD display HAT for Raspberry Pi with ST7789 display controller
-DKEDEI_V63_MPI3501=ON: If specified, targets a KeDei 3.5 inch SPI TFTLCD 480*320 16bit/18bit version 6.3 2018/4/9 display with MPI3501 display controller.
-DGPIO_TFT_DATA_CONTROL=number: Specifies/overrides which GPIO pin to use for the Data/Control (DC) line on the 4-wire SPI communication. This pin number is specified in BCM pin numbers. If you have a 3-wire SPI display that does not have a Data/Control line, set this value to -1, i.e. -DGPIO_TFT_DATA_CONTROL=-1 to tell fbcp-ili9341 to target 3-wire ("9-bit") SPI communication.
-DGPIO_TFT_RESET_PIN=number: Specifies/overrides which GPIO pin to use for the display Reset line. This pin number is specified in BCM pin numbers. If omitted, it is assumed that the display does not have a Reset pin, and is always on.
-DGPIO_TFT_BACKLIGHT=number: Specifies/overrides which GPIO pin to use for the display backlight line. This pin number is specified in BCM pin numbers. If omitted, it is assumed that the display does not have a GPIO-controlled backlight pin, and is always on. If setting this, also see the #define BACKLIGHT_CONTROL option in config.h.
Here is a full example of what to type to build and run, if you have the Adafruit 2.8" 320x240 TFT w/ Touch screen for Raspberry Pi with ILI9341 controller:
These lines hint native applications about the default display mode, and let them render to the native resolution of the TFT display. This can however prevent the use of the HDMI connector, if the HDMI connected display does not support such a small resolution. As a compromise, if both HDMI and SPI displays want to be used at the same time, some other compatible resolution such as 640x480 can be used. See Raspberry Pi HDMI documentation for the available options to do this.
Perhaps a bit counterintuitively, underclock the core. Setting a smaller core frequency than the default turbo 400MHz can enable using a smaller clock divider to get a higher resulting SPI bus speed. For example, if with default core_freq=400 SPI CDIV=8 works (resulting in SPI bus speed 400MHz/8=50MHz), but CDIV=6 does not (400MHz/6=66.67MHz was too much), you can try lowering core_freq=360 and set CDIV=6 to get an effective SPI bus speed of 360MHz/6=60MHz, a middle ground between the two that might perhaps work. Balancing core_freq= and CDIV options allows one to find the maximum SPI bus speed up to the last few kHz that the display controller can tolerate. One can also try the opposite direction and overclock, but that does then of course have all the issues that come along when overclocking. Underclocking does have the drawback that it makes the Pi run slower overall, so this is certainly a tradeoff.
A pleasing aspect of fbcp-ili9341 is that it introduces very little latency overhead: on a 119Hz refreshing ILI9341 display, fbcp-ili9341 gets pixels as response from GPIO input to screen in well less than 16.66 msecs time. I only have a 120fps recording camera, so can"t easily measure delays shorter than that, but rough statistical estimate of slow motion video footage suggests this delay could be as low as 2-3 msecs, dominated by the ~8.4msecs panel refresh rate of the ILI9341.
You can however choose between two distinct types of tearing artifacts: straight line tearing and diagonal tearing. Whichever looks better is a bit subjective, which is why both options exist. I prefer the straight line tearing artifact, it seems to be less intrusive than the diagonal tearing one. To toggle this, edit the option #define DISPLAY_FLIP_ORIENTATION_IN_SOFTWARE in config.h. When this option is enabled, fbcp-ili9341 produces straight line tearing, and consumes a tiny few % more CPU power. By default Pi 3B builds with straight line tearing, and Pi Zero with the faster diagonal tearing. Check out the video Latency and tearing test #2: GPIO input to display latency in fbcp-ili9341 and tearing modes to see in slow motion videos how these two tearing modes look like.
Another option that is known to affect how the tearing artifact looks like is the internal panel refresh rate. For ILI9341 displays this refresh rate can be adjusted in ili9341.h, and this can be set to range between ILI9341_FRAMERATE_61_HZ and ILI9341_FRAMERATE_119_HZ (default). Slower refresh rates produce less tearing, but have higher input-to-display latency, whereas higher refresh rates will result in the opposite. Again visually the resulting effect is a bit subjective.
If USE_GPU_VSYNC is disabled, then a busy spinning GPU frame snapshotting thread is used to drive the updates. This will produce smoother animation in content that does not maintain a fixed 60Hz rate. Especially in OpenTyrian, a game that renders at a fixed 36fps and has slowly scrolling scenery, the stuttering caused by USE_GPU_VSYNC is particularly visible. Running on Pi 3B without USE_GPU_VSYNC enabled produces visually smoother looking scrolling on an Adafruit 2.8" ILI9341 PiTFT set to update at 119Hz, compared to enabling USE_GPU_VSYNC on the same setup. Without USE_GPU_VSYNC, the dedicated frame polling loop thread "finds" the 36Hz update rate of the game, and then pushes pixels to the display at this exact rate. This works nicely since SPI displays disregard vsync - the result is that frames are pushed out to the SPI display immediately as they become available, instead of pulling them at a fixed 60Hz rate like HDMI does.
At the moment fbcp-ili9341 is only likely to work on 32-bit OSes, on Raspbian/Ubuntu/Debian family of distributions, where Broadcom and DispmanX libraries are available. 64-bit operating systems do not currently work (see issue #43). It should be possible to port the driver to 64-bit and other OSes, though the amount of work has not been explored.
If fbcp-ili9341 does not support your display controller, you will have to write support for it. fbcp-ili9341 does not have a "generic SPI TFT driver routine" that might work across multiple devices, but needs specific code for each. If you have the spec sheet available, you can ask for advice, but please do not request to add support to a display controller "blind", that is not possible.
Perhaps. This is a more recent experimental feature that may not be as stable, and there are some limitations, but 3-wire ("9-bit") SPI display support is now available. If you have a 3-wire SPI display, i.e. one that does not have a Data/Control (DC) GPIO pin to connect, configure it via CMake with directive -DGPIO_TFT_DATA_CONTROL=-1 to tell fbcp-ili9341 that it should be driving the display with 3-wire protocol.
Displays that have a 16-bit wide command word, such as ILI9486, do not currently work in 3-wire ("17-bit") mode. (But ILI9486L has 8-bit command word, so that does work)
I have done close to everything possible to my displays - cut power in middle of operation, sent random data and command bytes, set their operating voltage commands and clock timings to arbitrary high and low values, tested unspecified and reserved command fields, and driven the displays dozens of MHz faster than they managed to keep up with, and I have not yet done permanent damage to any of my displays or Pis.
In this kind of mode, you would probably strip the DispmanX bits out of fbcp-ili9341, and recast it as a static library that you would link to in your drawing application, and instead of snapshotting frames, you can then programmatically write to a framebuffer in memory from your C/C++ code.
make sure the display is configured to run 4-wire SPI mode, and not in parallel mode or 3-wire SPI mode. You may need to solder or desolder some connections or set a jumper to configure the specific driving mode. Support for 3-wire SPI displays does exist, but it is more limited and a bit experimental.
This suggests that the power line or the backlight line might not be properly connected. Or if the backlight connects to a GPIO pin on the Pi (and not a voltage pin), then it may be that the pin is not in correct state for the backlight to turn on. Most of the LCD TFT displays I have immediately light up their backlight when they receive power. The Tontec one has a backlight GPIO pin that boots up high but must be pulled low to activate the backlight. OLED displays on the other hand seem to stay all black even after they do get power, while waiting for their initialization to be performed, so for OLEDs it may be normal for nothing to show up on the screen immediately after boot.
If the backlight connects to a GPIO pin, you may need to define -DGPIO_TFT_BACKLIGHT=
All the ILI9341 displays work nice and super fast at ~70-80MHz. My WaveShare 3.5" 320x480 ILI9486 display runs really slow compared to its pixel resolution, ~32MHz only. See fbcp-ili9341 ported to ILI9486 WaveShare 3.5" (B) SpotPear 320x480 SPI display for a video of this display in action. Adafruit"s 320x480 3.5" HX8357D PiTFTs is ~64% faster in comparison.
The ILI9486L controller based maithoga display runs a bit faster than ILI9486 WaveShare, 50MHz versus 31.88MHz, i.e. +56.8% bandwidth increase. However fps-wise maithoga reaches only 13.56 vs WaveShare 12.97 fps, because the bandwidth advantage is fully lost in pixel format differences: ILI9486L requires transmitting 24 bits per each pixel (R6G6B6 mode), whereas ILI9486 supports 16 bits per pixel R5G6B5 mode. This is reflected in the above chart refresh rate for the maithoga display (marked with a star).
Tomáš Suk, Cyril Höschl IV, and Jan Flusser, Rectangular Decomposition of Binary Images., a useful research paper about merging monochrome bitmap images to rectangles, which gave good ideas for optimizing SPI span merges across multiple scan lines,
Improve support for 3-wire displays, e.g. for 1) "17-bit" 3-wire communication, 2) fix up SPI_3WIRE_PROTOCOL + ALL_TASKS_SHOULD_DMA to work together, or 3) fix up SPI_3WIRE_PROTOCOL + OFFLOAD_PIXEL_COPY_TO_DMA_CPP to work together.
Optimize away unnecessary zero padding that 3-wire communication currently incurs, by keeping a queue of leftover untransmitted partial bits of a byte, and piggybacking them onto the next transfer that comes in.
And here is how the TFT looks. As you see it also has a port for an SD card if you want to use e.g. for reading images from it. In my case, I didn’t connect it.
Once you have the connections ready next step is to install the TFT library in your Arduino IDE. Go to Tools – > Manage Libraries and then search for TFT_eSPI and click install. Alternatively, crab the lib from here.
Q: Do yo have LCD modules in stock?A: We don’t have products in stock now. But we may prepare some later on, please feel free to ask our staff to check.
A: Please ask your engineer for guidance to make sure the size of your product(length*width*thickness in mm) and the function of it. Based on the above information, we will suggest the ideal size of the LCD module for your product.
A: Think about the following key points to define a model you need, such as size/resolution/thickness/LCD interface/view angle/brightness/operation temperature and so on.
Thin film transistor liquid crystal display (TFT-LCD) is a variant of liquid crystal display (LCD) which uses thin-film transistor (TFT) technology to improve image quality (e.g., addressability, contrast).
TFT LCDs are used in television sets, computer monitors, mobile phones, handheld video game systems, personal digital assistants, navigation systems, projectors, etc.
void TFT_16bit_Set_Brush(char brush_enabled, unsigned int brush_color, char gradient_enabled, char gradient_orientation, unsigned int gradient_color_from, unsigned int gradient_color_to);
void TFT_16bit_Rectangle_Round_Edges(unsigned int x_upper_left, unsigned int y_upper_left, unsigned int x_bottom_right, unsigned int y_bottom_right, unsigned int round_radius);
void TFT_16bit_Partial_Image(unsigned int left, unsigned int top, unsigned int width, unsigned int height, code const far unsigned short * image, unsigned short stretch);
void TFT_16bit_Ext_Partial_Image(unsigned int left, unsigned int top, unsigned int width, unsigned int height, unsigned long image, unsigned short stretch);
Many Arduino projects use monochrome display, one of the reason is the limited resources of a MCU. 320 pixels width, 240 pixels height and 8 bits color for each RGB color channel means 230 KB for each full screen picture. But normal Arduino (ATmega328) only have 32 KB flash and it is time consuming (over a second) to read data from SD card and draw it to the color display.
ESP32 have changed the game! It have much faster processing power (16 MHz vs 240 MHz dual core), much more RAM (2 KB vs over 200 KB) and much more flash (32 KB vs 4 MB), so it is capable to utilize more color and higher resolution image for displaying. At the same time it is capable to do some RAM hungry process such as Animated GIF, JPEG or PNG file decoding, it is a very important feature for displaying information gathered from the internet.
Color display have many type of interfaces: Serial Peripheral Interface (SPI), 6-bit, 8-bit, 16-bit, 18-bit and 24-bit parallel interfaces and also NeoPixel!
SPI dominate the hobby electronics market, most likely because of fewer wire required to connect. Most display in my drawer only have SPI pins breaking out, so this instructables focus on SPI display and a few 8-bit display.
There are various color display for hobby electronics: LCD, IPS LCD, OLED with different resolutions and different driver chips. LCD can have higher image density but OLED have better viewable angle, IPS LCD can have both. OLED have more power efficient for each light up pixel but may have burn-in problems. Color OLED operate in 14 V, it means you need a dedicate step-up circuit, but it is not a problem if you simply use with a break-out board. LCD in most case can direct operate in 3.3 V, the same operating voltage as ESP32, so you can consider not use break out board to make a slimmer product.
For the beginner, I think buying adafruit, or similar supportive vendor, hardware and using its Arduino library can have good seamless experience (though I have no budget to try it all). TFT_eSPI library have better performance but configuration require make changes in the library folder. Ucglib and UTFT-ESP run a little bit slow but it support many hardware and it is a popular library, you can find many Arduino projects using it. LovyanGFX library start appear at 2019, it support many dev device such as M5Stack, M5StickC, TTGO T-Watch, ODROID-GO, ESP-WROVER-KIT, WioTerminal and more. I am also writing a new library called Arduino_GFX since 2019.
OLED have a big advantage, the pixel only draw power if it lights up. On the other hand, LCD back light always draw full power even you are displaying a black screen. So OLED can help save some power for the project powered by a battery.
This is a 1.5" 128 x 128 color OLED, this form factor is very fit for smart-watch-like wearable project. The most barrier of select this should be the price tag is around 4 times of a normal LCD.
This is the highest resolution color OLED I can find in hobby electronics market, it is a 1.69" 160x128 color OLED. Due to the large size breakout board, I have no idea how to use it yet.
ST7735 is a very popular LCD driver model for the resolution 128x128 and 128x160. It may cause by its popularity, there are many manufacturer produce compatible product. However, they are not fully compatible.
Thanks for the popularity of wearable gadget, I can find more small size IPS LCD in the market this year(2018). The above picture is an 0.96" 80x160 IPS color LCD using ST7735 driver chip. As you can see in the 3rd picture, you can treat it as a 128x160 color display in code but only the middle part is actually displaying. The 4th picture is the display without breakout board, it is thin, tiny and very fit for a wearable project!
It is a 2.2" 176x220 color LCD. It is relatively fewer projects using this chips and resolution. It may caused by the success of its chip family brother, ILI9341 (0.2" larger in size but have near double resolution).
I think ILI9341 is the most popular LCD driver chip in the hobby electronics market. In most case it is 240x320 resolution and have many screen size from 1.7" to 3.5". Some breakout board also built-in touch screen feature.
This also the highest pixel density color display in my drawer. As same as normal LCD, it can direct operate in 3.3 V, so it is very good for making slim wearable device.
The display speed is one of the most important thing we consider to select which library. I have chosen TFT_eSPI PDQ test for this comparison. I have made some effort to rewrite the PDQ test that can run in 4 libraries. All test will run with the same 2.8" ILI9341 LCD.
As I found TFT_eSPI is the most potential display library for ESP32 in this instructables, I have paid some effort to add support for all my display in hand. The newly added display support marked letter M in red at the above picture, here is my enhanced version:
Note: The most difficult part using this library is you are required to configure this library before you can use it. The configuration file is located at the library folder, it should be "Arduino/libraries/TFT_eSPI/User_setup.h" under you own documents folder. It have many comments help you to do that, please follow the comments step by step to finish the configuration. Here is my User_setup.h for ILI9341:
#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
ST7735 and ILI9341 are the most popular display, this 2 are better option for the beginner. You may notice LCD have a big weakness, the viewable angle, some color lost outside the viewable angle and the screen become unreadable. If you have enough budget, OLED or IPS LCD have much better viewable angle.
In most case, we study how to use a code library by searching sample on the web. I have tried search four libraries keyword in Github, Adafruit is most popular and UTFT the second.
ILI9341 should be most valuable display for the beginner. Adafruit GFX Library should be most easy to use for the beginner, and since TFT_eSPI have very similar method signature, it is very easy to switch to a faster library later on.
OLED require 14 V to light up the pixel so it is not easy to decouple the breakout board. On the other hand, LCD (also IPS LCD) usually operate in 3.3 V, as same as the ESP32. In most case, there are only the LED control circuit required between LCD and ESP32, i.e. a transistor and few resistors. So it relatively easy to make it.
It is very important to read the data sheet first before you decide not using breakout board. The pins layout, pin pitch size, the sample circuit connection and maximum rating all you can find in data sheet. The maximum voltage is especially important, you should sticky follow the rating or you will blow your LCD. The chip can operate in 3.3 V but LED may be 2.8 - 3.0 V so it require some electronics in the middle, most data sheet have the sample circuit. You may ask your seller send a soft copy of data sheet to you or simply Google it by the model number.
My special hint: I like to soldering a FPC cable with the same pin pitch size as the LCD to help the connection with the MCU. I have used this technique in these instructables:
If you read through the data sheet of the color display, you may find most of color display can support 18 bit color depth (6 bit for each RGB channel). 18 bit color depth can have a better image quality that 16 bit color depth (5 bit in red and blue channel, 6 bit for green channel). However, only Ucglib actually run at 18 bit color depth (262,144 colors), other 3 libraries all run at 16 bit color depth (65,536 colors). It is because 18 bit color depth actually require transfer 3 bytes (24 bit) of data for each pixel, it means 50% more data require to transfer and store in memory. It is one of the reason why Ucglib run slower, but it can have a better image quality.
Bonjour merci pour ce gros projet très instructifs. J"ai acheté un mini ips (rgb)0,96"80x160 et je n"arrive pas à trouver de librairie valide, j"utilise la librairie st7735 mais j"ai deux lignes de bruit sur le côté et en bas. J"ai testé toutes les inclinaison mais c"est toujours la. Et j"aimerais bien afficher une image . bmp dessus mais je ne sais pas comment connecter mon lecteur de carte micro sd externe vue que l"écran et le lecteur utilise des pins identique. Peut-être auriez vous une solution à me proposer ?
CS stands for cable select, it tell the device the SPI is active for that device. If you only have 1 device connected to the the SPI, you can simply pull down the CS pin to tell it always active. It can also simplify the code no need turn CS on and off for each message and run a little bit faster. Some breakout board not wire out CS pin and simply pull it down for you.0
So, basically I make a reset in the beggining (read datasheet) then next I use only SPI_DAT and SPLI_CLK. If I destroy the sequence touching with an oscilloscope, the LCD stops to understand the sequence DAT/CLK and I have to make another reset.
Those 2 pins must be dedicated to the display, otherwise the display will get confused without the CS pin. One DAT/CLK to LCD and another DAT/CLK to I2C.
Hello! Thank"s for your instruction. I want to use your 8pin ili9486 320x480 spi display with one of your presented libraries and esp32. 1.) Could you please tell me the connections between the display and the esp32 and 2.) which numbers do I have to write into the line utft myglcd (ili9486,?,?,?,?)?