Os smartwatches se tornaram parte do nosso cotidiano, oferecendo praticidade para acompanhar notificações, ver as horas, monitorar atividades físicas e muito mais. Neste projeto, você vai aprender a criar seu próprio smartwatch DIY (faça você mesmo), utilizando o ESP32 e um display LCD TFT redondo de 1,28”, que possui resolução de 240×240 pixels e interface SPI.

Além de ser um projeto educativo, ele também serve como uma excelente introdução ao uso de displays gráficos com microcontroladores e à comunicação Bluetooth. Ao final do tutorial, você terá um relógio que exibe a hora, data e temperatura, tudo isso com componentes simples e fáceis de encontrar.
Visão geral do display LCD redondo 1.28”
O display LCD redondo de 1.28 polegadas é um componente compacto, moderno e ideal para projetos vestíveis como smartwatches, pulseiras inteligentes ou interfaces gráficas compactas. Ele possui uma resolução de 240×240 pixels, o que garante uma boa definição para mostrar relógios analógicos, textos, ícones e gráficos.

A comunicação é feita por meio da interface SPI, tornando-o compatível com microcontroladores como o ESP32, placas Arduino e outras plataformas de desenvolvimento. O modelo disponível na MakerHero já conta com controlador gráfico GC9A01 integrado, o que facilita bastante a integração com bibliotecas como TFT_eSPI, amplamente utilizada com o ESP32.
Entre os principais destaques desse display estão:
- Formato redondo: ideal para interfaces inspiradas em relógios reais
- Resolução 240×240: boa nitidez em uma área pequena
- Interface SPI: comunicação rápida e fácil de usar com poucos pinos
- Compatibilidade: funciona muito bem com o ESP32, que tem recursos gráficos e Bluetooth integrados
- Retroiluminação: boa visibilidade em diferentes condições de luz
Com esse display, você pode desenvolver interfaces bonitas e funcionais, mesmo em projetos pequenos. No caso deste tutorial, ele será usado para exibir a hora, data e temperatura atual, simulando um smartwatch real. Veja no vídeo abaixo como isso funciona na prática:
Materiais necessários
Para montar o seu smartwatch DIY com ESP32 e display redondo, você vai precisar de alguns componentes eletrônicos básicos. Abaixo está a lista completa:

- Placa ESP32 Bluetooth
- Display Redondo LCD TFT 1.28″ 240×240 SPI
- Jumpers Macho-Macho
- Cabo micro USB
- Protoboard
Dica: Se quiser expandir o projeto, você pode incluir um sensor de batimentos cardíacos, acelerômetro, buzzer, ou até um RTC externo para maior precisão no horário.
Montagem do circuito do smartwatch DIY
A montagem do circuito consiste basicamente em conectar o display redondo LCD TFT ao ESP32 utilizando a interface SPI. Essa conexão exige atenção à pinagem correta e ao uso de níveis de tensão compatíveis com ambos os componentes.

