Sonderzeichen & Symbole auf ein SPI Display Zeichnen mit ESP32

Hallo Liebes Forum,

Ich habe Aktuell das Problem das ich auf meinem 4" TFT SPI Display mit ILI9488 Driver das "grad °" Zeichen nicht darstellen kann. Bei der Temperatur anzeige wird nur das "C" gezeigt. Ich habe es mit dem unicode "u00B0C" als auch mit dem Symbol direkt probiert, funktioniert nicht. Gibt es dafür eine bestimmte Lib zum nutzen bestimmter Symbole und Sonderzeichen ?

Das ist mein Aktueller Code der auf dem ESP32 soweit läuft:

/*
 BLACK: 0x0000 → BLUE: 0x001F → GREEN: 0x07E0 → CYAN: 0x07FF
 RED: 0xF800 → MAGENTA: 0xF81F → YELLOW: 0xFFE0 → WHITE: 0xFFFF
 ORANGE: 0xFDA0 → GREENYELLOW: 0xB7E0 → PINK: 0xFE19 →
 GOLD: 0xFEA0 → SILVER: 0xC618 → SKYBLUE: 0x867D → VIOLET: 0x915C      
*/
#include "DHT.h"
#include <SoftwareSerial.h>
SoftwareSerial HC12Serial(26, 27); // RX an Pin 26, TX an Pin 27

#define DHTPIN 25
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

#include "RTClib.h"
RTC_DS3231 rtc; // SDA → GPIO21 // SCL → GPIO22
DateTime lastDateTime; // Variable zur Speicherung des letzten Datums und der letzten Uhrzeit


#include <TFT_eSPI.h>
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI(); // G23>MOSI // G18>SCK // G4>RESET // G2>DC // G32>CS // G15>Led


const int buttonPin = 12;  
const int ledPin = 15;     
bool buttonState = LOW;
bool lastButtonState = LOW;
unsigned long lastDebounceTime = 0;
unsigned long ledStartTime = 0;
const unsigned long debounceDelay = 50;
const unsigned long ledDuration = 30000;

float lastTemp = 0; // Variable, um den letzten angezeigten Temperaturwert zu speichern
float lastHumidity = 0; // Variable, um den letzten angezeigten Luftfeuchtigkeitswert zu speichern
float outTemp = 0; // OUT Temperaturwert
float outHumidity = 0; // OUT Luftfeuchtigkeitswert





void setup()

{
 {
  {
    //Serial.begin(9600);
    HC12Serial.begin(4800);
    Wire.begin(SDA, SCL);
    dht.begin();
    rtc.begin();
  }
    pinMode(buttonPin, INPUT_PULLUP);          
    pinMode(ledPin, OUTPUT);         
    tft.init(); 
    tft.setRotation(1); 
    tft.fillScreen(TFT_GOLD); 
    tft.setTextColor(TFT_BLACK);
    tft.setFreeFont(&FreeSansBold12pt7b); // FreeSerifBold12pt7b // FreeSansBoldOblique12pt7b  // FreeSansBold12pt7b
    tft.drawString("OUT Temp:", 9, 115);            
    tft.drawString("IN Temp:", 9, 215);
    tft.drawString("OUT Humidity:", 245, 115);
    tft.drawString("IN Humidity:", 245, 215);
 }
   int x = 0; int width = 480; int height = 320; int y1 = 0;
   drawRectWithWidth(x, y1, width, height, TFT_WHITE, 6);   // Zeichne das erste Rechteck
   x = 0; width = 480; height = 106; int y2 = 106;
   drawRectWithWidth(x, y2, width, height, TFT_WHITE, 6);  // Zeichne das zweite Rechteck
   x = 0; width = 240; height = 320; int y3 = 106;
   drawRectWithWidth(x, y3, width, height, TFT_WHITE, 6);  // Zeichne das dritte Rechteck
   //Serial.println("initialize finished");
}





void drawRectWithWidth(int x, int y, int width, int height, uint16_t color, int lineWidth) 
{
  for (int i = 0; i < lineWidth; i++) 
  {
    tft.drawFastHLine(x, y + i, width, color);
    tft.drawFastHLine(x, y + height - i - 1, width, color);
    tft.drawFastVLine(x + i, y, height, color);
    tft.drawFastVLine(x + width - i - 1, y, height, color);
  }
}






