ST7789 TFT display Text is Blocky

When I enlarge the text on the ST7789 TFT so that I can tead it 4-5 feet away, the text come out looking very blocky. Here is a photo of the TFT display in Arduino IDE with the Text

Here is the same display using CircuitPython and bitmap (.bdf) fonts:

Does anyone know how to display (.bdf) fonts in Arduino IDE?

Thanks in advance for the help.

Here is my code:

#include <WiFi.h>
#include <HTTPClient.h>
#include <Adafruit_SHT4x.h>
#include <Adafruit_MAX1704X.h>
#include <Adafruit_NeoPixel.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#include <time.h>
#include "sntp.h" // included with Arduino ESP32 package
#include <Wire.h>
#include <SPI.h>
#include <ArduinoJson.h>

// --- Configuration ---
const char* ssid = "Pelican1";
const char* password = "Aquadesiac";
const char* serverUrl = "192.168.1.149";
const int port = 3000;
const char* ntpServer1 = "pool.ntp.org";
const char* ntpServer2 = "time.nist.gov";// more than one can be used 
const char* TZ_PST = "PST8PDT,M3.2.0,M11.1.0";  // TimeZone rule for Los Angeles including daylight adjustment rules
float cellVoltage = 0.00000;
uint8_t siz = 3;
char buf [15];
char timeStringBuff [50];
char dateStringBuff [50];
char batv [15];
char tempFs [5];
char humPs [10];
float tempF = 0;
float humP = 0;
int_fast64_t start = 0;

// --- Hardware Pins (Specific to ESP32-S3 TFT boards) ---
#define TFT_I2C_POWER 7   // Pin to enable I2C and Screen Power

// --- Objects ---
Adafruit_SHT4x sht4 = Adafruit_SHT4x();
Adafruit_MAX17048 maxlipo;
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

void setup() {
  Serial.begin(115200);
  
  // turn on the TFT / I2C power supply
  Serial.println("Init TFT");
  pinMode(TFT_I2C_POWER, OUTPUT);
  digitalWrite(TFT_I2C_POWER, HIGH);
  delay(10);
  pinMode(TFT_BACKLITE, OUTPUT);
  digitalWrite(TFT_BACKLITE, HIGH);
  tft.init(135, 240); // Standard ESP32-S3 TFT resolution
  tft.setRotation(3);
  tft.fillScreen(ST77XX_BLACK);
  Serial.println("TFT Initialized");

  // 3. Initialize I2C and Sensors
  Wire.begin(); 
  if (!maxlipo.begin()) 
  {
    Serial.println("MAX17048 not found");
  }
  maxlipo.setAlertVoltages(3.0, 4.2);

    Serial.println("Adafruit SHT4x test");
  if (! sht4.begin()) {
    Serial.println("Couldn't find SHT4x");
    while (1) delay(1);
  }
  Serial.println("Found SHT4x sensor");
  Serial.print("Serial number 0x");
  Serial.println(sht4.readSerial(), HEX);

  // You can have 3 different precisions.
  sht4.setPrecision(SHT4X_HIGH_PRECISION);
  sht4.setHeater(SHT4X_NO_HEATER);

  //connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
  Serial.print("WiFi CONNECTED IP: ");  //set the SNTP update time interval
  Serial.println(WiFi.localIP());
  sntp_servermode_dhcp(1);    // (optional)
  sntp_set_time_sync_notification_cb( timeavailable );// tiggers function timeavailable when SNTP update has taken place
  sntp_set_sync_interval(60*60*1000); //set time period after which a snpt server request for time update is made. 
  configTzTime(TZ_PST, ntpServer1);

}

void loop() {
  start = millis();
  simpleRead();
  drawtext1(tempFs);
  drawtext2(humPs);
  printLocalTime();
  drawtext3(timeStringBuff);
  ReadBattery();
  drawtext5(batv);
  PostData();
  int intv =(millis() - start);
  delay((30 * 60 * 1000) - intv); // 1hr Loop
}

void drawtext1(char *text) {
  tft.setCursor(0, 0);
  tft.setTextColor(ST77XX_RED, ST77XX_BLACK);
  tft.setTextWrap(true);
  tft.setTextSize(5);
  tft.print(text);
  tft.print("F");
}

