Manual

do

Maker

.

com

TTGO - Smartwatch com ESP32 (mais dicas)

TTGO - Smartwatch com ESP32 (mais dicas)

Esse é o penúltimo artigo da série sobre esse smartwatch com ESP32 (até que entre em outra aplicação). Como farei um vídeo de apresentação, escrevi um programa (ainda falta por os motores pra funcionar, mas já está satisfatório), que disponibilizo também nesse artigo.

Smartwatch com ESP32

Como citei anteriormente, não é um smartwatch delicado para o dia-a-dia, mas serve para muitos propósitos, pois tem um acabamento de produto final e é totalmente configurável, uma vez que temos API para desenvolvimento.

Por ser um ESP32, podemos utilizar todos os recursos do RTOS, explicados em outros artigos da categoria ESP32 (só ir ao menu e clicar em ESP32, ou então clique aqui e vasculhe nos artigos).

Tasks no ESP32

As tasks são como threads (para quem conhece programação multithread). Criei 3 tasks, sendo uma para monitorar o touchscreen, uma para controlar os screens e uma para usar o motor como vibracall. Só não habilitei os motores ainda, mas estou usando meu tempo livre para isso. Aliás, repare que o blog está com a aparência mais simples. Passei alguns dias fazendo ajustes para melhorar o desempenho, pois o carregamento em smartphones estava ruim pra caramba.

Carregar imagens no ST7789

O display desse smartwatch com ESP32 também é um ST7789. Esse display é incrível, já escrevi alguns artigos com ele e fiz até streaming da câmera, como pode ser visto nesse outro artigo.

Imagens podem ser carregadas através de duas chamadas diferentes; uma traz a imagem diretamente do cartão e a outra, carrega de um include. Para colocar uma imagem a partir do include, é necessário primeiramente converter a imagem em um array. Já descrevi o processo nesse outro artigo.

Fiz duas telas bem feias, mas serve para mostrar o conceito. Além disso, ao tocar no display, o background ficará preto e o número indicando a tela a seguir é exibido por um tempo X, onde X deve ser passado como parâmetro para a função screenInfo, que criei para esse propósito.

Código

O código que criei para utilizar no vídeo que disponibilizarei em breve é esse:

#include <Arduino.h> #include <WiFi.h> #include <Wire.h> #include <TFT_eSPI.h> #include "bitmap.h" #include "bb.h" #include "/home/djames/.platformio/lib/TFT_eSPI_ID1559/examples/320 x 240/Free_Font_Demo/Free_Fonts.h" #include "time.h" #include <FT5206.h> int timeFirst = millis(); //i2c touch #define TP_SDA 23 #define TP_SCL 32 #define TP_INT 38 //motors const int MOTOR_A1 = 25; const int MOTOR_A2 = 26; const int MOTOR_B1 = 13; const int MOTOR_B2 = 15; //pwm const int A1_CH = 4; const int A2_CH = 5; const int B1_CH = 6; const int B2_CH = 7; /* debug */ // motor outputs const int MA1 = 25; const int MA2 = 26; const int MB1 = 13; const int MB2 = 15; // setting PWM properties const int A1Ch = 4; const int A2Ch = 5; const int B1Ch = 6; const int B2Ch = 7; ////////////////////////////////////////////// bool doit = false; int timeoutGot = millis(); const char* ntpServer = "pool.ntp.org"; const long gmtOffset_sec = 0; const int daylightOffset_sec = -3600*3; const char* ssid = "SuhankoFamily"; const char* password = "fsjmr112"; uint8_t screenNumber = 0; TFT_eSPI tft = TFT_eSPI(); FT5206 cts = FT5206(TP_INT); TaskHandle_t motors; void printLocalTime(); void SysInfo(); /* Ao tocar na tela, o sistema informa para qual função irá. Os parâmetros são a cor de texto e o delay antes da exibição da próxima tela. */ void screenInfo(int color, int timeOf){ if (doit){ tft.fillRect(0,0,240,240,color); tft.setFreeFont(FSS24); tft.setTextColor(0x00FF00); tft.drawNumber(screenNumber,105,105); vTaskDelay(pdMS_TO_TICKS(timeOf)); } } /* Essa task faz a atualização da tela a cada 1 segundo ou se o usuário tocar a tela. No segundo caso, a resposta é imediata. */ void taskScreen(void *pvParameters){ while (true){ int oneSecond = millis() - timeoutGot; screenInfo(0,2000); if (doit || oneSecond > 1000){ Serial.println(oneSecond); timeoutGot = millis();

