cheap alternative to tft display free sample

The Arduino board has a wide variety of compatible displays that you can use in your electronic projects. In most projects, it’s very useful to give the user some sort of feedback from the Arduino.

With the TFT display you can display colorful images or graphics. This module has a resolution of 480 x 320. This module includes the SD card socket and SPI FLASH circuit.

This is a tiny display with just 1 x 0.96 Inch. This display has a black background, and displays characters in white. There are other similar displays that can show the characters in other colors.

cheap alternative to tft display free sample

This is a small graphics library, specifically aimed at ATtiny microcontrollers, for the variety of small colour TFT displays available at low cost from suppliers like Adafruit, AliExpress, or Banggood:

It"s an updated version of my Tiny TFT Graphics Library. This latest version of the library supports both the classic ATtiny processors, such as the ATtiny85, and the new 0-series, 1-series, and 2-series ATtiny processors, such as the ATtiny402. Like the original library it allows you to plot points, draw lines, draw filled rectangles, and plot characters and text with an optional scale factor, in 16-bit colour.

This version adds the ability to plot outline rectanges, and outline and filled circles. I"ve included demo curve-plotting and histogram-plotting programs that adjust to fit any display.

This library supports TFT displays that use an SPI interface and require four pins to drive the display. This leaves one pin free on an 8-pin chip such as the ATtiny85 or ATtiny402. If you need more pins choose a larger chip, such as the ATtiny84 or ATtiny404.

Unlike my Compact TFT Graphics Library which uses standard Arduino SPI calls, this library uses direct I/O pin manipulations. This means that you can use any assignment of pins to the four I/O lines needed by the display, and makes it about twice as fast as one using SPI calls. I"ve also added support for some additional displays, so it now supports 16 different TFT displays.

On the classic ATtiny processors, such as the ATtiny85, the library uses the feature that you can toggle one or more bits in a port by writing to the PINB register; for example, to enable or disable the chip-select signal:

So provided you set all the pins to their disabled state at startup, the display routines can simply toggle the appropriate pins to enable or disable them.

The differences between each family of processors are handled by constants to define the pin assignments, and preprocessor macros to define the bit manipulations. If you use the circuits given below you won"t need to change anything, apart from specifying which display you"re using.

The ClearDisplay() routine has been optimised further by realising that we don"t need to keep setting the mosi bit, since to clear the display it is always zero, so the routine only needs to toggle the sck bit the appropriate number of times. I"m grateful to Thomas Scherer for suggesting this.

This library will work with displays based on the ST7735 which supports a maximum display size of 162x132, or the ST7789 and ILI9340/1 which support a maximum display size of 320x240. It includes parameters for the following colour TFT displays:

* These Adafruit displays conveniently all have the same edge-connector layout, so you can make a prototyping board or PCB that will take any of them, such as my Universal TFT Display Backpack.

Some of the AliExpress displays include a LDO 3.3V regulator, but not logic-level translation, so I recommend only interfacing them to a processor running from 3.3V.

The Adafruit displays all include an LDO 3.3V regulator and logic-level translation, so can be safely interfaced to processors powered from either 5V or 3.3V.

On the AliExpress red 160x128 display you need to connect the backlight pin to Vcc to turn it on. This doesn"t seem to be necessary with the other displays.

The library will probably support other TFT displays that use the same ST7735, ST7789, ILI9340/1 driver chips, but you may need to experiment with the parameters to get the image scaled and centered correctly.

The display needs to be connected to the microcontroller via four I/O lines: MOSI, SCK, CS, and DC. You can use any pins for these, but they should all be in the same port. You need to specify the port pin numbers of the pins you are using at the start of the Tiny TFT Graphics Library listing.

The 33kΩ pullup resistor from the display"s CS pin is optional; it is only needed on the AliExpress displays, and holds the chip select high to prevent the display from flickering while programming the ATtiny85.

The different displays are catered for by seven constants which specify the size of the display, the offsets relative to the area supported by the display driver, whether the display is inverted, the rotation value, and the order of the colours; for example:

By default the parameters give the correct orientation assuming you"re using the display with the header pins along the top, except in the case of the larger displays which have the header pins along the shorter edge, in which case the header pins are assumed to be on the left.

To check or adjust the values for each display you can run the TestChart() program, which draws a one-pixel border around the display area, and plots a red "F" to show the orientation:

The library will probably support other TFT displays that use the same driver chips, but you may need to experiment with the parameters to get the image scaled and centered correctly.

The foreground and background colours are defined by the two global variables fore and back. Initially these are set to White (0xFFFF) and Black (0) respectively:

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:

DrawRect() draws an outline rectangle andFillRect() draws a filled rectangle in the foreground colour with width w and height h, and the bottom left corner at the current drawing position:

You can plot larger characters by setting the global variable scale, default value 1. After plotting a character PlotChar() moves the drawing position to the start of the next character to make it easy to plot several characters in a row without needing to call MoveTo().

