Forum: Mikrocontroller und Digitale Elektronik Laufschrift Denkanstöße


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Hans Dieter F. (Gast)


Bewertung
-3 lesenswert
nicht lesenswert
Guten abend Freunde der Elektrotechnik!

Wie Ich bemerkt habe, muss Ich ein mega großes Brett vor meinem kleinen 
Kopf haben.

Habe hier neben mir ein schönes Grafikdisplay zu liegen. Dort möchte Ich 
gerne eine Laufschrift von rechts nach links darstellen.

Der ganze String soll von rechts rein gerollt kommen und links wieder 
raus rollen.

Das ist sicherlich mit 2 - 3 schleifen gegessen. Mir fehlt jedoch der 
Ansatz und der Ablauf.

Kann mir jemand auf die Sprünge helfen oder gar einen Pseudo Kode 
posten?

von Frank E. (Firma: Q3) (qualidat)


Bewertung
0 lesenswert
nicht lesenswert
Es macht allerdings einen beachtlichen Unterschied, ob dein Text 
pixelweise oder zeichenweise scrollen soll.

Letzteres schafft man mit einfachen Text- bzw. Array/Listenfunktionen. 
Soll er pixelweise scrollen musst du quasi eine Ebene tiefer in die 
Rendering-Engine ...

von Dominik (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo

Hans Dieter F. schrieb:
> Habe hier neben mir ein schönes Grafikdisplay zu liegen.

welches?

Hans Dieter F. schrieb:
> Der ganze String soll von rechts rein gerollt kommen und links wieder
> raus rollen.

Zeichenweise oder Pixelweise?

gruß Dominik

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Frank E. schrieb:
> Es macht allerdings einen beachtlichen Unterschied, ob dein Text
> pixelweise oder zeichenweise scrollen soll.
Und ob der Font proportional oder monospaced ist...

: Bearbeitet durch Moderator
von Daniel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Frank E. schrieb:
> Soll er pixelweise scrollen musst du quasi eine Ebene tiefer in die
> Rendering-Engine ...

Nicht unbedingt.
Ich habe das mal so gemacht (schwer zu erklären):
- N Zeichen des Textes zunächst immer um V Pixel weiter nach links 
zeichnen
- sobald der Versatz V eine Zeichenbreite beträgt, V=0 und Textzeiger um 
1 erhöhen, also beim nächsten Zeichen weitermachen, aber wieder N 
Zeichen ausgeben
- an einer fixen Position links und rechts vom Scrollbereich nach jedem 
Neuzeichnen einen Block in der Hintergrundfarbe zeichnen. Dieser 
verdeckt den Teil des ersten und letzten Zeichens, der "wegscrollen" 
soll, und verhindert damit ein "Jittern".

Ein paar Randbedingungen beachten, dann geht das.
Ist für den Controller eine Menge Arbeit, aber was soll's.

von Jim M. (turboj)


Bewertung
0 lesenswert
nicht lesenswert
Ich hätte - bei ausreichend RAM - mir das Bitmap von der Laufschrift am 
Stück in den Speicher gepackt und dann jeweils die relevanten Teile per 
CopyRect aufs Display kopiert.

Eine CopyRect() Funktion hat man meistens schon irgendwo rumfliegen für 
das Grafikdisplay.

Braucht zwar RAM, ist aber einfacher als sich zu überlegen wo welcher 
Buchstabe anfängt und aufhören muss.

von Hans Dieter F. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Also es sollte wirklich Zeichenweise geschoben werden. Pixelweise bzw. 
Byteweise ist nicht notwendig.

von Daniel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Du brauchst doch als allererstes eine Funktion, um einen Text an einer 
bestimmten Stelle des Bildschirms anzuzeigen.
Gibt's die auf Deinem System schon, hast Du sie mal ausprobiert und 
funktioniert das?
Oder hast Du wirklich nur das Display herumliegen und sonst noch gar 
nix?

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Daniel schrieb:
> Du brauchst doch als allererstes eine Funktion, um einen Text an
> einer
> bestimmten Stelle des Bildschirms anzuzeigen.
> Gibt's die auf Deinem System schon, hast Du sie mal ausprobiert und
> funktioniert das?
> Oder hast Du wirklich nur das Display herumliegen und sonst noch gar
> nix?

Guten Morgen!

Ich kann an bestimmte Positionen schreiben und verschiedene Schriftarten 
habe Ich auch schon. Also das ist kein Problem.
Es geht wirklich einfach nur um das scrollen eines Textes.

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Nicht wundern. Habe mit meinem Kollegen ein Projekt am laufen (Hans 
Dieter F.)

von Daniel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Also angenommen, diese Funktion heißt lcd_printn(string, 
anzahl_zeichen), und sie gibt anzahl_zeichen Zeichen des Strings string 
aus.
Weiter angenommen, auf das Display passen 10 Zeichen und du willst 
"Guten Morgen" durchscrollen.
Weiter angenommen, du programmierst in C oder verstehst ein Beispiel in 
C.
Dann ist es erstmal am einfachsten, Du ergänzt vorn und hinten 10 
Leerzeichen für das Rein- und Rauslaufen:

char text[] = "          Guten Morgen          ";

Na und dann musst du doch einfach nur
- im ersten Schritt beim ersten Zeichen deines Textes beginnend 10 
Zeichen ausgeben
- im 2. Schritt beim 2. Zeichen beginnend 10 Zeichen ausgeben
- usw.

for(uint8_t i=0; i<strlen(text-10); i++) {
    lcd_printn(&text[i], 10);
    /* hier musst du entweder warten oder das Ganze so aufbauen, dass es 
zyklisch aufgerufen wird */
}

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Da würde ich aber wertvollen RAM verschwenden. An sowas habe ich auch 
schon gedacht.

Es muss doch aber noch andere Möglichkeiten geben..

von Dirk B. (dirkb2)


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> Da würde ich aber wertvollen RAM verschwenden. An sowas habe ich auch
> schon gedacht.

Der String muss ja nicht im RAM liegen
>
> Es muss doch aber noch andere Möglichkeiten geben..

Du kannst die vorderen und hinteren Leerzeichen auch mit Code erzeugen.
Ob der Speichersparender ist, muss man ausprobieren.


Fang doch erstmal an.

: Bearbeitet durch User
von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Dirk B. schrieb:
> Fang doch erstmal an.

Genau das ist Mein Problem. Wo?

von Erich (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> Genau das ist Mein Problem. Wo?

Vielleicht hilft ein Blatt Papier, idealerweise kariert.

Gruss

von Dr. f. Scrollologie (Gast)


Bewertung
0 lesenswert
nicht lesenswert
> Genau das ist Mein Problem. Wo?

Links. In unserem Schriftsystem immer Links, unabhängig von der 
Scrollrichtung. (Arabisch rechts)

von Peter W. (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Dr. f. Scrollologie schrieb:
>> Genau das ist Mein Problem. Wo?
>
> Links. In unserem Schriftsystem immer Links, unabhängig von der
> Scrollrichtung. (Arabisch rechts)

So wirklich verstanden hast du es wohl nicht.

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Hans Dieter F. schrieb:
> Also es sollte wirklich Zeichenweise geschoben werden.

Zeichenweise ist suboptimal. Das springt dann zu sehr und ist absolut 
unleserlich.

> Pixelweise bzw. Byteweise ist nicht notwendig.

Doch. Du hast 2 Möglichkeiten:

1. Pixel-Matrix des Strings im RAM komplett aufbauen. Braucht mehr RAM,
   ist aber etwas einfacher. Rechenzeit ist gering, da die Erstellung
   der Matrix nur einmal geschieht.

2. Nur den Ausschnitt, der dargestellt werden soll, berechnen. Braucht
   weniger RAM und ist etwas anspruchsvoller. Verbraucht auch mehr
   Rechenzeit, da hier für jeden Frame eine Neuberechnung notwendig
   wird.

Ich empfehle Dir 2.

Umgesetzt ist das zum Beispiel im Projekt WordClock mit WS2812. 
Denkanstöße findest Du im Source, wenn Du in display.c

https://www.mikrocontroller.net/svnbrowser/wordclock24h/src/display/display.c?revision=105&view=markup

nach der Funktion display_set_ticker() suchst.

EDIT:

Die für Dich relevanten Funktionen neben display_set_ticker() sind:

display_show_ticker_char ()
display_ticker_with_offset ()
display_ticker ()

Den Rest in display.c kannst Du getrost ignorieren, weils für Deine 
Aufgabe nicht relevant ist.

: Bearbeitet durch Moderator
von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> display_set_ticker()

Frank M. schrieb:
> 2. Nur den Ausschnitt, der dargestellt werden soll, berechnen. Braucht
>    weniger RAM und ist etwas anspruchsvoller. Verbraucht auch mehr
>    Rechenzeit, da hier für jeden Frame eine Neuberechnung notwendig
>    wird.
>
> Ich empfehle Dir 2.

Ich soll quasie für jedes einzelne Zeichen die Pixel in ein Array 
kopieren (hintereinander) ?

von Fabian H. (hdr)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe mir dazu mal eine Funktion geschrieben (hier pseudo):
1
void LcdSetText(int16_t x, int16_t y, const char[] text, ...);

Diese Funktion akzeptiert auch negative Positionen. Die Funktion setzt 
anhand des Textes und des Bitmap-Arrays den Text dann in einzelne
1
LcdSetPixel(int16_t x, int16_t y);
 und
1
LcdClearPixel(int16_t x, int16_t y);
 Funktionsaufrufe um. Diese akzeptieren auch negative Positionen, setzen 
es aber nur um, wenn die Position innerhalb des Displaybereichs liegt.

Dadurch kann man sehr flexible Bilder, Texte etc. in den sichtbaren 
Bildschirmbereich rein und rausscrollen...

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> ch soll quasie für jedes einzelne Zeichen die Pixel in ein Array
> kopieren (hintereinander) ?

Ich würde sie direkt ins Display (durch Pixel setzen/zurücksetzen) 
kopieren - an die richtige Stelle. Dann kannst Du auf das Array 
verzichten.

Wo Du in display_show_ticker_char()
1
led.matrix[start_line + line][start_col + col] = NEW_STATE;
liest, rufst Du stattdessen Deine Funktion
1
set_pixel (start_line + line, start_col + col);
auf.

Wo Du in display_show_ticker_char()
1
led.matrix[start_line + line][start_col + col] = CURRENT_STATE;
liest, rufst Du stattdessen Deine Funktion
1
clear_pixel (start_line + line, start_col + col);
auf.

Im WordClock-Source wird ein Array für das Display verwendet, weil hier 
verschiedene States für Überblendungen und andere Animationen verwendet 
werden. Das kannst Du aber getrost ignorieren.

: Bearbeitet durch Moderator
von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Fabian H. schrieb:
> Ich habe mir dazu mal eine Funktion geschrieben (hier pseudo):void
> LcdSetText(int16_t x, int16_t y, const char[] text, ...);

Pixel kann ich auch schon gezielt setzen..
Hört sich interessant an. Magst du deine Funktion mal vorstellen?

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Ich würde sie direkt ins Display (durch Pixel setzen/zurücksetzen)
> kopieren - an die richtige Stelle. Dann kannst Du auf das Array
> verzichten.

Okay. Diese müssen aber auch zyklisch aufgerufen werden, wo machst du 
das?

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
char A[] = {0x04,0x32,0x21,0x43,0x43};
glcdSetPixel(x,y);
Nun kann Ich ja mit "glcdSetPixel()" einen beliebigen Pixel setzen.
Die Anzahl von Pixel vom Buchstaben "A" müssten 5Bytes(8Bits) * 8 = 320 
Pixel sein.

Wie setze ich jetzt von jedem Byte von "A" gezielt die Pixel, wenn ich 
bei der "glcdSetPixel()"
nur die Koordinaten eingeben kann?

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> Okay. Diese müssen aber auch zyklisch aufgerufen werden, wo machst du
> das?

Hast Du Dir die Funktion display_set_ticker() angeschaut? Da steht doch 
drin:
1
        if (do_wait)
2
        {
3
            while (*ticker_ptr)
4
            {
5
                display_ticker ();
6
                delay_msec ((display.ticker_deceleration * 1000) / 64);
7
            }
8
        }

Das ist der simple Fall, dass auf die Ausgabe gewartet werden soll. Hier 
gehts dann mit einem simplen Delay. Der andere Fall, dass der Ticker im 
Hintergrund ausgeführt wird (ohne Warten) lassen wir mal weg. Das würde 
zu weit führen.

: Bearbeitet durch Moderator
von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Hast Du Dir die Funktion display_set_ticker() angeschaut? Da steht doch
> drin:        if (do_wait)
>         {
>             while (*ticker_ptr)
>             {
>                 display_ticker ();
>                 delay_msec ((display.ticker_deceleration * 1000) / 64);
>             }
>         }

Dein Kode ist ziemlich komplex. Muss Ich mir mal in Ruhe anschauen. Wie 
sieht es denn mit meiner anderen Frage aus bzgl. "glcdPixelSet"

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> char A[] = {0x04,0x32,0x21,0x43,0x43};
> glcdSetPixel(x,y);
> Nun kann Ich ja mit "glcdSetPixel()" einen beliebigen Pixel setzen.
> Die Anzahl von Pixel vom Buchstaben "A" müssten 5Bytes(8Bits) * 8 = 320
> Pixel sein.
>   Wie setze ich jetzt von jedem Byte von "A" gezielt die Pixel, wenn ich
> bei der "glcdSetPixel()"
> nur die Koordinaten eingeben kann?

Ich verstehe Dich überhaupt nicht mehr. Du willst eine Laufschrift 
anzeigen, weisst aber noch nichtmals, wie Du überhaupt einen einzigen 
Buchstaben aufs Display bringst?

Sorry, das Pferd von hinten aufzäumen bringt nichts. Du hättest den 
Thread besser "Buchstabe auf Display: Denkanstoß" nennen sollen. Denn 
man fängt vorne und nicht hinten an, wenn man eine Aufgabe lösen will.

Und wie ich aus Deinem obigen Beitrag entnehme, willst Du jetzt nicht 
nur einen "Denkanstoß", sondern jetzt auch den kompletten Source, wie Du 
einen Buchstaben auf Dein Display bringst.

Unter "Denkanstoß" verstehe ich etwas anderes.

Die Funktion display_show_ticker_char() macht doch genau das. Ich rate 
Dir, jetzt erstmal zu versuchen, die vier oben genannten Funktionen zu 
verstehen, bevor Du uns hier weiter mit Fragen bombardierst.

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Peter W. schrieb:
>> char A[] = {0x04,0x32,0x21,0x43,0x43};
>> glcdSetPixel(x,y);
>> Nun kann Ich ja mit "glcdSetPixel()" einen beliebigen Pixel setzen.
>> Die Anzahl von Pixel vom Buchstaben "A" müssten 5Bytes(8Bits) * 8 = 320
>> Pixel sein.
>>   Wie setze ich jetzt von jedem Byte von "A" gezielt die Pixel, wenn ich
>> bei der "glcdSetPixel()"
>> nur die Koordinaten eingeben kann?
>
> Ich verstehe Dich überhaupt nicht mehr. Du willst eine Laufschrift
> anzeigen, weisst aber noch nichtmals, wie Du überhaupt einen einzigen
> Buchstaben aufs Display bringst?
>

Strings kann ich Anzeigen lassen das ist alles kein Problem. Ich nutze 
für das schreiben von Zeichen nur nicht die Funktion "glcdSetPixel" 
sondern schreibe direkt immer 8 Bit. Für "glcdSetPixel" müsste Ich die 
Funktion zu oft aufrufen um ein Zeichen da zu stellen. Wir missverstehen 
uns!

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> Dein Kode ist ziemlich komplex.

Deine Aufgabenstellung ist auch komplex.

> Muss Ich mir mal in Ruhe anschauen.

Ja. Machs in Ruhe. Sammle Deine Fragen und versuche zunächst, sie Dir am 
Ende selbst zu beantworten. Gelingt Dir das, hast Du den Source auch 
verstanden. Die vier Ticker-Funktionen bauen aufeinander auf.

> Wie
> sieht es denn mit meiner anderen Frage aus bzgl. "glcdPixelSet"

Wie gesagt: schau Dir display_show_ticker_char() an. Das bildet einen 
einzelnen Buchstaben an beliebiger Stelle aufs Display ab. Dass die 
Funktion so komplex aussieht, liegt daran, dass sie auch Teile eines 
Buchstabens ausgeben kann. Das ist nämlich notwendig für den ersten und 
letzten sichtbaren Buchstaben Deines Ticker-Textes. Der erste rutscht 
links pixelweise raus, während der letzte rechts reinrutscht.

: Bearbeitet durch Moderator
von Dirk B. (dirkb2)


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> Dirk B. schrieb:
>> Fang doch erstmal an.
>
> Genau das ist Mein Problem. Wo?

Z.B da: 
Beitrag "Re: Laufschrift Denkanstöße"

von A. S. (achs)


Bewertung
0 lesenswert
nicht lesenswert
Mehrere Dutzend Leute hier haben sicher schon Schrift gescrollt. Auf 
ebenso viele Arten, meist kann das sogar der Grafikchip.

Wenn Du hier Deinen Pseudo-Code postest, wie Du einen String anzeigst, 
so haben wir erstmals ein Gefühl, wo Du stehst.

Wenn Du zudem folgende Fragen beantwortest, kann man Dir sogar konkret 
helfen:

- reicht vorerst ein (langsames, ruckartiges) Scrollen um jeweils ein 
Zeichen. Z.B. falls Du keinen Pixelzugriff hast?

- wird noch mehr auf dem Display angezeigt (drüber, drunter oder 
daneben)

- nutzt Du ein Framework (GUI), was vielleicht sogar im Internet 
beschrieb en ist?

- Hast Du Zugang zum Grafikchip (entweder weil Du den Treiber selbst 
geschrieben hast, oder weil Du dran kommen könntest)

- Nutzt Du eigene Fonts oder etwa Chipinternes?

von Nico W. (nico_w)


Bewertung
0 lesenswert
nicht lesenswert
Achim S. schrieb:
> - Hast Du Zugang zum Grafikchip (entweder weil Du den Treiber selbst
> geschrieben hast, oder weil Du dran kommen könntest)

- Manche Grafiktchips unterstützen auch nativ das Scrollen.

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Achim S. schrieb:
> - reicht vorerst ein (langsames, ruckartiges) Scrollen um jeweils ein
> Zeichen. Z.B. falls Du keinen Pixelzugriff hast?

Die Lösung mit den einzelnen Pixel setzen ist schon recht Interessant 
das würde ich gerne mal ausprobieren.

Achim S. schrieb:
> - wird noch mehr auf dem Display angezeigt (drüber, drunter oder
> daneben)

Auf dem Display wird noch mehr angezeigt. Es soll ganz unten als 
"Newsticker" laufen ( Page 0 ).

Achim S. schrieb:
> - nutzt Du ein Framework (GUI), was vielleicht sogar im Internet
> beschrieb en ist?

Ich programmiere mit ATMEL Studio 7.x

Achim S. schrieb:
> - Hast Du Zugang zum Grafikchip (entweder weil Du den Treiber selbst
> geschrieben hast, oder weil Du dran kommen könntest)

Den Treiber habe ich soweit selbst geschrieben. Ich kann also auf alle 
Funktionen vom "ST7565R" zugreifen.


Fonts nutze Ich die es auch so im Netz gibt mit den "Font Arrays".

Damit springe ich an Postion (x,y)
1
void glcdSetPageColumn(uint8_t pageAddr, uint8_t column)
2
{
3
    glcdSendCmd(((pageAddr & 0x0F )| 0xB0));
4
     
5
    /*
6
    *   Baue das Kommando für die Zeile (High Byte)
7
    */
8
    glcdSendCmd((((column&0xF0)>>4))| 0x10);
9
     
10
    /*
11
    *   Adresse (Low Byte)
12
    */
13
    glcdSendCmd(column & 0x0F);
14
}

Hiermit kann ich an beliebiger Stelle Pixel setzen oder löschen
1
void glcdSetPixel(uint8_t x, uint8_t y)
2
{
3
  glcdSetPageColumn(x/8,y);
4
  glcdSendData(1<<(x%8));
5
}
6
7
void glcdClearPixel(uint8_t x, uint8_t y)
8
{
9
  glcdSetPageColumn(x/8,y);
10
  glcdSendData(0<<(x%8));  
11
}

Fonts die nur eine Page benutzen, schreibe Ich so
1
      glcdGotoXY(x,y);
2
      for (index=0;index<font.fontPtr[2];index++)
3
      glcdSendData(swapBits(font.fontPtr[font.indexNum+index]));

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
1
display_show_ticker_char (uint8_t start_line, uint8_t start_col, uint8_t ch, uint8_t col_offset, uint8_t use_target)
2
{
3
    uint8_t    line;
4
    uint8_t    col;
5
    uint8_t    offset;
6
7
    for (line = 0; line < TICKER_LINES; line++)
8
    {
9
        offset = col_offset + 1;
10
11
        for (col = 0; offset < TICKER_COLS + 1; col++, offset++)
12
        {
13
            if (start_line + line < WC_ROWS && start_col + col < WC_COLUMNS)
14
            {
15
                    if (ticker_font[ch][line] & (1<<(TICKER_COLS - offset)))
16
                    {
17
                        glcdSetPixel(start_line + line, start_col + col);
18
                    }
19
                    else
20
                    {
21
                        glcdClearPixel(start_line + line, start_col + col);
22
                    }
23
                }
24
            }
25
        }
26
        while (start_col + col < WC_COLUMNS)
27
        {
28
            led.matrix[start_line + line][start_col + col] = CURRENT_STATE;
29
            col++;
30
        }
31
   }
32
}
Ist das jetzt richtig umgebaut? Du hattest noch eine Variable 
"use_target" in dem Source. Brauche Ich diese?

TICKER_COLS ist gleichzusetzen mit der Breite des Displays?
1
        while (start_col + col < WC_COLUMNS)
2
        {
3
            led.matrix[start_line + line][start_col + col] = CURRENT_STATE;
4
            col++;
5
        }
Müssen hier die Pixel gesetzt oder gelöscht werden?

Was ist mit "WC_COLUMNS"?

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> Ist das jetzt richtig umgebaut?

Ja, sieht schon ganz gut aus :-)

> Du hattest noch eine Variable
> "use_target" in dem Source. Brauche Ich diese?

Nein. Das ist im WordClock-Source eine alternative Pixel-Set-Methode. 
Hier nicht relevant. Nimm use_target am besten komplett aus den 
Parametern raus. Du musst dann natürlich alle Aufrufe von 
display_show_ticker_char() anpassen, also den letzten Parameter 
wegnehmen.

> TICKER_COLS ist gleichzusetzen mit der Breite des Displays?

Nein. In display.c findest Du für die WordClock24-Variante:
1
#define TICKER_LINES                    8
2
#define TICKER_COLS                     8

TICKER_LINES ist die Höhe des verwendeten Fonts in Pixeln, TICKER_COLS 
ist die Breite eines Zeichens in Pixel. Die Definition des 8x8-Fonts 
findest Du übrigens direkt darunter. Am besten übernimmst Du diese für 
Deine ersten Tests.

>        while
> (start_col + col < WC_COLUMNS)
>         {
>             led.matrix[start_line + line][start_col + col] =
> CURRENT_STATE;
>             col++;
>         }
>
> Müssen hier die Pixel gesetzt oder gelöscht werden?

Gelöscht. Sobald das letzte Zeichen des des Strings ausgegeben wird und 
rechts daneben ist noch Platz, muss dieser gelöscht werden, um alte 
Pixel-Reste vom Vorgänger-Frame wegzulöschen. Hier könnte man übrigens 
noch optimieren, würde aber für den ersten Lauf zu weit führen. First 
make it work, then make it fine ;-)

