C LED Matrix 8 x 8

Pefekt! Das klappt richtig gut ;)

Jetzt dürfte doch für die Laufschrift der Grundstein gelegt sein?
Jetzt muss halt das aktuelle Zeichen nur noch 8 x geschoben werden & das neue direkt dahinter kommen.

Dies sollte man ja auch so ähnlich in einer "for" Schleife machen können oder ?
 
Pefekt! Das klappt richtig gut ;)

Jetzt dürfte doch für die Laufschrift der Grundstein gelegt sein?
Jetzt muss halt das aktuelle Zeichen nur noch 8 x geschoben werden & das neue direkt dahinter kommen.

Dies sollte man ja auch so ähnlich in einer "for" Schleife machen können oder ?

Dies ist etwas komplizierter, wenn die Zeichen direkt hintereinander kommen sollen, weil dann Daten von zwei (oder bei größeren Displays auch mehr) Zeichen in das vram müssen. Probiere es einfach mal ;-) Allgemein empfehle ich hierzu das AVR GCC Tutorial.

Dirk :ciao:
 
Jetzt habe ich die Daten mal in den Flash ablegen lassen, nur werden die Zeichen dann falsch dargestellt....
Ich rufe wahrscheinlich die Daten nicht richtig ab... ?

Code:
    {

        for (uint8_t d= 0 ; d<8 ; d++)
        { 
            VRAM[d] = pgm_read_byte (&charset)[i][d];
        }
            _delay_ms(500);

    }

    
    }
 
Ich hatte einen Schreibfehler. Sorry ! Klappt alles ;)
 
Wie müsste das denn jetzt ablaufen mit der "Laufschrift" ?

Ich brauche wie du schon erwähnt hast Dirk, 2 Stk. von meinen VRAM...

Ich vermute mal das in dem "VRAM1" mein aktuelles Zeichen drinn ist...
Nun schiebe ich dieses Zeichen was aktuell in meinem "VRAM1" steht in einer while oder for Schleife 8 x nach Links... Nun ist nichts mehr im Display....
Ab dem 9 x schieben, müsste ja jetzt mein neues Zeichen von rechts rein kommen....
Zwischendurch belade ich schon mal das "VRAM2"... Nun kann ich nach den 8 x schieben umschalten auf "VRAM2"... usw...

sollte das so ungefähr ablaufen?
 
HALT!

Überleg Dir doch erstmal, wohin das ganze am Ende(!) gehen soll. Lösungen gibts für jedes Deiner Teilprobleme viele, wenn eine sich Anfangs gut implementieren läßt, kann es unter Berücksichtigung später hinzugekommener Aufgaben trotzdem besser sein, eine andere zu verwenden. Ich hatte ziemlich am Anfang ein Konzept vorgeschlagen, bei dem sich das Multiplexing das darzustellende Byte selbst aus der Charset-Tabelle holt. Ohne VRAM zu brauchen.

Derzeit legst Du eine 1zu1-Kopie eines Zeichens in's SRAM (VRAM), und Dein Multiplexing holt sich die Zeileninfos der gerade darzustellenden Spalte aus dem VRAM. Das ist aber dasselbe, wie auch noch im Charset steht. Also kann das Multiplexing sich das auch aus dem Charset holen.

Der Vorschlag ging sogar soweit, daß Du einen beliebigen String durch die Matrix schieben könntest (durch geschickte Anordnung der Zeichen im Charset).

Also nicht, daß wir Dir jetzt dabei helfen zu das programmieren (daß ein Zeichen angezeigt wird, dieses rausgeschoben wird, das 2te mit einem Schlag dargestellt wird. Und herausgeschoben wird.
Und Insbesondere die Reihenfolge der Zeichen die ist, die im charset steht), und Du danach plötzlich doch beliebige String darstellen willst, und die plötzlich wirklich durchgeschoben werden sollen...

Edit: Und Dirk hat angedeutet, daß seine Bibliothek verwendet werden könnte, die bereits mächtige Werkzeuge zum schreiben und Zeichnen auf einem VRAM (wie immer es dann auch da heißt) besitzt, insbesondere auch ein fertiges Charset.
Statt Dein eigenes VRAM und Dein eigenes Charset zu verwenden, verwendest Du das der Bibliothek. Die ist selbst nicht auf Multiplexing ausgelegt, deswegen die letzten Beiträge.

Welchen der Wege Du nun gehst, mußt Du festlegen - wir können Dir die nur vorschlagen...
 
HALT!

