Metainformationen zur Seite
  •  

Dies ist eine alte Version des Dokuments!


LED-Matrix max7219

In diesem Wiki-Eintrag soll es im Gegensatz zum anderen LED-Matrix-Eintag, nicht um die selbstgebauten Matrizen, sondern um LED-Matrizen vom Typ max7219 gehen. Hier sind im Folgenden einige Code-Beispiele, um solche Matrizen mit dem Arduino zu bedienen, sowie das Anschließen an eben diesen zu finden.

Anschließen

Initialisierung im Arduino Code

// *****************   Beginn Initialisierung Matrix   ************************
 
int dataIn = 2;
int load = 3;
int clock = 4;
 
int maxInUse = 4;    //change this variable to set how many MAX7219's you'll use
 
int e = 0;           // just a varialble
 
// define max7219 registers
byte max7219_reg_noop        = 0x00;
byte max7219_reg_digit0      = 0x01;
byte max7219_reg_digit1      = 0x02;
byte max7219_reg_digit2      = 0x03;
byte max7219_reg_digit3      = 0x04;
byte max7219_reg_digit4      = 0x05;
byte max7219_reg_digit5      = 0x06;
byte max7219_reg_digit6      = 0x07;
byte max7219_reg_digit7      = 0x08;
byte max7219_reg_decodeMode  = 0x09;
byte max7219_reg_intensity   = 0x0a;
byte max7219_reg_scanLimit   = 0x0b;
byte max7219_reg_shutdown    = 0x0c;
byte max7219_reg_displayTest = 0x0f;
 
void putByte(byte data) {
  byte i = 8;
  byte mask;
  while (i > 0) {
    mask = 0x01 << (i - 1);      // get bitmask
    digitalWrite( clock, LOW);   // tick
    if (data & mask) {           // choose bit
      digitalWrite(dataIn, HIGH);// send 1
    } else {
      digitalWrite(dataIn, LOW); // send 0
    }
    digitalWrite(clock, HIGH);   // tock
    --i;                         // move to lesser bit
  }
}
 
void maxAll (byte reg, byte col) {    // initialize  all  MAX7219's in the system
  int c = 0;
  digitalWrite(load, LOW);  // begin
  for ( c = 1; c <= maxInUse; c++) {
    putByte(reg);  // specify register
    putByte(col);//((data & 0x01) * 256) + data >> 1); // put data
  }
  digitalWrite(load, LOW);
  digitalWrite(load, HIGH);
}
void maxOne(byte maxNr, byte reg, byte col) {    
//maxOne is for adressing different MAX7219's, 
//whilele having a couple of them cascaded
 
  int c = 0;
  digitalWrite(load, LOW);  // begin     
 
  for ( c = maxInUse; c > maxNr; c--) {
    putByte(0);    // means no operation
    putByte(0);    // means no operation
  }
 
  putByte(reg);  // specify register
  putByte(col);//((data & 0x01) * 256) + data >> 1); // put data 
 
  for ( c =maxNr-1; c >= 1; c--) {
    putByte(0);    // means no operation
    putByte(0);    // means no operation
  }
 
  digitalWrite(load, LOW);
  digitalWrite(load,HIGH); 
}
 
void setup() {
 
  Serial.begin(9600);
 
  pinMode(dataIn, OUTPUT);
  pinMode(clock,  OUTPUT);
  pinMode(load,   OUTPUT);
 
  //initiation of the max 7219
  maxAll(max7219_reg_scanLimit, 0x07);
  maxAll(max7219_reg_decodeMode, 0x00);  // using an led matrix (not digits)
  maxAll(max7219_reg_shutdown, 0x01);    // not in shutdown mode
  maxAll(max7219_reg_displayTest, 0x00); // no display test
  for (e = 1; e <= 8; e++) { // empty registers, turn all LEDs off
    maxAll(e, 0);
  }
  maxAll(max7219_reg_intensity, 0x0f & 0x0f);    // the first 0x0f is the value you can set
  // range: 0x00 to 0x0f
 
}
 