| Display LCD | Descrição | ESP32 |
| VCC | Alimentação | 3.3V |
| GND | Terra | GND |
| CS | Chip Select | GPIO 4 |
| DC | Data/Command | GPIO 2 |
| SDA | Dados SPI (MOSI) | GPIO 23 |
| SCL | Clock SPI (SCK) | GPIO 18 |
Configuração do ambiente de desenvolvimento
Para começar a programar o ESP32 e configurar o display LCD redondo 1.28”, você precisará de um ambiente de desenvolvimento. Neste tutorial, vamos utilizar a Arduino IDE, uma das plataformas mais populares para programar microcontroladores.
- Abra a Arduino IDE e vá até Arquivo > Preferências.
- No campo URLs Adicionais para Gerenciadores de Placas, adicione a seguinte URL: https://dl.espressif.com/dl/package_esp32_index.json
- Em seguida, vá até Ferramentas > Placa > Gerenciador de Placas e pesquise por ESP32. Instale o pacote do ESP32.
Agora, precisamos instalar as bibliotecas GC9A01 e ArduinoJSON:
- Vá até Sketch > Incluir Biblioteca > Gerenciar Bibliotecas…
- Pesquise por Adafruit_GC9A01A e instale a versão mais recente e todas as suas dependências.
- Pesquise por ArduinoJSON e instale a versão mais recente e todas as suas dependências.
Com isso, você já terá o ambiente de desenvolvimento preparado para começar a programar seu smartwatch DIY com o ESP32 e o display LCD.
Programação do smartwatch DIY
Agora que você já conectou o display ao ESP32 e configurou o ambiente de desenvolvimento, é hora de programar o seu smartwatch!
Neste projeto, o microcontrolador ESP32 será responsável por:
- Conectar-se à internet via Wi-Fi;
- Sincronizar a hora correta automaticamente com um servidor NTP;
- Buscar a temperatura atual usando a API do OpenWeather;
- Exibir no display a hora, o dia da semana, a data (dia e mês) e a temperatura, tudo com uma interface colorida.
Você só precisa alterar quadro coisas no código: nome da rede Wi-Fi, senha da rede Wi-Fi, chave da API do OpenWeatherMap e nome da sua cidade.
|
1 2 3 4 5 6 7 8 9 |
// ========== CONFIGURAÇÃO DA REDE Wi-Fi ========== // Substitua pelo nome da sua rede Wi-Fi e senha const char* ssid = "SEU_SSID_AQUI"; const char* password = "SUA_SENHA_AQUI"; // ========== DADOS DA API OpenWeather ========== const char* apiKey = "SUA_CHAVE_API_OPENWEATHER_AQUI"; // Crie uma conta gratuita em https://openweathermap.org/api const char* city = "Cidade"; // Substitua pela sua cidade const char* countryCode = "BR"; // Código do país (ex: BR, US, PT) |
Com essas informações configuradas, basta conectar o ESP32 via USB, selecionar a porta correta na Arduino IDE e clicar em “Carregar”, usando o código abaixo.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
#include <WiFi.h> #include <HTTPClient.h> #include <ArduinoJson.h> #include <Adafruit_GFX.h> #include <Adafruit_GC9A01A.h> #include <SPI.h> #include <time.h> // ========== PINOS DO DISPLAY GC9A01A ========== #define TFT_CS 4 #define TFT_DC 2 Adafruit_GC9A01A tft(TFT_CS, TFT_DC); // ========== CONFIGURAÇÃO DA REDE Wi-Fi ========== // Substitua pelo nome da sua rede Wi-Fi e senha const char* ssid = "SEU_SSID_AQUI"; const char* password = "SUA_SENHA_AQUI"; // ========== DADOS DA API OpenWeather ========== const char* apiKey = "SUA_CHAVE_API_OPENWEATHER_AQUI"; // Crie uma conta gratuita em https://openweathermap.org/api const char* city = "Cidade"; // Substitua pela sua cidade const char* countryCode = "BR"; // Código do país (ex: BR, US, PT) // ========== CONFIGURAÇÃO DO SERVIDOR NTP ========== const char* ntpServer = "pool.ntp.org"; // Servidor para obter a hora certa (internet) const long gmtOffset_sec = -3 * 3600; // Fuso horário do Brasil (UTC-3) // ========== VARIÁVEIS GLOBAIS ========== String temperatura = "--°C"; long lastUpdate = 0; String diaSemana[7] = {"DOMINGO", "SEGUNDA", "TERCA", "QUARTA", "QUINTA", "SEXTA", "SABADO"}; // Armazenam os últimos valores mostrados (para evitar redesenhos desnecessários) String ultimaHora = ""; String ultimoDia = ""; String ultimaTemperatura = ""; // ========== CONFIGURAÇÕES INICIAIS ========== void setup() { Serial.begin(115200); // Inicializa o display tft.begin(); tft.fillScreen(GC9A01A_BLACK); tft.setRotation(0); // Rotação padrão // Conecta ao Wi-Fi WiFi.begin(ssid, password); Serial.print("Conectando ao Wi-Fi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nWi-Fi conectado"); // Configura a hora via NTP configTime(gmtOffset_sec, 0, ntpServer); // Desenha os círculos de fundo int centerX = 120; int centerY = 120; tft.fillCircle(centerX, centerY, 110, GC9A01A_PURPLE); tft.fillCircle(centerX, centerY, 100, GC9A01A_BLACK); } // ========== LOOP PRINCIPAL ========== void loop() { time_t now = time(nullptr); struct tm* timeinfo = localtime(&now); int centerX = 120; int centerY = 120; // Atualiza a temperatura a cada 10 minutos if (millis() - lastUpdate > 600000 || temperatura == "--°C") { atualizarTemperatura(); lastUpdate = millis(); } // ========== EXIBE TEMPERATURA ========== if (temperatura != ultimaTemperatura) { tft.fillRect(centerX - 30, centerY - 90, 60, 20, GC9A01A_BLACK); tft.setTextSize(2); tft.setTextColor(GC9A01A_ORANGE); tft.setCursor(centerX - 28, centerY - 88); tft.print(temperatura); tft.write(0xF7); // Símbolo de grau tft.print("C"); ultimaTemperatura = temperatura; } // ========== EXIBE DIA E MÊS ========== int diaNum = timeinfo->tm_mday; int mesNum = timeinfo->tm_mon + 1; static int ultimoDiaNum = -1; static int ultimoMesNum = -1; if (diaNum != ultimoDiaNum || mesNum != ultimoMesNum) { int yBase = centerY - 60; int diaX = centerX - 50; int mesX = centerX + 20; tft.fillRect(centerX - 80, yBase - 5, 140, 50, GC9A01A_BLACK); // Fundo dos números tft.fillRect(diaX - 5, yBase + 12, 38, 24, GC9A01A_DARKGREY); tft.fillRect(mesX - 5, yBase + 12, 38, 24, GC9A01A_DARKGREY); // Rótulos tft.setTextSize(1); tft.setTextColor(GC9A01A_LIGHTGREY); tft.setCursor(diaX, yBase); tft.print("DIA"); tft.setCursor(mesX, yBase); tft.print("MES"); // Números tft.setTextSize(2); tft.setTextColor(GC9A01A_WHITE); tft.setCursor(diaX + 5, yBase + 16); tft.printf("%02d", diaNum); tft.setCursor(mesX + 5, yBase + 16); tft.printf("%02d", mesNum); // Símbolo "***" entre eles tft.setTextSize(1); tft.setTextColor(GC9A01A_YELLOW); tft.setCursor(centerX - 8, yBase + 20); tft.print("***"); ultimoDiaNum = diaNum; ultimoMesNum = mesNum; } // ========== EXIBE DIA DA SEMANA ========== String dia = diaSemana[timeinfo->tm_wday]; if (dia != ultimoDia) { tft.fillRect(centerX - 60, centerY - 10, 120, 20, GC9A01A_BLACK); tft.setTextSize(2); tft.setTextColor(GC9A01A_CYAN); int textWidth = dia.length() * 12 / 2; tft.setCursor(centerX - textWidth, centerY - 6); tft.print(dia); ultimoDia = dia; } // ========== EXIBE HORA ========== char horaStr[6]; sprintf(horaStr, "%02d:%02d", timeinfo->tm_hour, timeinfo->tm_min); String horaAtual = String(horaStr); if (horaAtual != ultimaHora) { tft.fillRect(centerX - 60, centerY + 30, 120, 40, GC9A01A_BLACK); tft.setTextColor(GC9A01A_WHITE); tft.setTextSize(4); tft.setCursor(centerX - 58, centerY + 30); tft.print(horaAtual); ultimaHora = horaAtual; } delay(1000); // Atualiza a cada segundo } // ========== FUNÇÃO: ATUALIZAR TEMPERATURA ========== void atualizarTemperatura() { if (WiFi.status() == WL_CONNECTED) { HTTPClient http; String url = "http://api.openweathermap.org/data/2.5/weather?q=" + String(city) + "," + String(countryCode) + "&appid=" + apiKey + "&units=metric&lang=pt"; http.begin(url); int httpCode = http.GET(); if (httpCode == 200) { String payload = http.getString(); DynamicJsonDocument doc(1024); DeserializationError error = deserializeJson(doc, payload); if (!error) { float temp = doc["main"]["temp"]; temperatura = String((int)temp); } else { Serial.println("Erro ao fazer parsing do JSON"); temperatura = "--°C"; } } else { temperatura = "--°C"; } http.end(); } } |
A tela do smartwatch será atualizada automaticamente com a data, hora e temperatura da sua cidade.
Resultado final do smartwatch DIY
Com o código carregado no ESP32, o display passa a exibir as informações configuradas:
- Hora atual: mostrada no centro da tela com fonte grande para facilitar a leitura.
- Data: o dia e o mês aparecem na parte superior, organizados com rótulos.
- Dia da semana: exibido logo abaixo da data, em texto centralizado.
- Temperatura: mostrada na parte superior da tela, obtida a partir da API do OpenWeather.
A atualização da hora ocorre em tempo real, sincronizada pela internet por meio do servidor NTP. A temperatura é atualizada a cada 10 minutos automaticamente.

