rivisitazione e aggiornamento sketch coin hopper

Buonasera a tutti. Avendo un pò di tempo a disposizione in questo periodo mi sn messo a rivisitare lo sketch che grazie al vostro immenso aiuto , sono riuscito a far funzionare . Dunque si tratta di un coin hopper che ha un motorino a 12 volt e un sensore di passaggio monete (contaoggetti). Via seriale , arduino riceve un dato da un software windows (mamehooker) che per convenzione dello stesso software è composto da 1x . Mi spiego meglio , quando dal mamehooker invia per esempio 1x 1x 1x 1x , arduino mette in memoria 4 e comincia l'erogazione , quindi il countdown fino a tornare a 0 e far fermare di nuovo tutto. Mentre nel momento in cui non ci sono piu gettoni nella tramoggia c'è impostato un timer che , se dal sensore non ricevo nessun impulso , un buzzer suona e mi avvisa della mancanza dei gettoni , con conseguente print a lcd dei gettoni che non ha ancora erogato , facendomi cambiare il selettore della caduta delle monete direttamente nell hopper piuttosto che dal sensore per attivare la partita. Fin qui tutto ok. Adesso sto provando a inserire un matrix keypad 4x4 e una funzione di menù / password. Ho provato qualcosa ma è un bel pò ingarbugliato anche vista la mia totale inesperienza. Comunque l'idea sarebbe di poter avere un menu accessibile dalla lettera A del keypad . in questo menu mettere solo 2 sottomenu , ossia uno di modalità refill on/off (quella di quando mancano i gettoni ) senza dover inserire la password, e l'altro di erogazione di n. di gettoni (selezionando il numero sempre con il keypad e confermando con # o *) però questo con richiesta di password . Attualmente con lo sketch seguente ho il seguente risultato : funziona tutto bene , mi attiva la modalita refill quando finiscono i gettoni nella vasca e posso disattivarla dal keypad pero sempre e solo inserendo prima la password. riesco a erogare n gettoni ( da 1 a 9 mentre vorrei avere la possibilità di aumentare anche fino a 20 50 90 ecc ) e comunque e sempre devo inserire la password per ogni richiesta che vado a fare con keypad. Aiuti ? idee? P.s non mi dite niente se lo sketch è un garbuglio generale ... ma almeno mi funziona :smiley:

#include <LiquidCrystal.h>
LiquidCrystal lcd(13, 3, 4, 5, 6, 7);
#include <Keypad.h>
#include <Password.h>
Password password = Password( "1234" );
const int optoPin = 11; //questo è il pin a cui è collegato l'optoswitch
const int relePin = 2;
const int buzzerPin = 12;
const int relePinRefill = 8;
int pin;
int value;
bool optoState; //stato dell'opto
bool lastOptoState; //stato precedente dell'opto
int coins = 0;
unsigned long startTime;

#define TIMEOUT 10000
#define BUZTIME 100

const byte ROWS= 4; //number of rows on the keypad i.e. 4
const byte COLS= 4; //number of columns on the keypad i,e, 3
char keys[ROWS][COLS]=
{
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS]= {9, 10, 19, 18}; //Rows 0 to 3
byte colPins[COLS]= {14, 15, 16, 17}; //Columns 0 to 3
// command for library forkeypad
//initializes an instance of the Keypad class
Keypad keypad= Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

void setup() {
  // imposta il numero di colonne e righe del display utilizzato:
  lcd.begin(16, 2);
  pinMode(buzzerPin, OUTPUT);
  pinMode(optoPin, INPUT_PULLUP);
  pinMode(relePin, OUTPUT);
  pinMode(relePinRefill, OUTPUT);
  digitalWrite(relePin, HIGH);
  digitalWrite(relePinRefill, LOW);
  Serial.begin(9600); //inizio comunicazione seriale
  optoState = digitalRead(optoPin);
  digitalWrite(buzzerPin, HIGH);
      delay(500);
      digitalWrite(buzzerPin, LOW);
  lcd.setCursor(0, 0);
      lcd.print("LaBucciata  Slot");
      delay(5000);
      lcd.setCursor(0, 1);
      lcd.print("Configurazione..");
      delay(500);
      lcd.begin(16, 2);
      lcd.setCursor(5, 0);
      lcd.print("Ready");
      delay(400);
      digitalWrite(buzzerPin, HIGH);
      delay(200);
      digitalWrite(buzzerPin, LOW);
      delay(200);
      digitalWrite(buzzerPin, HIGH);
      delay(200);
      digitalWrite(buzzerPin, LOW);
      lcd.begin(16, 2);
      keypad.addEventListener(keypadEvent);
      }
      
void loop() {
  keypad.getKey();
  checkForCredits1();
  releaseTokens();
  tokensCountDown();
 
  }
  void keypadEvent(KeypadEvent eKey){
  switch (keypad.getState()){
    case PRESSED:
  Serial.print("Pressed: ");
  Serial.println(eKey);
  switch (eKey){
    case '*': checkPassword(); break;
    case '#': password.reset(); break;
    default: password.append(eKey);
     }
  }
}

void checkPassword(){
  checkForCredits2:
char keypressed = keypad.getKey();
     if (keypressed != NO_KEY)
     {
      coins = (keypressed) - 48;
      }
         if (Serial.available())
       {
          coins = Serial.read();
          Serial.flush();
          Serial.begin(9600);
          }
          if (keypressed == 'A')
     {
          value = 0;
          coins = 0;
          Serial.println("refill-mode") ;
          digitalWrite(relePinRefill, HIGH);
          }
          if (keypressed == 'D')
          {
          value = 0;
          coins = 0;
          digitalWrite(relePinRefill, LOW);
          Serial.begin(9600);
           }
  if (password.evaluate()){
    Serial.print("Success");
    Serial.flush();
    goto checkForCredits2;
    }else{
    Serial.println("Wrong");
    //add code to run if it did not work
  }
}
void checkForCredits1() {
  while (Serial.available() > 0) {
    value = Serial.parseInt();
    if (Serial.read() == 'x') {
      if (value > 0) {
        coins ++;
        Serial.flush();
        Serial.begin(9600);
        }
        }
        }
        }
 void releaseTokens() {
  if (coins > 0) {
    // Se il motore è fermo, memorizzo il momento in cui parte.
    // In questo modo mi assicuro di impostare la variabile solo al fronte di salita di relePin
    if(digitalRead(relePin) == HIGH){
      startTime = millis();
    }
    digitalWrite(relePin, LOW); //rilascio gettoni
    optoState = digitalRead(optoPin);
    }
  else {
    digitalWrite(relePin, HIGH);//STOP rilascio gettoni
    lcd.setCursor(0, 0);
    lcd.print("LaBucciata Slot $ $ Buona Fortuna $ $");
    delay(400);
    for (int positionCounter = 0; positionCounter < 1; positionCounter++) {
      lcd.scrollDisplayLeft(); 
    }
    
    
  }
 
  // Solo se il motore è ancora acceso, dopo 10 secondi dall'attivazione, resetto l'uscita  
  if(digitalRead(relePin) == LOW){
    if(millis() - startTime > TIMEOUT ){
      digitalWrite(relePin, HIGH); //STOP rilascio gettoni
      digitalWrite(buzzerPin, HIGH);
      lcd.begin(16, 2);
      lcd.setCursor(5, 0);
      lcd.print("refill");
      digitalWrite(relePinRefill, HIGH);
      delay(3000);
      lcd.begin(16, 2);
      lcd.setCursor(0, 0);
      lcd.print("gettoni mancanti:");
      delay(1000);
      lcd.setCursor(13, 1);
      lcd.println(coins);
      coins = 0;
      digitalWrite(buzzerPin, LOW);
      lcd.begin(16, 2);
      }
  }
 
}
 
void tokensCountDown() {
  if (optoState != lastOptoState) { // se lo stato dell'opto è cambiato (cioè qualcosa sta passando, in entrata o uscita)
    lastOptoState = optoState;
    delay (100); //debounce "economico" (questo serve perchè nel passaggio di stato possono esserci fluttuazioni che portano a conteggi errati)
    if (lastOptoState == LOW && coins > 0) {
      coins = coins - 1 ; //decremento gettoni
      startTime = millis(); //reset timer
      
    }
  }
}

Piccolo edit. Modificando qualcosa allo sketch sono riuscito adesso a impostare la modalita refill on / off senza dover chiedere la password , e sono riuscito adesso a fare l'erogazione dopo aver inserito la password , adesso in teoria mi mancherebbe costruire una sorta di menu visualizzabile a display lcd. Più tardi , appena torno a casa posto il nuovo sketch. Grazie ancora .