Überleg Dir doch erstmal, wohin das ganze am Ende(!) gehen soll. Lösungen gibts für jedes Deiner Teilprobleme viele, wenn eine sich Anfangs gut implementieren läßt, kann es unter Berücksichtigung später hinzugekommener Aufgaben trotzdem besser sein, eine andere zu verwenden. Ich hatte ziemlich am Anfang ein Konzept vorgeschlagen, bei dem sich das Multiplexing das darzustellende Byte selbst aus der Charset-Tabelle holt. Ohne VRAM zu brauchen.

Derzeit legst Du eine 1zu1-Kopie eines Zeichens in's SRAM (VRAM), und Dein Multiplexing holt sich die Zeileninfos der gerade darzustellenden Spalte aus dem VRAM. Das ist aber dasselbe, wie auch noch im Charset steht. Also kann das Multiplexing sich das auch aus dem Charset holen.

Der Vorschlag ging sogar soweit, daß Du einen beliebigen String durch die Matrix schieben könntest (durch geschickte Anordnung der Zeichen im Charset).

Also nicht, daß wir Dir jetzt dabei helfen zu das programmieren (daß ein Zeichen angezeigt wird, dieses rausgeschoben wird, das 2te mit einem Schlag dargestellt wird. Und herausgeschoben wird.
Und Insbesondere die Reihenfolge der Zeichen die ist, die im charset steht), und Du danach plötzlich doch beliebige String darstellen willst, und die plötzlich wirklich durchgeschoben werden sollen...

Edit: Und Dirk hat angedeutet, daß seine Bibliothek verwendet werden könnte, die bereits mächtige Werkzeuge zum schreiben und Zeichnen auf einem VRAM (wie immer es dann auch da heißt) besitzt, insbesondere auch ein fertiges Charset.
Statt Dein eigenes VRAM und Dein eigenes Charset zu verwenden, verwendest Du das der Bibliothek. Die ist selbst nicht auf Multiplexing ausgelegt, deswegen die letzten Beiträge.

Welchen der Wege Du nun gehst, mußt Du festlegen - wir können Dir die nur vorschlagen...

Die Idee mit dem ASCII Codesatz ist ja auch eine sehr gute. Nur benötige ich nicht die ganzen Zeichen!
Das mit dem VRAM & Co... Ist so weil ich es einfach mal lernen möchte und verstehen möchte wie das alles funktioniert.
Dank euch, komme ich immer ein Schritt weiter in die Sache rein (danke nochmal an euch beiden)...

Die Bibliothek von Dirk möchte ich halt nicht gerne nehmen, da ich es versuchen möchte alleine (natürlich auch mit eurer hilfe) zu bewerkstelligen (ich hoffe ihr versteht das, dass ich noch sehr viele Fragen dazu habe & seit mir nicht sauer, dass ich hier jeden Mist nachfrage :( )....
 
Das mit dem "Zwischenspeicher" vram finde ich gut, da hier in der TimerISR dann wirklich nur das nötigste ausgeführt wird. Die ISR muss nicht ständig die Adressen von Grafikbytes errechnen, muss auch nicht auf das Flash Memory zugreifen, in dem sich eine CharacterTabelle befindet ... mach also fast garnichts. Gut, weil ja sowieso die meiste Zeit nichts neues ausgegeben werden muss (Framerate ist ja mindestens 20ms, darin 8 ISR Aufrufe, schneller als 100ms läßt man wahrscheinlich kein Zeichen shiften). ... Ist aber alles Geschmacksache :)

Es soll sicherlich ein String als Laufschrift verwendet werden. Wenn ja und nicht mehr, wäre es wahrscheinlich gut, eine Routine zu schreiben, mit den Parametern angezeigte Bitposition in X Richtung und Pointer zum String. Diese könnte dann die Daten für vram errechnen. Berücksichtigen muss man hier noch, dass der Index der CharacterTabelle nicht dem Ascii Zeichensatz folgt, also ein bisschen muss man den Index für das Zeichen im Flash Memory anpassen (nur als Hinweis, wenn aufeinmal nicht das erscheint, was man erwartet ;-)

Eine Laufschrift könnte dann so aussehen:

Code:
for (uint16_t x=0; x<500; x++)
{
   DisplayString(x, "Das ist ein String!");
   _delay_ms(200);
}

// 500 könnte die Stringlänge in Bits sein, also strlen()*8, hier also nur das Prinzip dargestellt.

Ich weiß allerdings nicht, ob man das auf einer 8x8 LED Matrix gut erkennen kann :)

Dirk :ciao:
 