> Was ist mit "WC_COLUMNS"?

WC_ROWS ist die Anzahl der Zeilen des Displays
WC_COLUMNS ist die Anzahl der Spalten des Displays

WC steht hier für "WordClock". Setze die Konstanten auf die Höhe/Breite 
Deines Displays per #define. Vielleicht solltest Du Dir da auch noch 2 
andere Namen für diese Konstanten ausdenken ;-)

Beispiel:
1
#define DISPLAY_ROWS     320
2
#define DISPLAY_COLUMNS   64

Die Werte sind natürlich nur Phantasiewerte, welche an die tatsächlichen 
Pixel Deines Displays angepasst werden müssen.

: Bearbeitet durch Moderator
von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
1
#define TICKER_LINES                    7
2
#define TICKER_COLS                     5
3
4
#define DISPLAY_ROWS             320
5
#define DISPLAY_COLUMNS           64
6
7
display_show_ticker_char (uint8_t start_line, uint8_t start_col, uint8_t col_offset)
8
{
9
    uint8_t    line;
10
    uint8_t    col;
11
    uint8_t    offset;
12
13
    for (line = 0; line < TICKER_LINES; line++)
14
    {
15
        offset = col_offset + 1;
16
17
        for (col = 0; offset < TICKER_COLS + 1; col++, offset++)
18
        {
19
            if (start_line + line < DISPLAY_ROWS && start_col + col < DISPLAY_COLUMNS)
20
            {
21
                    if (ticker_font[ch][line] & (1<<(TICKER_COLS - offset)))
22
                    {
23
                        glcdSetPixel(start_line + line, start_col + col);
24
                    }
25
                    else
26
                    {
27
                        glcdClearPixel(start_line + line, start_col + col);
28
                    }
29
                }
30
            }
31
        }
32
        while (start_col + col < DISPLAY_COLUMNS)
33
        {
34
            glcdClearPixel(start_line + line, start_col + col);
35
            col++;
36
        }
37
   }
