Spiel mit einer RGB-Matrix

Lese­zeit: 10 Minu­ten

Lösung
Seite als PDF

Mit der RGB-Matrix soll ein klei­nes Spiel rea­li­siert wer­den:
Auf einer RGB-Matrix leuch­ten zufäl­lig eine Rei­he von LEDs. In der Mit­te leuch­tet beim Start eine gel­be LED. Das Tas­ten­pad „bewegt“ die­se LED über die RGB-Matrix und „löscht“ dabei die LED auf der aktu­el­len Posi­ti­on.
Wenn die äuße­re rech­te Tas­te des Tas­ten­pads gedrückt wird, zeigt der Seri­el­le Moni­tor die benö­tig­te Zeit und die Anzahl der Klicks an.

So sieht es aus: (um das Video kurz zu hal­ten, wur­den nur sechs LEDs verwendet)

RGB-Matrix

Die RGB-Matrix besteht aus mit­ein­an­der ver­bun­de­nen RGB-LEDs. Jede besitzt einen eige­nen Con­trol­ler und kann ein­zeln ange­steu­ert wer­den. Die RGB-Matrix benö­tigt nur einen digi­ta­len Eingang.

RGB ist eine Mischung aus den Far­ben rot, grün und blau. Die Wer­te wer­den durch Kom­ma­ta getrennt.

Bei­spie­le:

Hier fin­dest du einen Über­blick über die 🔗RGB-Farb­codes (exter­ner Link abge­ru­fen am 21.03.23).

Benö­tig­te Bauteile:

  • RGB-Matrix2 LEDs
  • Tas­ten­pad
  • Lei­tungs­dräh­te

Baue die Schal­tung auf.
(Fah­re mit der Maus über das Bild, um die Bezeich­nun­gen der Bau­tei­le zu sehen)

Benö­tig­te Bibliotheken:

oder: Sketch → Biblio­thek ein­bin­den → Biblio­the­ken verwalten

Direkt zum Programm

Funk­tio­nen der Biblio­thek Adafruit_NeoMatrix (Aus­wahl)

Schlüs­sel­wortPara­me­terAkti­on
begin();RGB-Matrix star­ten
setBrightness(Parameter)0 = aus, 255 = größ­te HelligkeitBild­schirm­hel­lig­keit setzen
setRotation(Richtung);Rich­tung = 0 → nicht drehen
Rich­tung = 1 → 90° drehen
Rich­tung = 2 → 180° drehen
Rich­tung = 3 → 270 ° drehen
Bild­schirm ausrichten
fillScreen(Farbe);Bild­schirm­hin­ter­grund füllen
Far­ben definieren:
#define Rot RGBMatrix.Color(255,0,0)
#define Gruen RGBMatrix.Color(0,255,0)
#define Blau RGBMatrix.Color(0,0,255)
#define Magen­ta RGBMatrix.Color(139,0,139)
#define Pink RGBMatrix.Color(255,20,147)
#define Weiss RGBMatrix.Color(255,255,255)
#define Gelb RGBMatrix.Color(255,255,0)
Bild­schirm­hin­ter­grund
drawLine(StartX, Star­tY, End­eX, EndeY, Farbe);Linie zeich­nen
drawFastHLine(StartX, Star­tY, Län­ge, Farbe);hori­zon­ta­le Linie zeichnen
drawFastVLine(StartX, Star­tY, Län­ge, Farbe);ver­ti­ka­le Linie zeichnen
drawRect(StartX, Star­tY,, Brei­te, Höhe, Farbe);Recht­eck zeichnen
drawRoundRect(StartX, Star­tY, Brei­te, Höhe, Ecken­ra­di­us, Farbe);abge­run­de­tes Recht­eck zeichnen
fill.Rect(StartX, Star­tY, Brei­te, Höhe, Füllfarbe);aus­ge­füll­tes Recht­eck zeichnen
drawCircle(MittelpunkX, Mit­tel­punk­tY, Radi­us, Farbe);Kreis zeich­nen
drawPixel(StartX, Star­tY, Farbe);ein­zel­nen Pixel zeichnen
drawChar(StartX, Star­tY, Zei­chen, Rot, Hin­ter­grund, Textgröße);drawChar(0, 1, 'Z', Rot, Weiss, 1);Ein­zel­nes Zei­chen schreiben
fillCircle(MittelpunktX, Mit­tel­punk­tY, Radi­us, Füllfarbe);Aus­ge­füll­ten Kreis zeichnen
setCursor(x, y);Cur­sor setzen
setTextSize(Textgröße);Text­grö­ße:
1 – 4
bei einer Matrix nur 1 möglich
Text­grö­ße setzen
setTextColor(Farbe);Text­far­be bestimmen
print("Text");Text schrei­ben

