Forum: Mikrocontroller und Digitale Elektronik Dot Matrix Spalten/Zeilen tauschen


von Stefan S. (sschultewolter)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe mir eine Libary für die Ansteuerung der Max7219 in Verbindung 
mit einem Atmega328p geschrieben.

Nun habe ich keine Möglichkeit, die Dot Matrizen in der typischen 
Orientierung später aufzubauen. Soll heißen, jede Matrize wird um 90° 
gedreht.

Im Anhang einmal die Platine, um zu sehen was ich meine. Die Matrizen 
sollen später in der waagerechten kaskadiert werden.
1
void max7219_puts(char *s, uint8_t bold, uint8_t invert, uint8_t scroll)
2
{
3
  uint8_t size_text = strlen(s);
4
5
  uint8_t width = 0;
6
7
  if(bold) width = 8;
8
  else width = 5;
9
10
  uint16_t i = 0;
11
  static uint16_t j = 0;
12
  while(i < (MAX7219_NUM_IC * 8))
13
  {
14
    uint8_t x = s[((i + j) / width) % size_text];
15
    uint8_t y = ((i + j) % width);
16
    uint8_t data = 0;
17
    if(bold) data = pgm_read_byte(&font_bold[x][y]);
18
    else data = pgm_read_byte(&font[x][y]);
19
    if(invert)max7219_send(i >> 3, ((i % 8) + 1), 255 - data);
20
    else max7219_send(i >> 3, ((i % 8) + 1), data);
21
    i++;
22
  }
23
  if(scroll)  if(++j > (size_text * width)-1) j = 0;
24
}

Wenn die Schrift angepasst werden muss, wäre das kein Problem. Habe 
diese in allen Variationen.

von Easylife (Gast)


Lesenswert?

Du glaubst nicht allen ernstes, dass jemand versuchen wird das Programm 
zu analysieren, und Datenblätter zu wälzen, um rauszufinden, wie die 
Schaltung zu dem PCB wohl aussehen könnte, um dann zu erraten, was dein 
Problem sein könnte?

von Stefan S. (sschultewolter)


Lesenswert?

Es gibt sicherlich Leute, die sich mit dem typischen Matrix(7-Segment) 
Baustein schon auseinander gesetzt haben.

Das Problem ist, das man hier nicht einfach die Spalten mit den Zeilen 
tauschen kann.

Die Spalten sind festgelegt vom Baustein und werden einzeln 
angesprochen. Jedoch muss mit jeder ausgewählten Spalte die komplette 
Zeile(8bit) mitgeschickt werden.

Ich habe irgendwo, meine sogar hier, einen Ansatz gefunden, eine 
Umrechnung zu machen damit Spalten wie Zeilen und Zeilen wie Spalten 
genutzt werden können.

Die PCB habe ich nur zur Veranschaulichung mitgeliefert, dass die Matrix 
nicht in der orginalen Orientierung sich befindet.

von Hartmut (Gast)


Angehängte Dateien:

Lesenswert?

Stefan S. schrieb:
> Dot Matrizen

Stefan S. schrieb:
> Matrix(7-Segment)

Was denn nun? Brust oder Keule?

von Stefan S. (sschultewolter)


Lesenswert?

Edit, da Hartmut sich gemeldet hat.
Ich meine schon Dot Matrizen(8x8). Das mit 7-Segment war nur darauf 
bezogen, da sich das Datenblatt hauptsächlich nur um diese 
Segment-Anzeigen kümmert.



Also das Layoutformat muss beigehalten werden mit den Pinanordnungen. 
Die Leiterbahnen könnten neugeroutet werden.

Sehe ich das richtig, das wenn ich anstatt der Common Cathode nun Common 
Annode nehme, dass es die gewünschte Ausrichtung hat?

Derzeit sind die Spalten (COL) an die SEG_ benannten Pins des MAX 
angeschlossen. Bei der draufsicht ergibt das aber, dass sich diese als 
Reihen darstellen. Die DIG_ Pins sind die Reihen (ROW) des Displays, die 
als Spalten dargestellt werden.
Somit alles um 90° verdreht.

Nun meine Idee mit den Common Anode. Hierbei werden die SEG_ benannten 
Pins des MAX mit den Reihen verbunden. Die DIG_ benannten Pins des MAX 
mit den Spalten.
Somit wären die Spalten und Reihen rein technisch verdreht. Jedoch mit 
der Drehung von 90° würden diese wieder passen.

Dem Programm würde es in dem Moment nicht einmal interessieren, dass 
diese vertauscht wurden. Denn ich schalte mit MAX immer noch die 
Cathoden.

Links CA, Rechts CC
http://img.weiku.com/a/000/439/8x8_led_dot_matrix_with_brightness_4529_2.jpg