38
}

Jetzt bleibt mir nur noch
1
if (ticker_font[ch][line] & (1<<(TICKER_COLS - offset)))
Was muss ich da abfragen? Das aktuelle Zeichen?

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> if (ticker_font[ch][line] & (1<<(TICKER_COLS - offset)))
>
> Was muss ich da abfragen? Das aktuelle Zeichen?

ch ist das aktuelle Zeichen, ja. Aber darum musst Du Dich gar nicht 
kümmern, da es ja übergeben wird.

Aber ich sehe, dass Du den Parameter "unsigned char ch" aus der 
Parameterliste von display_show_ticker_char() gestrichen hast... 
warum?!?

Baue den wieder ein. Sonst läuft das nicht.

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> ch ist das aktuelle Zeichen, ja. Aber darum musst Du Dich gar nicht
> kümmern, da es ja übergeben wird.

Das heißt die Abfrage kann raus?

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> Das heißt die Abfrage kann raus?

Nein, die Abfrage darf natürlich nicht raus. Abhängig vom Zeichen wird 
hier ein Pixel gesetzt oder ein Pixel gelöscht. Du musst den 
Funktionsparameter "unsigned char ch" wieder einsetzen. Warum hast 
Du den überhaupt rausgenommen?

von Frank M. (ukw) (Moderator) Benutzerseite


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Da Du offenbar extreme Probleme hast, einen "Denkanstoß" in ein 
laufendes Programm umzusetzen, habe ich das jetzt mal für Dich erledigt.

