Community project

Mam Taki Sprzet 40 Szt Zestaw Kabli Do

ESP32
Photo of Mam Taki Sprzet 40 Szt Zestaw Kabli Do
Generated with AI

maciekptasior

Published August 31, 2026

This guide builds a Wi-Fi connected clock and weather display using an ESP32 microcontroller and a 1.69-inch TFT LCD screen. The display fetches real-time data over the internet and renders it on the 240×280 pixel display with custom graphics and color-coded information.

The project includes a complete wiring diagram showing how to connect the ST7789V3 display to the ESP32 via SPI, a full parts list for the cable kit and components, step-by-step assembly instructions, and ready-to-upload firmware that handles Wi-Fi connectivity, weather API integration, and display rendering.

Wiring diagram

Wiring diagram for Mam Taki Sprzet 40 Szt Zestaw Kabli Do

Gather all the parts

QtyComponent
1

TFT LCD 1.69″ 240×280 ST7789V3, SPI, 8-pin

1.69 in, 240×280

Mały kolorowy ekran, który pokazuje godzinę i aktualną pogodę pobraną przez Wi‑Fi.

Assemble it in 5 steps

1. Odłącz zasilanie i przygotuj ekran

Odłącz kabel USB‑C od ESP32. Włóż płytkę ESP32 i ekran `tft_169` w płytkę stykową tak, aby metalowe piny nie dotykały przypadkowo sąsiednich rzędów.

  • Napisy przy pinach ekranu są bardzo małe — użyj światła z telefonu, aby je odczytać.
  • Jeżeli ekran ma osobny pasek ośmiu pinów do przylutowania, poproś o pomoc przy lutowaniu przed dalszym montażem.
  • Nie podłączaj ekranu ani przewodów, gdy ESP32 jest zasilane z USB — przypadkowe zwarcie może uszkodzić płytkę lub kabel.

2. Podłącz zasilanie ekranu

Użyj dwóch przewodów. Połącz `tft_169` VCC z pinem 3V3 ESP32 (zasilanie) oraz `tft_169` GND z pinem GND ESP32 (wspólny powrót prądu).

  • Szukaj dokładnie napisu „3V3”, a nie „VIN” lub „5V”.
  • Wspólne GND jest konieczne, aby ekran rozumiał sygnały z ESP32.
  • Nie zamieniaj VCC z GND — zamienione zasilanie może uszkodzić ekran.
  • Nie łącz VCC ekranu z pinem 5V/VIN, gdyż ten projekt używa bezpiecznego zasilania 3,3 V.

3. Podłącz przewody obrazu

Połącz `tft_169` SCL z GPIO18 ESP32 (zegar danych) oraz `tft_169` SDA z GPIO23 ESP32 (dane obrazu). Następnie połącz `tft_169` CS z GPIO4 ESP32 (wybór ekranu), DC z GPIO16 (rodzaj przesyłanej informacji) i RES z GPIO17 (reset ekranu).

  • Na niektórych ekranach SCL jest opisany jako SCK, a SDA jako MOSI — są to te same dwa przewody w tym projekcie.
  • Dobierz różne kolory przewodów i zapisz je, aby łatwo znaleźć ewentualną pomyłkę.
  • Nie podłączaj przewodu oznaczonego SDA do GPIO21 — w tym ekranie SDA oznacza dane SPI, a nie zwykłe przewody I2C.
  • Wpięcie przewodu o jeden rząd obok może sprawić, że ekran pozostanie czarny mimo poprawnego programu.

4. Włącz podświetlenie

Połącz pin BLK, LED albo BL na `tft_169` z pinem 3V3 ESP32 (włącza światło za ekranem).

  • Jeśli Twój moduł ma napis „BLK”, jest to właśnie pin podświetlenia.
  • Po tym kroku sprawdź jeszcze raz osiem nazw pinów na ekranie i porównaj je z przewodami.
  • Nie łącz pinu BLK z GND — ekran może wtedy pozostać ciemny i wyglądać na niesprawny.

5. Uruchom zegar i połącz go z Wi‑Fi