By default the ATtiny85 runs at 1MHz. Choose Burn Bootloader to set the fuses for 8MHz operation, or your graphics will run rather slowly, then upload the program using an ISP (in-system programming) programmer such as Sparkfun"s Tiny AVR Programmer Board

cheap alternative to tft display free sample

The content is intended to be updated from time to time, I will add more details if I found new display or library update. You can also help me enrich the content by leaving comments below.

You can run various IoT projects prefectly without any display. But not all IoT project only feed data in single direction (IoT to server), some IoT also gather real time information from the server for displaying.

My previous instructables, ESP32 Photo Clock is am example, it download a current minute photo from the Internet, decode the JPEG photo and display it.

There are various real time information in your server or Internet, such as all rooms temperature in your home, server CPU usage, weather forecast, news, stock price, your downloading file is done, your Youtube channel views :>

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.

NeoPixel matrix is a very special type of color display. If you are interested in NeoPixel matrix display, here are some of my instructables using it:

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.

Software support on the other side also influence your selection. You can develop ESP32 program with Arduino IDE or direct use ESP-IDF. But since ESP-IDF did not have too much display library and not much display hardware supported, so I will concentrate on Arduino display libraries only.

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.

The initial code have some variation, the color order can be RGB or BGR and the y coordinate range also have a few pixels variation. Some library differential it by red, green or black tag but the tag color may not always help. The worst case is alter the tag option one by one until you can see a fine result. The above last picture is an example of using wrong tag option, you can find 3 pixels height noise bar on the top.

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!

SSD1283A is 1.6" 130x130 display, it claim only consume 0.1 in sleep mode and backlight turned off. In sleep mode the last drawn screen still readable under sufficient lighting.

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.

There are many display libraries that can support various hardware. I have picked 4 of most popular Arduino library for comparison:Adafruit GFX Family

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:

Adafruit sell various display module in hobby electronics market and they also have very good support in software level. Their display libraries all built on a parent class called Adafruit_GFX, so I call it Adafruit GFX Family. This library generally support most Arduino hardware (also ESP32).

In Arduino Library Manager simply search "adafruit display", you can see all the family members. If you want to install it, say ILI9341, simply select "Adafruit ILI9341" and then click install. Remember also install its dependent library "Adafruit GFX Library".

This library method signature is very similar to Adafruit GFX, but it is tailor-made for ESP8266 or ESP32. I think the source code is optimised for ESP32, so the PDQ result is much faster than other libraries.

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:

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.

Only Adafruit GFX Family is fully configurable in user code level, other 3 libraries require some configuration in the library folder. And also Adafruit have very good portal, there are many detailed post teach you how to use their products.

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.

Thank you very much for posting this detailed review of the color display option available for "Duino users. You have saved me hours, maybe days of time wandering the web looking for information.0

Great article! Very interested in round displays. There are available round displays based on st7687s (128 * 128) and st7789 (240 * 240), but I have not found any information on practical use.

Hello! Yes, I purchased this display from keyestudio, connected it to esp32 using this library from dfrobot. It is only necessary to consider that the pinout of the display connectors differs from dfrobot and keyestudio.

I"m wanting to connect a VGA camera, the sort you find as a little module on eBay with OVPxxxx chip, to a screen such as ILxxxx family, which appears to have direct VGA input. I think it will work if I connect the camera directly with no MCU, but I"d also like to add a cross-hair to the display (for a drill targetting system). I wonder is it possible to intercept the serial video data and change individual pixels in a streaming fashion, instead of loading a whole screen into memory, changing it and passing it on? I ask because it seems to me it would need a much less powerful MCU.0

Thank you so much for such a great article. I have been trying to choose the best library to use for a project that will use either a SSD1351 or a ST7735 both being 128x128. The key to my project is to be able to dump a frame buffer in to the display and then recalculate the next frame buffer. :)

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,?,?,?,?)?

cheap alternative to tft display free sample

This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.

cheap alternative to tft display free sample

This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.

cheap alternative to tft display free sample

Have used Nextion displays for a number of projects and love them. All you need is RX and TX links and they can be driven by any processor with RX, TX communications. They have sufficient memory to accept jpg files for graphics making coding really easy.

It appears that Itead has worldwide distribution rights (except China). I imagine that TJC aren’t happy that their 0.55 editor version improvements that would gain them extra sales are being ignored. Instead, Nextion want paying extra for what we would call ‘product support’

Whilst I can use Nextion editor and Arduino IDE, I’m not in the same league as say Iuma and hag and similar experts who know what’s going on deep down.

But I do know that the Arduino, Esp and Esp8266 have usb, serial and SPI comms so why not attach one of these processors to a standard SPI touch screen, then develop a library and GUI similar to Nextion but with added features, which could also include remote firmware updates. If the Esp was used, then that includes GPIO pins.