void loop()
{
  {
  if (HC12Serial.available())
  {
    String receivedData = HC12Serial.readString();
    teileDaten(receivedData);
    readAndPrintSensorData();
  }

 int reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
    lastDebounceTime = millis();
}

if (millis() - lastDebounceTime > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == LOW) {
digitalWrite(ledPin, HIGH);
ledStartTime = millis();
  }
 }
}
if (digitalRead(ledPin) == HIGH && millis() - ledStartTime >= ledDuration) {
    digitalWrite(ledPin, LOW);
}
lastButtonState = reading;
}
readAndPrintRTC();
}



void teileDaten(String daten)
{
  char *daten2 = new char[daten.length() + 1];
  strcpy(daten2, daten.c_str());
  char *Part0 = strtok(daten2, ",");
  char *Part1 = strtok(NULL, ",");
 
  atof(Part0); // OUT Temperaturwert aktualisieren
  atof(Part1); // OUT Luftfeuchtigkeitswert aktualisieren

  tft.fillRect(90, 160, 138, 40, TFT_GREEN);
  tft.setFreeFont(&FreeSansBold24pt7b);
  tft.setTextColor(TFT_BLACK);
  tft.drawString(String(Part0) + " \u00B0C", 90, 160); // Hier die neuen Koordinaten anpassen

  tft.fillRect(334, 160, 133, 40, TFT_GREEN);
  tft.setFreeFont(&FreeSansBold24pt7b);
  tft.setTextColor(TFT_BLACK);
  tft.drawString(String(Part1) + " %", 334, 160); // Hier die neuen Koordinaten anpassen

  //Serial.print("OUT: ");
  //Serial.print(Part0);
  //Serial.println(" °C");
  //Serial.print("OUT: ");
  //Serial.print(Part1);
  //Serial.println(" %RH");
}






void readAndPrintSensorData() {
  float Temperatur = dht.readTemperature();
  float Luftfeuchtigkeit = dht.readHumidity();

  tft.fillRect(90, 270, 138, 40, TFT_GREEN);
  tft.setFreeFont(&FreeSansBold24pt7b);
  tft.setTextColor(TFT_BLACK);
  tft.drawString(String(Temperatur, 1) + " \u00B0C", 90, 270); // Hier die neuen Koordinaten anpassen
  lastTemp = Temperatur;

  tft.fillRect(334, 270, 133, 40, TFT_GREEN);
  tft.setFreeFont(&FreeSansBold24pt7b);
  tft.setTextColor(TFT_BLACK);
  tft.drawString(String((int)Luftfeuchtigkeit) + " %", 334, 270); // Hier die neuen Koordinaten anpassen
  lastHumidity = Luftfeuchtigkeit;

  //Serial.print("IN: ");
  //Serial.print(Temperatur, 1);
  //Serial.println(" °C");
  //Serial.print("IN: ");
  //Serial.print((int)Luftfeuchtigkeit);
  //Serial.println(" %RH");
  //Serial.println(" ");
}






void readAndPrintRTC()
{
  DateTime now = rtc.now();
  char datumAnzeige[15];
  sprintf(datumAnzeige, "%.1d.%.02d.%.2d", now.day(), now.month(), now.year());

  // Überprüfen, ob sich das Datum geändert hat
  if (now.day() != lastDateTime.day() || now.month() != lastDateTime.month() || now.year() != lastDateTime.year())
  {
    tft.fillRect(35, 35, 235, 40, TFT_GOLD);
    tft.setFreeFont(&FreeSansBold24pt7b);
    tft.setTextColor(TFT_BLACK);
    tft.drawString(String(datumAnzeige), 35, 35);
  }

  // Überprüfen, ob sich die Uhrzeit geändert hat
  if (now.hour() != lastDateTime.hour() || now.minute() != lastDateTime.minute())
  {
    // Vorherigen Text löschen
    tft.fillRect(325, 35, 120, 40, TFT_GOLD);

    // Hier werden die RTC-Daten auf der seriellen Schnittstelle angezeigt
    tft.setFreeFont(&FreeSansBold24pt7b);
    tft.setTextColor(TFT_BLACK);
    String minuteString = String(now.minute(), DEC);
    if (now.minute() < 10)
    {
      minuteString = "0" + minuteString;
    }
    tft.drawString(String(now.hour(), DEC) + ":" + minuteString, 325, 35);

    //Serial.print(now.hour(), DEC);
    //Serial.print(":");
    //Serial.println(minuteString);
  }

  lastDateTime = now; // Aktuelle Zeit und Datum als letzten bekannten Wert speichern
}

