Arduino MKR WiFi 1010 - TFT LCD Touch Display SPI

Think of this tutorial as a recipe: follow the ingredients list and the steps, and you will have a working SPI TFT display on your Arduino MKR WiFi 1010 by the end. The MKR WiFi 1010 runs a SAMD21 Cortex-M0+ at 48 MHz paired with a u-blox NINA-W102 module for Wi-Fi and Bluetooth. All I/O pins operate at 3.3V, which is perfect for most SPI TFT modules.

Ingredients in this recipe:

This recipe covers both touch and non-touch SPI TFT LCD displays. It works with 1.3, 1.54, 2.2, 2.4, 2.8, 3.2, and 3.5 inch panels driven by ILI9341, ILI9488, or ST7789 controller chips.

Arduino MKR WiFi 1010 TFT SPI Display

Hardware Preparation

1×Arduino MKR WiFi 1010
1×Micro USB Cable
1×SPI TFT display module
1×Jumper Wires

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

Ingredient: The SPI TFT Display

An SPI TFT module pairs a color LCD panel with a driver IC that accepts drawing commands over SPI. Three driver chips are supported:

  • ILI9341 - 16-bit RGB565 color, up to 40 MHz SPI.
  • ILI9488 - 18-bit RGB666 color over SPI, up to 24 MHz.
  • ST7789 - 16-bit RGB565 color, up to 40 MHz SPI.

Recommendation: If you have not yet purchased a display, we recommend the ST7789 driver. It is widely available, runs at full 40 MHz SPI speed, and is the most straightforward choice for new projects.

The DIYables_TFT_SPI library wraps Adafruit GFX to give you shapes, text, fonts, and bitmap drawing out of the box.

Note: The MKR WiFi 1010 operates at 3.3V. Connect TFT VCC to the 3.3V pin. A 5V supply will damage the board.

Pinout

Most SPI TFT LCD displays have the following pins:

Display pins:

Pin Function
VCC Power supply
GND Ground
CS Chip Select — pulled low to select the display on the SPI bus
DC / RS Data / Command select — high for pixel data, low for commands
RST Hardware reset — optional; tie to 3.3V if unused
MOSI / SDI / SDA SPI data in (MCU → display)
SCK / CLK SPI clock
MISO / SDO SPI data out (display → MCU) — optional for display-only use
LED / BL / BLK Backlight power — connect to 3.3V or a PWM pin for dimming

SD card pins (if your application needs to access the SD card):

Pin Function
SD_CS / TF_CS SD card Chip Select
MOSI / SDI MOSI — data from MCU to SD card
SCK / CLK SCK — SPI clock
MISO / SDO MISO — data from SD card to MCU

For TFT displays that support touch, there are additional touch pins (if your application uses the touch function and the display supports it):

Pin Function
T_CS Touch controller Chip Select
T_CLK SCK — SPI clock
T_DIN MOSI — data from MCU to touch controller
T_DO MISO — data from touch controller to MCU
T_IRQ Touch interrupt — optional; signals when the screen is being touched

Note: Some non-touch display modules also expose T_CS, T_CLK, T_DIN, T_DO, and T_IRQ pins. These are non-functional on those boards — the touch controller IC is not populated. They appear because the PCB reuses the same layout as the touch-enabled version to reduce manufacturing variants.

TFT SPI Display Pinout

Wiring Diagram

Without Touch

Connect MOSI to pin 8, SCK to pin 9, MISO to pin 10 on the MKR WiFi 1010. CS, DC, and RST can be any available GPIO — pins 7, 11, 12 are used in the examples because they sit on the same edge of the board as the SPI pins, which keeps all display wires on one side and simplifies wiring.

Display:

TFT Pin Arduino MKR WiFi 1010 Pin Description
VCC VCC (3.3V) Power supply (3.3V only)
GND GND Ground
CS 12 Chip Select
DC / RS 7 Data / Command select
RST 11 Reset (optional)
MOSI / SDI 8 Hardware SPI MOSI
SCK 9 Hardware SPI clock
MISO / SDO 10 Hardware SPI MISO (optional)
LED / BL VCC (3.3V) Backlight power

SD card (if your application needs to access the SD card):

SD Pin Arduino MKR WiFi 1010 Pin Description
SD_CS / TF_CS any free GPIO SD card Chip Select
MOSI / SDI 8 Shared with display MOSI (pin 8)
SCK / CLK 9 Shared with display SCK (pin 9)
MISO / SDO 10 Shared with display MISO (pin 10)
The wiring diagram between Arduino MKR WiFi 1010 TFT SPI Display  without touch

This image is created using Fritzing. Click to enlarge image

With Touch

Connect the XPT2046 touch controller to the MKR WiFi 1010 SPI bus, sharing pins 8, 9, and 10 with the display.

Display:

TFT Pin Arduino MKR WiFi 1010 Pin Description
VCC VCC (3.3V) Power supply (3.3V only)
GND GND Ground
CS 12 Chip Select
DC / RS 7 Data / Command select
RST 11 Reset (optional)
MOSI / SDI 8 Hardware SPI MOSI
SCK 9 Hardware SPI clock
MISO / SDO 10 Hardware SPI MISO (optional)
LED / BL VCC (3.3V) Backlight power

Touch controller (if your application uses the touch function and the display supports it):

Touch Pin Arduino MKR WiFi 1010 Pin Description
T_CS any free GPIO Touch Chip Select
T_IRQ any free GPIO Touch interrupt (optional)
T_DIN 8 Shared with display MOSI (pin 8)
T_CLK 9 Shared with display SCK (pin 9)
T_DO 10 Shared with display MISO (pin 10)
The wiring diagram between Arduino MKR WiFi 1010 TFT SPI Display  with touch

This image is created using Fritzing. Click to enlarge image

If your MCU has two or more hardware SPI interfaces, you can assign each peripheral (display, SD card, touch controller) to its own dedicated SPI bus. If your MCU has only one hardware SPI interface, all three peripherals share the same three data lines (MOSI, SCK, MISO) — on the MKR WiFi 1010 these are pins 8, 9, and 10. Each peripheral has its own CS pin, so only one is active at a time. The DIYables_TFT_SPI library manages both the display and the XPT2046 touch controller through a single API — no separate SPI library is needed for the touch side.

Prepare the Library

  1. Connect the Arduino MKR WiFi 1010 to your computer using a Micro-B USB cable.
  2. Open Arduino IDE. Under the board menu, select Arduino MKR WiFi 1010 and pick the correct port.
  3. Click the Libraries panel on the sidebar.
  4. Search for "DIYables_TFT_SPI" and find the DIYables listing.
  5. Click Install. Install all dependencies when prompted.
  • Search for DIYables TFT SPI created by DIYables.io and click the Install button.