Podłącz ESP32 do komputera przewodem USB‑C. Po wgraniu programu przez przycisk Deploy użyj telefonu lub komputera, aby połączyć się z siecią Wi‑Fi „Zegar-ESP32”; otwórz stronę logowania, wybierz swoją sieć domową i wpisz jej hasło. Ekran sam pobierze czas i pogodę dla Warszawy.

  • Sieć ustawień jest potrzebna tylko przy pierwszym połączeniu lub po zmianie domowego Wi‑Fi.
  • Jeśli strona nie otworzy się sama, po połączeniu z „Zegar-ESP32” otwórz w przeglądarce adres 192.168.4.1.
  • Wpisuj hasło tylko na stronie otwartej po połączeniu z własną siecią „Zegar-ESP32”; nie udostępniaj go osobom postronnym.

Review all connections

1. Connections between "tft_169" and "ESP32"

Functiontft_169ESP32
powerVCC3V3
groundGNDGND
spiSCLGPIO 18
spiSDAGPIO 23
digitalRESGPIO 17
digitalDCGPIO 16
digitalCSGPIO 4
powerBLK3V3

Deploy the firmware

#include <Arduino.h>
#include <SPI.h>
#include <WiFi.h>
#include <WiFiManager.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <time.h>

#define TFT_CS 4
#define TFT_DC 16
#define TFT_RST 17
#define TFT_MOSI 23


// Forward declarations
void segment(int x,int y,int n,int s,uint16_t c);
void number(const String &v,int x,int y,int s,uint16_t c);
void header();
void drawWeather();
void getWeather();
void clockUpdate();

constexpr int TFT_SCLK = 18;
constexpr uint16_t NAVY = 0x0861, SKY = 0x5DDF, PALE = 0xE73C, WHITE = 0xFFFF, YELLOW = 0xFFE0, RED = 0xF800;
constexpr unsigned long WEATHER_INTERVAL_MS = 600000UL;

class ST7789Direct {
 public:
  void begin() {
    pinMode(TFT_CS, OUTPUT); pinMode(TFT_DC, OUTPUT); pinMode(TFT_RST, OUTPUT);
    SPI.begin(TFT_SCLK, -1, TFT_MOSI, TFT_CS);
    digitalWrite(TFT_CS, HIGH); digitalWrite(TFT_RST, LOW); delay(20); digitalWrite(TFT_RST, HIGH); delay(120);
    cmd(0x01); delay(150); cmd(0x11); delay(120); cmdData(0x3A, 0x55); cmdData(0x36, 0x00);
    const uint8_t porch[] = {0x0C, 0x0C, 0x00, 0x33, 0x33};
    const uint8_t power[] = {0xA4, 0xA1};
    cmdData(0xB2, porch, sizeof(porch));
    cmdData(0xB7, 0x35); cmdData(0xBB, 0x19); cmdData(0xC0, 0x2C); cmdData(0xC2, 0x01);
    cmdData(0xC3, 0x12); cmdData(0xC4, 0x20); cmdData(0xC6, 0x0F); cmdData(0xD0, power, sizeof(power));
    cmd(0x21); cmd(0x29); delay(20); fill(0, 0, 240, 280, NAVY);
  }
  void fill(int x, int y, int w, int h, uint16_t c) {
    if (x < 0) { w += x; x = 0; } if (y < 0) { h += y; y = 0; }
    if (x + w > 240) w = 240 - x; if (y + h > 280) h = 280 - y; if (w <= 0 || h <= 0) return;
    uint8_t d[4]; d[0]=x>>8; d[1]=x; d[2]=(x+w-1)>>8; d[3]=x+w-1; cmdData(0x2A,d,4);
    d[0]=y>>8; d[1]=y; d[2]=(y+h-1)>>8; d[3]=y+h-1; cmdData(0x2B,d,4); cmd(0x2C);
    digitalWrite(TFT_DC,HIGH); digitalWrite(TFT_CS,LOW); SPI.beginTransaction(SPISettings(40000000, MSBFIRST, SPI_MODE0));
    uint8_t hi=c>>8, lo=c; for (uint32_t i=0;i<(uint32_t)w*h;i++) { SPI.transfer(hi); SPI.transfer(lo); }
    SPI.endTransaction(); digitalWrite(TFT_CS,HIGH);
  }
 private:
  void cmd(uint8_t c) { digitalWrite(TFT_DC,LOW); digitalWrite(TFT_CS,LOW); SPI.beginTransaction(SPISettings(40000000,MSBFIRST,SPI_MODE0)); SPI.transfer(c); SPI.endTransaction(); digitalWrite(TFT_CS,HIGH); }
  void cmdData(uint8_t c,uint8_t v) { cmdData(c,&v,1); }
  void cmdData(uint8_t c,const uint8_t *p,uint8_t n) { cmd(c); digitalWrite(TFT_DC,HIGH); digitalWrite(TFT_CS,LOW); SPI.beginTransaction(SPISettings(40000000,MSBFIRST,SPI_MODE0)); while(n--) SPI.transfer(*p++); SPI.endTransaction(); digitalWrite(TFT_CS,HIGH); }
};
ST7789Direct tft;

