C LED Matrix 8 x 8

Janiiiix,
du kannst die Werte natürlich zwischenspeichern, zum Beispiel in einem array MeineWerte uint8_t [], aber warum. Ich hatte die eine Funktion geschrieben (weiss allerdings nicht ob die geht), die schreibt dir gleich die Werte in dein vram, abhängig von der Spaltenposition x. Da muss nichts zwischengespeichert werden.
 
Janiiiix,
du kannst die Werte natürlich zwischenspeichern, zum Beispiel in einem array MeineWerte uint8_t [], aber warum. Ich hatte die eine Funktion geschrieben (weiss allerdings nicht ob die geht), die schreibt dir gleich die Werte in dein vram, abhängig von der Spaltenposition x. Da muss nichts zwischengespeichert werden.

Die Funktioniert wunderbar! Nur Da wird nichts in den "VRAM" geschrieben 0.o?
 
Achso, Sorry!

Du meintest die Funktion zum schieben?
Diese Funktioniert leider nicht... Es wird als erstes das Zeichen in der Mitte angezeigt... Dann wird das nächste reingeschoben (von rechts) und das nächste wird wieder mittig dargestellt...
 
Würde mich sehr freuen...
Was ich noch nicht so wirklich verstehen tuhe, dass mit dem Maskieren der Anzeige.
Da meine Matrix "low active" verschaltet ist, sind immer LED´s an die ich nicht anhaben will (gerade bei deiner schieberoutine) wenn ich die Symbole so anzeigen lasse, klappt es!

Mit welchen Werten muss ich "Maskieren" und vor allem wo ?
 
funktioniert sie?
Irgendwie machst Du Dir das ganze zu schwer...
Du hast bereits 'ne funktionierende Lösung, die die Interruptbasiert den jeweiligen Inhalt des VRAM auf Deine Matrix klatscht. Aus Sicht Deines Hauptprogrammes brauchst Du Dich da nicht mehr drum kümmern, das geht mehr oder weniger im Hintergrund.

Dann hattest Du(?) eine Subroutine, welche ein Zeichen paßgenau in den VRAM übertragen konnte, mit Dirks "GetCharacterIndex()" die den zu zeigenden "Character" in Deiner Tabelle adressiert, und mit einer weiteren Subroutine, die nacheinander die 8 Bytes des zu zeigenden Zeichen nach VRAM kopiert.

Dein Weg ist, das Laufen irgendwie durch Schiebereien im VRAM zu realisieren - ich(!) würde an Deiner Stelle stattdessen einfach die Bytes neu nach VRAM laden.
Also für jedes VRAM-Byte (=Matrix-column) das anzuzeigende Byte des anzuzeigenden Chars aus Deiner Tabelle ausrechnen und von Dort nach VRAM laden.
Das Laufen wird dann also durch wiederholtes (pixelversetztes) neubeschreiben des VRAM realisiert. Meine Empfehlung war weiter, eine Ganzzahl zu nutzen, die quasi angibt, welche Pixelposition im String die ist, die in der ersten Spalte des VRAM (Matrix) erscheinen soll.

Die Hierarchie der Subroutinen ist dann so:
Vom Hauptprogramm aus wird dann in der Schrittfrequenz des Lauftextes (Timergesteuert, über delay, ...) die Pixelposition rauf-/runtergezählt, und danach eine Subroutine aufgerufen, die die VRAM-Bytes mit Daten füllen soll.
Diese Subroutine "holt" sich für jedes (der 8) VRAM-Bytes das darzustellende Byte aus Deiner Tabelle, und schreibt es in die VRAM-Zelle. Also eine FOR..TO-Schleife über alle VRAM-Bytes.
"Holt" heißt, daß eine weitere Subroutine aufgerufen wird (für jeden Durchlauf der FOR-Schleife), welche aus der Pixelposition und dem String das anzuzeigende Byte im jeweiligen Character, und die Startposition des Characters selbst in Deiner Tabelle bestimmt (unter Zuhilfenahme von "GetCharacterIndex()"), dieses Byte lädt, und zurückliefert.

