LCD Text Scrollen wie bei einer Bahnhof Anzeige

Hallo zusammen,

ich möchte eine Bahnhof Anzeige basteln, hierzu habe ich zwei unterschiedliche Display in der Bastelkiste die ich dafür nehmen könnte.

Einmal ein 1,8" Farb TFT / LCD mit ST7735.

Und ein LCD mit 20 Zeichen und 4 Zeilen.

Meine Frage hierzu, ist es möglich damit nur einen Teil eines Textes zu Scrollen?

Damit meine ich zu lange Namen zu Scrollen, aber die Minuten Anzeige immer rechts fixiert stehen zu haben?

Folgendes Format:
Berlin Hauptbahnhof - 5 min
Berlin Brandenburger Tor - 10 min

5 min und 10 min sollen hierbei untereinander stehen bleiben.

Ich finde hierzu leider nichts im Forum.

Danke :v:t2:

du brauchst nur anstatt über alle 20 Zeichen zu scrollen, eben nur auf den eingechränkten Platz scrollen.

Und wie mache ich das genau? Kannst du mir ein Beispiel geben?

Wie scrollst du denn bisher?

Ja, siehe im Thema Zuganzeige mit Scroll text wie bei der Bahn, da ist die schwarze Schrift auf weißem Grund ein Lauftext.

Welchen µC möchtest Du verwenden? UNO könnte vom Speicher knapp werden, die Fonts brauchen viel davon.

Keine Ahnung ob die Displaygröße für dich wichtig ist, leider fehlen da Informationen von dir. Aber mit einem Nextiondisplay funktioniert das schon ohne großen Programmieraufwand.

Danke, aber das kann ich denke ich nicht übernehmen, hier wird ja ein OLED angesteuert das funktioniert 1:1 für das LCD bestimmt nicht.

ESP32

Danke.

Die größe ist nicht so wichtig. Es sollte nur mit einem der beiden von mir verlinkten Displays funktionieren. Ich möchte nur drei Zeilen als Zug / Busanzeige verwenden.

Richtig, eine andere Bibliothek (Ucglib) von Oli Kraus, die aber in letzter Zeit nicht mehr gepflegt wurde, was zu vielen Warnungen führt, die in Summe als Fehler gewertet werden. Nach Rauswurf der Warnungen ist das für den ST7735 aber meine derzeit einzige Realisierungsmöglichkeit.

grafik

Dann käme auch TFT_eSPI in Betracht.

Möchtest Du das Display hochkant oder quer nutzen?

Das sieht doch gut aus. :thinking:

Was war hiermit?

Quer.

Meine momentan beste Variante, die aber leicht flackert, das stört mich. Schaue ich mir nochmal mit etwas größerer Schrift mit dem Display quer an.

TFT_eSPI geht nur mit ESP32, wäre also durchaus eine Möglichkeit, aber die Sprites sind noch nicht meine Freunde. Text nach links verschieben ist unproblematisch, aber wenn ich von rechts neue Buchstaben haben möchte, flackert es stärker als bei Ucglib.

Wenn ich Dir eine Bibliothek empfehle, möchte ich auch sicher sein, daß es funktioniert. Derzeit bin ich noch unsicher.

1 Like

Aktuell ist seine u8g2 die auch gepflegt wird.

Ja, geht aber nicht für ST7735.

Hallo,

okay, den hat er bewusst rausgeschmissen. discussions/1477
Musste von Adafruit nehmen. Oder du reparierst seine Lib. :wink:

Inzwischen konnte ich mich mit den Sprites der Bibliothek TFT_eSPI etwas anfreunden und habe zumindest eine einigermaßen akzeptable Lösung. Bis die präsentabel ist, könntest Du die Bibliothek installieren und ein "Hallo Welt" (TFT_eSPI\examples\160 x 128\TFT_Print_Test\TFT_Print_Test.ino) zum Laufen bekommen.

Dazu muß die Datei TFT_eSPI\User_Setup.h angepaßt werden, hier meine für ESP32 und ST7735 aktiven Zeilen:

#define USER_SETUP_INFO "User_Setup"
#define ST7735_DRIVER      // Define additional parameters below for this display
#define TFT_WIDTH  128
#define TFT_HEIGHT 160
#define ST7735_REDTAB
#define TFT_MISO 19
//#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_CS   17  // Chip select control pin
#define TFT_DC    2  // Data Command control pin
#define TFT_RST  14  // Reset pin (could connect to RST pin)
#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
#define SMOOTH_FONT
#define SPI_FREQUENCY  27000000
#define SPI_READ_FREQUENCY  20000000
#define SPI_TOUCH_FREQUENCY  2500000
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite ziel_1 = TFT_eSprite(&tft); // Sprite object stext2
TFT_eSprite ziel_2 = TFT_eSprite(&tft); // Sprite object stext2
#define FONT2 2

void setup() {
  tft.init();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);
  tft.drawString("Abfahrtszeiten", 30, 0, FONT2);

  ziel_1.setColorDepth(8);
  ziel_1.createSprite(160, 20);
  ziel_1.fillSprite(TFT_BLUE);
  ziel_1.setScrollRect(0, 0, 110, 20, TFT_BLUE); // Scroll the "Hello" in the first 40 pixels
  ziel_1.setTextColor(TFT_WHITE, TFT_BLUE); // White text, no background

  ziel_2.setColorDepth(8);
  ziel_2.createSprite(160, 20);
  ziel_2.fillSprite(TFT_BLUE);
  ziel_2.setScrollRect(0, 0, 110, 20, TFT_BLUE); // Scroll the "Hello" in the first 40 pixels
  ziel_2.setTextColor(TFT_WHITE, TFT_BLUE); // White text, no background
}