Im Anhang findest Du ein vollständig compilierbares Programm.

Du musst nur noch die Stellen, die mit "CHANGE HERE" kommentiert sind, 
entsprechend an Dein Display anpassen.

P.S.
Der Ticker wird auf Höhe der Display-Mitte ausgegeben. Wenn Du ihn unten 
durchlaufen lassen möchtest, musst Du die Zeile
1
    start_line = (DISPLAY_ROWS - TICKER_LINES) / 2;

auf die gewünschte Lage anpassen.

: Bearbeitet durch Moderator
von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Da Du offenbar extreme Probleme hast, einen "Denkanstoß" in ein
> laufendes Programm umzusetzen, habe ich das jetzt mal für Dich erledigt.
>
> Im Anhang findest Du ein vollständig compilierbares Programm.
>
> Du musst nur noch die Stellen, die mit "CHANGE HERE" kommentiert sind,
> entsprechend an Dein Display anpassen.
>
> P.S.
> Der Ticker wird auf Höhe der Display-Mitte ausgegeben. Wenn Du ihn unten
> durchlaufen lassen möchtest, musst Du die Zeile    start_line =
> (DISPLAY_ROWS - TICKER_LINES) / 2;
>
> auf die gewünschte Lage anpassen.

Habe es ausprobiert. Da sollte ja laut deinem Source "Hello World" durch 
laufen. Da laufen nur einzelne Pixel durch also kein Zeichen zu 
erkennen.

