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

int txt = 6;
 
unsigned long prev = 0;
const long interval = 200;        //Durchlaufgeschwindigkeit                    
 
int z[] = {
           Initialisieren,
           R, A, T, S, G, Y, M, N, A, S, I, U, M, _,
           P, E, I, N, E,
           };
 
int x = 119;          // Zustände in z[]   --- siehe Buchstaben.h
 
int h1 = 24;
int h2 = 23;
int h3 = 22;
int h4 = 21;
int h5 = 20;
int h6 = 19;
int h7 = 18;
int h8 = 17;
int h9 = 16;
int h10 = 15;
int h11 = 14;
int h12 = 13;
int h13 = 12;
int h14 = 11;
int h15 = 10;
int h16 = 9;
int h17 = 8;
int h18 = 7;
int h19 = 6;
int h20 = 5;
int h21 = 4;
int h22 = 3;
int h23 = 2;
int h24 = 1;
 
void loop () {
 
  unsigned long cur = millis();
 
  if(cur - prev >= interval){
    h1 += 1;
    h2 += 1;
    h3 += 1;
    h4 += 1;
    h5 += 1;
    h6 += 1;
    h7 += 1;
    h8 += 1;
    h9 += 1;
    h10 += 1;
    h11 += 1;
    h12 += 1;
    h13 += 1;
    h14 += 1;
    h15 += 1;
    h16 += 1;
    h17 += 1;
    h18 += 1;
    h19 += 1;
    h20 += 1;
    h21 += 1;
    h22 += 1;
    h23 += 1;
    h24 += 1;
 
    prev = cur;
  }
 
 if(h1 == x){
    h1 = 0;
  }
 if(h2 == x){
    h2 = 0;
  }
 if(h3 == x){
    h3 = 0;
  }
 if(h4 == x){
    h4 = 0;
  }
 if(h5 == x){
    h5 = 0;
  }
 if(h6 == x){
    h6 = 0;
  }
 if(h7 == x){
    h7 = 0;
  }
 if(h8 == x){
    h8 = 0;
  }
 if(h9 == x){
    h9 = 0;
  }
 if(h10 == x){
    h10 = 0;
  }
 if(h11 == x){
    h11 = 0;
  }
 if(h12 == x){
    h12 = 0;
  }
 if(h13 == x){
    h13 = 0;
  }
 if(h14 == x){
    h14 = 0;
  }
 if(h15 == x){
    h15 = 0;
  }
 if(h16 == x){
    h16 = 0;
  }
 if(h17 == x){
    h17 = 0;
  }
 if(h18 == x){
    h18 = 0;
  }
 if(h19 == x){
    h19 = 0;
  }
 if(h20 == x){
    h20 = 0;
  }
 if(h21 == x){
    h21 = 0;
  }
 if(h22 == x){
    h22 = 0;
  }
 if(h23 == x){
    h23 = 0;
  }
 if(h24 == x){
    h24 = 0;
  } 
 
  maxOne(1,8,z[h1]);
  maxOne(1,7,z[h2]);
  maxOne(1,6,z[h3]);
  maxOne(1,5,z[h4]);
  maxOne(1,4,z[h5]);
  maxOne(1,3,z[h6]);
  maxOne(1,2,z[h7]);
  maxOne(1,1,z[h8]);
  maxOne(2,8,z[h9]);
  maxOne(2,7,z[h10]);
  maxOne(2,6,z[h11]);
  maxOne(2,5,z[h12]);
  maxOne(2,4,z[h13]);
  maxOne(2,3,z[h14]);
  maxOne(2,2,z[h15]);
  maxOne(2,1,z[h16]);
  maxOne(3,8,z[h17]);
  maxOne(3,7,z[h18]);
  maxOne(3,6,z[h19]);
  maxOne(3,5,z[h20]);
  maxOne(3,4,z[h21]);
  maxOne(3,3,z[h22]);
  maxOne(3,2,z[h23]);
  maxOne(3,1,z[h24]);
 
}
// Alphabet Definition
 
 #define A  126, 17, 17, 126, 0        //5
 #define B  127, 73, 73, 54, 0         //5
 #define C  62, 65, 65, 65, 0          //5
 #define D  127, 65, 65, 62, 0         //5
 #define E  127, 73, 73, 65, 0         //5
 #define F  127, 9, 9, 1, 0            //5
 #define G  62, 65, 81, 50, 0          //5
 #define H  127, 8, 8, 127, 0          //5
 #define I  65, 127, 65, 0             //4
 #define J  65, 65, 63, 0              //4
 #define K  127, 20, 34, 65, 0         //5
 #define L  127, 64, 64, 0             //4
 #define M  127, 2, 12, 2, 127, 0      //6
 #define N  127, 4, 8, 16, 127, 0      //6
 #define O  62, 65, 65, 62, 0          //5
 #define P  127, 9, 9, 6, 0            //5
 #define Q  62, 65, 81, 33, 94, 0      //6
 #define R  127, 25, 41, 70, 0         //5
 #define S  38, 73, 73, 50, 0          //5
 #define T  1, 1, 127, 1, 1, 0         //6
 #define U  63, 64, 64, 63, 0          //5
 #define V  31, 32, 64, 32, 31, 0      //6
 #define W  127, 32, 28, 32, 127, 0    //6
 #define X  99, 20, 8, 20 ,99, 0       //6
 #define Y  3, 4, 120, 4, 3, 0         //6
 #define Z  97, 81, 73, 69 ,67, 0      //6
 
 #define AK  32, 84, 84, 120, 0        //5
 #define BK  63, 72, 72, 48, 0         //5
 #define CK  48, 72, 72, 72, 0         //5
 #define DK  48, 72, 72, 127, 0        //5
 #define EK  56, 84, 84, 88, 0         //5
 #define FK  126, 9, 1, 0              //4
 #define GK  76, 146, 146, 124, 0      //5
 #define HK  127, 8, 8, 112, 0         //5
 #define IK  122, 0                    //2
 #define JK  64, 136, 122, 0           //4
 #define KK  127, 16, 40, 68, 0        //5
 #define LK  63, 64, 64, 0             //4
 #define MK  120, 8, 112, 8, 120, 0    //6
 #define NK  8, 112, 8, 8, 112, 0      //6
 #define OK  48, 72, 72, 48, 0         //5
 #define PK  252, 36, 36, 24, 0        //5                (Alternative: 248, 72, 72, 48, 0)
 #define QK  24, 36, 36, 252, 0        //5                (Alternative: 48, 72, 72, 248, 0)
 #define RK  8, 112, 8, 8, 0           //5
 #define SK  72, 84, 84, 36, 0         //5
 #define TK  8, 63, 72, 64, 0          //5
 #define UK  56, 64, 64, 56, 0         //5
 #define VK  24, 32, 64, 32, 24, 0     //6
 #define WK  56, 64, 48, 64, 56, 0     //6
 #define XK  72, 48, 48, 72, 0         //5
 #define YK  4, 8, 112, 8, 4, 0        //6                (Alternative: 24, 160, 160, 120, 0)
 #define ZK  72, 104, 88, 72, 0        //5
 
 #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
 
 #define Fragezeichen    2, 1, 89, 6, 0  //5
 #define Ausrufezeichen  79, 0           //2
 #define Punkt           64, 0           //2
 #define Appostroph      5, 3, 0         //3
 #define Komma           160, 96, 0      //3
 #define _               0, 0            //2    (Leerzeichen)
 
 #define Plus    8, 8, 62, 8, 8, 0         //6
 #define Minus   8, 8, 8, 8, 8, 0          //6
 #define Mal     20, 8, 62, 8, 20, 0       //6
 #define Geteilt 32, 16, 8, 4, 2, 0        //6
 #define Gleich  20, 20, 20, 20, 20, 0     //6
 
 #define Initialisieren 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0  //24        Pro Matrix 8x 0 dazu
 
 #define Herz  28, 62, 126, 252, 126, 62, 28, 0                           //8

Hinweis: Code wird noch überarbeitet

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.