Ob die Aus­rich­tung der RGB-Matrix kor­rekt ist, kannst du mit die­sem Pro­gramm feststellen:

# include "Adafruit_NeoMatrix.h"

# define RGBMatrixPin 7

// RGBMatrix -> Name der RGB-Matrix
/*
  die wichtigsten Parameter:
  Parameter 1 = Breite der Matrix (8)
  Parameter 2 = Höhe der Matrix (8)
  Parameter 3 = Name des Daten-Pins (RGBMatrixPin)
*/
Adafruit_NeoMatrix RGBMatrix =   Adafruit_NeoMatrix(8, 8, RGBMatrixPin,
                                 NEO_MATRIX_TOP + NEO_MATRIX_RIGHT +
                                 NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE,
                                 NEO_GRB + NEO_KHZ800);

void setup()
{
  RGBMatrix.setBrightness(10);

  // RGBMatrix starten
  RGBMatrix.begin();
}

void loop()
{
  RGBMatrix.clear();

  // horizintale Linie
  RGBMatrix.drawFastHLine(0, 2, 8, RGBMatrix.Color(0, 0, 255));

  // vertikale Linie
  RGBMatrix.drawFastVLine(2, 0, 8, RGBMatrix.Color(0, 0, 255));

  /* 
    leuchtende LEDs in den Ecken
    oben links
    oben rechts
    unten links
    unten rechts
  */
  RGBMatrix.drawPixel(0, 0, RGBMatrix.Color(0, 0, 255));
  RGBMatrix.drawPixel(7, 0, RGBMatrix.Color(0, 0, 255));
  RGBMatrix.drawPixel(0, 7, RGBMatrix.Color(0, 0, 255));
  RGBMatrix.drawPixel(7, 7, RGBMatrix.Color(0, 0, 255));

  RGBMatrix.show();
}

So muss es aussehen:

Ein Lauf­licht:

Das dazu­ge­hö­ri­ge Programm:

# include "Adafruit_NeoMatrix.h"

// Startposition links oben
int Spalte = 0;

# define RGBMatrixPin 7

// RGBMatrix -> Name der RGB-Matrix
/*
  die wichtigsten Parameter:
  Parameter 1 = Breite der Matrix (8)
  Parameter 2 = Höhe der Matrix (8)
  Parameter 3 = Name des Daten-Pins (RGBMatrixPin)
*/
Adafruit_NeoMatrix RGBMatrix = Adafruit_NeoMatrix(8, 8, RGBMatrixPin,
                               NEO_MATRIX_TOP + NEO_MATRIX_RIGHT +
                               NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE,
                               NEO_GRB + NEO_KHZ800);

void setup()
{
  // Helligkeit setzen
  RGBMatrix.setBrightness(10);

  // RGBMatrix starten
  RGBMatrix.begin();
}

void loop()
{
  RGBMatrix.clear();

  // von oben nach unten
  for (int i = 0; i <= 7; i ++)
  {
    RGBMatrix.drawPixel(Spalte, i, RGBMatrix.Color(0, 0, 255));
    delay(100);
    RGBMatrix.show();
  }

  RGBMatrix.clear();

  // eine Spalte nach rechts
  Spalte++;

  // von unten nach oben
  for (int i = 7; i >= 0; i--)
  {
    RGBMatrix.drawPixel(Spalte, i, RGBMatrix.Color(0, 0, 255));
    delay(100);
    RGBMatrix.show();
  }

  // solange das Ende (Spalte = 7) nicht erreicht ist
  // -> eine Spalte hinzufügen
  if (Spalte < 6) Spalte++;

  // Ende erreicht, Spalte wieder auf 0 setzen
  else Spalte = 0;
}