.2Das mit den ASCII ist auch nur eine Einfache Möglichkeit, um beliebige Strings darstellen (und eben ggf auch durchscrollen lassen) zu können. Insbesondere wird der Zugriff im Charset auf den konkreten ASCII vereinfacht, weil C die Nummern bereits kennt, selbst damit arbeitet.
Du sagst, Du verwendest nicht alle Zeichen, ok...
Aber die meisten.
Von den 0..127 Zeichen (128) nutzt Du nur 65 (63 und zwei selbstdefinierte). Ich hatte ja bereits vorgeschlagen, die ersten 32 (Steuerzeichen) wegzulassen, ebenso könnten die letzten 5 raus. Die 15 Zeichen zwischen 0x20 (Space) und 0x30 (0) willst Du auch nicht. Also schneidet man das (erstmal mit dem Space) auch weg, bleibt der Bereich 0x30 (48dez)..0x7A (122dez). Darin hättest Du dann 13 "unerwünschte" Zeichen. Dir fehlen allerdings 3 Zeichen: das Space (alle aus), alle an und der Smiley. Die tippst Du jetzt einfach anstelle 3 der unnützen Zeichen ein ( remapping - möglichst welche, die man auf der Tastatur gut tippen kann) - dann hast Du nur noch 10 Ballast-Zeichen mit.

Unabhängig davon kannst Du natürlich auch bei Deiner eigenen Tabelle bleiben, dem JSCII sozusagen;).
Den kennt C halt nicht, insbesondere nicht als String-Format, aber mein Algorithmus kann damit genauso umgehen - bis auf den String eben. Statt eines Stringes, also eines Feldes mit Bytes die ASCII sind, brauchst Du halt ein Feld mit Bytes, die Deine JSCII sind.

Alternativ kannst Du natürlich auch bei dem VRAM bleiben, und echtes Scrollen implementieren.
Stell Dir Dein charset nicht als 65x8-Feld vor, sondern als ein Feld mit 520 Einträgen.
Für das erste Zeichen müssen die Einträge 0..7 in's VRAM. Für das 2te die Einträge 8..15. Und beim Scrollen willst Du halt zwischendurch mal die Einträge 4..11 sehen (also vorn die letzten 4 Spalten von Zeichen 1 (einträge 4..7) und hinten die ersten 4 von Zeichen2 (Einträge 8..11)
Ähnlich Dirks Post kannst Du dann auch so'ne Doppelschleife umsetzen, die Bei jedem Durchlauf der inneren Schleife 8 Spalten in VRAM kopiert, den Index in der äußeren Schleife um eins weiterschiebt. Dafür brauchst Du das charset als eindimensionales Feld, bzw mußt darauf eindimensional zugreifen können. In Wirklichkeit liegt das 2dimensionale natürlich eindimensional im Speicher, der ist ja eindimensional indiziert - wie du In C jetzt einfach darauf zugreifst, weiß ich nicht. Könntest das natürlich einfach eindimensional definieren.

Dann wäre die Doppelschleife ähnlich Dirks - denk mal drüber nach...
 
Hallo Dirk,

Was ich noch nicht ganz so durchschaut habe ist das "*"
Wozu ist das genau gut ? Wie funktioniert das ?
 
Berücksichtigen muss man hier noch, dass der Index der CharacterTabelle nicht dem Ascii Zeichensatz folgt, also ein bisschen muss man den Index für das Zeichen im Flash Memory anpassen (nur als Hinweis, wenn aufeinmal nicht das erscheint, was man erwartet ;-)


Dirk :ciao:


Was meinst du mit " Index für das Zeichen im Flash Memory anpassen "?
 
Hallo Janiiix,

durch "*" wird die Anfangsadresse des Strings übergeben, also der Zeiger (engl. Pointer). Such vielleicht einfach mal nach

"uart string" oder "string pointer avr gcc" ö.ä.

Vielleicht kann hier ja auch mal ein anderer User helfen, der sich in C auskennt, leider fehlt mir die Zeit :-/
 
Das mit dem "Zwischenspeicher" vram finde ich gut, da hier in der TimerISR dann wirklich nur das nötigste ausgeführt wird. Die ISR muss nicht ständig die Adressen von Grafikbytes errechnen, muss auch nicht auf das Flash Memory zugreifen, in dem sich eine CharacterTabelle befindet ... mach also fast garnichts. Gut, weil ja sowieso die meiste Zeit nichts neues ausgegeben werden muss (Framerate ist ja mindestens 20ms, darin 8 ISR Aufrufe, schneller als 100ms läßt man wahrscheinlich kein Zeichen shiften). ... Ist aber alles Geschmacksache :)