von Frank M. (ukw) (Moderator) Benutzerseite


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> Habe es ausprobiert. Da sollte ja laut deinem Source "Hello World" durch
> laufen. Da laufen nur einzelne Pixel durch also kein Zeichen zu
> erkennen.

Dann stimmt was mit Deinen set/clear-Funktionen nicht. Oder hast Du 
einen anderen Font genommen, der evtl. eine andere Breite/Höhe hat?

Ich habe jetzt mal die entsprechenden Stellen, wo CHANGE HERE steht, mit 
Werten gefüllt für eine ASCII-Ausgabe, wobei ich die Display-Größe auf 
10x40 Pixel gesetzt habe:
1
#define DISPLAY_ROWS                    10                  // Number of lines of display, CHANGE HERE!
2
#define DISPLAY_COLUMNS                 40                  // Number of columns of display, CHANGE HERE!
3
...
4
static unsigned char matrix[DISPLAY_ROWS][DISPLAY_COLUMNS];
5
6
static void
7
show_display (void)
8
{
9
    int y, x;
10
11
    for (y = 0; y < DISPLAY_ROWS; y++)
12
    {
13
        for (x = 0; x < DISPLAY_COLUMNS; x++)
14
        {
15
            if (matrix[y][x])
16
            {
17
                putchar ('X');
18
            }
19
            else
20
            {
21
                putchar (' ');
22
            }
23
        }
24
        putchar ('\n');
25
    }
26
}
27
28
static void
29
glcdSetPixel (uint_fast16_t line, uint_fast16_t col)
30
{
31
    matrix[line][col] = 1;
32
}
33
34
static void
35
glcdClearPixel (uint_fast16_t line, uint_fast16_t col)
36
{
37
    matrix[line][col] = 0;
38
}