Gra­fik­funk­tio­nen:

Download

Das dazu­ge­hö­ri­ge Programm:

# include "Adafruit_NeoMatrix.h"

# define RGBMatrixPin 7

// RGBMatrix -> Name der RGB-Matrix
/*
  die wichtigsten Parameter:
  Parameter 1 = Breite der Matrix (8)
  Parameter 2 = Höhe der Matrix (8)
  Parameter 3 = Name des Daten-Pins (RGBMatrixPin)
*/
Adafruit_NeoMatrix RGBMatrix =  Adafruit_NeoMatrix(8, 8, RGBMatrixPin,
                                NEO_MATRIX_TOP + NEO_MATRIX_RIGHT +
                                NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE,
                                NEO_GRB + NEO_KHZ800);

// Farben definieren
# define Rot          RGBMatrix.Color(255,0,0)
# define Gruen        RGBMatrix.Color(0,255,0)
# define Blau         RGBMatrix.Color(0,0,255)
# define Magenta      RGBMatrix.Color(139,0,139)
# define Pink         RGBMatrix.Color(255,20,147)
# define Weiss        RGBMatrix.Color(255,255,255)
# define Gelb         RGBMatrix.Color(255,255,0)
# define ZufallsFarbe RGBMatrix.Color(random(1, 255), random(1, 255), random(1, 255))


void setup()
{
  RGBMatrix.setBrightness(10);

  // RGBMatrix starten
  RGBMatrix.begin();
}

void loop()
{
  RGBMatrix.clear();
  char Text[7] = {'A', 'r', 'd', 'u', 'i', 'n', 'o'};
  for (int i = 0; i < sizeof(Text); i++)
  {
    RGBMatrix.drawChar(0, 1, Text[i], Rot, 1, 1);
    RGBMatrix.show();
    delay(500);
    RGBMatrix.clear();
  }
  delay(1000);
  RGBMatrix.clear();

  // Matrix mit Farbe füllen
  RGBMatrix.fillScreen(Blau);
  RGBMatrix.show();
  delay(500);
  RGBMatrix.clear();

  RGBMatrix.fillScreen(Gelb);
  RGBMatrix.show();
  delay(500);
  RGBMatrix.clear();

  RGBMatrix.fillScreen(Rot);
  RGBMatrix.show();
  delay(500);

  RGBMatrix.clear();
  RGBMatrix.fillScreen(Gruen);
  RGBMatrix.show();
  delay(500);
  RGBMatrix.clear();

  RGBMatrix.fillScreen(Magenta);
  RGBMatrix.show();
  delay(500);
  RGBMatrix.clear();

  // einzelnes Zeichen schreiben
  RGBMatrix.setCursor(0, 1);
  RGBMatrix.setTextColor(Pink);
  RGBMatrix.setTextSize(1);
  RGBMatrix.print('Z');
  RGBMatrix.show();
  delay(500);
  RGBMatrix.clear();

  // Linie zeichnen
  for (int i = 0; i <= 7; i ++)
  {
    RGBMatrix.drawLine(i, 0, i, 8, Gelb);
    RGBMatrix.show();
    delay(200);
  }
  delay(500);
  RGBMatrix.clear();

  // horizontale Linie zeichnen
  for (int i = 1; i < 9; i ++)
  {
    RGBMatrix.drawFastHLine(0, i , i, Gruen);
    RGBMatrix.show();
    delay(200);
  }
  delay(500);
  RGBMatrix.clear();

  // vertikale Linie zeichnen
  for (int i = 1; i < 9; i ++)
  {
    RGBMatrix.drawFastVLine(i, 0 , i, Magenta);
    RGBMatrix.show();
    delay(100);
  }
  delay(500);
  RGBMatrix.clear();

  // Kreis zeichnen
  RGBMatrix.drawCircle(4, 4, 3, Weiss);
  RGBMatrix.show();
  delay(500);
  RGBMatrix.clear();

  // ausgefüllten Kreis zeichnen
  RGBMatrix.fillCircle(4, 4, 3, Blau);
  RGBMatrix.show();
  delay(500);

  // Rechtecke zeichnen
  RGBMatrix.clear();
  for (int i = 1; i < 9; i ++)
  {
    RGBMatrix.drawRect(0, 0, i, i, RGBMatrix.Color(0, 255, 255));
    RGBMatrix.show();
    delay(200);
  }
  delay(500);
  RGBMatrix.clear();
}