if (screenNumber == 0){ printLocalTime(); //(1) se estiver na tela do relogio, atualiza... } else{ SysInfo(); } doit = false; } vTaskDelay(pdMS_TO_TICKS(100)); }

} /*TODO: movimenta o motor*/ void motorMovement(void *pvParameters){ Serial.println("^v"); ledcWriteTone(B1_CH, 0); ledcWriteTone(B2_CH, 255); vTaskDelay(pdMS_TO_TICKS(2000)); ledcWriteTone(B1_CH, 0); ledcWriteTone(B2_CH, 0); vTaskDelete(NULL); } //TODO void motorDettachment(){ ledcDetachPin(MOTOR_A1); ledcDetachPin(MOTOR_A2); ledcDetachPin(MOTOR_B1); ledcDetachPin(MOTOR_B2); } //TODO void motorAttachment(){ ledcAttachPin(MOTOR_A1, A1_CH); ledcAttachPin(MOTOR_A2, A2_CH); ledcAttachPin(MOTOR_B1, B1_CH); ledcAttachPin(MOTOR_B2, B2_CH); ledcSetup(A1_CH, 1000, 8); ledcSetup(A2_CH, 1000, 8); ledcSetup(B1_CH, 1000, 8); ledcSetup(B2_CH, 1000, 8); } //TELA 2: informacoes do sistema void SysInfo(){ int xpos = 00; int ypos = 100; if (screenNumber == 1){ vTaskDelay(pdMS_TO_TICKS(200)); tft.setTextColor(0x03EFF); tft.setCursor(xpos, ypos); tft.pushImage(0,0,240,240,bb); tft.setFreeFont(FSS12); // seleciona fonte //tft.println(); String myIP = WiFi.localIP().toString(); String mySSID = "SSID: " + String(ssid); myIP = "IP: " + myIP;

tft.println(myIP); tft.println(mySSID); } } /*Task para gerenciamento do touchscreen. Quando implementado, acionará brevemente o motor. No momento essa tarefa reage somente ao toque.*/ void taskManager(void *pvParameters){ while (true){ if (cts.touched()){ if (millis()-timeFirst >500){ timeFirst = millis(); // se tocou na tela, muda o screenNumber screenNumber = screenNumber > 0 ? 0 : 1; //vTaskDelay(pdMS_TO_TICKS(1000)); doit = true; //tft.fillCircle(120, 120, 30, TFT_BLACK); //tft.fillCircle(120, 120, 40, 0x03FF); xTaskCreatePinnedToCore(motorMovement,"motorMovement", 10000, NULL, 0, &motors,0);

} } vTaskDelay(pdMS_TO_TICKS(10)); } } /*Função de horas para exibição no screen 1. Invés de pegar no RTC, está pegando da internet, sendo útil somente se for utilizado em uma rede WiFi.*/ void printLocalTime() { struct tm timeinfo; if(!getLocalTime(&timeinfo)){ Serial.println("Failed to obtain time"); return; } char myTimeIs[64]; memset(myTimeIs,0,sizeof(myTimeIs)); timeinfo.tm_hour = (timeinfo.tm_hour -3) > -1 ? timeinfo.tm_hour -3 : timeinfo.tm_hour + 9; strftime(myTimeIs, 64, " %H:%M:%S", &timeinfo); int xpos = 00; int ypos = 80; tft.setTextColor(0xFFFF0); tft.setCursor(xpos, ypos); tft.pushImage(0,0,240,240,mercy); tft.setFreeFont(FSS24); // Select Free Serif 12 point font tft.println(); // Move cursor down a line tft.print(myTimeIs); } void setup(void) { Serial.begin(9600); vTaskDelay(pdMS_TO_TICKS(500)); cts.begin(); //inicia o touch screen WiFi.begin(ssid, password); while (WiFi.waitForConnectResult() != WL_CONNECTED){ Serial.print("."); } Serial.println(); Serial.println(WiFi.localIP()); configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); //configuração do NTP tft.begin(); //inicia o display tft.setSwapBytes(true); //inverte a ordem dos bytes para exibir as cores corretamente. tft.fillScreen(TFT_BLACK); //preenche a tela com preto. tft.pushImage(0,0,240,240,mercy); //carrega o bitmap declarado no arquivo bitmap.h motorAttachment(); //inicialização das configurações de pinos dos motores. //inicia as tasks xTaskCreatePinnedToCore(taskManager,"taskManager", 10000, NULL, 1, NULL,0); xTaskCreatePinnedToCore(taskScreen,"taskScreen", 10000, NULL, 1, NULL,0); xTaskCreatePinnedToCore(motorMovement,"motorMovement", 10000, NULL, 0, &motors,0); } void loop() { //nada aqui. }

 

Vou explicar um pouco no vídeo, estou disponibilizando o código mais para ter referência.

Onde comprar o smartwatch com ESP32 da LilyGo

O site da LilyGo com diversos produtos pode ser visto aqui. Já escrevi sobre vários deles, todos de excelente qualidade. É compra sem arrependimento!

Vídeo

O vídeo relacionado estará disponível em nosso canal DobitaobyteBrasil no Youtube. Se não é inscrito, aproveite para se inscrever e clique no sininho para receber notificação tão logo o vídeo seja publicado.

Inscreva-se no nosso canal Manual do Maker no YouTube.

Também estamos no Instagram.

Nome do Autor

Djames Suhanko

Autor do blog "Do bit Ao Byte / Manual do Maker".

Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.