const uint8_t segs[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void segment(int x,int y,int n,int s,uint16_t c) { uint8_t m=segs[n]; int w=3*s, l=10*s; if(m&1)tft.fill(x+w,y,l,w,c); if(m&2)tft.fill(x+w+l,y+w,w,l,c); if(m&4)tft.fill(x+w+l,y+2*w+l,w,l,c); if(m&8)tft.fill(x+w,y+2*(w+l),l,w,c); if(m&16)tft.fill(x,y+2*w+l,w,l,c); if(m&32)tft.fill(x,y+w,w,l,c); if(m&64)tft.fill(x+w,y+w+l,l,w,c); }
void number(const String &v,int x,int y,int s,uint16_t c) { for (unsigned i=0;i<v.length();i++) { char q=v[i]; if(q>='0'&&q<='9') segment(x,y,q-'0',s,c); else if(q==':') { tft.fill(x+3*s,y+8*s,3*s,3*s,c); tft.fill(x+3*s,y+17*s,3*s,3*s,c); } else if(q=='.') tft.fill(x+3*s,y+25*s,3*s,3*s,c); else if(q=='-') tft.fill(x,y+13*s,10*s,3*s,c); x+=17*s; } }
void header() { tft.fill(0,0,240,280,NAVY); tft.fill(0,0,240,40,SKY); tft.fill(14,157,212,2,SKY); tft.fill(14,233,212,2,SKY); }
String weather = "--.-"; int weatherCode = -1; unsigned long lastWeather=0; String lastTime;
void drawWeather() { tft.fill(0,164,240,64,NAVY); number(weather,18,170,2,YELLOW); if(weatherCode==0) { tft.fill(175,178,32,32,YELLOW); } else if(weatherCode>=51) { tft.fill(165,182,50,16,PALE); for(int x=170;x<215;x+=12)tft.fill(x,204,3,12,SKY); } else { tft.fill(165,184,52,22,PALE); } }
void getWeather() { if(WiFi.status()!=WL_CONNECTED)return; HTTPClient h; h.begin("http://api.open-meteo.com/v1/forecast?latitude=52.2297&longitude=21.0122&current=temperature_2m,weather_code"); int r=h.GET(); if(r==HTTP_CODE_OK){JsonDocument d; if(!deserializeJson(d,h.getStream())) { weather=String((float)(d["current"]["temperature_2m"]|0.0),1); weatherCode=d["current"]["weather_code"]|-1; drawWeather(); }} h.end(); }
void clockUpdate() { struct tm tm; if(!getLocalTime(&tm,50)) return; char b[6]; strftime(b,sizeof b,"%H:%M",&tm); String now(b); if(now!=lastTime){lastTime=now; tft.fill(0,48,240,102,NAVY); number(now,18,67,3,WHITE);} }
void setup() { Serial.begin(115200); tft.begin(); header(); WiFiManager wm; wm.setConfigPortalTimeout(180); wm.autoConnect("Zegar-ESP32"); configTzTime("CET-1CEST,M3.5.0,M10.5.0/3","pool.ntp.org","time.nist.gov"); clockUpdate(); getWeather(); lastWeather=millis(); }
void loop() { clockUpdate(); unsigned long n=millis(); if(n-lastWeather>=WEATHER_INTERVAL_MS){lastWeather=n;getWeather();} delay(50); }

Remix this project

Make it yours in one click

Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.

Open in Schematik