Das eigent­li­che Programm:

Bin­de die benö­tig­ten Biblio­the­ken ein und defi­nie­re die Varia­blen. Beach­te die Kommentare.

# include "Adafruit_NeoMatrix.h"

# define RGBMatrixPin 7

// Anzahl der LEDs für das Pixelmuster → kann angepasst werden
# define AnzahlLED 40

// RGBMatrix -> Name der Matrix
Adafruit_NeoMatrix RGBMatrix = Adafruit_NeoMatrix(8, 8, RGBMatrixPin,
                               NEO_MATRIX_TOP + NEO_MATRIX_RIGHT +
                               NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE,
                               NEO_GRB + NEO_KHZ800);
                               
// Farben definieren
# define Schwarz      RGBMatrix.Color(0,0,0)
# define Rot          RGBMatrix.Color(255,0,0)
# define Gruen        RGBMatrix.Color(0,255,0)
# define Blau         RGBMatrix.Color(0,0,255)
# define Magenta      RGBMatrix.Color(139,0,139)
# define Pink         RGBMatrix.Color(255,20,147)
# define Weiss        RGBMatrix.Color(255,255,255)
# define Gelb         RGBMatrix.Color(255,255,0)
# define MarineBlau   RGBMatrix.Color(0,0,128)
# define DunkelGruen  RGBMatrix.Color(0,100,0)
# define Golden       RGBMatrix.Color(205,149,12)
# define ZufallsFarbe RGBMatrix.Color(random(1, 255), random(1, 255), random(1, 255))

// PixelFarbe  -> Farbe der zufällig leuchtenden Pixel
// PixelCursor -> Farbe des sich bewegenden Pixels
# define PixelFarbe Blau
# define PixelCursor Gelb

// Variablen der Zeit
float StartZeit;
float VerstricheneZeit;
float Sekunden;

// entscheidet über den Neustart
bool Start = true;

int AnzahlKlicks = 1;

// Startposition der LED
int Zeile = 4;
int Spalte = 4;
int Taster;
int Analogwert;

Der set­up-Teil. Beach­te die Kommentare:

void setup()
{
  // setBrightness(0..255)
  RGBMatrix.setBrightness(10);

  // NeoPixel Bibliothek initialisieren
  RGBMatrix.begin();

  // Zufallsgenerator starten
  randomSeed(analogRead(0));
  Serial.begin(9600);
}

Die Tas­ten des Tas­ten­pads wer­den mit der Funk­ti­on ➨Tas­ter­ab­fra­ge gelesen.

int Tasterabfrage()
{
  Analogwert = analogRead(A0);

  // kurzes delay() -> doppelten Tastendruck so weit wie möglich verhindern
  delay(200);
  /* 
     A0 gibt je nach Taster einen Wert aus
     über den Seriellen Monitor kann dieser Wert angezeigt
     und kann dann eventuell angepasst werden
  */
  // Serial.println(Analogwert);  
  switch (Analogwert)
  {
    case 0 ... 20:
      Taster = 1;
      break;
    case 30 ... 60:
      Taster = 2;
      break;
    case  70 ... 120:
      Taster = 3;
      break;
    case 150 ... 200:
      Taster = 4;
      break;
    case 300 ... 400:
      Taster = 5;
      break;
    default:
      return 0;
  }

  // gedrückten Taster zurückgeben
  return Taster;
} 

Der „Par­cour“ wird mit der Funk­ti­on Par­cour­Bau­en() erstellt.