Da so aus der VRAM-Spalte, der Pixelposition und dem String heraus berechnet wird welches Byte aus der Tabelle zu laden ist, könnte in jeder Spalte ein Byte eines anderen Characters landen - insbesondere kann in einer Spalte des letzte Byte des einen, und in der nächsten das erste eines anderen Characters landen.
 
Lotadac...

Man(n) hat immer leicht reden, wenn man weiß wie alles funktioniert... Als Anfänger, ist es nun mal nicht so einfach da durch zu steigen (geht mir zumindest so) !!!
 
Ich habe die letzten Beiträge leider nicht mehr mitverfolgt. Wie versprochen, habe ich mir den einen Lösungsansatz noch einmal angeschaut und überarbeitet, deshalb hier schnell das Ergebnis:


Zum Code in Beitrag 95, habe ich noch einen Fehler gefunden. Ich kanns leider nicht testen, aber das kannst du ja einfach mal probieren ...

(Die Funktion DisplayString ist geändert)

Code:
// Aufruf zum Beispiel:

    char s[30] = "Das ist ein Teststring";
    
    for (uint16_t x=0; x<(strlen(s)*8); x++)
    {
        DisplayString(x, s);
        _delay_ms(50);
    }


// Der Lösungsansatz:

#include <string.h>

void DisplayString(uint16_t x, const char *s)
{
    uint16_t len;
    uint8_t i, d, u1, u2;
    
    len = strlen(s)*8;
    
    if (x < len)
    {
        
        i = x >> 3; // Index vom ersten Zeichen
        u1 = GetCharacterIndex(s[i++]); // erstes Zeichen
        u2 = GetCharacterIndex(s[i]);  // zweites Zeichen
        for (d=0 ; d<8 ; d++)
        {
            vram[d] = pgm_read_byte(&charset[u1][d]) << (x & 7); // erstes Zeichen verschoben nach links
            vram[d] =| (pgm_read_byte(&charset[u2][d]) >> (8-(x & 7)));  // zweites Zeichen verschoben nach rechts
        }            
        
    } else {
        // x zu groß, alles aus
        for (d=0 ; d<8 ; d++)
           vram[d] = 0xFF;
        
    }
    
}

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

    if ((a >= '0') && (a <= '9'))
      index = a+2-48;  
    else if ((a >= 'A') && (a <= 'Z'))
      index = a+12-65;
    else if ((a >= 'a') && (a <= 'z'))
      index = a+38-97;
    else if ((a == '.'))
      index = a+70-46;
        
    return index;

}
 
Also das vordere Zeichen nach links schieben klappt nicht.

Probiere noch einmal folgenden Code:
(ersetze den Bereich)

Code:
for (d=0 ; d<8 ; d++)
{
  vram[d] = 0xFF;
  vram[d] &= ~(pgm_read_byte(&charset[u1][d]) << (x & 7)); // erstes Zeichen verschoben nach links
  vram[d] &= ~(pgm_read_byte(&charset[u2][d]) >> (8-(x & 7)));  // zweites Zeichen verschoben nach rechts
}

Es hat vielleicht etwas mit dem Invertieren zu tun. Hier schalte ich zunächst alle LEDs aus, dann verschiebe ich Character 1 nach links und lösche dort die Bits in vram, die in Character 1 gesetzt sind. Das selbe mache ich mit Character 2, nur hier schiebe ich zuvor nach rechts.
Im Sonderfall, dass nur ein Character auch das Display passt, wird Character 1 garnicht verschoben und Character 2 um 8 Bits (erscheint also nicht auf dem Display, diese zweite Codezeile könnte man auch zuvor durch if-Abfrage nicht ausführen).

Probiere das oben nochmal aus.
 
Okay...
Also wenn ich in der MultiplexRoutine VRAM durch ~(VRAM) ersetze, klappt es !
Bekomme ich es auch noch hin das dass erste Zeichen direkt rechts anfängt?

Einige Zeichen haben auch mehr Platz zwischen den nächsten Zeichen... Das muss aber in den Grafiken angepasst werden?
 
