// Mit zwei Buttons werden die Resultate auf dem Display angezeigt. Zudem werden die Ergebnisse
// auf ein 2. Display gestreamt.

#include <MD_MAX72xx.h>
#include <SPI.h>
#include <WiFi.h>
#include <esp_now.h>
#include "myButton.h"

//die zwei Buttons mit einer eigenen Klasse damit nicht alles doppelt Programmiert werden muss
#define BTN_HOME  20                  // Eingänge für die 2 Buttons, können hier geändert werden
#define BTN_AWAY  21

ButtonSpielanzeige bHome(BTN_HOME);   //die 2 Buttons Objekte
ButtonSpielanzeige bAway(BTN_AWAY);   


// Panel einrichten
#define MAX_DEVICES 4
#define CLK_PIN   18
#define DATA_PIN  23
#define CS_PIN    5
MD_MAX72XX mx = MD_MAX72XX(MD_MAX72XX::FC16_HW, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

int scoreHome = 0;                  //Spielstände welche aktuell angezeigt werden
int scoreAway = 0;

//für Display Abschaltung nach einer Stunde..
bool displayOn = true;

// Zeichensatz (Ziffern 0–9), Zeilenweise definiert: digits[Ziffer][Zeile][Spalte]
// Zeichen sind nur 4 Spalten breit, es könnte auch mehr als 4 Zeichen dargestellt werden
const uint8_t digits[10][8][4] = {
  { // 0
    {0,1,1,0},
    {1,0,0,1},
    {1,0,0,1},
    {1,0,0,1},
    {1,0,0,1},
    {1,0,0,1},
    {1,0,0,1},
    {0,1,1,0}
  },
  { // 1
    {0,0,1,0},
    {0,1,1,0},
    {1,0,1,0},
    {0,0,1,0},
    {0,0,1,0},
    {0,0,1,0},
    {0,0,1,0},
    {1,1,1,1}
  },
  { // 2
    {0,1,1,0},
    {1,0,0,1},
    {0,0,0,1},
    {0,0,1,0},
    {0,1,0,0},
    {1,0,0,0},
    {1,0,0,0},
    {1,1,1,1}
  },
  { // 3
    {1,1,1,0},
    {0,0,0,1},
    {0,0,0,1},
    {0,1,1,0},
    {0,0,0,1},
    {0,0,0,1},
    {0,0,0,1},
    {1,1,1,0}
  },
  { // 4
    {0,0,1,0},
    {0,1,1,0},
    {1,0,1,0},
    {1,0,1,0},
    {1,1,1,1},
    {0,0,1,0},
    {0,0,1,0},
    {0,0,1,0}
  },
  { // 5
    {1,1,1,1},
    {1,0,0,0},
    {1,0,0,0},
    {1,1,1,0},
    {0,0,0,1},
    {0,0,0,1},
    {1,0,0,1},
    {0,1,1,0}
  },
  { // 6
    {0,1,1,0},
    {1,0,0,1},
    {1,0,0,0},
    {1,1,1,0},
    {1,0,0,1},
    {1,0,0,1},
    {1,0,0,1},
    {0,1,1,0}
  },
  { // 7
    {1,1,1,1},
    {0,0,0,1},
    {0,0,1,0},
    {0,0,1,0},
    {0,1,0,0},
    {0,1,0,0},
    {1,0,0,0},
    {1,0,0,0}
  },
  { // 8
    {0,1,1,0},
    {1,0,0,1},
    {1,0,0,1},
    {0,1,1,0},
    {1,0,0,1},
    {1,0,0,1},
    {1,0,0,1},
    {0,1,1,0}
  },
  { // 9
    {0,1,1,0},
    {1,0,0,1},
    {1,0,0,1},
    {0,1,1,1},
    {0,0,0,1},
    {0,0,0,1},
    {1,0,0,1},
    {0,1,1,0}
  }
};

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);

  esp_now_init();
  esp_now_peer_info_t peerInfo = {};
  memset(peerInfo.peer_addr, 0xFF, 6);
  peerInfo.channel = 1;
  esp_now_add_peer(&peerInfo);

  mx.begin();
  mx.control(MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
  mx.clear();

  showScore();
}

void loop() {
 

  bHome.check();                              //Auslesen ob Button grdückt wurde - 
  bAway.check();
  if (bHome.getScore() != scoreHome || bAway.getScore() != scoreAway){  // Prüfen ob sich Ergebnis geändert hat
    scoreHome = bHome.getScore();
    scoreAway = bAway.getScore();
    showScore();
  }

    //  Display ausschalten nach 1 Stunde (3600000 ms) - zum Testen 1 min
  if (displayOn && millis() - bHome.getLastChange() > 60000) { 
    mx.clear();
    mx.update();
    displayOn = false;
  }

  delay(50);      // sollte evtl. etwas wegen der Auslastung bringen - Wokwi zeigt aber das nicht an
}

const uint8_t colMap[32] = {                      // Panel Colums sind nicht von 0 - 31 ansprechbar..
  24,25,26,27,28,29,30,31,   // 1. Modul          // Damit frei geschrieben werden kann, richtige Reihenfolge
  16,17,18,19,20,21,22,23,   // 2. Modul
   8, 9,10,11,12,13,14,15,   // 3. Modul
   0, 1, 2, 3, 4, 5, 6, 7    // 4. Modul
};

void drawDigit(uint8_t digit, uint8_t digitOffset) {
  // Schreiben der Zahlen mit dem Zeichensatz und der richtigen Spaltenreihenfolge
 

  for (uint8_t row = 0; row < 8; row++) {
    for (uint8_t col = 0; col < 4; col++) {
      if (digits[digit][row][col]) {
        uint8_t mappedCol = colMap[digitOffset + col];
        mx.setPoint(row, mappedCol, true);
      }
    }
  }
}






void showScore() {
  displayOn = true;
  sendScore();      // senden an 2. Display

  mx.clear();

  uint8_t z4 = scoreHome / 10;      // Aufsplitung des Resultats
  uint8_t z3 = scoreHome % 10;
  uint8_t z2 = scoreAway / 10;
  uint8_t z1 = scoreAway % 10;

  drawDigit(z2, 20);              // genaues positionieren der Ziffern
  drawDigit(z1, 26);
  drawDigit(z4, 2);
  drawDigit(z3, 8);

  mx.update();
}
uint8_t broadcastAddress[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
void sendScore() {                                                        // Senden an 2. Display
  int scoreData[2] = { scoreHome, scoreAway };
  esp_now_send(broadcastAddress, (uint8_t*)scoreData, sizeof(scoreData));
  Serial.printf("📤 Sende Score: Heim=%d, Gast=%d\n", scoreHome, scoreAway);
}
Loading
esp32-c6-devkitc-1