Newbiely | Arduino IDE 2.3.8
──
File
Edit
Sketch
Tools
Help
Arduino MKR WiFi 1010
Library Manager
Type:
All
Topic:
All
DIYables TFT SPI by DIYables.io
Supports ILI9341 (240x320, 16-bit RGB565), ILI9488 (320x480, 18-bit RGB666), and ST7789 (240x320, 16-bit RGB565) TFT displays over SPI interface. Extends Adafruit GFX for full graphics support. Works with any Arduino-compatible board that has SPI. More info
1.0.0
INSTALL
Newbiely.ino
···
1 void setup() {
Output
Serial Monitor
Ln 1, Col 1
Arduino MKR WiFi 1010 on COM15
1

Note: If the board does not appear in the board manager, install the Arduino SAMD Boards core first.

Recipe Base

Before baking in any features, start with this template:

#include <DIYables_TFT_SPI.h> #define TFT_CS_PIN 12 #define TFT_DC_PIN 7 #define TFT_RST_PIN 11 // Uncomment the line that matches your driver chip: // DIYables_ILI9341_SPI TFT_display(240, 320, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(320, 480, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(240, 320, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); void setup() { TFT_display.begin(); TFT_display.setRotation(1); } void loop() { // drawing code here }

Make It Happen - Draw Shapes

The DrawShapes example shows how to draw circles, rectangles, triangles, rounded rectangles, and lines with the Adafruit GFX library.

/* * This Arduino MKR WiFi 1010 code was developed by newbiely.com * * This Arduino MKR WiFi 1010 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-mkr/arduino-mkr-wifi-1010-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino MKR WiFi 1010) // --------------------------------------------- // TFT module Arduino MKR WiFi 1010 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> 12 (TFT_CS_PIN) // DC / RS -> 7 (TFT_DC_PIN) // RESET -> 11 (TFT_RST_PIN) // SDI / MOSI -> 8 (hardware SPI MOSI) // SCK -> 9 (hardware SPI SCK) // SDO / MISO -> 10 (only needed when reading from display) // LED -> 3.3V (or any GPIO via initBacklight) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 12 #define TFT_DC_PIN 7 #define TFT_RST_PIN 11 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // MOSI and SCK use default hardware SPI pins // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define BLACK DIYables_TFT_SPI::colorRGB(0, 0, 0) #define BLUE DIYables_TFT_SPI::colorRGB(0, 0, 255) #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) #define GREEN DIYables_TFT_SPI::colorRGB(0, 255, 0) #define ORANGE DIYables_TFT_SPI::colorRGB(255, 165, 0) #define PINK DIYables_TFT_SPI::colorRGB(255, 192, 203) #define VIOLET DIYables_TFT_SPI::colorRGB(148, 0, 211) #define TURQUOISE DIYables_TFT_SPI::colorRGB(64, 224, 208) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) // Helper to draw a filled diamond void fillDiamond(int cx, int cy, int h, int v, uint16_t color) { int x0 = cx, y0 = cy - v; int x1 = cx + h, y1 = cy; int x2 = cx, y2 = cy + v; int x3 = cx - h, y3 = cy; TFT_display.fillTriangle(x0, y0, x1, y1, x2, y2, color); TFT_display.fillTriangle(x0, y0, x2, y2, x3, y3, color); } void setup() { TFT_display.begin(); TFT_display.setRotation(1); // Landscape } void loop() { TFT_display.fillScreen(WHITE); uint16_t w = TFT_display.width(); uint16_t h = TFT_display.height(); // Scale positions relative to screen size with better spacing int col1 = w / 8; int col2 = w * 3 / 8; int col3 = w * 5 / 8; int col4 = w * 7 / 8; int row1 = h / 4; int row2 = h / 2; int row3 = h * 3 / 4; // Outlined circle TFT_display.drawCircle(col1, row1, 30, RED); // Filled circle TFT_display.fillCircle(col2, row1, 30, RED); // Outlined triangle TFT_display.drawTriangle(col3 - 30, row1 + 25, col3 + 30, row1 + 25, col3, row1 - 25, BLUE); // Filled triangle TFT_display.fillTriangle(col4 - 30, row1 + 25, col4 + 30, row1 + 25, col4, row1 - 25, GREEN); // Outlined rectangle TFT_display.drawRect(col1 - 35, row2 - 20, 70, 40, ORANGE); // Filled rectangle TFT_display.fillRect(col2 - 35, row2 - 20, 70, 40, TURQUOISE); // Outlined round rectangle TFT_display.drawRoundRect(col3 - 35, row2 - 20, 70, 40, 10, VIOLET); // Filled round rectangle TFT_display.fillRoundRect(col4 - 35, row2 - 20, 70, 40, 10, PINK); // Outlined diamond (centered between col1 and col2) int diamond1_x = (col1 + col2) / 2; TFT_display.drawLine(diamond1_x, row3 - 30, diamond1_x + 25, row3, GREEN); TFT_display.drawLine(diamond1_x + 25, row3, diamond1_x, row3 + 30, GREEN); TFT_display.drawLine(diamond1_x, row3 + 30, diamond1_x - 25, row3, GREEN); TFT_display.drawLine(diamond1_x - 25, row3, diamond1_x, row3 - 30, GREEN); // Filled diamond (centered between col3 and col4) int diamond2_x = (col3 + col4) / 2; fillDiamond(diamond2_x, row3, 25, 30, BLUE); delay(10000); }

Make It Happen

  • Connect the TFT module to the MKR WiFi 1010 with the wiring table above. Use 3.3V for VCC.
  • Plug in the Micro-B USB cable.
  • In Arduino IDE, select the board and port, paste the code, and click Upload.
  • A continuously updating pattern of colored shapes appears on the display.

Key Methods

Method What It Does Example
begin() Initialize the display controller. TFT_display.begin();
setRotation(r) Set screen rotation 0-3. TFT_display.setRotation(1);
fillScreen(color) Fill screen with a solid color. TFT_display.fillScreen(BLACK);
colorRGB(r,g,b) Convert RGB values to 16-bit color. colorRGB(0,0,255)
drawCircle(x,y,r,color) Circle outline. TFT_display.drawCircle(80,80,50,RED);
fillRect(x,y,w,h,color) Solid rectangle. TFT_display.fillRect(10,10,80,50,GREEN);
drawLine(x0,y0,x1,y1,color) Straight colored line. TFT_display.drawLine(0,0,320,240,WHITE);

Make It Happen - Show Text and Number

The ShowTextAndNumber example prints strings and numeric values on screen using the GFX text engine.

/* * This Arduino MKR WiFi 1010 code was developed by newbiely.com * * This Arduino MKR WiFi 1010 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-mkr/arduino-mkr-wifi-1010-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino MKR WiFi 1010) // --------------------------------------------- // TFT module Arduino MKR WiFi 1010 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> 12 (TFT_CS_PIN) // DC / RS -> 7 (TFT_DC_PIN) // RESET -> 11 (TFT_RST_PIN) // SDI / MOSI -> 8 (hardware SPI MOSI) // SCK -> 9 (hardware SPI SCK) // SDO / MISO -> 10 (only needed when reading from display) // LED -> 3.3V (or any GPIO via initBacklight) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 12 #define TFT_DC_PIN 7 #define TFT_RST_PIN 11 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define MAGENTA DIYables_TFT_SPI::colorRGB(255, 0, 255) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) void setup() { Serial.begin(9600); Serial.println(F("TFT SPI Display - Show text and numbers")); TFT_display.begin(); TFT_display.setRotation(1); // Landscape TFT_display.fillScreen(WHITE); // Set text color and size TFT_display.setTextColor(MAGENTA); TFT_display.setTextSize(3); // Sample values float temperature = 23.5; float humidity = 78.6; // Display temperature TFT_display.setCursor(20, 20); TFT_display.print("Temperature: "); TFT_display.print(temperature, 1); TFT_display.print(char(247)); TFT_display.println("C"); // Display humidity TFT_display.setCursor(20, 60); TFT_display.print("Humidity: "); TFT_display.print(humidity, 1); TFT_display.print("%"); } void loop() { }

Make It Happen

  • Wire and upload as shown above.
  • The display shows lines of text and numbers in various sizes and colors.

Key Methods

Method What It Does Example
setTextColor(color) Sets the text foreground color. TFT_display.setTextColor(WHITE);
setTextSize(size) Scales text. Size 1 = 6×8 px, size 2 = 12×16 px. TFT_display.setTextSize(2);
setCursor(x, y) Moves the cursor to pixel position (x, y). TFT_display.setCursor(10, 20);
print(value) Prints a string or number at the cursor. TFT_display.print("MKR!");
println(value) Prints and advances cursor to the next line. TFT_display.println(3.14);

Make It Happen - Draw Image

Ingredient: a PROGMEM bitmap image. The DrawImage example places a full-color RGB565 image on the display by reading pixel data directly from flash memory. The image is declared inside bitmap.h as a const uint16_t array marked PROGMEM. The MKR WiFi 1010 has 256 KB of flash available for your sketch, so storing a reasonably sized bitmap there is perfectly practical.

Add bitmap.h to the sketch folder before you compile.

/* * This Arduino MKR WiFi 1010 code was developed by newbiely.com * * This Arduino MKR WiFi 1010 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-mkr/arduino-mkr-wifi-1010-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> #include "bitmap.h" // ============================================= // Wiring (Arduino MKR WiFi 1010) // --------------------------------------------- // TFT module Arduino MKR WiFi 1010 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> 12 (TFT_CS_PIN) // DC / RS -> 7 (TFT_DC_PIN) // RESET -> 11 (TFT_RST_PIN) // SDI / MOSI -> 8 (hardware SPI MOSI) // SCK -> 9 (hardware SPI SCK) // LED -> 3.3V (or any GPIO via initBacklight) // SDO / MISO -> 10 (only needed when reading from display) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 12 #define TFT_DC_PIN 7 #define TFT_RST_PIN 11 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) int img_width = 120; int img_height = 53; void setup() { Serial.begin(9600); Serial.println(F("TFT SPI Display - Draw Image")); TFT_display.begin(); uint16_t SCREEN_WIDTH = TFT_display.width(); uint16_t SCREEN_HEIGHT = TFT_display.height(); int x = (SCREEN_WIDTH - img_width) / 2; int y = (SCREEN_HEIGHT - img_height) / 2; TFT_display.fillScreen(WHITE); TFT_display.drawRGBBitmap(x, y, myBitmap, img_width, img_height); } void loop() { delay(2000); TFT_display.invertDisplay(true); delay(2000); TFT_display.invertDisplay(false); }

Make It Happen

  • Place bitmap.h in the same folder as the sketch.
  • Connect the TFT module to the MKR WiFi 1010. Use 3.3V for VCC. CS→12, DC→7, RST→11, MOSI→8, SCK→9.
  • Plug in the Micro-B USB cable.
  • In Arduino IDE, select the board and port, paste the code, and click Upload.
  • The display shows the bitmap image from flash.

Key Methods

Method What It Does Example
drawRGBBitmap(x,y,bitmap,w,h) Draws an RGB565 PROGMEM bitmap with its top-left at (x, y). TFT_display.drawRGBBitmap(0, 0, myImage, 240, 320);
fillScreen(color) Clears the screen before drawing the image. TFT_display.fillScreen(BLACK);

Make It Happen - Draw Image SD Card

Ingredient: an SD card with an image file. The DrawImageSDcard example streams a raw RGB565 binary image from a micro SD card to the display. The SD module plugs into the same SPI bus (pins 8/9/10) as the display. A separate CS pin for the SD module is defined as SD_CS_PIN in the sketch.

/* * This Arduino MKR WiFi 1010 code was developed by newbiely.com * * This Arduino MKR WiFi 1010 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-mkr/arduino-mkr-wifi-1010-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> #include <SD.h> // ============================================= // Wiring (Arduino MKR WiFi 1010) // ============================================= // TFT + SD module pins // TFT + SD module Arduino MKR WiFi 1010 // ----------------------- --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // TFT CS -> 12 (TFT_CS_PIN) // TFT DC / RS -> 7 (TFT_DC_PIN) // TFT RESET -> 11 (TFT_RST_PIN) // SD CS -> 4 (SD_CS) // SDI / MOSI (shared) -> 8 (hardware SPI MOSI) // SDO / MISO (shared) -> 10 (hardware SPI MISO) // SCK (shared) -> 9 (hardware SPI SCK) // LED -> 3.3V (or any GPIO via initBacklight) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 12 #define TFT_DC_PIN 7 #define TFT_RST_PIN 11 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 #define SD_CS 4 // SD card chip select (must differ from TFT_CS_PIN) // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) #define BUFFPIXEL 20 File bmpFile; uint16_t SCREEN_WIDTH; uint16_t SCREEN_HEIGHT; // Helper functions to read BMP file header uint16_t read16(File &f) { uint16_t result; result = f.read(); result |= (f.read() << 8); return result; } uint32_t read32(File &f) { uint32_t result; result = f.read(); result |= ((uint32_t)f.read() << 8); result |= ((uint32_t)f.read() << 16); result |= ((uint32_t)f.read() << 24); return result; } int32_t readS32(File &f) { int32_t result; result = f.read(); result |= ((uint32_t)f.read() << 8); result |= ((uint32_t)f.read() << 16); result |= ((uint32_t)f.read() << 24); return result; } bool getBMPDimensions(const char *filename, uint32_t &w, uint32_t &h) { File f = SD.open(filename); if (!f) return false; if (read16(f) != 0x4D42) { f.close(); return false; } read32(f); // file size read32(f); // reserved read32(f); // image offset read32(f); // DIB header size w = read32(f); int32_t sh = readS32(f); h = (sh < 0) ? -sh : sh; f.close(); return true; } void drawBMP(const char *filename, int x, int y) { bmpFile = SD.open(filename); if (!bmpFile) { Serial.println("File not found"); return; } if (read16(bmpFile) != 0x4D42) { Serial.println("Not a BMP file"); bmpFile.close(); return; } uint32_t fileSize = read32(bmpFile); read32(bmpFile); // Reserved uint32_t imageOffset = read32(bmpFile); uint32_t dibHeaderSize = read32(bmpFile); uint32_t bmpWidth = read32(bmpFile); int32_t bmpHeight = readS32(bmpFile); bool topDown = false; if (bmpHeight < 0) { bmpHeight = -bmpHeight; topDown = true; } if (read16(bmpFile) != 1) { Serial.println("Invalid BMP file"); bmpFile.close(); return; } uint16_t depth = read16(bmpFile); if (depth != 24) { Serial.println("Only 24-bit BMP is supported"); bmpFile.close(); return; } if (read32(bmpFile) != 0) { Serial.println("Unsupported BMP compression"); bmpFile.close(); return; } bmpFile.seek(imageOffset); uint8_t sdbuffer[3 * BUFFPIXEL]; uint16_t color; uint32_t rowSize = (bmpWidth * 3 + 3) & ~3; if (x >= SCREEN_WIDTH || y >= SCREEN_HEIGHT) return; uint32_t maxRow = min((uint32_t)bmpHeight, (uint32_t)(SCREEN_HEIGHT - y)); uint32_t maxCol = min(bmpWidth, (uint32_t)(SCREEN_WIDTH - x)); for (uint32_t row = 0; row < maxRow; row++) { int32_t rowPos = topDown ? row : bmpHeight - 1 - row; uint32_t filePosition = imageOffset + rowPos * rowSize; bmpFile.seek(filePosition); for (uint32_t col = 0; col < maxCol; col += BUFFPIXEL) { uint32_t pixelsToRead = min((uint32_t)BUFFPIXEL, maxCol - col); bmpFile.read(sdbuffer, 3 * pixelsToRead); for (uint32_t i = 0; i < pixelsToRead; i++) { uint8_t b = sdbuffer[i * 3]; uint8_t g = sdbuffer[i * 3 + 1]; uint8_t r = sdbuffer[i * 3 + 2]; color = DIYables_TFT_SPI::colorRGB(r, g, b); if ((x + col + i) < SCREEN_WIDTH && (y + row) < SCREEN_HEIGHT) { TFT_display.drawPixel(x + col + i, y + row, color); } } } } bmpFile.close(); Serial.println("BMP drawn"); } void setup() { Serial.begin(9600); if (!SD.begin(SD_CS)) { Serial.println("SD card initialization failed!"); return; } Serial.println("SD card initialized."); TFT_display.begin(); TFT_display.setRotation(1); // Landscape SCREEN_WIDTH = TFT_display.width(); SCREEN_HEIGHT = TFT_display.height(); TFT_display.fillScreen(WHITE); uint32_t imgWidth, imgHeight; if (getBMPDimensions("diyables.bmp", imgWidth, imgHeight)) { int x = (SCREEN_WIDTH - imgWidth) / 2; int y = (SCREEN_HEIGHT - imgHeight) / 2; drawBMP("diyables.bmp", x, y); } else { Serial.println("Failed to get BMP dimensions"); } } void loop() { }

Make It Happen

  • Wire the SD module to the MKR WiFi 1010, sharing MOSI (pin 8), SCK (pin 9), MISO (pin 10) with the display. Connect SD CS to the pin defined as SD_CS_PIN.
  • Copy a raw RGB565 binary image file to the root of the SD card. File dimensions must match your panel.
  • Plug in the Micro-B USB cable.
  • In Arduino IDE, select board and port, paste the code, and click Upload.
  • The display shows the image streamed from the SD card.

Key Methods

Method What It Does Example
startWrite() Opens a direct SPI write session, keeping the display CS asserted. TFT_display.startWrite();
setAddrWindow(x0,y0,x1,y1) Sets the rectangular pixel write region. TFT_display.setAddrWindow(0, 0, 239, 319);
pushColors(buf, len) Sends a buffer of RGB565 pixel data to the display. TFT_display.pushColors(buf, 512);
endWrite() Closes the SPI session and releases CS. TFT_display.endWrite();

Make It Happen - Use External Font

Ingredient: a custom Adafruit GFX font header. The UseExternalFont example upgrades the text output of the display from the built-in 5×7 raster font to a higher-quality GFX-compatible outline font. Select the font by calling setFont() with a pointer to the font descriptor.

/* * This Arduino MKR WiFi 1010 code was developed by newbiely.com * * This Arduino MKR WiFi 1010 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-mkr/arduino-mkr-wifi-1010-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> #include <Fonts/FreeSansBold12pt7b.h> // ============================================= // Wiring (Arduino MKR WiFi 1010) // --------------------------------------------- // TFT module Arduino MKR WiFi 1010 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> 12 (TFT_CS_PIN) // DC / RS -> 7 (TFT_DC_PIN) // RESET -> 11 (TFT_RST_PIN) // SDI / MOSI -> 8 (hardware SPI MOSI) // SCK -> 9 (hardware SPI SCK) // LED -> 3.3V (or any GPIO via initBacklight) // SDO / MISO -> 10 (only needed when reading from display) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 12 #define TFT_DC_PIN 7 #define TFT_RST_PIN 11 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define MAGENTA DIYables_TFT_SPI::colorRGB(255, 0, 255) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) void setup() { Serial.begin(9600); Serial.println(F("TFT SPI Display - Use external font")); TFT_display.begin(); TFT_display.setFont(&FreeSansBold12pt7b); TFT_display.setRotation(1); // Landscape TFT_display.fillScreen(WHITE); TFT_display.setTextColor(MAGENTA); TFT_display.setTextSize(1); float temperature = 23.5; float humidity = 78.6; TFT_display.setCursor(20, 30); TFT_display.print("Temperature: "); TFT_display.print(temperature, 1); TFT_display.print(char(247)); TFT_display.println("C"); TFT_display.setCursor(20, 70); TFT_display.print("Humidity: "); TFT_display.print(humidity, 1); TFT_display.print("%"); } void loop() { }

Make It Happen

  • Wire the TFT module to the MKR WiFi 1010 as shown in the wiring table. Use 3.3V for VCC.
  • Plug in the Micro-B USB cable.
  • In Arduino IDE, select board and port, paste the code, and click Upload.
  • The display renders text with the custom font. Compare it to the built-in font to see the difference.

Key Methods

Method What It Does Example
setFont(&FontName) Activates a custom GFX-compatible font. Pass NULL to restore the built-in 5×7 font. TFT_display.setFont(&FreeSans12pt7b);
setCursor(x, y) Positions the text cursor at the given pixel coordinate. TFT_display.setCursor(10, 40);
setTextColor(color) Sets the text foreground color. TFT_display.setTextColor(WHITE);
print(text) Prints a string using the active font at the cursor position. TFT_display.print("MKR WiFi 1010");

Make It Happen - Touch Get Point

Ingredient: an XPT2046 touch controller. The TouchGetPoint example reads raw ADC coordinates from the XPT2046 and prints them to the Serial Monitor. Run this recipe step before the calibration step so you know the raw numeric range your panel produces.

Wiring: T_CLK shares pin 9 (SCK), T_DIN shares pin 8 (MOSI), T_DO shares pin 10 (MISO). T_CS→pin 6. T_IRQ is not used (pass -1). All signals are at 3.3V.

/* * This Arduino MKR WiFi 1010 code was developed by newbiely.com * * This Arduino MKR WiFi 1010 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-mkr/arduino-mkr-wifi-1010-tft-lcd-touch-display-spi */ /* Touch Get Point Example ----------------------- This example demonstrates how to read and display touch coordinates using a DIYables SPI TFT display with a 4-wire resistive touch panel. When you touch the screen, the sketch prints the mapped (screen) X and Y coordinates to the Serial Monitor and draws a red dot at the touched location. NOTE: Run the TouchCalibration example first and paste the calibration values into setTouchCalibration() below if the touch coordinates are inaccurate. Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino MKR WiFi 1010) // ============================================= // TFT pins (always required) // TFT module Arduino MKR WiFi 1010 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> 12 (TFT_CS_PIN) // DC / RS -> 7 (TFT_DC_PIN) // RESET -> 11 (TFT_RST_PIN) // SDI / MOSI -> 8 (hardware SPI MOSI) // SCK -> 9 (hardware SPI SCK) // SDO / MISO -> 10 (only needed when reading from display) // LED -> 3.3V (or any GPIO via initBacklight) // // XPT2046 / ADS7843 SPI touch controller // (modules with pins: T_CS, T_CLK, T_DIN, T_DO, T_IRQ) // Touch pin Arduino MKR WiFi 1010 // ------------ --------------------------------- // T_CS -> 6 (TOUCH_CS_PIN) // T_IRQ -> -1 (TOUCH_IRQ_PIN, optional - use -1 to skip) // T_CLK -> 9 (shared with display SCK) // T_DIN -> 8 (shared with display MOSI) // T_DO -> 10 (shared with display MISO) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 12 #define TFT_DC_PIN 7 #define TFT_RST_PIN 11 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // MOSI and SCK use default hardware SPI pins // ============================================= // Touch pin definitions (XPT2046 SPI touch controller) // ============================================= #define TOUCH_CS_PIN 6 // T_CS (any GPIO) #define TOUCH_IRQ_PIN -1 // T_IRQ (any GPIO, or -1 if not connected) // ============================================= // ============================================= // Calibration values. // Run the TouchCalibration example and update these if touch is inaccurate. // Typical raw ranges: // - XPT2046 : ~200..3900 (default below) // - 4-wire resistive : ~100..900 // ============================================= #define TOUCH_LEFT_X 300 #define TOUCH_RIGHT_X 3700 #define TOUCH_TOP_Y 300 #define TOUCH_BOT_Y 3700 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) void setup() { Serial.begin(9600); TFT_display.begin(); TFT_display.setRotation(0); TFT_display.fillScreen(WHITE); TFT_display.initTouchSPI(TOUCH_CS_PIN, TOUCH_IRQ_PIN); TFT_display.setTouchCalibration(TOUCH_LEFT_X, TOUCH_RIGHT_X, TOUCH_TOP_Y, TOUCH_BOT_Y); Serial.println("Touch the screen to see coordinates."); } void loop() { int x, y; if (TFT_display.getTouch(x, y)) { Serial.print("Touch at: "); Serial.print(x); Serial.print(", "); Serial.println(y); TFT_display.fillCircle(x, y, 4, RED); delay(200); } }

Make It Happen

  • Wire the XPT2046 to the MKR WiFi 1010, sharing the SPI bus with the display. T_CS→pin 6. T_IRQ is not used (pass -1).
  • Plug in the Micro-B USB cable.
  • In Arduino IDE, select board and port, paste the code, and click Upload.
  • Open the Serial Monitor at 9600 baud. Touch the display to see raw X, Y, and Z pressure values.

Key Methods

Method What It Does Example
initTouchSPI(cs, irq) Initializes the XPT2046 on the shared 3.3V SPI bus. Pass -1 for irq if that pin is not wired. TFT_display.initTouchSPI(1, 0);
readTouchRaw(x, y, z) Returns raw ADC values from the controller without applying calibration. Returns true when pressed. TFT_display.readTouchRaw(x, y, z);

Make It Happen - Touch Draw

Ingredient: calibrated touch coordinates. The TouchDraw example lets you paint on the MKR WiFi 1010's display using a finger. Each detected touch position draws a small colored dot, and dragging the finger produces a continuous brushstroke.

/* * This Arduino MKR WiFi 1010 code was developed by newbiely.com * * This Arduino MKR WiFi 1010 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-mkr/arduino-mkr-wifi-1010-tft-lcd-touch-display-spi */ /* Touch Draw Lines Example ------------------------- Draws lines on the screen following the pen. - Touch and drag on the screen to draw. - Lift the pen to stop drawing. - Touch again to start a new line from the last point. NOTE: Run the TouchCalibration example and update setTouchCalibration() below if the touch coordinates are inaccurate. Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino MKR WiFi 1010) // ============================================= // TFT pins (always required) // TFT module Arduino MKR WiFi 1010 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> 12 (TFT_CS_PIN) // DC / RS -> 7 (TFT_DC_PIN) // RESET -> 11 (TFT_RST_PIN) // SDI / MOSI -> 8 (hardware SPI MOSI) // SCK -> 9 (hardware SPI SCK) // SDO / MISO -> 10 (only needed when reading from display) // LED -> 3.3V (or any GPIO via initBacklight) // // XPT2046 / ADS7843 SPI touch controller // (modules with pins: T_CS, T_CLK, T_DIN, T_DO, T_IRQ) // Touch pin Arduino MKR WiFi 1010 // ------------ --------------------------------- // T_CS -> 6 (TOUCH_CS_PIN) // T_IRQ -> -1 (TOUCH_IRQ_PIN, optional - use -1 to skip) // T_CLK -> 9 (shared with display SCK) // T_DIN -> 8 (shared with display MOSI) // T_DO -> 10 (shared with display MISO) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 12 #define TFT_DC_PIN 7 #define TFT_RST_PIN 11 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Touch pin definitions (XPT2046 SPI touch controller) // ============================================= #define TOUCH_CS_PIN 6 // T_CS (any GPIO) #define TOUCH_IRQ_PIN -1 // T_IRQ (any GPIO, or -1 if not connected) // ============================================= // ============================================= // Calibration values. // Run the TouchCalibration example and update these if touch is inaccurate. // Typical raw ranges: // - XPT2046 : ~200..3900 (default below) // - 4-wire resistive : ~100..900 // ============================================= #define TOUCH_LEFT_X 300 #define TOUCH_RIGHT_X 3700 #define TOUCH_TOP_Y 300 #define TOUCH_BOT_Y 3700 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) #define PEN_RADIUS 3 void setup() { TFT_display.begin(); TFT_display.setRotation(0); TFT_display.fillScreen(WHITE); TFT_display.initTouchSPI(TOUCH_CS_PIN, TOUCH_IRQ_PIN); TFT_display.setTouchCalibration(TOUCH_LEFT_X, TOUCH_RIGHT_X, TOUCH_TOP_Y, TOUCH_BOT_Y); } void loop() { int x, y; if (TFT_display.getTouch(x, y)) { TFT_display.fillCircle(x, y, PEN_RADIUS, RED); } }

Make It Happen

  • Wire the XPT2046 to the MKR WiFi 1010 as described in the Touch Get Point step above.
  • Plug in the Micro-B USB cable.
  • In Arduino IDE, select board and port, paste the code, and click Upload.
  • Drag a finger across the display to paint on screen.

Key Methods

Method What It Does Example
initTouchSPI(cs, irq) Starts the XPT2046 on the shared SPI bus. TFT_display.initTouchSPI(1, 0);
setTouchCalibration(minX,maxX,minY,maxY) Maps raw ADC readings to screen pixel coordinates. Get the four values from the TouchCalibration recipe step. TFT_display.setTouchCalibration(200, 3800, 300, 3700);
getTouch(x, y) Returns calibrated touch coordinates in screen pixels. Returns true while touched. if (TFT_display.getTouch(x, y)) { ... }
fillCircle(x, y, r, color) Draws a dot at the touch point to build up the stroke. TFT_display.fillCircle(x, y, 3, RED);

Make It Happen - Touch Button

Ingredient: on-screen touch targets. The TouchButton example draws rectangular buttons on the display and detects taps by comparing calibrated touch coordinates against each button's bounding box. A confirmed tap highlights the button and triggers an action.

T_IRQ does not need to be wired for polling-based detection. Pass -1 as the irq argument to skip it.

/* * This Arduino MKR WiFi 1010 code was developed by newbiely.com * * This Arduino MKR WiFi 1010 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-mkr/arduino-mkr-wifi-1010-tft-lcd-touch-display-spi */ /* Touch Button Press/Release Example ------------------------------------ This example shows how to detect press and release events on a rectangular button using a DIYables SPI TFT display with a 4-wire resistive touch panel. When you touch inside the button, it changes colour and shows "PRESSED". When you release, it returns to its original state. NOTE: Run the TouchCalibration example and update setTouchCalibration() below if the touch coordinates are inaccurate. Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino MKR WiFi 1010) // ============================================= // TFT pins (always required) // TFT module Arduino MKR WiFi 1010 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> 12 (TFT_CS_PIN) // DC / RS -> 7 (TFT_DC_PIN) // RESET -> 11 (TFT_RST_PIN) // SDI / MOSI -> 8 (hardware SPI MOSI) // SCK -> 9 (hardware SPI SCK) // SDO / MISO -> 10 (only needed when reading from display) // LED -> 3.3V (or any GPIO via initBacklight) // // XPT2046 / ADS7843 SPI touch controller // (modules with pins: T_CS, T_CLK, T_DIN, T_DO, T_IRQ) // Touch pin Arduino MKR WiFi 1010 // ------------ --------------------------------- // T_CS -> 6 (TOUCH_CS_PIN) // T_IRQ -> -1 (TOUCH_IRQ_PIN, optional - use -1 to skip) // T_CLK -> 9 (shared with display SCK) // T_DIN -> 8 (shared with display MOSI) // T_DO -> 10 (shared with display MISO) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 12 #define TFT_DC_PIN 7 #define TFT_RST_PIN 11 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Touch pin definitions (XPT2046 SPI touch controller) // ============================================= #define TOUCH_CS_PIN 6 // T_CS (any GPIO) #define TOUCH_IRQ_PIN -1 // T_IRQ (any GPIO, or -1 if not connected) // ============================================= // ============================================= // Calibration values. // Run the TouchCalibration example and update these if touch is inaccurate. // Typical raw ranges: // - XPT2046 : ~200..3900 (default below) // - 4-wire resistive : ~100..900 // ============================================= #define TOUCH_LEFT_X 300 #define TOUCH_RIGHT_X 3700 #define TOUCH_TOP_Y 300 #define TOUCH_BOT_Y 3700 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define BLACK DIYables_TFT_SPI::colorRGB( 0, 0, 0) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) #define GRAY DIYables_TFT_SPI::colorRGB(128, 128, 128) #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) #define BUTTON_X 30 #define BUTTON_Y 100 #define BUTTON_W 180 #define BUTTON_H 60 #define DEBOUNCE_DELAY 50 bool lastPressed = false; bool stablePressed = false; unsigned long lastDebounceTime = 0; void drawButton(bool pressed) { uint16_t bg = pressed ? GRAY : RED; TFT_display.fillRect(BUTTON_X, BUTTON_Y, BUTTON_W, BUTTON_H, bg); TFT_display.drawRect(BUTTON_X, BUTTON_Y, BUTTON_W, BUTTON_H, BLACK); TFT_display.setTextColor(WHITE, bg); TFT_display.setTextSize(3); TFT_display.setCursor(BUTTON_X + 10, BUTTON_Y + 16); TFT_display.print(pressed ? "PRESSED" : " PRESS "); } void setup() { Serial.begin(9600); TFT_display.begin(); TFT_display.setRotation(0); TFT_display.fillScreen(WHITE); TFT_display.initTouchSPI(TOUCH_CS_PIN, TOUCH_IRQ_PIN); TFT_display.setTouchCalibration(TOUCH_LEFT_X, TOUCH_RIGHT_X, TOUCH_TOP_Y, TOUCH_BOT_Y); drawButton(false); } void loop() { int x, y; bool pressed = false; if (TFT_display.getTouch(x, y)) { if (x >= BUTTON_X && x < (BUTTON_X + BUTTON_W) && y >= BUTTON_Y && y < (BUTTON_Y + BUTTON_H)) { pressed = true; } } if (pressed != lastPressed) { lastDebounceTime = millis(); } lastPressed = pressed; if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY) { if (pressed != stablePressed) { stablePressed = pressed; drawButton(stablePressed); Serial.println(stablePressed ? "Button PRESSED" : "Button RELEASED"); } } }

Make It Happen

  • Connect T_CS to pin 6. T_IRQ can be left unconnected (the library does not use it).
  • Plug in the Micro-B USB cable.
  • In Arduino IDE, select board and port, paste the code, and click Upload.
  • Tap each button on the display. It should highlight and trigger its action.

Key Methods

Method What It Does Example
initTouchSPI(cs, irq) Initializes the XPT2046. Passing -1 for irq disables the interrupt pin. TFT_display.initTouchSPI(1, -1);
setTouchCalibration(minX,maxX,minY,maxY) Applies calibration so getTouch() returns display-pixel coordinates. TFT_display.setTouchCalibration(200, 3800, 300, 3700);
getTouch(x, y) Gets the calibrated touch position. Returns true while the screen is pressed. if (TFT_display.getTouch(x, y)) { ... }
fillRect(x, y, w, h, color) Renders the button background as a solid colored rectangle. TFT_display.fillRect(10, 10, 120, 60, BLUE);

Make It Happen - Touch Calibration

Ingredient: four calibration constants. The TouchCalibration example measures the raw ADC extremes of your XPT2046 panel. Touch each corner of the display as instructed and read the minimum and maximum X and Y values from the Serial Monitor. Those are the four numbers you will supply to setTouchCalibration() in every other touch recipe.

/* * This Arduino MKR WiFi 1010 code was developed by newbiely.com * * This Arduino MKR WiFi 1010 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-mkr/arduino-mkr-wifi-1010-tft-lcd-touch-display-spi */ /* Touch Screen Calibration Example --------------------------------- This example measures the raw touch coordinates at all four screen corners and prints ready-to-use calibration values to the Serial Monitor. It uses readTouchRaw() directly — it does NOT rely on getTouch() or any existing calibration values, so it works even when touch is completely broken. INSTRUCTIONS: 1. Upload this sketch to your board. 2. Open the Serial Monitor (Ctrl+Shift+M) and set baud rate to 9600. 3. The screen shows a blinking red dot in each corner, numbered 1-4: 1 = Top-left 2 = Top-right 3 = Bottom-right 4 = Bottom-left 4. Press and HOLD firmly on the blinking dot. Keep holding until the Serial Monitor prints "Captured!" for that corner. 5. Release, then wait for the next dot to appear and repeat. 6. After all 4 corners, the Serial Monitor prints the calibration values and a ready-to-use setTouchCalibration() call. Copy it into your sketch. NOTE: While waiting, the Serial Monitor continuously prints the live raw Z/X/Y readings so you can confirm that touch is being detected. Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino MKR WiFi 1010) // ============================================= // TFT pins (always required) // TFT module Arduino MKR WiFi 1010 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> 12 (TFT_CS_PIN) // DC / RS -> 7 (TFT_DC_PIN) // RESET -> 11 (TFT_RST_PIN) // SDI / MOSI -> 8 (hardware SPI MOSI) // SCK -> 9 (hardware SPI SCK) // SDO / MISO -> 10 (only needed when reading from display) // LED -> 3.3V (or any GPIO via initBacklight) // // XPT2046 / ADS7843 SPI touch controller // (modules with pins: T_CS, T_CLK, T_DIN, T_DO, T_IRQ) // Touch pin Arduino MKR WiFi 1010 // ------------ --------------------------------- // T_CS -> 6 (TOUCH_CS_PIN) // T_IRQ -> -1 (TOUCH_IRQ_PIN, optional - use -1 to skip) // T_CLK -> 9 (shared with display SCK) // T_DIN -> 8 (shared with display MOSI) // T_DO -> 10 (shared with display MISO) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 12 #define TFT_DC_PIN 7 #define TFT_RST_PIN 11 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Touch pin definitions (XPT2046 SPI touch controller) // ============================================= #define TOUCH_CS_PIN 6 // T_CS (any GPIO) #define TOUCH_IRQ_PIN -1 // T_IRQ (any GPIO, or -1 if not connected) // ============================================= // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // Minimum pressure to count as a valid touch. #define TOUCH_Z_MIN 10 // How many consecutive valid samples required before a corner is accepted. #define SAMPLES_NEEDED 10 // Delay between samples (ms). #define SAMPLE_DELAY_MS 30 #define DOT_RADIUS 12 #define BLACK DIYables_TFT_SPI::colorRGB( 0, 0, 0) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) // Corner pixel positions - filled in setup() once display size is known. // Order: 0=top-left, 1=top-right, 2=bottom-right, 3=bottom-left int cx[4], cy[4]; // Captured averaged raw values per corner. int cap_x[4], cap_y[4]; // ----------------------------------------------------------------------- void drawDot(int corner, bool on) { uint16_t color = on ? RED : WHITE; TFT_display.fillCircle(cx[corner], cy[corner], DOT_RADIUS, color); TFT_display.setTextSize(2); TFT_display.setTextColor(BLACK, color); TFT_display.setCursor(cx[corner] - 6, cy[corner] - 8); TFT_display.print(corner + 1); } void captureCorner(int corner) { const char* names[] = { "Top-left", "Top-right", "Bottom-right", "Bottom-left" }; Serial.println(); Serial.print("Corner "); Serial.print(corner + 1); Serial.print(" ("); Serial.print(names[corner]); Serial.println(")"); Serial.println(" Press and HOLD firmly on the blinking dot."); Serial.println(" Keep holding until you see 'Captured!'"); unsigned long lastBlink = 0; unsigned long lastPrint = 0; bool dotOn = false; int goodSamples = 0; long sumX = 0, sumY = 0; while (true) { // Blink the dot if (millis() - lastBlink > 400) { lastBlink = millis(); dotOn = !dotOn; drawDot(corner, dotOn); } int raw_x, raw_y, z; TFT_display.readTouchRaw(raw_x, raw_y, z); // Print live readings every 500 ms if (millis() - lastPrint > 500) { lastPrint = millis(); Serial.print(" Z="); Serial.print(z); Serial.print(" X="); Serial.print(raw_x); Serial.print(" Y="); Serial.println(raw_y); } if (z >= TOUCH_Z_MIN) { sumX += raw_x; sumY += raw_y; goodSamples++; if (goodSamples >= SAMPLES_NEEDED) { cap_x[corner] = sumX / goodSamples; cap_y[corner] = sumY / goodSamples; Serial.print(" Captured! raw_x="); Serial.print(cap_x[corner]); Serial.print(" raw_y="); Serial.println(cap_y[corner]); drawDot(corner, false); delay(500); return; } } else { goodSamples = 0; sumX = 0; sumY = 0; } delay(SAMPLE_DELAY_MS); } } // ----------------------------------------------------------------------- void setup() { Serial.begin(9600); TFT_display.begin(); TFT_display.setRotation(0); // Always calibrate in rotation 0 TFT_display.fillScreen(WHITE); TFT_display.initTouchSPI(TOUCH_CS_PIN, TOUCH_IRQ_PIN); int w = TFT_display.width(); int h = TFT_display.height(); int m = DOT_RADIUS + 4; cx[0] = m; cy[0] = m; cx[1] = w - m; cy[1] = m; cx[2] = w - m; cy[2] = h - m; cx[3] = m; cy[3] = h - m; Serial.println("=== Touch Calibration ==="); for (int i = 0; i < 4; i++) { captureCorner(i); } // Derive calibration values from the four corners int min_x = (cap_x[0] + cap_x[3]) / 2; // left edge int max_x = (cap_x[1] + cap_x[2]) / 2; // right edge int min_y = (cap_y[0] + cap_y[1]) / 2; // top edge int max_y = (cap_y[2] + cap_y[3]) / 2; // bottom edge Serial.println(); Serial.println("=== Calibration Results ==="); Serial.print(" Left X (min_x): "); Serial.println(min_x); Serial.print(" Right X (max_x): "); Serial.println(max_x); Serial.print(" Top Y (min_y): "); Serial.println(min_y); Serial.print(" Bot Y (max_y): "); Serial.println(max_y); Serial.println(); Serial.println("Copy this line into your sketch:"); Serial.print(" TFT_display.setTouchCalibration("); Serial.print(min_x); Serial.print(", "); Serial.print(max_x); Serial.print(", "); Serial.print(min_y); Serial.print(", "); Serial.print(max_y); Serial.println(");"); TFT_display.fillScreen(WHITE); TFT_display.setTextColor(BLACK); TFT_display.setTextSize(2); TFT_display.setCursor(10, 10); TFT_display.println("Done! Check"); TFT_display.setCursor(10, 35); TFT_display.println("Serial Monitor"); } void loop() {}

Make It Happen

  • Wire the XPT2046 to the MKR WiFi 1010 as described in the Touch Get Point step.
  • Plug in the Micro-B USB cable.
  • In Arduino IDE, select board and port, paste the code, and click Upload.
  • Open the Serial Monitor at 9600 baud. Follow the prompts and touch each corner.
  • Write down the printed minX, maxX, minY, maxY values for use in setTouchCalibration() elsewhere.

Key Methods

Method What It Does Example
initTouchSPI(cs, irq) Initializes the XPT2046 touch controller. TFT_display.initTouchSPI(1, 0);
readTouchRaw(x, y, z) Reads raw ADC values to measure the calibration range. TFT_display.readTouchRaw(x, y, z);
setTouchCalibration(minX,maxX,minY,maxY) Stores the calibration constants so getTouch() maps correctly to pixel coordinates. TFT_display.setTouchCalibration(200, 3800, 300, 3700);

Make It Happen - Custom SPI

Ingredient: an explicit SPI bus configuration. The CustomSPI example shows how to pass a specific SPIClass instance to the display constructor. On the MKR WiFi 1010 there is one hardware SPI bus on pins 8/9/10. Passing &SPI explicitly gives you direct control over the SPI clock speed and settings, which is useful for long cables or when sharing the bus with a peripheral that has strict timing requirements.

/* * This Arduino MKR WiFi 1010 code was developed by newbiely.com * * This Arduino MKR WiFi 1010 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-mkr/arduino-mkr-wifi-1010-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io This example demonstrates how to use a custom (non-default) SPI bus with the DIYables TFT SPI library. This is useful on boards that have multiple SPI interfaces, such as: - ESP32: HSPI / VSPI - Arduino Giga / Portenta: SPI1 - Raspberry Pi Pico: SPI1 */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino MKR WiFi 1010 - default SPI bus) // --------------------------------------------- // NOTE: The Arduino MKR WiFi 1010 exposes one hardware SPI bus on the MKR // header pins (8=MOSI, 9=SCK, 10=MISO). MY_SPI must remain &SPI // and the wiring uses the standard hardware SPI mapping below. // // TFT module Arduino MKR WiFi 1010 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> 12 (TFT_CS_PIN) // DC / RS -> 7 (TFT_DC_PIN) // RESET -> 11 (TFT_RST_PIN) // SDI / MOSI -> 8 (hardware SPI MOSI) // SCK -> 9 (hardware SPI SCK) // LED -> 3.3V (or any GPIO via initBacklight) // SDO / MISO -> 10 (only needed when reading from display) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 12 #define TFT_DC_PIN 7 #define TFT_RST_PIN 11 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Select SPI bus // ============================================= // --- Default SPI (8/9/10 on MKR WiFi 1010) --- #define MY_SPI &SPI // ============================================= // Create display object with custom SPI bus // (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN, MY_SPI); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN, MY_SPI); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN, MY_SPI); #define BLACK DIYables_TFT_SPI::colorRGB(0, 0, 0) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) #define GREEN DIYables_TFT_SPI::colorRGB(0, 255, 0) #define BLUE DIYables_TFT_SPI::colorRGB(0, 0, 255) void setup() { Serial.begin(9600); TFT_display.begin(); TFT_display.setRotation(1); // Landscape TFT_display.fillScreen(BLACK); uint16_t w = TFT_display.width(); uint16_t h = TFT_display.height(); // Draw a simple test pattern TFT_display.fillRect(0, 0, w / 3, h, RED); TFT_display.fillRect(w / 3, 0, w / 3, h, GREEN); TFT_display.fillRect(w * 2 / 3, 0, w / 3, h, BLUE); TFT_display.setTextColor(WHITE); TFT_display.setTextSize(2); TFT_display.setCursor(10, h / 2 - 10); TFT_display.print("Custom SPI bus OK"); } void loop() { // Nothing to do }