Und dann noch in Funktion display_set_ticker() vor dem 
delay_msec()-Aufruf ein
1
        show_display ();

eingefügt, weil ich der Einfachheit halber für die Text-Ausgabe mit 
einem Array matrix[][] arbeite.

Die Ausgabe siehst Du im Anhang. Die einzelnen Frames stehen hier 
untereinander.

Irgendwas machst Du falsch.

: Bearbeitet durch Moderator
von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Peter W. schrieb:
>> Habe es ausprobiert. Da sollte ja laut deinem Source "Hello World" durch
>> laufen. Da laufen nur einzelne Pixel durch also kein Zeichen zu
>> erkennen.
>
>
> Irgendwas machst Du falsch.

Erstmal Danke das du dir die Zeit nimmst um Mir zu helfen.
Benutzen tue ich ein 64 x 128 Pixel Display mit einem verbauten ST7565 
Kontroller.

Betreiben tue ich das Display anders herum. Das sollte aber erstmal egal 
sein. Da ist dann nur die Schrift nicht lesbar bzw. verkehrt herrum.

Die Funktionen um ein Pixel zu setzen bzw. zu löschen sehen bei mir so 
aus..
1
void glcdSetPixel(uint8_t x, uint8_t y)
2
{
3
  glcdSetPageColumn(x/8,y);
4
  glcdSendData(_BV(7-(y%8)));
5
}
6
7
void glcdClearPixel(uint8_t x, uint8_t y)
8
{
9
  glcdSetPageColumn(x/8,y);
10
  glcdSendData(0<<(x%8));  
11
}

Bei mir wird ohne einen VRAM gearbeitet, dass sollte jedoch keine Rolle 
spielen oder?

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> void glcdSetPixel(uint8_t x, uint8_t y)
> void glcdClearPixel(uint8_t x, uint8_t y)

Was sehe ich da? x und y vertauscht.

Drehe das mal rum. Egal, ob jetzt in Deinen Set/Clear-Parametern oder im 
Aufruf. Hauptsache, nicht beides ;-)

> Bei mir wird ohne einen VRAM gearbeitet, dass sollte jedoch keine Rolle
> spielen oder?

Sollte nicht.

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Peter W. schrieb:
>> void glcdSetPixel(uint8_t x, uint8_t y)
>> void glcdClearPixel(uint8_t x, uint8_t y)
>
> Was sehe ich da? x und y vertauscht.
>
> Drehe das mal rum. Egal, ob jetzt in Deinen Set/Clear-Parametern oder im
> Aufruf. Hauptsache, nicht beides ;-)
>
>> Bei mir wird ohne einen VRAM gearbeitet, dass sollte jedoch keine Rolle
>> spielen oder?
>
> Sollte nicht.

Ich habe es ein bisschen doof beschrieben in meinen Funktionen.
1
x
2
|
3
|
4
|
5
|
6
|_ _ _ _ _ _ y

daran sollte es nicht liegen.
1
void glcdSetPageColumn(uint8_t pageAddr, uint8_t column)
2
{
3
    glcdSendCmd(((pageAddr & 0x0F )| 0xB0));
4
     
5
    /*
6
    *   Baue das Kommando für die Zeile (High Byte)
7
    */
8
    glcdSendCmd((((column&0xF0)>>4))| 0x10);
9
     
10
    /*
11
    *   Adresse (Low Byte)
12
    */
13
    glcdSendCmd(column & 0x0F);
14
}

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Ok. Ich kenne Dein Display nicht, kann also nichts näheres zu Deinen 
HW-Routinen sagen.

Ist es denn so, dass das Display den jeweiligen Pixel instantan leuchten 
lässt oder muss man da noch eine Art Flush senden, damit die 
vorangegangenen Pixel-Befehle auch wirksam werden?

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Ok. Ich kenne Dein Display nicht, kann also nichts näheres zu
> Deinen
> HW-Routinen sagen.
>
> Ist es denn so, dass das Display den jeweiligen Pixel instantan leuchten
> lässt oder muss man da noch eine Art Flush senden, damit die
> vorangegangenen Pixel-Befehle auch wirksam werden?

Da du mich darauf aufmerksam gemacht hast (habe die Pixel funktion sonst 
nicht weiter im Betrieb) ist mir aufgefallen das die Berechnung nicht 
sauber funtkioniert.
1
void glcdSetPixel(uint8_t x, uint8_t y)
2
{
3
  glcdSetPageColumn(x/8,y);
4
  glcdSendData((x%8));
5
}
muss Ich mal forschen woran das liegt..

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
> Da du mich darauf aufmerksam gemacht hast (habe die Pixel funktion sonst
> nicht weiter im Betrieb) ist mir aufgefallen das die Berechnung nicht
> sauber funtkioniert.void glcdSetPixel(uint8_t x, uint8_t y)
> {
>   glcdSetPageColumn(x/8,y);
>   glcdSendData((x%8));
> }
> muss Ich mal forschen woran das liegt..

Kann es sein, dass man die Pixel die gesetzt sind im Displayram vorher 
noch auslesen muss und dann verODERN?

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
>> Da du mich darauf aufmerksam gemacht hast (habe die Pixel
> funktion sonst
>> nicht weiter im Betrieb) ist mir aufgefallen das die Berechnung nicht
>> sauber funtkioniert.void glcdSetPixel(uint8_t x, uint8_t y)
>> {
>>   glcdSetPageColumn(x/8,y);
>>   glcdSendData((x%8));
>> }
>> muss Ich mal forschen woran das liegt..
>
> Kann es sein, dass man die Pixel die gesetzt sind im Displayram vorher
> noch auslesen muss und dann verODERN?

Also das mit dem auslesen fällt wohl flach. Die Pins sind leider nicht 
dafür vorgesehen.

Dann könnte Ich ja die Methode mit dem VRAM nehmen?

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> Die Pins sind leider nicht dafür vorgesehen.

Wenn jedes Setzen eines Bits die anderen desselben Bytes wieder 
zurücksetzen, ist das natürlich der Grund, warum Du da nur einzelne 
Pixel siehst.