// *********************************   Ende Initialisierung Matrix   **********************************

Laufschrift

Pong

Um ein Pongspiel mit zwei Spielern auf ebenfalls zwei Led-Matrizen zu realiesieren, die man mit zwei Tasten steuert, kann man hinter die Initialisierung nachfolgende Code-Zeilen setzen:

int zeit = 0;
 
  int Schlaegerrechts = 24;      // Schläger 1
  int Schlaegerlinks = 24;      // Schläger 2
 
  int taster1 = 5;      // Taster 1        1 und 2 für Schläger rechts
  int taster2 = 6;      // Taster 2
  int taster3 = 7;      // Taster 3        3 und 4 für Schläger links
  int taster4 = 8;      // Taster 4  
 
  int read_taster1;
  int read_taster2; 
  int read_taster3; 
  int read_taster4; 
 
  unsigned long time1 = 0;       
  unsigned long time2 = 0;
  unsigned long time3 = 0;
  unsigned long debounce = 100;
  unsigned long debounce2 = 10000;
 
  int matrix = 1;                    // Matrix auf der sich der Ball aktuell befindet
  int xball = 3;
  int dx = 1;                   // x-Richtung
  int yball = 1;
  float dy = 2.0;               // y-Richtung als float, da die Änderung teilweise 0,5 ist. Kommazahlen nicht als int
  int r = 0;                    // Variable für Zufallsgenerierung
  int vball = 25;               // Ballgeschwindigkeit
 
  int zahl[] = {nul, eins, zwei, drei, vier, fuenf, sechs, sieben, acht, neun};
  int xz = 0;                  // xz + den aktuelen Wert x ergibt zahl[] 
  int Wert1 = 0;               // Wert1 - Wert4 für den Punktestand der beiden Spieler --> pro Matrix (und Spieler) zwei Zahlen
  int Wert2 = 0;
  int Wert3 = 0;
  int Wert4 = 0;
 
 