Make It Happen

  • Wire the TFT display to the MKR WiFi 1010 as described in the wiring section. Use 3.3V for VCC.
  • Plug in the Micro-B USB cable.
  • In Arduino IDE, select board and port, paste the code, and click Upload.
  • The display starts on the explicitly configured SPI bus and shows a color-bar pattern.

Key Methods

Method What It Does Example
DIYables_ILI9341_SPI(w,h,cs,dc,rst,spi) Constructor that accepts a pointer to any SPIClass instance. Defaults to &SPI when the argument is omitted. DIYables_ILI9341_SPI tft(240, 320, 12, 7, 11, &SPI);
begin() Initializes the display on the configured SPI bus. TFT_display.begin();

Troubleshoot

  • Black screen -- Verify that VCC is connected to the 3.3V pin, not 5V. Check CS (pin 12), DC (pin 7), MOSI (pin 8), and SCK (pin 9).
  • Garbage pixels -- Confirm only one driver constructor is active; comment out the other two.
  • Image shifted -- The width and height in the constructor must match the physical panel.
  • Touch not responding -- Run the TouchCalibration example and embed the resulting values in your sketch.
  • MKR WiFi 1010 not in board list -- Install the Arduino SAMD Boards core from the Boards Manager.

Platform Support

The library uses only Arduino standard APIs and the architectures=* flag ensures it compiles on every Arduino-compatible platform.

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!