Es soll sicherlich ein String als Laufschrift verwendet werden. Wenn ja und nicht mehr, wäre es wahrscheinlich gut, eine Routine zu schreiben, mit den Parametern angezeigte Bitposition in X Richtung und Pointer zum String. Diese könnte dann die Daten für vram errechnen. Berücksichtigen muss man hier noch, dass der Index der CharacterTabelle nicht dem Ascii Zeichensatz folgt, also ein bisschen muss man den Index für das Zeichen im Flash Memory anpassen (nur als Hinweis, wenn aufeinmal nicht das erscheint, was man erwartet ;-)

Eine Laufschrift könnte dann so aussehen:

Code:
for (uint16_t x=0; x<500; x++)
{
   DisplayString(x, "Das ist ein String!");
   _delay_ms(200);
}

// 500 könnte die Stringlänge in Bits sein, also strlen()*8, hier also nur das Prinzip dargestellt.

Ich weiß allerdings nicht, ob man das auf einer 8x8 LED Matrix gut erkennen kann :)

Dirk :ciao:

Hallo Janiiix,

durch "*" wird die Anfangsadresse des Strings übergeben, also der Zeiger (engl. Pointer). Such vielleicht einfach mal nach

"uart string" oder "string pointer avr gcc" ö.ä.

Vielleicht kann hier ja auch mal ein anderer User helfen, der sich in C auskennt, leider fehlt mir die Zeit :-/

Ah okay,

Was brauche ich um z.B aus dem Array irgendein Zeichen raus zu greifen?
Wie mache ich das denn, wenn ich z.B ein "Hallo" schreiben möchte, wie hole ich mir die Zeichen aus dem Array ?
 
Was meinst du mit " Index für das Zeichen im Flash Memory anpassen "?

LotadaC hatte es ebenfalls erwähnt. Es ist so, dass der Index eines Zeichens im Array nicht mit dem Index im Ascii Code übereinstimmt, da du nicht alle Zeichen übernommen hast, bzw auch eigene Zeichen verwendest.
 
Moment, das waren gleich 2 Sachen:
1. hatte ich vorgeschlagen, im charset die ersten n (und die letzten m) Zeichen wegzulassen, die Reihen des Restes dazwischen abe beizubehalten. Dann kann man aus dem gegebenen String noch einfach die Adresse im gekürzten charset berechnen, da man ja lediglich die Anzahl der weggelassenen Zeichen abziehen muß (da die nicht existieren).
2. hatte ich vorgeschlagen, einige Zeichen zu remappen, also irgendein ASCII innerhalb des verwendeten Bereiches, welches selbst nicht benötigt wird (unerwünscht ist) mit der Grafik eines genutzten Zeichens zu versehen (im charset). Also nehmen wir mal an, Du hättest gerne das "+" (0x2B), da Du Rechenaufgaben ausgeben willst - aber Dein charset soll nur die ASCII von 0x30 bis 0x7A verwenden. Dann nimmst Du eben irgendein anderes ungenutztes Zeichen aus diesem Bereich, zB "@" (0x40) und verpaßt dem im charset die Plus-Grafik. die Rechenaufgae "7+4" muß dann halt als "7@4"-String eingegeben werden - auf dem Display erscheint das "@" dann mit seiner Plus-Grafik.

Ein String ist ein Byte-Array, jedes Zeichen des Stringes wird in Form eines Bytes im Controller abgelegt (eben in Form der ASCII-Codes).
Wenn Du Deinen eigenen Standard Code for Information Interchange nutzen willst, mußt Du den entweder in der IDE auf ASCII umrechnen, oder auf den Komfort des Stringes verzichten. Der String existiert nur in der IDE, im Controller sind das letztendlich nur die ASCII-Bytes. Du kannst also statt des Stringes ebenso ein Byte-Array verwenden, in dem die Zeichen Durch Deinen Code verschlüsselt sind.

Der String "Hallo" wird als ASCII zum Array "0x48 0x61 0x6C 0x6C 0x6F" - die IDE interpretiert den String als diese Bytefolge. (und hängt noch ein 0x00 als EndOfString-Symbol mitran)
Für Deine Codierung bräuchtest Du das Feld "0x13 0x26 0x31 0x31 0x34" - für das Ende ggf auch ein Ende-Symbol welches aber nicht darstellbar ist (sein muß).
Die anfangs weggelassenen Zeichen kann man als Offset rausrechnen aber Die Lücken... dadurch wirds unnötig kompliziert... gehen tut das aber auch. Dieser Weg würde durch die Rechnung also mehr Laufzeit kosten, der Weg mit der angepaßten ASCII-Tabelle Flash, und der verzicht auf Strings (also Deine eigene Tabelle) Komfort.

Es ist (wieder einmal) Deine Wahl...
 