Costly? – I don’t think so - have priced a 3.5 inch touch screen and Esp for less than £8.00 retail. I pay about £20 for same size Nextion. Surely that would allow a manufacturer to get reasonable profit margin for a superior product.

cheap alternative to tft display free sample

ER-TFT043A2-3 is 480x272 dots 4.3" color tft lcd module display with driver IC ST7282 and optional capacitive touch panel with controller and connector,optional 4-wire resistive touch panel with connector,superior display quality,wide view angle and easily controlled by MCU such as 8051, PIC, AVR, ARDUINO,ARM and Raspberry PI .

It can be used in any embedded systems,car,mp4,gps,industrial device,security and hand-held equipment which requires display in high quality and colorful image.It supports rgb interface. FPC with zif connector is easily to assemble or remove.Of course, we wouldn"t just leave you with a datasheet and a "good luck!".Here is the link for 4.3"TFT Touch Shield with Libraries, Examples.Schematic Diagram for Arduino Due,Mega 2560,Uno and 8051 Microcontroller Development Board&Kit.

cheap alternative to tft display free sample

Providing a high level of design flexibility and user-friendly programming, the Graphic PMVA technology from GTK and is a cost-effective alternative to TFTs. Since the display can adapt dynamically to show what is required, customers can achieve a greater level of customisation and are not restrained to one single layout by use of graphic technology over segment and icons.

The PMVA technology features a negative transmissive display, which offers a very black contrast ratio, and typically comes with a white LED backlight, though other colours are available on request. Colour content can be added via silk screen printing for fixed colour content, or an LED array which offers a greater choice of backlit colour combinations.

The PMVA is a high performance product with good all-round viewing angles, a high contrast ratio and can operate in temperatures ranging from -10 to +80°C. It has an operating life of 100,000 hours MTBF and interface to the PCB can be achieved via flexible printed circuit (FPC) or metal pins.

"The addition of graphics to PMVA display technology really opens up opportunities for OEMs. The ability to add graphics dynamically means that they can utilise PMVA as a standard technology across their range but still produce custom solutions for different markets or applications: an example of this would be designing and programming the displays for different language requirements. This can also result in economies of scale. Programming this type of display is simpler and less time consuming when compared with TFTs and this assists in reducing time to market for new products. The versatility of this product makes it ideal for a wide variety of market applications,” commented: Clive Dickinson, Business Manager, Optoelectronics, GTK.

cheap alternative to tft display free sample

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:

Given that the SPI bus can be so constrained on bandwidth, how come fbcp-ili9341 seems to be able to update at up to 60fps? The way this is achieved is by what could be called adaptive display stream updates. Instead of uploading each pixel at each display refresh cycle, only the actually changed pixels on screen are submitted to the display. This is doable because the ILI9341 controller, as many other popular controllers, have communication interface functions that allow specifying partial screen updates, down to subrectangles or even individual pixel levels. This allows beating the bandwidth limit: for example in Quake, even though it is a fast pacing game, on average only about 46% of all pixels on screen change each rendered frame. Some parts, such as the UI stay practically constant across multiple frames.

A hybrid of both Polled Mode SPI and DMA based transfers are utilized. Long sequential transfer bursts are performed using DMA, and when DMA would have too much latency, Polled Mode SPI is applied instead.

Undocumented BCM2835 features are used to squeeze out maximum bandwidth: SPI CDIV is driven at even numbers (and not just powers of two), and the SPI DLEN register is forced in non-DMA mode to avoid an idle 9th clock cycle for each transferred byte.