void ParcoursBauen()
{
  int Minimum = 0;
  int Maximum = 8;
  RGBMatrix.clear();

  for (int i = 0; i < AnzahlLED; i++)
  {
    // Zufallsposition der Pixel
    Spalte =  random(Minimum, Maximum);
    Zeile =  random(Minimum, Maximum);

    RGBMatrix.drawPixel(Zeile, Spalte, PixelFarbe);
  }
  Zeile = 4;
  Spalte = 4;
  RGBMatrix.drawPixel(Zeile, Spalte, PixelCursor);
  RGBMatrix.show();
}
Download

Der loop-Teil. Beach­te die Kommentare.

void loop()
{
  // wenn Start = true -> Parcour erstellen
  if (Start)
  {
    RGBMatrix.clear();
    ParcoursBauen();
    Start = false;
    StartZeit = millis();
    int Zeile = 4;
    int Spalte = 4;
  }

  Taster = Tasterabfrage();

  // Ergebnisse anzeigen und Neustart
  if (Taster == 5)
  {
    Start = true;

    // Zeit berechnen
    float Sekunden;
    VerstricheneZeit = millis() - StartZeit;
    Sekunden = VerstricheneZeit / 1000;
    String GesamtSekunden = String(Sekunden);

    // . durch , ersetzen
    GesamtSekunden.replace(".", ",");

    // Ausgabe im Seriellen Monitor
    Serial.println("Sekunden insgesamt: " + GesamtSekunden + " Sekunden");

    // Minuten berechnen
    int Minute  = int(Sekunden) / 60;

    // nur Ausgabe der Minuten wenn Minute > 0
    if (Minute > 0)
    {
      // Ausgabe verschönern, wenn Minute > 1 -> Ausgabe "Minuten"
      // "Minute"
      if (Minute > 1)
      {
        Serial.print(String(Minute) + " Minuten ");
      }
      else
      {
        Serial.print(String(Minute) + " Minute ");
      }
    }
    // von Sekunden Anzahl der Minuten abziehen
    Sekunden = Sekunden - Minute * 60;

    // Sekunden in String umwandeln
    // damit . durch , ersetzt werden kann
    String AnzahlSekunden = String(Sekunden);

    // . durch , ersetzen
    AnzahlSekunden.replace(".", ",");
    Serial.println(AnzahlSekunden + " Sekunden");
    Serial.println(String(AnzahlKlicks) + " Klicks!");
    AnzahlKlicks = 1;
  }

  /*
    bei der Matrix gibt es kein oben oder unten
    links oder rechts
    die Funktion der Tasten muss durch Drehen der Matrix
    entsprechend angepasst werden
  */

  // links
  if (Taster == 1)
  {
    RGBMatrix.drawPixel(Zeile, Spalte, Schwarz);
    if (Zeile < 7) Zeile++;
    RGBMatrix.drawPixel(Zeile, Spalte, PixelCursor);
    RGBMatrix.show();
    AnzahlKlicks ++;
  }

  // oben
  if (Taster == 2)
  {
    RGBMatrix.drawPixel(Zeile, Spalte, Schwarz);
    if (Spalte < 7) Spalte++;
    RGBMatrix.drawPixel(Zeile, Spalte, PixelCursor);
    RGBMatrix.show();
    AnzahlKlicks ++;
  }

  // unten
  if (Taster == 3)
  {
    RGBMatrix.drawPixel(Zeile, Spalte, Schwarz);
    if (Spalte > 0) Spalte--;
    RGBMatrix.drawPixel(Zeile, Spalte, PixelCursor);
    RGBMatrix.show();
    AnzahlKlicks ++;
  }

  // rechts
  if (Taster == 4)
  {
    RGBMatrix.drawPixel(Zeile, Spalte, Schwarz);
    if (Zeile > 0) Zeile--;
    RGBMatrix.drawPixel(Zeile, Spalte, PixelCursor);
    RGBMatrix.show();
    AnzahlKlicks ++;
  }
}

Startseite
Aufgaben A-Z
Suchen
Downloads
Fehlermeldungen
Seite als PDF

Ver­wand­te Aufgaben:


Letzte Aktualisierung: 1. Jan 2024 @ 19:43