Bekomme ich es auch noch hin das dass erste Zeichen direkt rechts anfängt?
Das geht sicherlich auch (mir fehlt die Zeit im Moment). Behelfen kannst du dich schnell mit einem Leerzeichen am Stringanfang.
Einige Zeichen haben auch mehr Platz zwischen den nächsten Zeichen... Das muss aber in den Grafiken angepasst werden?

Ups, also haben die verwendeten Zeichen unterschiedliche Breite. Das wird dann schon wieder etwas komplizierter :) Am einfachsten wäre es, einen passenden Font zu verwenden.
 
Okay Dirk, Danke für die Mühe!

Das hat mich sehr viel weiter gebracht. Nun weiß ich wie es funktioniert. Um das andere werde ich mich selbst kümmern ;)
 
Hallo Leute,

@Dirk hatte mir mal ein Beispiel geschrieben, wie man eine Laufschrift auf meiner 8x8 Matrix ausgibt. Das funktioniert bis heute soweit richtig gut.
Nur geht es mir langsam auf den "Keks" das ich es bis heute immer noch nicht geschafft habe, die Leerzeichen zwischen den Zeichen zu eliminieren.
Da die Schriftart bzw. der Font zum Teil keine feste Breite aufweist, ist es wohl nicht so einfach.. Hat jemand eine Idee, wie ich die Leerzeichen flexibel ändern könnte?
Ich hatte daran gedacht, die Breite noch mit in die "font.h" zu intigrieren.


Das ist der Kode, der dafür sorgt das die Zeichen über den Bildschirm flitzen..


CodeBox C
/* Schreibt den aktuellen String auf die Matrix */
void DisplayString(uint16_t x, const char *s)
{
   uint16_t len;
   uint8_t i, d, u1, u2;
   
   len = strlen(s)*8;
   
   if (x < len)
   {
       i = x >> 3; // Index vom ersten Zeichen
       u1 = GetCharacterIndex(s[i++]); // erstes Zeichen
       u2 = GetCharacterIndex(s[i]);  // zweites Zeichen
       for (d=0 ; d<16 ; d++)
       {
           VRAM[d] = 0xFFFF;
           VRAM[d] &= ~(pgm_read_byte(&charMap[u1][d]) << ( x & 7 ) ); // erstes Zeichen verschoben nach links
           VRAM[d] &= ~(pgm_read_byte(&charMap[u2][d]) >> ( 8 - ( x & 7 ) ) );  // zweites Zeichen verschoben nach rechts
       }
   }
}
 
Huhu, ich bin's.
Dein font liegt als 8 Zeilen pro Buchstabe vor? bit7 ist links, bit0 rechts in der Zeile und die Zeichen sind linksbündig? Dann könnte man zur Zeichenbreitemessung alle Zeilen nacheinander abfragen, ob alle 8 bit0=0 ist. Sollte immer sein, weil das ja der Mindestabstand zwischen den Zeichen sein sollte. Nächste Abfrage, ob alle 8 bit1=0. Wenn ja, dann ist das Zeichen bloß 6bit breit. Das macht man so weiter, bis halt ein bit der 8 Zeilen(bytes) mal den Wert 1 hat. Dann kann man annehmen, dass dieses bit zum Zeichen gehört. (Ein Sonderfall ist space, den müsste man extra behandeln.) So bekommt man die Zeichenbreite. Wenn so ein Zeichen kommt, dann scrollt man nur Zeichenbreite+1 Spalten, bevor man den nächsten Buchstaben nimmt.
 
Hier hast du mal eine font-Sammlung, die ich mal aus dem mc.net-Forum geladen habe
https://www.dropbox.com/sh/19ef2i7fviw8ltp/AAD2yx1iXUZF2OBzdsIImKH1a?dl=0
Da sind auch .bmps dabei, als Schnellansicht. Man sieht schon, das die breiten Buchstaben linksbündig sind und die schmalen ein bisschen nach rechts gerückt sind. Muss wohl aus optischen Gründen so sein. Ich persönlich finde aber die Abstände nicht so groß, dass man da was reduzieren müsste.
 
Danke. Habe noch nicht nach geschaut. Sind da auch die Breiten von den einzelnen Zeichen hinterlegt?
 

Ü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)