void drawtext2(char *text) {
  tft.setCursor(110, 0);
  tft.setTextColor(ST77XX_GREEN, ST77XX_BLACK);
  tft.setTextWrap(true);
  tft.setTextSize(5);
  tft.print(text);
  tft.print("%");
}

void drawtext3(char *text) {
  tft.setCursor(0, 50);
  tft.setTextColor(ST77XX_BLUE, ST77XX_BLACK);
  tft.setTextWrap(true);
  tft.setTextSize(4);
  tft.print(text);
}

void drawtext4(char *text) {
  tft.setCursor(0, 100);
  tft.setTextColor(ST77XX_ORANGE, ST77XX_BLACK);
  tft.setTextWrap(true);
  tft.setTextSize(siz);
  tft.print(text);
}

void drawtext5(char *text) {
  tft.setCursor(0, 95);
  tft.setTextColor(ST77XX_ORANGE, ST77XX_BLACK);
  tft.setTextWrap(true);
  tft.setTextSize(siz);
  tft.print(text);
}
void timeavailable(struct timeval *t)
{
  Serial.println("Got time adjustment from NTP!");
  //Put any code in here that you want executed when NTP updates
  //e.g.
  //printLocalTime();
}
void printLocalTime()// routine to get the local time and print it in day date and time format
{
   struct tm timeinfo; // used to strore the latest time/date information used with time.h functions
  // function to get the system time and print it in date and time format
  if(!getLocalTime(&timeinfo)){
    Serial.println("No time available (yet)");
    return;
  }
  // Serial.print("Local Time: ");Serial.println(&timeinfo, "%Y-%B-%d, %H:%M:%S");
  strftime(timeStringBuff, sizeof(timeStringBuff), "%H:%M:%S", &timeinfo);
  strftime(dateStringBuff, sizeof(dateStringBuff), "%Y-%b-%d %H:%M:%S", &timeinfo);
}
void simpleRead ()
{
  sensors_event_t humidity, temp;
  sht4.getEvent(&humidity, &temp);
  tempF = (temp.temperature * 9.0 / 5.0) + 32.0;
  dtostrf(tempF, 3, 0, tempFs);
  humP = (humidity.relative_humidity);
  dtostrf(humP, 3, 0, humPs);

}
void ReadBattery()
{
  int i = 0;
  while (i < 3) {
    cellVoltage = maxlipo.cellVoltage();
    if (isnan(cellVoltage)) {
      Serial.println("Failed to read cell voltage, check battery is connected!");
        delay(500);
      return;
    }
  i++;
  }
  dtostrf(cellVoltage, 1, 3, batv);
  strcat(batv, " Volts");
}

void PostData()
{
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    
    // Construct the full URL: http://IP:PORT/PATH
    String serverPath = "http://" + String(serverUrl) + ":" + String(port) + "api/data";
    
    http.begin(serverPath);
    http.addHeader("Content-Type", "application/json");

    // Prepare JSON payload
    JsonDocument doc; 
      doc["timestamp"] = dateStringBuff;
      doc["temperature"] = tempF;
      doc["humidity"] = humP;
      doc["batvolts"] = cellVoltage;
      String jsonPayload;
      serializeJson(doc, jsonPayload);

    //Send post request.
    int httpResponseCode = http.POST(jsonPayload);
    if (httpResponseCode != 0) {
      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
      String payload = http.getString();
      Serial.println("Response: " + payload);
    } else {
      Serial.print("Error code: ");
      Serial.println(httpResponseCode);
    }
    
    http.end(); // Free resources
  } else {
    Serial.println("HTTP Disconnected");
  }
}

The hardware is the Adafruit Feather ESP32-S3 Reverse TFT.

Thanks Again.

setFont

2 Likes

Hi,

I looked into using the Adafruit GFX library but I found several shortcomings. This gfx library does not support the .BDF fonts that I used with success. I tried using the fonts that come with the library, but for the same point size the letters are much larger and even more blocky than the same point size of the .BDF font. The 9 point 7b.h font was much larger than the 42 point .bdf font.

If you have setTextSize() set to anything larger than 1 you will get blocky letters. If you want good looking text at larger sizes, you need to encode the font at a larger point size.

1 Like

Hi David,

Thanks for the suggestion. I did have the text size set to 5.