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 folgende 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 } }
Hinweis: Das Pongspiel lässt sich auch mit einem schöneren und kürzeren Code realisieren. Obiger Code wird daher demnächst noch ersetzt.