Adafruit ST7735 and ST7789: small color TFTs on Arduino
One Adafruit library covers two common small color screens: the 1.8 inch 128x160 ST7735 and the 1.3 or 1.54 inch 240x240 ST7789 IPS panel. Both are SPI devices with a data/command pin, and both draw with the Adafruit_GFX calls, so text, lines, rectangles and bitmaps work the same as on any Adafruit display.
Built in on Mokxi: #include <Adafruit_ST7735.h> and it builds, with nothing to install. Free, and no account needed.
What Adafruit ST7735 and ST7789 Library does
Where they differ is in starting up. An ST7735 is started with initR() and the color of the tab on its protective film, because that tab tells you where the glass sits in the chip’s memory: a wrong tab leaves a band of noise along one or two edges. An ST7789 is started with init(width, height), since its memory is always 240x320 and the panel is a window into it. Its IPS glass also shows colors inverted until the start-up sends INVON, which the library does for you.
The 1.3 inch ST7789 board usually has no CS pin, so it listens to every byte on its clock and data lines. The runnable project wires one of each screen to an Uno, the ST7789 on pins of its own with the five-argument constructor, so the two never hear each other’s pixels.
| Library Manager name | Adafruit ST7735 and ST7789 Library |
|---|---|
| Author | Adafruit |
| Include | #include <Adafruit_ST7735.h>#include <Adafruit_ST7789.h> |
| Boards | every board Mokxi compiles for but ATtiny85 |
| In the simulator | Simulated: it runs against the part the way it does on the bench. |
| Parts it drives | TFT display, 1.8 inch ST7735, IPS display, ST7789 |
Install it
It builds on every board Mokxi compiles for but ATtiny85.
In Mokxi it is built in: #include <Adafruit_ST7735.h> and the sketch compiles, with no download, no zip and no Library Manager.
On a real board, install "Adafruit ST7735 and ST7789 Library" by Adafruit from the Arduino IDE’s Library Manager (Sketch, Include Library, Manage Libraries), or add Adafruit ST7735 and ST7789 Library to lib_deps in PlatformIO. Mokxi follows the calls of release 1.12.0, so a sketch written here builds there too.
- ESP32-C3
- Arduino Uno
- Arduino Nano
- Arduino Mega 2560
- Arduino Leonardo
- SparkFun Pro Micro
- Arduino Micro
- ESP32-C6
- WCH CH32V003
- Raspberry Pi Pico
- Raspberry Pi Pico W
- Seeed XIAO SAMD21
- STM32
- STM32 Nucleo-F411RE
- STM32 Blue Pill
- micro:bit V2
- Arduino Uno R4
- ESP32 DevKit
- ESP32-S3-DevKitC-1
- ESP8266 NodeMCU
- Arduino Pro Mini 3.3 V
- Seeed XIAO ESP32-C3
- ESP32-C3 SuperMini
- Seeed XIAO ESP32-C6
- ESP32-DevKitC V4
- LOLIN32 Lite
- Wemos D1 R32
- Cheap Yellow Display
- TTGO T-Display
- Seeed XIAO ESP32-S3
- Arduino Nano ESP32
- Arduino Nano RP2040 Connect
- Seeed XIAO RP2040
- Waveshare RP2040-Zero
- Arduino Uno R4 WiFi
The calls you will use
In the order a sketch meets them.
Adafruit_ST7735 tft(10, 9, 8)
Makes an ST7735 on the hardware SPI pins, with CS, DC (marked A0 on many boards) and reset on the pins given.
tft.initR(INITR_BLACKTAB)
Starts a 1.8 inch ST7735. Use the tab color on your screen’s film: INITR_BLACKTAB, INITR_REDTAB or INITR_GREENTAB.
Adafruit_ST7789 square(-1, 7, A0, A1, 6)
Makes an ST7789 with no CS, on software SPI: DC, data, clock and reset on any pins you like.
square.init(240, 240, SPI_MODE3)
Starts the ST7789 for a 240x240 panel. Pass 135, 240 for the small T-Display style glass, or 240, 320 for the 2 inch one.
tft.setRotation(2)
Turns the drawing by 0 to 3 quarter turns. On a 240x240 ST7789 some rotations start at row 80 of memory; the library handles that offset.
tft.fillScreen(ST77XX_BLACK)
Paints the whole screen one color. Over SPI on an Uno this is slow, so clear once and then redraw only what moves.
Adafruit_ST7789::color565(r, g, b)
Packs 8-bit red, green and blue into the 16-bit 5-6-5 color the screens use. It is static, so it can be called on the class or on a screen.
uint16_t orange = Adafruit_ST7789::color565(255, 128, 0);
tft.fillRect(10, 40, 24, 24, orange);tft.invertDisplay(true)
Shows the negative of the picture. On the ST7789 this sends INVOFF, because its normal state is already inverted.
Example: Two color screens
On the Arduino Uno R3. It runs in the browser exactly as printed.
// Two color screens: a 1.8 inch ST7735 and a 1.3 inch ST7789.
//
// ST7735 SCK -> 13 SDA -> 11 CS -> 10 A0 -> 9 RESET -> 8 LED -> 5 V
// ST7789 SCL -> A1 SDA -> A0 DC -> 7 RES -> 6 BLK -> 5 V CS unwired
//
// Both chips speak the same command set as the ILI9341: a column window, a row
// window, then pixels, with DC saying which bytes are commands. What differs
// is the glass. The ST7789's memory is 240x320 and this panel shows 240x240 of
// it, so rotations that count rows from the bottom start at row 80; and its
// IPS glass shows colors inverted until INVON, which init() sends.
//
// The ST7789 is wired the way the 1.3 inch board comes: no chip select, so it
// listens to every clock on its pins. That is why it has pins of its own here
// (the five-argument constructor is software SPI on any pins). On the ST7735's
// bus it would take that panel's bytes as its own.
//
// Every pixel goes out bit by bit, so an Uno draws a small square quickly and
// a whole screen slowly: draw what moves.
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <Adafruit_ST7789.h>
Adafruit_ST7735 small(10, 9, 8);
Adafruit_ST7789 square(-1, 7, A0, A1, 6); // no CS; DC, SDA, SCL, RES
void setup() {
small.initR(INITR_BLACKTAB);
small.fillScreen(ST77XX_BLACK);
small.setTextColor(ST77XX_GREEN);
small.setCursor(4, 4);
small.print("ST7735 128X160");
square.init(240, 240, SPI_MODE3);
square.setRotation(2);
square.fillRect(0, 0, 240, 40, ST77XX_BLUE);
square.setTextColor(ST77XX_WHITE);
square.setTextSize(2);
square.setCursor(8, 12);
square.print("ST7789 IPS");
}
void loop() {
// A block that walks around each screen, in a color that changes as it goes.
static uint8_t step = 0;
uint16_t color = Adafruit_ST7789::color565((uint8_t)(step * 16), 255 - step * 16, 128);
small.fillRect((int16_t)(8 + (step % 8) * 14), 40, 12, 12, color);
square.fillRect((int16_t)(10 + (step % 8) * 28), 120, 24, 24, color);
step = (uint8_t)((step + 1) % 16);
delay(100);
}Open it in the editor, wired and ready to run · Two color screens: the project page
Common errors and how to fix them
A strip of random colored pixels along the top or left edge
The initR() tab does not match the panel. Try INITR_GREENTAB if you used BLACKTAB, or the reverse, until the edge is clean; the film’s tab color is the usual hint.
Colors come out inverted: black background shows white
This is an ST7789 IPS panel started as an ST7735, or with code that skips the INVON command. Use Adafruit_ST7789 and init(), which sends it, or call invertDisplay() to flip it.
A 1.3 inch ST7789 stays black while the ST7735 on the same bus works
Boards without a CS pin need SPI mode 3 and must not share the bus with another screen. Give the ST7789 its own pins with the five-argument constructor and pass SPI_MODE3 to init().
Questions and answers
Why is the screen so slow to fill on an Uno?
Every pixel is two bytes over SPI, and a full 240x240 frame is over 115,000 bytes. Draw only the parts that change, as the project does with its moving block.
Projects that use Adafruit ST7735 and ST7789 Library
Built-in projects that include it. Each page has the full sketch and opens in the editor, already wired.
Try Adafruit ST7735 and ST7789 Library without installing anything
Open the example, change the sketch, and keep your version in a free account.