RFID Reader - Hilfe benötigt

ich denke das LCD vom POS Terminal soll Teil des POS Terminals sein (so wie die Buttons):

https://wokwi.com/projects/327664466288181843

Habs mal auf 0x25 gegeben.

// https://forum.arduino.cc/t/rfid-reader-hilfe-benotigt/943475/259
// by noiasca

#include <LiquidCrystal_I2C.h>

class Button {                         // a simple class for buttons based on the "state change detection" example
    const byte buttonPin;
    static constexpr byte debounceDelay = 30;    // the debounce time; increase if the output flickers
    const bool active;                 // is the pin active HIGH or active LOW (will also activate the pullups!)
    bool lastButtonState = HIGH;       // the previous reading from the input pin
    byte lastDebounceTime = 0;         // the last time the output pin was toggled - we check only ONE byte, so I didn't mess around with unsigned long

  public:
    /**
       \brief constructor for a button

       The constructor takes the GPIO as parameter.
       If you omit the second parameter, the library will activate the internal pullup resistor
       and the button should connect to GND.
       If you set the second parameter to HIGH, the button is active HIGH. The button should
       connect to VCC. The internal pullups will not be used.

       \param attachTo the GPIO for the button
       \param active LOW (default) - if button connects to GND, HIGH if button connects to VCC
    */
    Button(byte attachTo, bool active = LOW) : buttonPin(attachTo), active(active) {}

    /**
       \brief set the pin to the proper state

       Call this function in your setup().
       The pinMode will be set according to your constructor.
    */
    void begin() {
      if (active == LOW)
        pinMode(buttonPin, INPUT_PULLUP);
      else
        pinMode(buttonPin, INPUT);
    }

    /**
        \brief indicate if button was pressed since last call

        @return HIGH if button was pressed since last call - debounce
    */
    bool wasPressed() {
      bool buttonState = LOW;                                        // the current reading from the input pin
      byte reading = LOW;
      if (digitalRead(buttonPin) == active) reading = HIGH;          // if we are using INPUT_PULLUP we are checking invers to LOW Pin
      if (((millis() & 0xFF ) - lastDebounceTime) > debounceDelay)   // If the switch changed, AFTER any pressing or noise
      {
        if (reading != lastButtonState && lastButtonState == LOW)    // If there was a change and and last state was LOW
        {
          buttonState = HIGH;
        }
        lastDebounceTime = millis() & 0xFF;
        lastButtonState = reading;
      }
      return buttonState;
    }
};

/* ein POS Terminal */
class POS {
  protected:
    Button btnAdd;            // Button zum hochzählen
    Button btnReduce;         // Button zum runterzählen
    Button btnEnter;          // Button zum bestätigen
    LiquidCrystal_I2C lcd;    // a LCD for the POS Terminal
    static const byte amountPerStep = 10;   // the default increase/decrease amount per button press
    static const byte clearAfter = 3;       // clear display after n seconds
    uint32_t previousMillis = 0;            // time management
    int currentCar = -1;      // das aktuelle Auto
    int amount = 0;           // current topup amount
    enum State {IDLE,         // auf ein Auto/Kunde warten
                ACTIVE,       // einen Kunden bedienen
                DIRTY         // Am Display steht was vom alten Kunden
                };
    State state;

  public:
    POS (byte addPin, byte reducePin, byte enterPin, byte lcdAddr, byte cols, byte rows) : btnAdd{addPin},  btnReduce{reducePin}, btnEnter{enterPin}, lcd(lcdAddr, cols, rows) {}

    void begin()
    {
      btnAdd.begin();
      btnReduce.begin();
      btnEnter.begin();
      lcd.init();                      // initialize the lcd
      // Print a message to the LCD.
      lcd.backlight();
      showIdle();
    }

    void start(int newCar)   // Übergabe der Car ID an die Terminal Klasse
    {
      if (state == IDLE || state == DIRTY)
      {
        currentCar = newCar;
        amount = 0;
        state = ACTIVE;
        showIdle();
        lcd.setCursor(0,1);
        lcd.print(F("topup car ")); lcd.print(newCar);
      }
      else
      {
        Serial.println(F("Session ist schon aktiv - kein neues Auto möglich"));
      }
    }

    void showIdle()
    {
      lcd.clear();
      lcd.print(F("    Kassaterminal"));
    }

    void showAmount()  // Ausgabe des gewählten Betrages am LCD
    {
      lcd.setCursor(0, 2);
      lcd.print(F("amount:             "));
      lcd.setCursor(7, 2);
      lcd.print(amount);
    }

    void update()
    {
      switch (state)
      {
        case IDLE:
          if (btnAdd.wasPressed() ) {
            Serial.println(F("add idle"));  // nur damit man sieht das sich was tut
            start(0); // nur Simulation Auto n geht zur Kassa.
          }
          if (btnReduce.wasPressed() ) {
            Serial.println(F("reduce idle"));
            start(1); // nur Simulation Auto n geht zur Kassa.
          }
          if (btnEnter.wasPressed() ) {
            Serial.println(F("enter idle"));
            start(2); // nur Simulation Auto n geht zur Kassa.
          }
          break;
        case ACTIVE:
          if (btnAdd.wasPressed()) {
            Serial.println(F("add pressed"));
            amount += amountPerStep;
            showAmount();
          }
          if (btnReduce.wasPressed()) {
            Serial.println(F("reduce pressed"));
            amount -= amountPerStep;
            if (amount < 0) amount= 0;
            showAmount();
          }
          if (btnEnter.wasPressed()) {
            Serial.println(F("Enter pressed"));
            int32_t saldo;
            // saldo = car[currentCar].getSaldo;        // aktuellen Saldo lesen, todo: getter fehlt vermutlich noch
            saldo += amount;
            // car[currentCar].setSaldo (saldo); 
            // irgend eine Ausgabe:
            lcd.setCursor(0, 2);
            lcd.print(F("Saldo neu        "));
            lcd.setCursor(10, 2);
            lcd.print(saldo);
            currentCar = -1; // auto löschen
            previousMillis = millis();
            state = DIRTY;
          }
          break;
          case DIRTY:
            if (millis() - previousMillis > clearAfter * 1000UL)  // löscht alte Displayausgabe nach einer bestimmten Zeit
            {
              showIdle();
              state = IDLE;
            }
          break;

      }
    }
};

POS pos{A0, A1, A2, 0x25, 20, 4};  // ein POS Terminal mit 3 Tasten und einem I2C LCD

void setup()
{
  Serial.begin(115200);
  pos.begin();
}

void loop()
{
  pos.update();
}