Good old interlacing is added into the mix: if the amount of pixels that needs updating is detected to be too much that the SPI bus cannot handle it, the driver adaptively resorts to doing an interlaced update, uploading even and odd scanlines at subsequent frames. Once the number of pending pixels to write returns to manageable amounts, progressive updating is resumed. This effectively doubles the maximum display update rate. (If you do not like the visual appearance that interlacing causes, it is easy to disable this by uncommenting the line #define NO_INTERLACING in file config.h)

A number of other micro-optimization techniques are used, such as batch updating rectangular spans of pixels, merging disjoint-but-close spans of pixels on the same scanline, and latching Column and Page End Addresses to bottom-right corner of the display to be able to cut CASET and PASET messages in mid-communication.

The result is that the SPI bus can be kept close to 100% saturation, ~94-97% usual, to maximize the utilization rate of the bus, while only transmitting practically the minimum number of bytes needed to describe each new frame.

although not all boards are actively tested on, so ymmv especially on older boards. (Bug fixes welcome, use https://elinux.org/RPi_HardwareHistory to identify which board you are running on)

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.

Likewise, if you have any touch controller related dtoverlays active, such as dtoverlay=ads7846,... or anything that has a penirq= directive, those should be removed as well to avoid conflicts. It would be possible to add touch support to fbcp-ili9341 if someone wants to take a stab at it.

If you have been running existing fbcp driver, make sure to remove that e.g. via a sudo pkill fbcp first (while running in SSH prompt or connected to a HDMI display), these two cannot run at the same time. If /etc/rc.local or /etc/init.d contains an entry to start up fbcp at boot, that directive should be deleted.

When using one of the displays that stack on top of the Pi that are already recognized by fbcp-ili9341, you don"t need to specify the GPIO pin assignments, but fbcp-ili9341 code already has those. Pass one of the following CMake directives for the hats:

-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.

If you connected wires directly on the Pi instead of using a Hat from the above list, you will need to use the configuration directives below. In addition to specifying the display, you will also need to tell fbcp-ili9341 which GPIO pins you wired the connections to. To configure the display controller, pass one of:

-DILI9341=ON: If you are running on any other generic ILI9341 display, or on Waveshare32b display that is standalone and not on the FreeplayTech CM3/Zero device, pass this flag.

-DILI9340=ON: If you have a ILI9340 display, pass this directive. ILI9340 and ILI9341 chipsets are very similar, but ILI9340 doesn"t support all of the features on ILI9341 and they will be disabled or downgraded.

-DILI9486L=ON: If you have a ILI9486L display, pass this directive. Note that ILI9486 and ILI9486L are quite different, mutually incompatible controller chips, so be careful here identifying which one you have. (or just try both, should not break if you misidentified)

-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.

fbcp-ili9341 always uses the hardware SPI0 port, so the MISO, MOSI, CLK and CE0 pins are always the same and cannot be changed. The MISO pin is actually not used (at the moment at least), so you can just skip connecting that one. If your display is a rogue one that ignores the chip enable line, you can omit connecting that as well, or might also be able to get away by connecting that to ground if you are hard pressed to simplify wiring (depending on the display).

To get good performance out of the displays, you will drive the displays far out above the rated speed specs (the rated specs yield about ~10fps depending on display). Due to this, you will need to explicitly configure the target speed you want to drive the display at, because due to manufacturing variances each display copy reaches a different maximum speed. There is no "default speed" that fbcp-ili9341 would use. Setting the speed is done via the option

-DSPI_BUS_CLOCK_DIVISOR=even_number: Sets the clock divisor number which along with the Pi core_freq= option in /boot/config.txt specifies the overall speed that the display SPI communication bus is driven at. SPI_frequency = core_freq/divisor. SPI_BUS_CLOCK_DIVISOR must be an even number. Default Pi 3B and Zero W core_freq is 400MHz, and generally a value -DSPI_BUS_CLOCK_DIVISOR=6 seems to be the best that a ILI9341 display can do. Try a larger value if the display shows corrupt output, or a smaller value to get higher bandwidth. See ili9341.h and waveshare35b.h for data points on tuning the maximum SPI performance. Safe initial value could be something like -DSPI_BUS_CLOCK_DIVISOR=30.

There are a couple of options to explicitly say which Pi board you want to target. These should be autodetected for you and generally are not needed, but e.g. if you are cross compiling for another Pi board from another system, or want to be explicit, you can try:

-DSINGLE_CORE_BOARD=ON: Pass this option if you are running on a Pi that has only one hardware thread (Pi Model A, Pi Model B, Compute Module 1, Pi Zero/Zero W). If not present, autodetected.

-DARMV8A=ON: Pass this option to specifically optimize for ARMv8-A instruction set (Pi 2B >= rev. 1.2, 3B, 3B+, CM3, CM3 lite, 4B, CM4, Pi400). If not present, autodetected.

-DBACKLIGHT_CONTROL=ON: If set, enables fbcp-ili9341 to control the display backlight in the given backlight pin. The display will go to sleep after a period of inactivity on the screen. If not, backlight is not touched.

-DDISPLAY_CROPPED_INSTEAD_OF_SCALING=ON: If set, and source video frame is larger than the SPI display video resolution, the source video is presented on the SPI display by cropping out parts of it in all directions, instead of scaling to fit.

-DDISPLAY_BREAK_ASPECT_RATIO_WHEN_SCALING=ON: When scaling source video to SPI display, scaling is performed by default following aspect ratio, adding letterboxes/pillarboxes as needed. If this is set, the stretching is performed breaking aspect ratio.

-DSTATISTICS=number: Specifies the level of overlay statistics to show on screen. 0: disabled, 1: enabled, 2: enabled, and show frame rate interval graph as well. Default value is 1 (enabled).

-DDISPLAY_SWAP_BGR=ON: If this option is passed, red and blue color channels are reversed (RGB<->BGR) swap. Some displays have an opposite color panel subpixel layout that the display controller does not automatically account for, so define this if blue and red are mixed up.

-DDISPLAY_INVERT_COLORS=ON: If this option is passed, pixel color value interpretation is reversed (white=0, black=31/63). Default: black=0, white=31/63. Pass this option if the display image looks like a color negative of the actual colors.

-DLOW_BATTERY_PIN=: Specifies a GPIO pin that can be polled to get the battery state. By default, when this is set, a low battery icon will be displayed if the pin is pulled low (see config.h for ways in which this can be tweaked).

In addition to the above CMake directives, there are various defines scattered around the codebase, mostly in config.h, that control different runtime options. Edit those directly to further tune the behavior of the program. In particular, after you have finished with the setup, you may want to build with -DSTATISTICS=0 option in CMake configuration line.

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:

If the above does not work, try specifying -DSPI_BUS_CLOCK_DIVISOR=8 or =10 to make the display run a little slower, or try with -DUSE_DMA_TRANSFERS=OFF to troubleshoot if DMA might be the issue. If you are using another display controller than ILI9341, using a much higher value, like 30 or 40 may be needed. When changing CMake options, you can reissue the CMake directive line without having to reclone or recreate the build directory. However you may need to manually delete file CMakeCache.txt between changing options to avoid CMake remembering old settings.

If you want to do a full rebuild from scratch, you can rm -rf build to delete the build directory and recreate it for a clean rebuild from scratch. There is nothing special about the name or location of this directory, it is just my usual convention. You can also do the build in some other directory relative to the fbcp-ili9341 directory if you please.

If the user name of your Raspberry Pi installation is something else than the default pi, change the directory accordingly to point to the user"s home directory. (Use pwd to find out the current directory in terminal)

If the size of the default HDMI output /dev/fb0 framebuffer differs from the resolution of the display, the source video size will by default be rescaled to fit to the size of the SPI display. fbcp-ili9341 will manage setting up this rescaling if needed, and it will be done by the GPU, so performance should not be impacted too much. However if the resolutions do not match, small text will probably appear illegible. The resizing will be done in aspect ratio preserving manner, so if the aspect ratios do not match, either horizontal or vertical black borders will appear on the display. If you do not use the HDMI output at all, it is probably best to configure the HDMI output to match the SPI display size so that rescaling will not be needed. This can be done by setting the following lines in /boot/config.txt:

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.

The refresh speed of the display is dictated by the clock speed of the SPI bus that the display is connected to. Due to the way the BCM2835 chip on Raspberry Pi works, there does not exist a simple speed=xxx Mhz option that could be set to define the bus speed. Instead, the SPI bus speed is derived from two separate parameters: the core frequency of the BCM2835 SoC in general (core_freq in /boot/config.txt), and the SPI peripheral CDIV (Clock DIVider) setting. Together, the resulting SPI bus speed is then calculated with the formula SPI_speed=core_freq/CDIV.

Adjust the CDIV value by passing the directive -DSPI_BUS_CLOCK_DIVISOR=number in CMake command line. Possible values are even numbers 2, 4, 6, 8, .... Note that since CDIV appears in the denominator in the formula for SPI_speed, smaller values result in higher bus speeds, whereas higher values make the display go slower. Initially when you don"t know how fast your display can run, try starting with a safe high setting, such as -DSPI_BUS_CLOCK_DIVISOR=30, and work your way to smaller numbers to find the maximum speed the display can cope with. See the table at the end of the README for specific observed maximum bus speeds for different displays.

Ensure turbo speed. This is critical for good frame rates. On the Raspberry Pi 3 Model B, the BCM2835 core runs by default at 400MHz (resulting in 400/CDIV MHz SPI speed) if there is enough power provided to the Pi, and if the CPU temperature does not exceed thermal limits. If the CPU is idle, or voltage is low, the BCM2835 core will instead revert to non-turbo 250MHz state, resulting in 250/CDIV MHz SPI speed. This effect of turbo speed on performance is significant, since 400MHz vs non-turbo 250MHz comes out to +60% of more bandwidth. Getting 60fps in Quake, Sonic or Tyrian often requires this turbo frequency, but e.g. NES and C64 emulated games can often reach 60fps even with the stock 250MHz. If for some reason under-voltage protection is kicking in even when enough power should be fed, you can force-enable turbo when low voltage is present by setting the value avoid_warnings=2 in the file /boot/config.txt.

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.

On the other hand, it is desirable to control how much CPU time fbcp-ili9341 is allowed to use. The default build settings are tuned to maximize the display refresh rate at the expense of power consumption on Pi 3B. On Pi Zero, the opposite is done, i.e. by default the driver optimizes for battery saving instead of maximal display update speed. The following options can be controlled to balance between these two:

The main option to control CPU usage vs performance aspect is the option #define ALL_TASKS_SHOULD_DMA in config.h. Enabling this option will greatly reduce CPU usage. If this option is disabled, SPI bus utilization is maximized but CPU usage can be up to 80%-120%. When this option is enabled, CPU usage is generally up to around 15%-30%. Maximal CPU usage occurs when watching a video, or playing a fast moving game. If nothing is changing on the screen, CPU consumption of the driver should go down very close to 0-5%. By default #define ALL_TASKS_SHOULD_DMA is enabled for Pi Zero, but disabled for Pi 3B.

The CMake option -DUSE_DMA_TRANSFERS=ON should always be enabled for good low CPU usage. If DMA transfers are disabled, the driver will run in Polled SPI mode, which generally utilizes a full dedicated single core of CPU time. If DMA transfers are causing issues, try adjusting the DMA send and receive channels to use for SPI communication with -DDMA_TX_CHANNEL= and -DDMA_RX_CHANNEL= CMake options.

The statistics overlay prints out quite detailed information about execution state. Disabling the overlay with -DSTATISTICS=0 option to CMake improves performance and reduces CPU usage. If you want to keep printing statistics, you can try increasing the interval with the #define STATISTICS_REFRESH_INTERVAL option in config.h.

The option #define SELF_SYNCHRONIZE_TO_GPU_VSYNC_PRODUCED_NEW_FRAMES can be used in conjunction with #define USE_GPU_VSYNC to try to find a middle ground between raspberrypi/userland#440 issues - moderate to little stuttering while not trying to consume too much CPU. Try experimenting with enabling or disabling this setting.

There are a number of #define SAVE_BATTERY_BY_x options in config.h, which all default to being enabled. These should be safe to use always without tradeoffs. If you are experiencing latency or performance related issues, you can try to toggle these to troubleshoot.

If your SPI display bus is able to run really fast in comparison to the size of the display and the amount of content changing on the screen, you can try enabling #define UPDATE_FRAMES_IN_SINGLE_RECTANGULAR_DIFF option in config.h to reduce CPU usage at the expense of increasing the number of bytes sent over the bus. This has been observed to have a big effect on Pi Zero, so is worth checking out especially there.

If the SPI display bus is able to run really really really fast (or you don"t care about frame rate, but just about low CPU usage), you can try enabling #define UPDATE_FRAMES_WITHOUT_DIFFING option in config.h to forgo the adaptive delta diffing option altogether. This will revert to naive full frame updates for absolutely minimum overall CPU usage.

The option #define RUN_WITH_REALTIME_THREAD_PRIORITY can be enabled to make the driver run at realtime process priority. This can lock up the system however, but still made available for advanced experimentation.

In display.h there is an option #define TARGET_FRAME_RATE . Setting this to a smaller value, such as 30, will trade refresh rate to reduce CPU consumption.

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.

This does not mean that overall input to display latency in games would be so immediate. Briefly testing a NES emulated game in Retropie suggests a total latency of about 60-80 msecs. This latency is caused by the NES game emulator overhead and extra latency added by Linux, DispmanX and GPU rendering, and GPU framebuffer snapshotting. (If you ran fbcp-ili9341 as a static library bypassing DispmanX and the GPU stack, directly linking your GPIO input and application logic into fbcp-ili9341, you would be able to get down to this few msecs of overall latency, like shown in the above GPIO input video)

Interestingly, fbcp-ili9341 is about ~33msecs faster than a cheap 3.5" KeDei HDMI display. I do not know if this is a result of the KeDei HDMI display specifically introducing extra latency, or if all HDMI displays connected to the Pi would have similar latency overhead. An interesting question is also how SPI would compare with DPI connected displays on the Pi.

Unfortunately a limitation of SPI connected displays is that the VSYNC line signal is not available on the display controllers when they are running in SPI mode, so it is not possible to do vsync locked updates even if the SPI bus bandwidth on the display was fast enough. For example, the 4 ILI9341 displays I have can all be run faster than 75MHz so SPI bus bandwidth-wise all of them would be able to update a full frame in less than a vsync interval, but it is not possible to synchronize the updates to vsync since the display controllers do not report it. (If you do know of a display that does actually expose a vsync clock signal even in SPI mode, you can try implementing support to locking on to it)

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.

To get tearing free updates, you should use a DPI display, or a good quality HDMI display. Beware that cheap small 3.5" HDMI displays such as KeDei do also tear - that is, even if they are controlled via HDMI, they don"t actually seem to implement VSYNC timed internal operation.

Having no vsync is not all bad though, since with the lack of vsync, SPI displays have the opportunity to obtain smoother animation on content that is not updating at 60Hz. It is possible that content on the SPI display will stutter even less than what DPI or HDMI displays on the Pi can currently provide (although I have not been able to test this in detail, except for the KeDei case above).

The main option that affects smoothness of display updates is the #define USE_GPU_VSYNC line in config.h. If this is enabled, then the internal Pi GPU HDMI vsync clock is used to drive frames onto the display. The Pi GPU clock runs at a fixed rate that is independent of the content. This rate can be discovered by running tvservice -s on the Pi console, and is usually 59Hz or 60Hz. If your application renders at this rate, animation will look smooth, but if not, there will be stuttering. For example playing a PAL NES game that updates at 50Hz with HDMI clock set at 60Hz will cause bad microstuttering in video output if #define USE_GPU_VSYNC is enabled.

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.

A drawback is that this kind of polling consumes more CPU time than the vsync option. The extra overhead is around +34% of CPU usage compared to the vsync method. It also requires using a background thread, and because of this, it is not feasible to be used on a single core Pi Zero. If this polling was unnecessary, this mode would also work on a Pi Zero, and without the added +34% CPU overhead on Pi 3B. See the Known Issues section below for more details.

There are two other main options that affect frame delivery timings, #define SELF_SYNCHRONIZE_TO_GPU_VSYNC_PRODUCED_NEW_FRAMES and #define SAVE_BATTERY_BY_PREDICTING_FRAME_ARRIVAL_TIMES. Check out the video fbcp-ili9341 frame delivery smoothness test on Pi 3B and Adafruit ILI9341 at 119Hz for a detailed side by side comparison of these different modes. The conclusions drawn from the four tested scenarios in the video are:

2. vc_dispmanx_vsync_callback() + self synchronization (top right), set #define USE_GPU_VSYNC and #define SELF_SYNCHRONIZE_TO_GPU_VSYNC_PRODUCED_NEW_FRAMES:

This mode uses the GPU vsync signal, but also aims to find and synchronize to the edge trigger when content is producing frames. This is the default build mode on Pi Zero.

The codebase captures screen framebuffers by snapshotting via the VideoCore vc_dispmanx_snapshot() API, and the obtained pixels are then routed on to the SPI-based display. This kind of polling is performed, since there does not exist an event-based mechanism to get new frames from the GPU as they are produced. The result is inefficient and can easily cause stuttering, since different applications produce frames at different paces. Ideally the code would ask the VideoCore API to receive finished frames in callback notifications immediately after they are rendered, but this kind of functionality does not exist in the current GPU driver stack. In the absence of such event delivery mechanism, the code has to resort to polling snapshots of the display framebuffer using carefully timed heuristics to balance between keeping latency and stuttering low, while not causing excessive power consumption. These heuristics keep continuously guessing the update rate of the animation on screen, and they have been tuned to ensure that CPU usage goes down to 0% when there is no detected activity on screen, but it is certainly not perfect. This GPU limitation is discussed at raspberrypi/userland#440. If you"d like to see fbcp-ili9341 operation reduce latency, stuttering and power consumption, please throw a (kind!) comment or a thumbs up emoji in that bug thread to share that you care about this, and perhaps Raspberry Pi engineers might pick the improvement up on the development roadmap. If this issue is resolved, all of the #define USE_GPU_VSYNC, #define SAVE_BATTERY_BY_PREDICTING_FRAME_ARRIVAL_TIMES and #define SELF_SYNCHRONIZE_TO_GPU_VSYNC_PRODUCED_NEW_FRAMES hacks from the previous section could be deleted from the driver, hopefully leading to a best of all worlds scenario without drawbacks.

Currently if one resizes the video frame size at runtime, this causes DispmanX API to go sideways. See raspberrypi/userland#461 for more information. Best workaround is to set the desired screen resolution in /boot/config.txt and configure all applications to never change that at runtime.

The speed of the SPI bus is linked to the BCM2835 core frequency. This frequency is at 250MHz by default (on e.g. Pi Zero, 3B and 3B+), and under CPU load, the core turbos up to 400MHz. This turboing directly scales up the SPI bus speed by 400/250=+60% as well. Therefore when choosing the SPI CDIV value to use, one has to pick one that works for both idle and turbo clock speeds. Conversely, the BCM core reverts to non-turbo speed when there is only light CPU load active, and this slows down the display, so if an application is graphically intensive but light on CPU, the SPI display bus does not get a chance to run at maximum speeds. A way to work around this is to force the BCM core to always stay in its turbo state with force_turbo=1 option in /boot/config.txt, but this has an unfortunate effect of causing the ARM CPU to always run in turbo speed as well, consuming excessive amounts of power. At the time of writing, there does not yet exist a good solution to have both power saving and good performance. This limitation is being discussed in more detail at raspberrypi/firmware#992.

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.

By default fbcp-ili9341 builds with a statistics overlay enabled. See the video fbcp-ili9341 ported to ILI9486 WaveShare 3.5" (B) SpotPear 320x480 SPI display to find details on what each field means. Build with CMake option -DSTATISTICS=0 to disable displaying the statistics. You can also try building with CMake option -DSTATISTICS=2 to show a more detailed frame delivery timings histogram view, see screenshot and video above.

The fbcp part in the name means framebuffer copy; specifically for the ILI9341 controller. fbcp-ili9341 is not actually a framebuffer copying driver, it does not create a secondary framebuffer that it would copy bytes across to from the primary framebuffer. It is also no longer a driver only for the ILI9341 controller. A more appropriate name might be userland-raspi-spi-display-driver or something like that, but the original name stuck.

Yes, it does, although not quite as well as on Pi 3B. If you"d like it to run better on a Pi Zero, leave a thumbs up at raspberrypi/userland#440 - hard problems are difficult to justify prioritizing unless it is known that many people care about them.

Edit the file config.h and comment out the line #define DISPLAY_OUTPUT_LANDSCAPE. This will make the display output in portrait mode, effectively rotating it by 90 degrees. Note that this only affects the pixel memory reading mode of the display. It is not possible to change the panel scan order to run between landscape and portrait, the SPI displays typically always scan in portrait mode. The result is that it will change the panel vsync tearing mode from "straight line tearing" over to "diagonal tearing" (see the section About Tearing above).

If you do not want to have diagonal tearing, but would prefer straight line tearing, then additionally enable the option #define DISPLAY_FLIP_ORIENTATION_IN_SOFTWARE in config.h. That will restore straight line tearing, but it will also increase overall CPU consumption.

Enable the option #define DISPLAY_ROTATE_180_DEGREES in config.h. This should rotate the SPI display to show up the other way around, while keeping the HDMI connected display orientation unchanged. Another option is to utilize a /boot/config.txt option display_rotate=2, which rotates both the SPI output and the HDMI output.

Note that the setting DISPLAY_ROTATE_180_DEGREES only affects the pixel memory reading mode of the display. It is not possible to flip the panel scan to run inverted by 180 degrees. This means that adjusting these settings will also have effects of changing the visual appearance of the vsync tearing artifact. If you have the ability to mount the display 180 degrees around in your project, it is recommended to do that instead of using the DISPLAY_ROTATE_180_DEGREES option.

Edit the file config.h in a text editor (a command line one such as pico, vim, nano, or SSH map the drive to your host), and find the appropriate line in the file. Add comment lines // in front of that text to disable the option, or remove the // characters to enable it.

Some options are passed to the build from the CMake configuration script. You can run with make VERBOSE=1 to see which configuration items the CMake build is passing. See the above Configuring Build Options section to customize the CMake configure items. For example, to remove the statistics overlay, pass -DSTATISTICS=0 directive to CMake.

Yes, both work fine. For linux command line terminal, the /dev/tty1 console should be set to output to Linux framebuffer 0 (/dev/fb0). This is the default mode of operation and there do not exist other framebuffers in a default distribution of Raspbian, but if you have manually messed with the con2fbmap command in your installation, you may have inadvertently changed this configuration. Run con2fbmap 1 to see which framebuffer the /dev/tty1 console is outputting to, it should print console 1 is mapped to framebuffer 0. Type con2fbmap 1 0 to reset console 1 back to outputting to framebuffer 0.

Likewise, the X windowing system should be configured to render to framebuffer 0. This is by default the case. The target framebuffer for X windowing service is usually configured via the FRAMEBUFFER environment variable before launching X. If X is not working by default, you can try overriding the framebuffer by launching X with FRAMEBUFFER=/dev/fb0 startx instead of just running startx.

I don"t know, I don"t currently have any to test. Perhaps the code does need some model specific configuration, or perhaps it might work out of the box. I only have Pi 3B, Pi 3B+, Pi Zero W and a Pi 3 Compute Module based systems to experiment on. Pi 2 B has been reported to work by users (#17).

If the display controller is one of the currently tested ones (see the list above), and it is wired up to run using 4-line SPI, then it should work. Pay attention to configure the Data/Control GPIO pin number correctly, and also specify the Reset GPIO pin number if the device has one.

If the display controller is not one of the tested ones, it may still work if it is similar to one of the existing ones. For example, ILI9340 and ILI9341 are practically the same controller. You can just try with a specific one to see how it goes.

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.

The performance option ALL_TASKS_SHOULD_DMA is currently not supported, there is an issue with DMA chaining that prevents this from being enabled. As result, CPU usage on 3-wire displays will be slightly higher than on 4-wire displays.

The performance option OFFLOAD_PIXEL_COPY_TO_DMA_CPP is currently not supported. As a result, 3-wire displays may not work that well on single core Pis like Pi Zero.

This has only been tested on my Adafruit SSD1351 128x96 RGB OLED display, which can be soldered to operate in 3-wire SPI mode, so testing has not been particularly extensive.

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)

No. Those are completely different technologies altogether. It should be possible to port the driver algorithm to work on I2C however, if someone is interested.

At the moment one cannot utilize the XPT2046/ADS7846 touch controllers while running fbcp-ili9341, so touch is mutually incompatible with this driver. In order for fbcp-ili9341 to function, you will need to remove all dtoverlays in /boot/config.txt related to touch.

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.

Easiest w