Ich habe keine Ahnung, wie der Speicher Deines Displays organisiert ist. 
Theoretisch könnte man, wenn man es geschickt anstellt, das Display 
byteweise füttern, indem man ein Byte als Buffer nimmt. Aber dann kannst 
Du natürlich nur an Bytegrenzen das Display pixelweise ansteuern.

> Dann könnte Ich ja die Methode mit dem VRAM nehmen?

Wie gesagt: ich kenne die HW nicht, von daher sagt mir VRAM auch nichts. 
Wenn es ein Speicher ist, den man erstmal füllen kann, bevor man ihn ins 
Display kopiert, wäre das natürlich eine Möglichkeit. Dann musst Du 
einfach vor der Stelle, wo der Delay-Aufruf steht, den Copy ins 
physikalische RAM durchführen.

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
>> Dann könnte Ich ja die Methode mit dem VRAM nehmen?
>
> Wie gesagt: ich kenne die HW nicht, von daher sagt mir VRAM auch nichts.
> Wenn es ein Speicher ist, den man erstmal füllen kann, bevor man ihn ins
> Display kopiert, wäre das natürlich eine Möglichkeit. Dann musst Du
> einfach vor der Stelle, wo der Delay-Aufruf steht, den Copy ins
> physikalische RAM durchführen.

VRAM = VideoRam. Genau.
Das man wirklich jedes Pixel einzeln setzt ist bei mir vielleicht auch 
ein bisschen zu viel. Es müsste schon reichen wenn Ich jedes Byte 
einzeln Übertrage. Nehmen wir an das dass 'A' bei mir im Font 5x8(BxH) 
hat.
So kopiere Ich in den VRAM
1
for(uint8_t i = 0 ; i < 5 ; i++)
2
VRAM[i] = font['A][i++];
So hätte ich jetzt das 'A' Byte weise im VRAM dahinter kommen dann noch 
die anderen Buchstaben und evtl. Leerzeichen.

Jetzt ist nur die Frage wie Ich das an deinen Funktionen ankopple.

Du meintest.:
> Dann musst Du
> einfach vor der Stelle, wo der Delay-Aufruf steht, den Copy ins
> physikalische RAM durchführen.

So habe Ich das jetzt verstanden.:
1
void display_set_ticker (const char * ticker)
2
{
3
    ticker_str[0] = ' ';
4
    ticker_str[1] = ' ';
5
    strncpy ((char *) ticker_str + 2, ticker, MAX_TICKER_LEN - 2);
6
    ticker_col = 0;
7
    ticker_ptr = ticker_str;
8
9
    while (*ticker_ptr)
10
    {
11
        display_ticker();
12
    VRAM[i] = *ticker_ptr;
13
    _delay_ms(x);
14
    }
15
}

Damit hätte man das scrollen immer noch nicht realisiert. Also habe Ich 
es wahrscheinlich falsch verstanden.

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Diesen "VRAM" könnte Ich mir auch sparen indem man das so ähnlich 
realisiert wie Du in deinem Quellkode.
Bloß das Ich an meiner Stelle gleich 1 Spalte übertrage (also ein Byte). 
Da bei mir das Display so angeordnet ist.
1
| | | | | | |
'|' Stellen ein Byte dar. Es gibt wohl auch Display die Waagerecht 
schreiben und nicht wie meins Senkrecht.

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> Diesen "VRAM" könnte Ich mir auch sparen indem man das so ähnlich
> realisiert wie Du in deinem Quellkode.

Ja. Das ginge. Man definiert ein Array matrix[][] und setzt dann im 
Display direkt immer ein ganzes Byte.

Blöd ist nur, dass bei Deinem Display die Bytes senkrecht stehen. Aber 
das bekommt man auch hin. Lass mich mal ein wenig nachdenken, dann kann 
ich heute abend eine Lösung posten.

Frage dazu: Ist das LSB oder MSB eines Bytes immer "oben"?

: Bearbeitet durch Moderator
von Dieter F. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Frage dazu: Ist das LSB oder MSB eines Bytes immer "oben"?

Jetzt schreib ihm doch das Programm, so wie er es gerne hätte und gut is 
:-)

von Hans Dieter F. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Peter W. schrieb:
> Diesen "VRAM" könnte Ich mir auch sparen indem man das so ähnlich
> realisiert wie Du in deinem Quellkode.
>
> Ja. Das ginge. Man definiert ein Array matrix[][] und setzt dann im
> Display direkt immer ein ganzes Byte.
>
> Blöd ist nur, dass bei Deinem Display die Bytes senkrecht stehen. Aber
> das bekommt man auch hin. Lass mich mal ein wenig nachdenken, dann kann
> ich heute abend eine Lösung posten.
>
> Frage dazu: Ist das LSB oder MSB eines Bytes immer "oben"?

Habe mir schon eine kleine Routine geschrieben die mir dies umtauscht 
also das MSB, LSB. Das sollte kein Problem sein.
Ich lerne hierbei schon sehr viel danke dafür!

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Auch noch mal ein danke von meiner Seite für die tolle Hilfe!

von Frank M. (ukw) (Moderator) Benutzerseite


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Habe eben mal den Source angepasst, siehe Anhang.

Ich nehme mal an, dass das Display 64 Zeilen und 128 Spalten hat und 
nicht umgekehrt.

Sonst muss man halt die Werte für
1
#define DISPLAY_ROWS                    64                  // Number of lines of display, CHANGE HERE!
2
#define DISPLAY_COLUMNS                128                  // Number of columns of display, CHANGE HERE!

vertauschen.

In der Funktion show_display() werden die Pixel byteweise ins 
Display-RAM kopiert:
1
static void
2
show_display (void)
3
{
4
    int x;
5
6
    for (x = 0; x < DISPLAY_COLUMNS; x++)
7
    {
8
        glcdSetPageColumn (0, x);
9
        glcdSendData (matrix[x]);
10
    }
11
}

Hier werden die untersten 8 Pixelzeilen verwendet, wenn ich es richtig 
verstanden habe.

Wenn der Text auf dem Kopf erscheinen sollte, liegt es daran, dass die 
Bits verkehrt herum gesetzt wurden. Du hattest meine Frage, ob das LSB 
oder MSB "oben" erscheint, leider nicht beantwortet.

