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
#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
}
}
}