Specs
- Screen size: 135 x 240 (14.86 x 24.91 mm)
- Module size: 30.40 x 28 (mm)
- Colors: 65K
- Protocol: SPI
- IC: ST7789V datasheet
- VCC: 3.3V
- store link
- OLED ?
Connection
Important
- For Arduino boards do NOT forget resistors to make voltage dividers. Connecting to 3.3V pin is not enough to save the display from 5V.
- Do not skip the Reset pin (-1 doesn't mean that it is not connected)
In order to avoid level shifting (voltage dividers) use 3.3V boards. Here are some options
- Adafruit Feather HUZZAH ESP8266 80MHz with 3.3V (80MHz, Carl!)
- Arduino Pro Mini 328 3.3V/8MHz (higher clock requires higher voltage, so if you see 16MHz quarts on the board with ATmega328P then it's definitely 5V)
- Pro Micro ATmega32U4 3.3V/8MHz
- Seeeduino-V4.2
Wemos D1 R1
- GND -> GND obviously
- VCC -> 3.3V
- SCL -> D5 / SCK (clock)
- SDA -> D7 / MOSI (data out)
- RES -> D0 (reset, any port is good)
- DC -> D3 (?, any port is good)
- CS -> D4 (child select, any port is good)
- BLK - not connected
Test code
Based on ST7789 class I added ST7789V
ST7789V.h
#ifndef _ADAFRUIT_ST7789VH_
#define _ADAFRUIT_ST7789VH_
#include "Adafruit_ST77xx.h"
/// Subclass of ST77XX type display for ST7789V TFT Driver
class Adafruit_ST7789V : public Adafruit_ST77xx {
public:
Adafruit_ST7789V(int8_t cs, int8_t dc, int8_t mosi, int8_t sclk,
int8_t rst = -1);
Adafruit_ST7789V(int8_t cs, int8_t dc, int8_t rst);
#if !defined(ESP8266)
Adafruit_ST7789V(SPIClass *spiClass, int8_t cs, int8_t dc, int8_t rst);
#endif // end !ESP8266
void setRotation(uint8_t m);
void init(uint16_t width, uint16_t height, uint8_t spiMode = SPI_MODE0);
protected:
uint8_t _colstart2 = 0, ///< Offset from the right
_rowstart2 = 0; ///< Offset from the bottom
private:
uint16_t windowWidth;
uint16_t windowHeight;
};
#endif // _ADAFRUIT_ST7789VH_
ST7789V.cpp
#include "ST7789V.h"
#include "Adafruit_ST77xx.h"
Adafruit_ST7789V::Adafruit_ST7789V(int8_t cs, int8_t dc, int8_t mosi, int8_t sclk,
int8_t rst)
: Adafruit_ST77xx(240, 320, cs, dc, mosi, sclk, rst) {}
Adafruit_ST7789V::Adafruit_ST7789V(int8_t cs, int8_t dc, int8_t rst)
: Adafruit_ST77xx(240, 320, cs, dc, rst) {}
static const uint8_t PROGMEM
generic_ST7789V[] = { // Init commands for 7789 screens
9, // 9 commands in list:
ST77XX_SWRESET, ST_CMD_DELAY, // 1: Software reset, no args, w/delay
150, // ~150 ms delay
ST77XX_SLPOUT , ST_CMD_DELAY, // 2: Out of sleep mode, no args, w/delay
10, // 10 ms delay
ST77XX_COLMOD , 1+ST_CMD_DELAY, // 3: Set color mode, 1 arg + delay:
0x55, // 16-bit color/ 65K
10, // 10 ms delay
ST77XX_MADCTL , 1, // 4: Mem access ctrl (directions), 1 arg:
0x08, // Row/col addr, bottom-top refresh
ST77XX_CASET , 4, // 5: Column addr set, 4 args, no delay:
0x00,
0, // XSTART = 0
0,
134, // XEND
ST77XX_RASET , 4, // 6: Row addr set, 4 args, no delay:
0x00,
0, // YSTART = 0
0,
239, // YEND
ST77XX_INVON , ST_CMD_DELAY, // 7: hack
10,
ST77XX_NORON , ST_CMD_DELAY, // 8: Normal display on, no args, w/delay
10, // 10 ms delay
ST77XX_DISPON , ST_CMD_DELAY, // 9: Main screen turn on, no args, delay
10 }; // 10 ms delay
void Adafruit_ST7789V::init(uint16_t width, uint16_t height, uint8_t mode) {
spiMode = mode;
commonInit(NULL);
width = 135;
height = 240;
_rowstart = _rowstart2 = (int)((320 - height) / 2);
_colstart = (int)((240 - width + 1) / 2);
_colstart2 = (int)((240 - width) / 2);
// _colstart = _colstart2 = 2;
windowWidth = width;
windowHeight = height;
displayInit(generic_ST7789V);
setRotation(0);
}
void Adafruit_ST7789V::setRotation(uint8_t m) {
uint8_t madctl = 0;
rotation = m & 3; // can't be higher than 3
switch (rotation) {
case 0:
madctl = ST77XX_MADCTL_MX | ST77XX_MADCTL_MY | ST77XX_MADCTL_RGB;
_xstart = _colstart;
_ystart = _rowstart;
_width = windowWidth;
_height = windowHeight;
break;
case 1:
madctl = ST77XX_MADCTL_MY | ST77XX_MADCTL_MV | ST77XX_MADCTL_RGB;
_xstart = _rowstart;
_ystart = _colstart2;
_height = windowWidth;
_width = windowHeight;
break;
case 2:
madctl = ST77XX_MADCTL_RGB;
_xstart = _colstart2;
_ystart = _rowstart2;
_width = windowWidth;
_height = windowHeight;
break;
case 3:
madctl = ST77XX_MADCTL_MX | ST77XX_MADCTL_MV | ST77XX_MADCTL_RGB;
_xstart = _rowstart2;
_ystart = _colstart;
_height = windowWidth;
_width = windowHeight;
break;
}
sendCommand(ST77XX_MADCTL, &madctl, 1);
}
main.ino
/**************************************************************************
This is a library for several Adafruit displays based on ST77* drivers.
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
**************************************************************************/
#include <Adafruit_GFX.h> // Core graphics library
//#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include "ST7789V.h"
#include <SPI.h>
#define TFT_CS D4
#define TFT_RST D0
#define TFT_DC D3
// OPTION 1 (recommended) is to use the HARDWARE SPI pins, which are unique
// to each board and not reassignable. For Arduino Uno: MOSI = pin 11 and
// SCLK = pin 13. This is the fastest mode of operation and is required if
// using the breakout board's microSD card.
// For 1.14", 1.3", 1.54", 1.69", and 2.0" TFT with ST7789:
Adafruit_ST7789V tft = Adafruit_ST7789V(TFT_CS, TFT_DC, TFT_RST);
// OPTION 2 lets you interface the display using ANY TWO or THREE PINS,
// tradeoff being that performance is not as fast as hardware SPI above.
//#define TFT_MOSI 11 // Data out
//#define TFT_SCLK 13 // Clock out
// For ST7735-based displays, we will use this call
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
// OR for the ST7789-based displays, we will use this call
//Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
float p = 3.1415926;
void setup(void) {
Serial.begin(9600);
Serial.print(F("Hello! ST77xx TFT Test"));
// OR use this initializer (uncomment) if using a 1.14" 240x135 TFT:
tft.init(135, 240, SPI_MODE0); // Init ST7789 240x135
// SPI speed defaults to SPI_DEFAULT_FREQ defined in the library, you can override it here
// Note that speed allowable depends on chip and quality of wiring, if you go too fast, you
// may end up with a black screen some times, or all the time.
//tft.setSPISpeed(40000000);
Serial.println(F("Initialized"));
uint16_t time = millis();
tft.fillScreen(ST77XX_RED);
//tft.setRotation(1);
time = millis() - time;
Serial.println(time, DEC);
delay(1500);
// large block of text
tft.fillScreen(ST77XX_BLACK);
// 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. ", ST77XX_WHITE);
delay(1000);
// tft print function!
tftPrintTest();
delay(4000);
// a single pixel
tft.drawPixel(tft.width()/2, tft.height()/2, ST77XX_GREEN);
delay(500);
// line draw test
testlines(ST77XX_YELLOW);
delay(500);
// optimized lines
testfastlines(ST77XX_RED, ST77XX_BLUE);
delay(500);
testdrawrects(ST77XX_GREEN);
delay(500);
testfillrects(ST77XX_YELLOW, ST77XX_MAGENTA);
delay(500);
tft.fillScreen(ST77XX_BLACK);
testfillcircles(10, ST77XX_BLUE);
testdrawcircles(10, ST77XX_WHITE);
delay(500);
testroundrects();
delay(500);
testtriangles();
delay(500);
mediabuttons();
delay(500);
Serial.println("done");
delay(1000);
}
void loop() {
// tft.invertDisplay(true);
// delay(500);
// tft.invertDisplay(false);
// delay(500);
}
void testlines(uint16_t color) {
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(0, 0, x, tft.height()-1, color);
delay(0);
}
for (int16_t y=0; y < tft.height(); y+=6) {
tft.drawLine(0, 0, tft.width()-1, y, color);
delay(0);
}
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(tft.width()-1, 0, x, tft.height()-1, color);
delay(0);
}
for (int16_t y=0; y < tft.height(); y+=6) {
tft.drawLine(tft.width()-1, 0, 0, y, color);
delay(0);
}
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(0, tft.height()-1, x, 0, color);
delay(0);
}
for (int16_t y=0; y < tft.height(); y+=6) {
tft.drawLine(0, tft.height()-1, tft.width()-1, y, color);
delay(0);
}
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(tft.width()-1, tft.height()-1, x, 0, color);
delay(0);
}
for (int16_t y=0; y < tft.height(); y+=6) {
tft.drawLine(tft.width()-1, tft.height()-1, 0, y, color);
delay(0);
}
}
void testdrawtext(char *text, uint16_t color) {
tft.setCursor(0, 0);
tft.setTextColor(color);
tft.setTextWrap(true);
tft.print(text);
}
void testfastlines(uint16_t color1, uint16_t color2) {
tft.fillScreen(ST77XX_BLACK);
for (int16_t y=0; y < tft.height(); y+=5) {
tft.drawFastHLine(0, y, tft.width(), color1);
}
for (int16_t x=0; x < tft.width(); x+=5) {
tft.drawFastVLine(x, 0, tft.height(), color2);
}
}
void testdrawrects(uint16_t color) {
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color);
}
}
void testfillrects(uint16_t color1, uint16_t color2) {
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=tft.width()-1; x > 6; x-=6) {
tft.fillRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color1);
tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color2);
}
}
void testfillcircles(uint8_t radius, uint16_t color) {
for (int16_t x=radius; x < tft.width(); x+=radius*2) {
for (int16_t y=radius; y < tft.height(); y+=radius*2) {
tft.fillCircle(x, y, radius, color);
}
}
}
void testdrawcircles(uint8_t radius, uint16_t color) {
for (int16_t x=0; x < tft.width()+radius; x+=radius*2) {
for (int16_t y=0; y < tft.height()+radius; y+=radius*2) {
tft.drawCircle(x, y, radius, color);
}
}
}
void testtriangles() {
tft.fillScreen(ST77XX_BLACK);
uint16_t color = 0xF800;
int t;
int w = tft.width()/2;
int x = tft.height()-1;
int y = 0;
int z = tft.width();
for(t = 0 ; t <= 15; t++) {
tft.drawTriangle(w, y, y, x, z, x, color);
x-=4;
y+=4;
z-=4;
color+=100;
}
}
void testroundrects() {
tft.fillScreen(ST77XX_BLACK);
uint16_t color = 100;
int i;
int t;
for(t = 0 ; t <= 4; t+=1) {
int x = 0;
int y = 0;
int w = tft.width()-2;
int h = tft.height()-2;
for(i = 0 ; i <= 16; i+=1) {
tft.drawRoundRect(x, y, w, h, 5, color);
x+=2;
y+=3;
w-=4;
h-=6;
color+=1100;
}
color+=100;
}
}
void tftPrintTest() {
tft.setTextWrap(false);
tft.fillScreen(ST77XX_BLACK);
tft.setCursor(0, 30);
tft.setTextColor(ST77XX_RED);
tft.setTextSize(1);
tft.println("Hello World!");
tft.setTextColor(ST77XX_YELLOW);
tft.setTextSize(2);
tft.println("Hello World!");
tft.setTextColor(ST77XX_GREEN);
tft.setTextSize(3);
tft.println("Hello World!");
tft.setTextColor(ST77XX_BLUE);
tft.setTextSize(4);
tft.print(1234.567);
delay(1500);
tft.setCursor(0, 0);
tft.fillScreen(ST77XX_BLACK);
tft.setTextColor(ST77XX_WHITE);
tft.setTextSize(0);
tft.println("Hello World!");
tft.setTextSize(1);
tft.setTextColor(ST77XX_GREEN);
tft.print(p, 6);
tft.println(" Want pi?");
tft.println(" ");
tft.print(8675309, HEX); // print 8,675,309 out in HEX!
tft.println(" Print HEX!");
tft.println(" ");
tft.setTextColor(ST77XX_WHITE);
tft.println("Sketch has been");
tft.println("running for: ");
tft.setTextColor(ST77XX_MAGENTA);
tft.print(millis() / 1000);
tft.setTextColor(ST77XX_WHITE);
tft.print(" seconds.");
}
void mediabuttons() {
// play
tft.fillScreen(ST77XX_BLACK);
tft.fillRoundRect(25, 10, 78, 60, 8, ST77XX_WHITE);
tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_RED);
delay(500);
// pause
tft.fillRoundRect(25, 90, 78, 60, 8, ST77XX_WHITE);
tft.fillRoundRect(39, 98, 20, 45, 5, ST77XX_GREEN);
tft.fillRoundRect(69, 98, 20, 45, 5, ST77XX_GREEN);
delay(500);
// play color
tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_BLUE);
delay(50);
// pause color
tft.fillRoundRect(39, 98, 20, 45, 5, ST77XX_RED);
tft.fillRoundRect(69, 98, 20, 45, 5, ST77XX_RED);
// play color
tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_GREEN);
}
Libraries
- Fast SPI in C for ST7789 code
- Python library
- Adafruit GFX: how config sent to the controller, number of columns and rows set in the config, and how SPI works