Esse resultado pode ser usado como base para projetos com foco em relógios, painéis informativos ou dispositivos vestíveis. A estrutura do código também permite incluir novas funcionalidades, como sensores ou comunicação Bluetooth.
Expansões possíveis com o smartwatch DIY
O projeto apresentado é uma base funcional que pode ser expandida de várias formas, de acordo com o objetivo e os recursos disponíveis. Algumas possibilidades de melhoria incluem:
- Sensor de batimentos cardíacos: integrar um sensor como o MAX30100 para medir o pulso e exibir a frequência cardíaca no display.
- Acelerômetro e giroscópio (IMU): usar um módulo como o MPU6050 para detectar movimento, gestos ou contar passos.
- RTC (Relógio de tempo real): adicionar um módulo RTC como o DS3231 para manter a hora mesmo sem conexão com a internet.
- Comunicação Bluetooth: usar o Bluetooth do próprio ESP32 para enviar notificações de um smartphone para o relógio.
- Interface sensível ao toque: substituir o display por uma versão com touchscreen ou incluir botões capacitivos para interação.
- Melhoria no design físico: montar o projeto em uma caixa 3D ou pulseira para uso no pulso, com alimentação por bateria Li-Ion ou Li-Po.
Essas expansões podem ser feitas gradualmente, conforme o usuário avança no desenvolvimento. A estrutura modular do código permite adicionar novos recursos sem a necessidade de reescrever todo o sistema.
Conclusão
Neste projeto, você viu como é possível montar um smartwatch simples usando o ESP32 e um display LCD redondo com interface SPI. O sistema obtém a hora e a temperatura da internet e exibe as informações de forma organizada na tela. Esse projeto serve como ponto de partida para outras aplicações que usam microcontroladores com interface gráfica. A integração com APIs, uso de NTP e manipulação de display gráfico são conceitos que podem ser aplicados em várias áreas, como automação, wearables e dispositivos conectados. Se quiser continuar explorando, experimente adicionar sensores, novas telas ou até mesmo integração com aplicativos via Bluetooth. Cada modificação abre espaço para aprendizado e inovação.
Curtiu montar seu próprio smartwatch com ESP32? Ficou com alguma dúvida ou quer mostrar como ficou o seu projeto? Deixe um comentário aqui embaixo! Aproveite para seguir a MakerHero no Instagram e acompanhar mais projetos com ESP32, displays e eletrônica criativa.