Die Anzeige:

Vielen dank für eure unterstützung :blush:

EDIT:
Die RTC wurde ersetzt und läuft auch 1A, das layout der Platine wurde komplett überarbeitet und ist jetzt Maßstabsgetreu

Ich habe da auch keine einfache Lösung gefunden und verwende die Anweisung:

tft.drawCircle(Xo + 27, 62, 2, YELLOW);

Musst du dir natürlich passen einbauen. :wink:
Und das mit der RTC wurde dir ja schon mehrfach empfohlen.

Funktioniert ja jetzt zum Glück, habe nur die nervige Rote LED bei der neuen RTC ausgelötet...hat nur ewig gedauert da ich das bei Ali bestellt habe

Oki vielen dank, ich Probier das aus

Der Status stimmt nicht

Das kennt die IDE nicht

'Xo' was not declared in this scope

.
.
.
.

Die vorschläge aus dem Beitrag hatten kein effekt

Xo ist in meinem Projekt eine feste Position.
Kannst du für dich entfernen oder anpassen.

Habe dir im irgend einen Post geschrieben "baue dir eigne Schriftart mit Processing"
Dan haste eigne Schriftart mit allem drum und dran, welsche du in Dataspeicher verschiebst, für meine Projekte mit ESP + TFT mache das schon lange so.
Ich suche mir bei Google Schrift aus lade die runter und konvertiere, je nach Rechner dauert das bis 10 Sek :wink:

Ui, wie macht mann das? dass hört sich vielversprehchend an

Lade Processing runter entpacke auf dem Desktop


Danach

Charakters auswählen

das habe ich bis hier her schon gemacht, da wird eine Datei mit der Endung .vlw erstellt die ich nicht öffnen kann

Schön :wink:
jetzt nur das in ESP hochladen :
Ordner data erstellen
in dem ordner die vlw verschieben und in esp hochladen

Warum arbeitest Du immer noch mit der langsamen alten Variante über den Data-Ordner und nicht mit dem Filesystem-Manager von Fips?

Gruß Tommy

Sorry wenn ich da nachfrage:
Wo soll der Ordner erstellt werden
und wird das mit der IDE oder dem Processing hochgeladen ?

Weil es einfacher ist. Brauche nicht extra Sketch dafür.

hast schon die vlw auf deinem Rechner und die must in Flasch auf dem ESP.

oder Beispiel vom Fips

Ich arbeite weiter hin mit SPIFFS habe keine Lust alle Projekte ändern und auf LittleFS portieren. Erst bei neuem Projekt kommt LittleFS zum Einsatz

Wenn Du keine Besonderheiten von SPIFFS benutzt hast, genügt der Austausch der Includes und ein

#define SPIFFS LittleFS

oder einmal Suchen und Ersetzen. LittleFS ist in den Grundfunktionen Aufruf kompatibel zu SPIFFS.

Gruß Tommy

OK, Danke werde mall testen.

Ich habe die Erweiterung Instaliert für die IDE in meinem Sketchordner ein Ordner "data" erstelt die .vlw hinein Kopiert und "ESP32 Sketch Data Upload" gemacht hat auch Funktioniert. Muss mann noch was machen oder war es das ? weil das Ergebniss ist in moment noch unverändert oder muss in meinem Arduino Sketch noch was gemacht werden ?

EDIT:
Die .vlw Datei heißt Arial-Black-45.vlw, muss ich in meinem Arduino Sketch einfach die Schriftart tauschen durch Arial-Black-45 ?