void loop() {
  anzeige_1();
  anzeige_2();
  delay(50);
}

void anzeige_1()
{
  char buf[31] = {"Berlin Hauptbahnhof - "};
  char verspTxt[] = " 5 Min";
  static char laufTxt[] = {"                      "}; // 22 Leerzeichen und \0
  const byte laufLaenge = sizeof(laufTxt);
  static int8_t zeiger = 0;
  static int8_t pos = 0;

  ziel_1.pushSprite(0, 25);
  ziel_1.scroll(-1);     // scroll ziel_ 1 pixel left, up/down default is 0

  pos--;
  if (pos <= 0) {
    byte k = zeiger;
    for (byte j = 0; j < (laufLaenge - 1); j++) {
      if (buf[k] == '\0') k = 0;
      laufTxt[j] = buf[k];
      k++;
    }
    zeiger++;
    if (buf[zeiger] == '\0') zeiger = 0;
    char tmp[] = {"X"};
    tmp[0] = laufTxt[0];
    pos = ziel_1.textWidth(tmp, FONT2);
    ziel_1.drawString(laufTxt, 0, 2, FONT2);
    ziel_1.drawString(verspTxt, 110, 2, FONT2);
  }
}

void anzeige_2()
{
  char buf[31] = {"Berlin Brandenburger Tor - "};
  char verspTxt[] = " 10 Min";
  static char laufTxt[] = {"                      "}; // 22 Leerzeichen und \0
  const byte laufLaenge = sizeof(laufTxt);
  static int8_t zeiger = 0;
  static int8_t pos = 0;

  ziel_2.pushSprite(0, 45);
  ziel_2.scroll(-1);     // scroll ziel_ 1 pixel left, up/down default is 0

  pos--;
  if (pos <= 0) {
    byte k = zeiger;
    for (byte j = 0; j < (laufLaenge - 1); j++) {
      if (buf[k] == '\0') k = 0;
      laufTxt[j] = buf[k];
      k++;
    }
    zeiger++;
    if (buf[zeiger] == '\0') zeiger = 0;
    char tmp[] = {"X"};
    tmp[0] = laufTxt[0];
    pos = ziel_2.textWidth(tmp, FONT2);
    ziel_2.drawString(laufTxt, 0, 2, FONT2);
    ziel_2.drawString(verspTxt, 110, 2, FONT2);
  }
}

Sieht jetzt so aus:

grafik

2 Likes

@agmue
Auch wenn ich es aktuell nicht brauche, danke für deine Infos und Arbeit.

Bitte gerne :slightly_smiling_face:

Mir ist noch ein anderes Beispiel in die IDE gerutscht, das eventuell besser ist, aber das muß ich erst noch verstehen :smiling_face:

Inzwischen konnte ich das Beispiel umsetzen, Anzeige wie in #18.

#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite ziel_1 = TFT_eSprite(&tft); // Sprite object stext2
TFT_eSprite ziel_2 = TFT_eSprite(&tft); // Sprite object stext2
#define FONT2 2

void setup() {
  tft.init();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);
  tft.drawString("Abfahrtszeiten", 30, 0, FONT2);

  ziel_1.setColorDepth(8);
  ziel_1.createSprite(160, 20);
  ziel_1.fillSprite(TFT_BLUE);
  ziel_1.setTextColor(TFT_WHITE, TFT_BLUE); // White text, no background

  ziel_2.setColorDepth(8);
  ziel_2.createSprite(160, 20);
  ziel_2.fillSprite(TFT_BLUE);
  ziel_2.setTextColor(TFT_WHITE, TFT_BLUE); // White text, no background
}

void loop() {
  char zielTxt_1[] = {"Berlin Hauptbahnhof - "};
  char verspTxt_1[] = "  5 Min ";
  static int16_t pos_1 = 0;
  anzeige(ziel_1, 25, zielTxt_1, verspTxt_1, pos_1);

  char zielTxt_2[] = {"Berlin Brandenburger Tor - "};
  char verspTxt_2[] = " 10 Min ";
  static int16_t pos_2 = 0;
  anzeige(ziel_2, 45, zielTxt_2, verspTxt_2, pos_2);

  delay(50);
}

void anzeige(TFT_eSprite & ziel, const byte ypos, char * zielTxt, char * verspTxt, int16_t & pos)
{
  uint32_t txtLaenge = ziel.textWidth(zielTxt, FONT2);

  ziel.drawString(zielTxt, pos, 2, FONT2);
  ziel.drawString(zielTxt, pos + txtLaenge, 2, FONT2);
  ziel.drawString(verspTxt, 110, 2, FONT2);
  ziel.pushSprite(0, ypos);

  pos--;
  if (pos <= -txtLaenge) pos = 0;
}

Erst wird im µC-Speicher (Sprite) ein Textteil zusammengestellt, dann mittels pushSprite in den Displayspeicher übertragen. Dadurch entfällt das Flackern. Diese Vorgehensweise wird auch in #18 verwendet, nur wird dort die Zeichenbreite eines proportionalen Fonts verwendet, während hier die Pixelbreite der gesamten Nachricht berechnet wird.

Eventuell könnte man auch nur ein Sprite verwenden. Vermutlich schlummert in den Sprites auch noch nicht von mir erkanntes Potential :thinking:

1 Like

Hallo agmue, schonmal vielen lieben Dank für deine Nachforschungen, ich komme leider erst am Wochenende dazu diese auszuprobieren. Ich melde mich dann hier auch nochmal zu Wort!

Edit: Habe dich nicht vergessen, aber ich komme gerade nicht dazu es vernünftig auszuprobieren. :frowning: