I recently got a Heltec HTIT Tracker based on ESP32S3 with a 0.96 160x80 TFT, multi-system GNSS and LoRa
https://docs.heltec.org/en/node/esp32/wireless_tracker/index.html
I was astonished that there was no ready-made ESPHome yaml around, so I started nearly from scratch with this device.
Because I took several loooooong evenings to get this done, I thought why not share here for others
Most trickiest for me was the TFT display. It does not suffice to define the display model st7735
with spi
. Looking up schematics I found that also 2 GPIOs are needed to turn the TFT on.
The gps
part using uart
was straight forward.
I have no interest in LoRa so this is not available in following esphome yaml.
The display shows GNSS data
Full yaml config:
substitutions:
name: "heltec-htit-tracker"
friendly_name: ESPHome Heltec HTIT Tracker
esphome:
name: ${name}
friendly_name: ${friendly_name}
name_add_mac_suffix: false
platformio_options:
board_build.flash_mode: dio
project:
name: esphome.web
version: '1.0'
esp32: # Heltec HTIT Tracker v1.1 = ESP32-S3FN8
board: esp32-s3-devkitc-1
framework:
type: arduino # gps requires arduino
#type: esp-idf # recommended for variants of the ESP32 like this ESP32S3
#sdkconfig_options:
# COMPILER_OPTIMIZATION_SIZE: y
# COMPILER_OPTIMIZATION_PERFORMANCE: y
# Enable logging
logger:
level: DEBUG
logs:
component: ERROR
ili9xxx: INFO
uart_debug: DEBUG
gps: DEBUG
# Enable Home Assistant API
api:
# Allow Over-The-Air updates
ota:
- platform: esphome
# Allow provisioning Wi-Fi via serial
improv_serial:
wifi:
networks:
- ssid: !secret wifi_ssid
password: !secret wifi_password
# Set up a wifi access point
# ap: {}
# In combination with the `ap` this allows the user
# to provision wifi credentials to the device via WiFi AP.
# captive_portal:
dashboard_import:
package_import_url: github://esphome/firmware/esphome-web/esp32s3.yaml@v2
import_full_config: true
# Sets up Bluetooth LE (Only on ESP32) to allow the user
# to provision wifi credentials to the device.
esp32_improv:
authorizer: none
# To have a "next url" for improv serial
web_server:
#############################################################
################## TFT display ##############################
font:
- file: "gfonts://Roboto Mono" # https://fonts.google.com/specimen/Roboto+Mono
id: my_font
size: 20
color:
- id: white
red: 100%
green: 100%
blue: 100%
- id: red
red: 100%
green: 0%
blue: 0%
- id: yellow
red: 100%
green: 100%
blue: 0%
# see https://esphome.io/components/display/ili9xxx#ili9xxx
display:
- platform: ili9xxx
model: st7735
id: st7735
# from HT_st7735.h [1]
# #define ST7735_DC_Pin 40 // schematics: MTDO --- RS
dc_pin: GPIO40
# #define ST7735_REST_Pin 39 // schematics: MTCK --- RES
reset_pin: GPIO39
# #define ST7735_CS_Pin 38 // schematics: GPIO38 --- CS
cs_pin: GPIO38
#define ST7735_IS_160X80 1
#define ST7735_XSTART 1
#define ST7735_YSTART 26
#define ST7735_WIDTH 160
#define ST7735_HEIGHT 80
#define ST7735_ROTATION (ST7735_MADCTL_MY | ST7735_MADCTL_MV | ST7735_MADCTL_BGR)
color_order: bgr # corresponds to ST7735_MADCTL_BGR
invert_colors: true # usually you want text on black background
dimensions:
width: 160
height: 80
offset_width: 1
offset_height: 26
transform:
swap_xy: true # corresponds to ST7735_MADCTL_MV
mirror_y: true # corresponds to ST7735_MADCTL_MY
mirror_x: false
data_rate: 40MHz
auto_clear_enabled: true # else text would draw over old text
lambda: |-
// Display the string "Hello World!" at [0,10]
//it.print(0, 10, id(my_font), "Hello World!");
// Display some GNSS values
it.printf(0, 0, id(my_font), id(white), "Sats %.0f ", id(htit_gnss_satellites).state);
it.printf(0, 20, id(my_font), id(white), " LAT %.2f °", id(htit_gnss_latitude).state);
it.printf(0, 40, id(my_font), id(white), "LONG %.2f °", id(htit_gnss_longitude).state);
it.printf(0, 60, id(my_font), id(white), " ALT %.1f m", id(htit_gnss_altitude).state);
# display st7735 requires spi
spi:
- id: spi_st7735
# from HT_st7735.h [1]
# #define ST7735_SCLK_Pin 41 // schematics: MTDI --- SCLK --- SCL
clk_pin: GPIO41
# #define ST7735_MOSI_Pin 42 // schematics: MTMS --- SDIN --- SDA
mosi_pin: GPIO42
#miso_pin: GPIOxx // not needed
# display st7735 requires 2 GPIOs set to HIGH to turn on TFT
switch:
# from HT_st7735.h [1]
# #define ST7735_LED_K_Pin 21
- platform: gpio
pin: GPIO21
id: led_k_pin
restore_mode: ALWAYS_ON
# #define ST7735_VTFT_CTRL_Pin 3
- platform: gpio
pin: GPIO3 # it's safe to ignore_strapping_warning
id: vtft_ctrl_pin # schematics: Vext_Ctrl
restore_mode: ALWAYS_ON
######################################################
################## GNSS ##############################
uart: # GNSS requires Vext_Ctrl to be HIGH
id: uart_gnss
# it's safe to ignore: WARNING GPIO33/34 is used by the PSRAM interface on ESP32-S3R8 / ESP32-S3R8V and should be avoided on these models
tx_pin: GPIO34 # schematics_ GPIO34 --- GNSS_RX --- RX (tx_pin of ESP = RX of GNSS chip)
rx_pin: GPIO33 # schematics_ GPIO33 --- GNSS_TX --- TX (rx_pin of ESP = TX of GNSS chip)
baud_rate: 115200
debug:
direction: BOTH
dummy_receiver: false # true if no UART device component (=gps) is configured for the UART bus (yet)
after:
delimiter: "\n"
sequence:
- lambda: UARTDebug::log_string(direction, bytes);
gps:
latitude:
name: "Latitude"
id: htit_gnss_latitude
longitude:
name: "Longitude"
id: htit_gnss_longitude
altitude:
name: "Altitude"
id: htit_gnss_altitude
speed:
name: "Speed"
id: htit_gnss_speed
course:
name: "Course"
id: htit_gnss_course
satellites:
name: "Satellites"
id: htit_gnss_satellites
time:
- platform: gps
id: gnss_time
# Some helper functions to restart ESPHome from HA
button:
- platform: restart
name: HTIT Restart
- platform: safe_mode
name: HTIT Safe Mode Boot
######################################################
################## References ########################
# [1] https://github.com/HelTecAutomation/Heltec_ESP32/blob/35c3adf9261fa005714ab6227a02a0e1171d3a7f/src/HT_st7735.h