Okay...

Habe ich das richtig verstanden...
Wenn ich jetzt mein "charset Array" nach dem ASCII Standart angelegt hätte, könnte ich in einem String direkt mit ASCII schreiben... Sprich.... DisplayString("Hallo")...
Da ich jetzt aber gerne mit meiner eigenen Tabelle arbeiten möchte (versuchen möchte ob das so klappt wie ich es mir vorstelle) muss ich halt jetzt dementsprechend....
DisplayString(" 0x00....0x84 ") angeben ? ist das soweit richtig ?

Wie muss ich jetzt weiter vorgehen...? Abgesehen von der Laufschrift... Könnte ich doch jetzt meinen String auf der Matrix ausgeben lassen... So das halt nur die einzelnen Zeichen des Stringes kurz dargestellt werden... ?
 
Also das ist doch alles überhaupt kein Problem.
Dann passt man den Index einfach an. Das geht ganz schnell, man muss nicht im String irgendwelche komischen Zeichen eingeben, um den richtigen Index zu erwischen und Maschinenzyklen oder Code ist das auch nicht die Welt, irgendwas muss der Controller ja auch machen ;-)

Hier mal eine Funktion, die eventuell weiterhilft.
Index ist korrigiert für 0..9, A..Z, a..z, alles andere gibt Index=1 alles aus.
Es fehlt noch der smilie und alles an.
(nicht getestet)
Code:
// http://www.torsten-horn.de/techdocs/ascii.htm

uint8_t GetCharsetIndex(char a)
{
    uint8_t index = 1;    // alles aus

    if ((a >= '0') && (a <= '9'))
        index = a+2-48;  // erste Zahl ist Index in der Tabelle des ersten Zeichens, zweite Zahl ist Index in Ascii Code des ersten Zeichens
    else if ((a >= 'A') && (a <= 'Z'))
        index = a+12-65;
    else if ((a >= 'a') && (a <= 'z'))
        index = a+38-97;

    // usw...

    return index;
}


Zunächst erstellt man sich eine Funktion, die sich nacheinander ein Zeichen vom String holt, bis zum Stringende. Hier hat man also eine Schleife, in dieser ...
1. ... holt man sich dann den richtigen Index = GetCharsetIndex(a)
2. Dann adressiert man das CharsetArray mit dem Index (besser wäre, das Array liegt nur im Flash Memory) und kopiert die Daten ins vram
 
fehler.jpg

Habt ihr schon mal so einen "Fehler" gehabt? Was mache ich denn nun falsch?
Ich möchte einfach sehen, welchen Wert "Index" bekommt.
 

Anhänge

  • fehler.jpg
    fehler.jpg
    83,4 KB · Aufrufe: 5
Also das ist doch alles überhaupt kein Problem.
Dann passt man den Index einfach an. Das geht ganz schnell, man muss nicht im String irgendwelche komischen Zeichen eingeben, um den richtigen Index zu erwischen und Maschinenzyklen oder Code ist das auch nicht die Welt, irgendwas muss der Controller ja auch machen ;-)

Hier mal eine Funktion, die eventuell weiterhilft.
Index ist korrigiert für 0..9, A..Z, a..z, alles andere gibt Index=1 alles aus.
Es fehlt noch der smilie und alles an.
(nicht getestet)
Code:
// http://www.torsten-horn.de/techdocs/ascii.htm

uint8_t GetCharsetIndex(char a)
{
    uint8_t index = 1;    // alles aus

    if ((a >= '0') && (a <= '9'))
        index = a+2-48;  // erste Zahl ist Index in der Tabelle des ersten Zeichens, zweite Zahl ist Index in Ascii Code des ersten Zeichens
    else if ((a >= 'A') && (a <= 'Z'))
        index = a+12-65;
    else if ((a >= 'a') && (a <= 'z'))
        index = a+38-97;

    // usw...

    return index;
}


Zunächst erstellt man sich eine Funktion, die sich nacheinander ein Zeichen vom String holt, bis zum Stringende. Hier hat man also eine Schleife, in dieser ...
1. ... holt man sich dann den richtigen Index = GetCharsetIndex(a)
2. Dann adressiert man das CharsetArray mit dem Index (besser wäre, das Array liegt nur im Flash Memory) und kopiert die Daten ins vram

& Wenn ich den Code richtig verstehe... Müsste doch gleich bei der ersten "Maskierung" - 52 (abgesehen von den ganzen anderen Zeichen im Array) anstatt -48 sein oder sehe ich das falsch ?
 
Ich nehme alles zurück! Habe es verstanden ;)
Geniale Sache diese Funktion ;)
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)