In diesem Fall müssen die Funktionen set_pixel() und clear_pixel() 
derart geändert werden, dass man "line" durch (7 - line) ersetzt wird, 
also:
1
static void
2
set_pixel (uint_fast16_t line, uint_fast16_t col)
3
{
4
    matrix[col] |= (1 << (7- line));
5
}
6
7
static void
8
clear_pixel (uint_fast16_t line, uint_fast16_t col)
9
{
10
    matrix[col] &= ~(1 << (7 - line));
11
}

Es kann auch sein, dass ich die Funktionalität von glcdSetPageColumn() 
falsch verstanden habe. Bitte mal den Aufruf in show_display() prüfen.

Du solltest auf jeden Fall noch die Funktion delay_msec() füllen, sonst 
geschieht alles so schnell, dass man kaum etwas sehen wird.

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo Frank!
Wie es aussieht klappt das jetzt wunderbar. Musste die Schrift umdrehen 
weil es sonst auf den Kopf steht.

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Rollt die Schrift bei deinem Projekt denn komplett von rechts rein oder 
fängt sie auch in der Mitte vom Display an?

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Wenn ich meinen eigenen Font dort einbauen möchte, kann ich das wie 
folgt machen?
1
void display_show_ticker_char (uint_fast16_t start_line, uint_fast16_t start_col, unsigned char ch, uint_fast16_t col_offset, font_t f)
2
{
3
    uint_fast16_t    line;
4
    uint_fast16_t    col;
5
    uint_fast16_t    offset;
6
7
  if (f.fontPtr != NULL)
8
  {
9
    f = calcFontStart(ch,f,f.fontPtr);
10
  }
11
  
12
    for (line = 0; line < TICKER_LINES; line++)
13
    {
14
        offset = col_offset + 1;
15
16
        for (col = 0; offset < TICKER_COLS + 1; col++, offset++)
17
        {
18
            if (start_line + line < DISPLAY_ROWS && start_col + col < DISPLAY_COLUMNS)
19
            {
20
                if (f.fontPtr[f.indexNum+line] & (1<<(TICKER_COLS - offset)))
21
                {
22
                    set_pixel (start_line + line, start_col + col);
23
                }
24
                else
25
                {
26
                    clear_pixel (start_line + line, start_col + col);
27
                }
28
            }
29
        }
30
31
        while (start_col + col < DISPLAY_COLUMNS)
32
        {
33
            clear_pixel (start_line + line, start_col + col);
34
            col++;
35
        }
36
    }
37
}

Mit
1
f = calcFontStart(ch,f,f.fontPtr);
Suche ich das aktuelle Zeichen aus meinem Font Array.
und mit f.IndexNum, zeige Ich auf den Startwert vom ersten Zeichen.
Müsste doch eigentlich hinhauen? Ist nur die Frage ob der Aufruf dort an 
der richtigen Stelle ist.

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> Rollt die Schrift bei deinem Projekt denn komplett von rechts rein
> oder fängt sie auch in der Mitte vom Display an?

Sie rollt von rechts rein. Allerdings hat die WordClock wesentlich 
weniger Pixel. Schau mal nach in display_set_ticker(). Da stelle ich 2 
Blanks voran. Da solltest Du entsprechend mehr Leerzeichen einfügen - 
dann besser in einer Schleife.

Peter W. schrieb:
> Wenn ich meinen eigenen Font dort einbauen möchte, kann ich das wie
> folgt machen?

Probiere es aus. Ich kenne Deinen Font nicht. Meine Glaskugel ist heute 
etwas trüb ;-)

Wenn Dir bei dem Font die kleinen Buchstaben (welche kleinere 
Großbuchstaben sind) nicht gefallen, kannst Du auch den anderen 
Alternativfont aus display.c für die WordClock12 statt WordClock24 
ausprobieren. Der hat echte Kleinbuchstaben.

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Peter W. schrieb:
>> Wenn ich meinen eigenen Font dort einbauen möchte, kann ich das wie
>> folgt machen?
>
> Probiere es aus. Ich kenne Deinen Font nicht. Meine Glaskugel ist heute
> etwas trüb ;-)

Es geht nicht direkt um den Font sondern um das lesen vom Font.
Direkt am Anfang deiner Funktion suche Ich das Zeichen aus meinem Font 
raus und zeige auf dessen Startadresse im Array.
Dann kommt deine for Schleife und knallt die ganzen Bytes von der 
aktuellen Startadresse meines Zeichens in den "VRAM(matrix)" sehe Ich 
das richtig?

Das Zeichen bzw. die Startadresse von dem Zeichen wo die "Pixeldaten" 
anfangen muss immer nur immer beim Funktionsaufruf gelesen werden oder 
muss in der for Schleife noch ein neues Zeichen gelesen werden?

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> Das Zeichen bzw. die Startadresse von dem Zeichen wo die "Pixeldaten"
> anfangen muss immer nur immer beim Funktionsaufruf gelesen werden oder
> muss in der for Schleife noch ein neues Zeichen gelesen werden?

Es wird der Funktion doch nur ein Zeichen namens "ch" übergeben, wie 
soll da in der Schleife noch ein weiteres gelesen werden?

Du solltest erst einmal den Source verstehen, bevor Du da selber Hand 
anlegst. Die paar Zeilen sind nicht die Welt.

von Peter W. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Du solltest erst einmal den Source verstehen, bevor Du da selber Hand
> anlegst. Die paar Zeilen sind nicht die Welt.

Genau das ist das Problem. Wie die Schleifen funktionieren, ist mir 
bekannt. Nur sich in die ganzen Werte rein zu denken, fällt mir ziemlich 
schwer wenn Ich nicht gerade den Kode geschrieben habe.

von Daniel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Peter W. schrieb:
> Nur sich in die ganzen Werte rein zu denken, fällt mir ziemlich
> schwer wenn Ich nicht gerade den Kode geschrieben habe.

Ein Teufelskreis.

von Dieter F. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Daniel schrieb:
> Ein Teufelskreis.

Fürwahr :-)

Der lässt sich wohl nur durch ein fertiges Programm incl. (Online-) 
Hilfe und kostenlosem Support-Vertrag durchbrechen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.