: Bearbeitet durch User
von Oliver R. (orb)


Lesenswert?

Stefan S. schrieb:
> Links CA, Rechts CC
> http://img.weiku.com/a/000/439/8x8_led_dot_matrix_with_brightness_4529_2.jpg

Nö, die Bezeichnung CC und CA ist hier (bei einfarbigen) unsinnig, bei 
den Matrixanzeigen hast Du immer gleichviele gemeinsame Anoden wie 
Kathoden.
Das hatten wir doch grad erst in einem anderen Thread.
Im Datenblatt vom MAX steht, welche Anschlüsse mehr Strom liefern und 
welche mehr abführen können, das solltest Du beachten.

von Stefan S. (sschultewolter)


Lesenswert?

Hallo Oliver,

das ist mir bewusst, dass es hier der eigentliche Begriff CA/CC falsch 
ist.
Darum geht es mir auch nicht.

Ich habe die 16 Pins (2x8) waagerecht auf dem Breadboard angeordnert.

Soll heißen
M1.16 => Matrix 1, physikalischer Pin 16.


obere Reihe auf dem Breadboard
M1.16 - M1.09, M2.16 - M2.09, ...

untere Reihe auf dem Breadboard
M1.01 - M1.08, M2.01 - M2.08, ...

Da ich diese sehr platzsparend 1dimensional kaskadieren möchte (PCB nur 
unter der Matrixenfläche selber, ist die einfachste und passenste 
Möglichkeit, die Matrizen hochkant zu stellen. (siehe PCB oben).

Edit:
Der Kontrolle halber,

Die Segmente(Spalten/Col/Anode) könne mit bis zu 320mA (Source) 
angetrieben werden. Digits können mit ~40mA (Sink/Row/Cathode) gegen 
Masse geschaltet werden. Soweit denke ich ist das richtig, und von daher 
würde ich jetzt sagen, dass ich bei den "CA" Modulen die Möglichkeit 
habe, Spalten und Reihen zu vertauschen. So dass die Matrizen auf der 
Seite liegen können. Testen kann ich es gerade nicht, da ich nur die 
anderen Module hier hab.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Ich würde das Programm aufteilen:
1. Ausgabe des Bildspeichers an die MAX7219.
Dieser Routine ist es wurscht, wie die Anordnung ist.

2. Schreiben des Pixelmusters eines Zeichens in den Bildspeicher.
Diese Routine muß die Pixel entsprechend der Anordnung setzten.
Man sollte dann auch den Zeichensatz so definieren, daß er dafür optimal 
ist.

Quasi, wie es jede Grafikkarte macht.
Dazu muß man einen Bildspeicher über die komplette Matrix (Bildschirm) 
anlegen.

: Bearbeitet durch User
von Stefan S. (sschultewolter)


Lesenswert?

Peter Dannegger schrieb:
> Ich würde das Programm aufteilen:
> 1. Ausgabe des Bildspeichers an die MAX7219.
> Dieser Routine ist es wurscht, wie die Anordnung ist.
>
> 2. Schreiben des Pixelmusters eines Zeichens in den Bildspeicher.
> Diese Routine muß die Pixel entsprechend der Anordnung setzten.
> Man sollte dann auch den Zeichensatz so definieren, daß er dafür optimal
> ist.
>
> Quasi, wie es jede Grafikkarte macht.
> Dazu muß man einen Bildspeicher über die komplette Matrix (Bildschirm)
> anlegen.

Hallo Peter, danke für die Antwort. So könnte ich es mal angehen. Der 
Zeichensatz ist kein Problem.
Der liegt als 8x5 und 8x8 in allen Ausrichtungen vor

von Stefan S. (sschultewolter)


Lesenswert?

So, habe mich mal an Peters Vorschlag gehalten. Habe noch nicht so viel 
Zeit gehabt. Aber einen ersten Test gestartet. So geht es eigentlich 
ganz gut. Alles nur als Test angelegt. Werde das ganze später noch 
einkürzen, da je Pixel ein Byte doch etwas zu viel des guten ist.
1
uint8_t max7219_buffer[8][MAX7219_NUM_IC*8]  =
2
{
3
  {1, 1, 1, 0, 0, 0, 0, 1, /**/ 1, 1, 1, 1, 1, 1, 1, 1, /**/ 0, 0, 0, 0, 0, 0, 0, 0, /**/ 0, 0, 0, 0, 0, 0, 0, 0},
4
  {1, 0, 0, 0, 0, 0, 1, 0, /**/ 0, 0, 0, 0, 0, 0, 1, 0, /**/ 0, 0, 0, 0, 0, 0, 0, 0, /**/ 0, 0, 0, 0, 0, 0, 0, 0},
5
  {1, 0, 0, 0, 0, 1, 0, 0, /**/ 0, 0, 0, 0, 0, 1, 0, 0, /**/ 0, 0, 0, 0, 0, 0, 0, 0, /**/ 0, 0, 0, 0, 0, 0, 0, 0},
6
  {0, 0, 0, 0, 1, 0, 0, 0, /**/ 0, 0, 0, 0, 1, 0, 0, 0, /**/ 0, 0, 0, 0, 0, 0, 0, 0, /**/ 0, 0, 0, 0, 0, 0, 0, 0},
7
  {1, 0, 0, 1, 0, 0, 0, 0, /**/ 0, 0, 0, 1, 0, 0, 0, 0, /**/ 0, 0, 0, 0, 0, 0, 0, 0, /**/ 0, 0, 0, 0, 0, 0, 0, 0},
8
  {1, 0, 1, 0, 0, 0, 0, 0, /**/ 0, 0, 1, 0, 0, 0, 0, 0, /**/ 0, 0, 0, 0, 0, 0, 0, 0, /**/ 0, 0, 0, 0, 0, 0, 0, 0},
9
  {1, 1, 0, 0, 0, 0, 0, 0, /**/ 0, 1, 0, 0, 0, 0, 0, 0, /**/ 0, 0, 0, 0, 0, 0, 0, 0, /**/ 0, 0, 0, 0, 0, 0, 0, 0},
10
  {1, 0, 0, 0, 0, 0, 0, 0, /**/ 1, 0, 0, 0, 0, 0, 0, 0, /**/ 0, 0, 0, 0, 0, 0, 0, 0, /**/ 0, 0, 0, 0, 0, 0, 0, 0},
11
};
12
13
void max7219_out()
14
{
15
  for(int i = 0; i < 8; i++)
16
  {
17
    uint8_t val = 0;
18
    for(int j = 0; j < 8; j++)
19
    {
20
      val += max7219_buffer[i][j] << (7 - j);
21
    }
22
    max7219_send(0, i+1, val);
23
    val = 0;
24
  }
25
}

von Stefan S. (sschultewolter)


Angehängte Dateien:

Lesenswert?

Hallo,

habe mich mit dem Problem nun ein paar Tage auseinandergesetzt. Soweit 
funktioniert das alles ganz gut. Was mich aber wundert ist die 
Ausführungszeit. Es wird laut dem Logik Level Analyser 6ms gebraucht, 
den Puffer zu beschreiben und abzusenden.
Habe dazu einen Pin überwacht der am Anfang sowie am Ende gesetzt/nicht 
gesetzt wird.

Wo kann ich jetzt noch ansetzen um es weiter zu optimieren.

1
  while(1)
2
  {
3
    static int start = -1;
4
    static uint32_t last_output_millis;
5
    if(millis() - last_output_millis >= 50)
6
    {
7
      last_output_millis = millis();
8
      
9
      max7219_puts_scroll("abcdefg_", &start);
10
    }
11
  }


1
void max7219_puts_scroll(char *s, int8_t *run)
2
{
3
MAX7219_PORT |= (1 << MAX7219_DEBUG);  // DEBUG
4
5
  int16_t size_str = max7219_width_string(s);
6
  static int16_t offset = MAX7219_MAX_COL;
7
  int16_t x = offset;
8
  
9
  if(*run == 0) return;
10
  // Ausfuehren, solange noch mindesten 1 Durchlauf ansteht,
11
  // oder -1 fuer unendlich Durchlaeufe
12
  else if(*run < 0 || *run > 0)
13
  {
14
    for(uint8_t c = 0; c < strlen(s); c++)
15
    {
16
      // Spalten des Zeichens ermitteln (0 - 8 Spalten)
17
      uint8_t size_char = pgm_read_byte(&font_bold[s[c]][0]);
18
      
19
      for(uint8_t i = 0; i < size_char; i++)
20
      {
21
        max7219_buffer_write(i+x, pgm_read_byte(&font_bold[s[c]][i+1]));
22
      }
23
      
24
      // Leere Spalte nach jedem Zeichen schreiben
25
      max7219_buffer_write(x+size_char, 0x00);
26
      
27
      x += size_char+1;
28
    }
29
    
30
    // Speicher an MAX7219 senden
31
    max7219_buffer_send();
32
    
33
    // Wenn Ende erreicht, von vorne anfangen
34
    if(--offset < 0 - size_str ) { offset = MAX7219_MAX_COL; *run -= 1; }
35
  }
36
  MAX7219_PORT &= ~(1 << MAX7219_DEBUG);  // DEBUG ENDE
37
}

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.