void loop() {
 
  maxOne (2, 1, Schlaegerrechts);          // Position Schläger 1
  maxOne (1, 8, Schlaegerlinks);          // Position Schläger 2
  delay(2);
 
  // ******   Schläger   ******
 
  read_taster1 = digitalRead (taster1);
  read_taster2 = digitalRead (taster2);
  read_taster3 = digitalRead (taster3);
  read_taster4 = digitalRead (taster4);
 
  if (read_taster1 == HIGH && Schlaegerrechts >= 6 && millis() - time1 > debounce) {          // Bewegung Schläger über Taster
    time1 = millis();
    Schlaegerrechts = Schlaegerrechts /= 2;
  }
 
  if (read_taster2 == HIGH && Schlaegerrechts <= 96 && millis() - time1 > debounce) {         // Bewegung Schläger über Taster
    time1 = millis();
    Schlaegerrechts = Schlaegerrechts *= 2;
  }
 
  if (read_taster3 == HIGH && Schlaegerlinks >= 6 && millis() - time2 > debounce) {          // Bewegung Schläger über Taster
    time2 = millis();
    Schlaegerlinks = Schlaegerlinks /= 2;
  }
 
  if (read_taster4 == HIGH && Schlaegerlinks <= 96 && millis() - time2 > debounce) {         // Bewegung Schläger über Taster
    time2 = millis();
    Schlaegerlinks = Schlaegerlinks *= 2;
  }
 
  delay(1);
 
  // ******   Ball   ******
 
  r = random (0, 3);                                      // y-Richtung Ball ändert zufaällig am Schläger
                                                          // random zwischen 0-5 --> jeweils 2 random Werte stehen für ein dy --> Zuweisung dort, wo Schläger und Ball zusammentreffen
 
   if (millis() - time3 > debounce2 && vball > 3) {       // Änderung der Ballgeschwindigkeit --> wird immer schneller
      time3 = millis();
      vball--;
    }
 
  if (zeit == 0) {
 
    maxOne (matrix, xball, 0);                            // Null setzt die Spalte zurück, sodass der Ball immer ein Punkt bleibt
    xball += dx;                                     // Bewegung in x-Richtung
    yball *= dy;                                     // Bewegung in y-Richtung
 
    if (yball == 128) {                              // Ball am oberen Spielfeldrand
      dy = 0.5;
    }
 
    if (yball == 1) {                                // Ball am unteren Spielfeldrand
      dy = 2;
    }
 
    if (xball == 9 && matrix == 2 && dx == 1) {          // Ball am rechten Rand der linken Matrix
      matrix = 1;                                        // Ball springt auf die rechte Matrix
      xball = 1;                                    // x Komponente wieder 1, da rechte Matrix dort wieder bei 1 los geht
    }
 
    if (xball == 0 && matrix == 1&& dx == -1) {         // Ball am linken Rand der rechten Matrix
      matrix = 2;                                       // Ball springt auf die linke Matrix
      xball = 8;                                   // x Komponente 8, da linke Matrix dort wieder bei 8 anfängt
    }
 
    // ******   rechter Spielfeldrand   ******
 
    if (xball == 7 && matrix == 1) {
 
      int pos1 = Schlaegerlinks / 3;                                           // zur Ermittlung ob Schläger den Ball trifft
 
      if (yball == pos1 || yball == 2 * pos1) {                    // Schläger trifft
        dx = -1;
 
        if(r == 0 && yball != 1) {                     // Änderung der y-Richtung wird mit den folgenden 3 if-Schleifen bestimmt
          dy = 0.5;                                                
        }
        else if (r == 1) {
          dy = 1;
        }
        else if (r == 2 && yball != 128) {
          dy = 2;
        }
      }
      else {                                          // Schläger trifft nicht
 
        Wert2 = Wert2 + 4;                            // ab hier Punktezähler für den linken Spieler
        if (Wert2 == 40) {                            // Zahl immer plus 4, da jede Zahl vier Spalten belegt (siehe Buchstaben.h)
          Wert2 = 0;
          Wert1 = Wert1 + 4;
        }
        for (int a = 0; a < 4; a++) {
          xz = a + Wert1;
          maxOne (2, a + 1, zahl [xz]);
        }
        for (int a = 0; a < 4; a++) {
          xz = a + Wert2;
          maxOne (2, a + 5, zahl [xz]);
        }                                            // Ende Punkezähler linker Spieler
 
        for (int a = 0; a < 4; a++) {                // Analog dazu der Punktestand des anderen Spielers ; ändert sich nicht
          xz = a + Wert3;
          maxOne (1, a + 2, zahl [xz]);
        }
        for (int a = 0; a < 4; a++) {
          xz = a + Wert4;
          maxOne (1, a + 6, zahl [xz]);
        }
 
        delay(2000);
 
        for (int a = 1; a < 9; a++) {
          maxAll (a, 0);                            // Matrix zurücksetzen
        }
 
        xball = 3;                                  // Variablen zurücksetzen
        yball = 1;
        dx = 1;
        dy = 2;
        Schlaegerrechts = 24;
        Schlaegerlinks = 24;
        vball = 18;
      }
    }
 
    // ******   linker Spielfeldrand   ******
 
    if (xball == 2 && matrix == 2) {
 
     int pos2 = Schlaegerrechts / 3;                                              // zur Ermittlung ob Schläger den Ball trifft
      if (yball == pos2 || yball == 2 * pos2) {                      // Schläger trifft
        dx = 1;
 
        if(r == 0 && yball != 1) {                                   // Änderung der y-Richtung wird mit den folgenden 3 if-Schleifen bestimmt
          dy = 0.5;
        }
        else if (r == 1) {
          dy = 1;
        }
        else if (r == 2 && yball != 128) {
          dy = 2;
        }
      }
      else {                                                        // Schläger trifft nicht
 
        Wert4 = Wert4 + 4;                                          // ab hier Punktezähler für den rechten Spieler
        if (Wert4 == 40) {
          Wert4 = 0;
          Wert3 = Wert3 + 4;
        }
        for (int b = 0; b < 4; b++) {
          xz = b + Wert3;
          maxOne (1, b + 2, zahl [xz]);
        }
        for (int b = 0; b < 4; b++) {
          xz = b + Wert4;
          maxOne (1, b + 6, zahl [xz]);
        }                                                          // Ende Punktezähler rechter Spieler
 
        for (int b = 0; b < 4; b++) {                              // Analog der Punktestand des anderen Spielers ; ändert sich nicht
          xz = b + Wert1;
          maxOne (2, b + 1, zahl [xz]);
        }
        for (int b = 0; b < 4; b++) {
          xz = b + Wert2;
          maxOne (2, b + 5, zahl [xz]);
        }
 
        delay(2000);
 
        for (int b = 1; b < 9; b++) {
          maxAll (b, 0);                            // Matrix zurücksetzen
        }
        xball = 3;                                  // Variablen zurücksetzen
        yball = 1;
        dx = 1;
        dy = 2;
        Schlaegerrechts = 24;
        Schlaegerlinks = 24;
        matrix = 1;
        vball = 18;
      }
    }
 
    maxOne (matrix, xball, yball);        // Position Ball
  }
 
  zeit = (zeit + 1) % vball;         // Nach jedem dritten Durchgang wird die Schleife für den Ball ausgeführt
                                     // Modulo ist erforderlich, da mit einem längeren delay die Schläger langsamer wären
                                     // Duch das Modulo läuft der Ball unabhängig von den Schläger
 
 Serial.println(zeit);
 
 // ******   Spielende erreicht --> Spiel wird auf Null zurückgesetzt   ******
 
 if (Wert1 == 8 && Wert2 == 4 || Wert3 == 8 && Wert4 == 4) {                  // Puntestand von 21 ist Spiel gewonnen und startet von Vorne
 
   for (int c = 0; c < 9; c++) {
     maxAll (c, 0);
   }
 
   Wert1 = 0;
   Wert2 = 0;
   Wert3 = 0;
   Wert4 = 0;
 
   for (int c = 1; c < 9; c++) {
     maxOne (2, c, 255);
     maxOne (1, 9 - c, 255);
     delay(200);
     maxOne (2, c, 0);
     maxOne (1, 9 - c, 0);
   }
   for (int c = 0; c < 9; c++) {
     maxAll (c, 255);
   }
   delay (4000);
 
   for (int c = 0; c < 9; c++) {
     maxAll (c, 0);
   }
 
   vball = 25;                                      // Geschwindigkeit zurückstzen
 }
 
}

In diesem Codebeispiel sind die Zahlen der Spielstände in eine extra Header-Datei ausgelagert, um den Code übersichtlicher zu machen. Um eine Header-Datei im Code zu includieren fügt man als erste Zeile des Codes

#include "HeaderDateiName.h" 

ein.

Die Header-Datei hat in unserem Beispiel folgenden Inhalt:

 #define nul     127, 65, 127, 0       //4
 #define eins    0, 0, 127, 0          //4
 #define zwei    121, 73, 79, 0        //4
 #define drei    73, 73, 127, 0        //4
 #define vier    15, 8, 127, 0         //4
 #define fuenf   79, 73, 121, 0        //4
 #define sechs   127, 73, 121, 0       //4
 #define sieben  1, 1, 127, 0          //4
 #define acht    127, 73, 127, 0       //4
 #define neun    79, 73, 127, 0        //4

Anmerkung zur 0: Da null bereits durch die C++Syntax belegt ist, wurde hier statt dem Wort null, das Wort nul als Variable gesetzt.

Hinweis: Das Pongspiel lässt sich auch mit einem schöneren und kürzeren Code realisieren. Obiger Code wird daher demnächst noch ersetzt.