Salve,quello che vorrei poter fare e' questo:
L'utente preme il tasto PET,e lo sketch esegue le sue operazioni. Ad un certo punto l'utente vuole arrestare questo ciclo,perche ha finito,e invece di aspettare lo scadere del timer,decide di premere il tasto PS,per poter eseguire la relativa parte dello sketch.
Ho inserito a fine ciclo while:
if (digitalRead(PET) == LOW)
break;
if (digitalRead(PS) == LOW)
break;
Ma non funziona.
I pin degli switch relativi,sono cosi' dichiarati:
pinMode(PET,INPUT_PULLUP);
pinMode(PS,INPUT_PULLUP);
Ecco il codice:
while (stato <1)
{
if (!smartcard.IsCardPresent(1))
stato=1;
duration =millis() - startTime;
if ( duration > Timeout)
{
stato = 1;
// Manda l'impulso solo se non l'ha già mandato prima
if (impulso_mandato == false)
{
Serial.println("BLOCCATO");
impulso_mandato = true;
}
}
else
{
// SCELTA PET
if (pulsantePremuto(PET) == true && giaPremuto == false)
{
stato = 1;
giaPremuto = true;
Serial.println("Scelta effettuata : PET");
apriportelloPET();
Contatore_PET=0;
contaPET();
}
//SCELTA PS
if (pulsantePremuto(PS) == true && giaPremuto == false)
{
stato = 1;
giaPremuto = true;
Serial.println("Scelta effettuata : PS");
// apriportelloPS();
Contatore_PS=0;
contaPS();
}
}
if (digitalRead(PET) == LOW)
break;
if (digitalRead(PS) == LOW)
break;
} // CHIUSURA CICLO WHILE
Tu vuoi uscire da un ciclo se è passato un certo tempo oppure al verificarsi di un evento.
A te serve un doppio controllo, un timeout per controllare il tempo ed un check su una condizione che vuoi verificare, ad esempio la pressione di un pulsante
Ho da poco scritto un articolo sui timeout, credo che ti potrà tornare utile.
leo72:
Tu vuoi uscire da un ciclo se è passato un certo tempo oppure al verificarsi di un evento.
A te serve un doppio controllo, un timeout per controllare il tempo ed un check su una condizione che vuoi verificare, ad esempio la pressione di un pulsante
leo72:
Tu vuoi uscire da un ciclo se è passato un certo tempo oppure al verificarsi di un evento.
A te serve un doppio controllo, un timeout per controllare il tempo ed un check su una condizione che vuoi verificare, ad esempio la pressione di un pulsante
Si,ma utilizzando il tuo metodo,dovrei reimpostare TUTTO il codice e nel mio caso non e' semplice......
Se vuoi fare la cosa con un timeout, devi cambiare un pò di codice, non tutto il codice
Devi cambiare i controlli, solo i blocchi dove fai la lettura dei comandi. La gestione degli stessi resta invariata.
if (digitalRead(PET) == LOW || digitalRead(PS) == LOW)
break;
Ciao Brado! Purtroppo non va,da quanto ho capito la variabile "giaPremuto" alla prima esecuzione diventa true e mai più false, quindi entrambi gli if di "pulsantePremuto"falliscono!Forse questo e' il problema? :~
Hai ragione, in quel pezzo di sketch non rimetti mai a false giaPremuto.
Ora che più o meno mi ricordo lo sketch completo, prima dell'uscita dalle sub ContaPET e ContaPS, prova a settare giaPremuto = false.
Brado:
Hai ragione, in quel pezzo di sketch non rimetti mai a false giaPremuto.
Ora che più o meno mi ricordo lo sketch completo, prima dell'uscita dalle sub ContaPET e ContaPS, prova a settare giaPremuto = false.
In che senso?Settarlo qui? (in questo caso ho settato giaPremuto da True a False)
Allora avevo capito bene,ma non c'e' la variabile giaPremuto in queste subroutine!
void contaPET() // Funzione che conta i pezzi del materiale PET,rilevati dal sensore
{
Timer = millis(); // PARTE IL TIMER
while((millis() - Timer) < Timeout) { // Mentre t < timeout
distance = Dist.getDistanceCentimeter(); // Acquisisci dati dal sensore
if (distance>=7) { // Se la distanza e' maggiore di 7,non contare
premuto = false;
}
if ((distance<7) && premuto == false) { // Se la distanza e'minore di 7 comincia a contare
Contatore_PET ++; // incrementa contatore
Timer = millis(); // timer partito/resettato
premuto = true;
Serial.print("Contatore PET: ");
Serial.println(Contatore_PET);
Scrivi_numero_pezzi(Contatore_PET); // Scrivi il numero di pezzi relativi al materiale PET,su SMARTCARD
}
if (!smartcard.IsCardPresent(1)) // Verifico presenza card <<< Modifica proposta
Timer = millis()+millis(); // Faccio scadere il timeout
}
}
Infatti la mettiamo.
Se giaPremuto l'hai dichiarata insieme alle costanti, all'inizio del listato, la puoi vedere in tutto lo sketch.
Quindi, secondo me, potresti provare così:
void contaPET() // Funzione che conta i pezzi del materiale PET,rilevati dal sensore
{
Timer = millis(); // PARTE IL TIMER
while((millis() - Timer) < Timeout) { // Mentre t < timeout
distance = Dist.getDistanceCentimeter(); // Acquisisci dati dal sensore
if (distance>=7) { // Se la distanza e' maggiore di 7,non contare
premuto = false;
}
if ((distance<7) && premuto == false) { // Se la distanza e'minore di 7 comincia a contare
Contatore_PET ++; // incrementa contatore
Timer = millis(); // timer partito/resettato
premuto = true;
Serial.print("Contatore PET: ");
Serial.println(Contatore_PET);
Scrivi_numero_pezzi(Contatore_PET); // Scrivi il numero di pezzi relativi al materiale PET,su SMARTCARD
}
if (!smartcard.IsCardPresent(1)) // Verifico presenza card <<< Modifica proposta
Timer = millis()+millis(); // Faccio scadere il timeout
}
giaPremuto=false;
}
Niente da fare,ti allego la parte dello sketch interessata con le subroutine e le modifiche effettuate!Quando seleziono ad esempio PET,comincia a conteggiare,se premo il tasto PS,dovrebbe fermarsi la conta di PET e cominciare quella di PS,ma non va!
if ((VAL_CTRL1==LOW) || (VAL_CTRL2==LOW)) { // simulazione errori tramite i pulsanti
Serial.println("Attenzione!Errore!");
}
else {
Serial.println ("Effettua la scelta del materiale da conferire entro 10 secondi..");
// Parte il conto alla rovescia per la scelta del materiale da conferire:
impulso_mandato = false;
giaPremuto = false;
stato=0;
while (stato <1)
{
if (!smartcard.IsCardPresent(1))
stato=1;
duration =millis() - startTime;
if ( duration > Timeout)
{
stato = 1;
// Manda l'impulso solo se non l'ha già mandato prima
if (impulso_mandato == false)
{
Serial.println("BLOCCATO");
impulso_mandato = true;
}
}
else
{
// SCELTA PET
if (pulsantePremuto(PET) == true && giaPremuto == false)
{
stato = 1;
giaPremuto = true;
Serial.println("Scelta effettuata : PET");
apriportelloPET();
Contatore_PET=0;
contaPET();
}
//SCELTA PS
if (pulsantePremuto(PS) == true && giaPremuto == false)
{
stato = 1;
giaPremuto = true;
Serial.println("Scelta effettuata : PS");
// apriportelloPS();
Contatore_PS=0;
contaPS();
}
}
if (digitalRead(PET) == LOW || digitalRead(PS) == LOW)
break;
}
}
} // CHIUSURA PARENTESI if ascii
else
{
//Se la simcard non e' riconosciuta,spegni il led
digitalWrite(2, LOW);
Serial.println("Simcard non valida!");
Serial.println();
}
chiudiportelloPET(); // Chiude portello PET quando si estrae la scheda.
Serial.print("Estrarre la SIMCARD,Grazie...");
Serial.println();
smartcard.PowerOffSC();
//wait smartcard extraction
while(smartcard.IsCardPresent(1)){
delay(500);
}
Serial.println("Operazione conclusa");
Serial.println();
} // Fine LOOP
///////////////////////////////////////////////////////////////////////
void apriportelloPET () // Funzione per l'apertura del portello PET
{
digitalWrite (Rele_PET,HIGH); // pin 9
Serial.print("PREGO CONFERIRE PET");
Serial.println();
}
void chiudiportelloPET () // Funzione per la chiusura del portello PET
{
digitalWrite (Rele_PET,LOW); // pin 9
}
void contaPET() // Funzione che conta i pezzi del materiale PET,rilevati dal sensore
{
Timer = millis(); // PARTE IL TIMER
while((millis() - Timer) < Timeout) { // Mentre t < timeout
distance = Dist.getDistanceCentimeter(); // Acquisisci dati dal sensore
if (distance>=7) { // Se la distanza e' maggiore di 7,non contare
premuto = false;
}
if ((distance<7) && premuto == false) { // Se la distanza e'minore di 7 comincia a contare
Contatore_PET ++; // incrementa contatore
Timer = millis(); // timer partito/resettato
premuto = true;
Serial.print("Contatore PET: ");
Serial.println(Contatore_PET);
Scrivi_numero_pezzi(Contatore_PET); // Scrivi il numero di pezzi relativi al materiale PET,su SMARTCARD
}
if (!smartcard.IsCardPresent(1)) // Verifico presenza card <<< Modifica proposta
Timer = millis()+millis(); // Faccio scadere il timeout
}
giaPremuto=false;
}
void contaPS()
{
Timer = millis(); // PARTE IL TIMER
while((millis() - Timer) < Timeout) { // Mentre t < timeout
distance1 = Dist1.getDistanceCentimeter(); // Acquisisci dati dal sensore
if (distance1>=7) { // Se la distanza e' maggiore di 7,non contare
premuto = false;
}
if ((distance1<7) && premuto == false) { // Se la distanza e'minore di 7 comincia a contare
Contatore_PS ++; // incrementa contatore
Timer = millis(); // timer partito/resettato
premuto = true;
Serial.print("Contatore PS: ");
Serial.println(Contatore_PS);
Scrivi_numero_pezzi(Contatore_PS); // Scrivi il numero di pezzi relativi al materiale PS,su SMARTCARD
}
if (!smartcard.IsCardPresent(1)) // Verifico presenza card
Timer = millis()+millis(); // Faccio scadere il timeout
}
giaPremuto=false;
}
bool pulsantePremuto(int pinPulsante)
{
// pulsante premuto
if (digitalRead(pinPulsante) == LOW)
{
delay(20); // ritardo antiribalzo
// conferma pulsante premuto
if (digitalRead(pinPulsante) == LOW )
{
//Pulsante premuto, ritorna true e ferma la funzione
return true;
}
}
//Nessun pulsante è stato premuto, la funzione ritorna false
return false;
}
Ok, diciamo che con la modifica inserita, se l'utente lasciasse scadere il timeout, potrebbe tornare a selezionare il pulsante differente rispetto a quanto fatto in precedenza.
Allora, bisogna inserire nel while presente nelle sub ContaPET e ContaPS il controllo sulla pressione dell'altro tasto.
void contaPET() // Funzione che conta i pezzi del materiale PET,rilevati dal sensore
{
Timer = millis(); // PARTE IL TIMER
while((millis() - Timer) < Timeout) { // Mentre t < timeout
distance = Dist.getDistanceCentimeter(); // Acquisisci dati dal sensore
if (distance>=7) { // Se la distanza e' maggiore di 7,non contare
premuto = false;
}
if ((distance<7) && premuto == false) { // Se la distanza e'minore di 7 comincia a contare
Contatore_PET ++; // incrementa contatore
Timer = millis(); // timer partito/resettato
premuto = true;
Serial.print("Contatore PET: ");
Serial.println(Contatore_PET);
Scrivi_numero_pezzi(Contatore_PET); // Scrivi il numero di pezzi relativi al materiale PET,su SMARTCARD
}
if (!smartcard.IsCardPresent(1)) // Verifico presenza card <<< Modifica proposta
Timer = millis()+millis(); // Faccio scadere il timeout
if (pulsantePremuto(PS) == true) {
//inserire e gestire il ritorno
}
}
giaPremuto=false;
}
L'ho fatto per PET, ovviamente in PS controllerai il tasto PET. Se poi dovrai inserire altri materiali, li metterai tutti.
Ora devi gestire il ritorno volontario, e non per timeout o assenza smartcard.
Credo che tu debba inserire un'ulteriore variabile di controllo.
Allora ci sono passi avanti,ho modificato lo sketch come segue,riesco a passare da un materiale all'altro,premendo gli appositi switch,il conteggio risulta esatto ma la scrittura degli stessi su smart card no.
Se inserisco la scheda,seleziono PET e poi la estraggo oppure faccio scadere il timeout,scrive correttamente,cosi' come se seleziono PS.. Il problema si pone se per esempio da PET passo a PS,il conteggio è esatto ma i punti accumulati su smart card risultano sballati!Forse mi sfugge qualcosa?Ecco il codice modificato!
if ((VAL_CTRL1==LOW) || (VAL_CTRL2==LOW)) // simulazione errori tramite i pulsanti
{
Serial.println("Attenzione!Errore!");
}
else
{
Serial.println ("Effettua la scelta del materiale da conferire entro 10 secondi..");
// Parte il conto alla rovescia per la scelta del materiale da conferire:
impulso_mandato = false;
giaPremuto = false;
stato=0;
while (stato <1)
{
if (!smartcard.IsCardPresent(1))
stato=1;
duration =millis() - startTime;
if (duration > Timeout)
{
stato = 1;
// Manda l'impulso solo se non l'ha già mandato prima
if (impulso_mandato == false)
{
Serial.println("BLOCCATO");
impulso_mandato = true;
}
}
else
{
// SCELTA PET
if (pulsantePremuto(PET) == true && giaPremuto == false)
{
stato = 1;
giaPremuto = true;
Serial.println("Scelta effettuata : PET");
apriportelloPET();
Contatore_PET=0;
contaPET();
}
//SCELTA PS
if (pulsantePremuto(PS) == true && giaPremuto == false)
{
stato = 1;
giaPremuto = true;
Serial.println("Scelta effettuata : PS");
// apriportelloPS();
Contatore_PS=0;
contaPS();
}
}
if (digitalRead(PET) == LOW || digitalRead(PS) == LOW)
break;
}
}
} // CHIUSURA PARENTESI if ascii
else
{
//Se la simcard non e' riconosciuta,spegni il led
digitalWrite(2, LOW);
Serial.println("Simcard non valida!");
Serial.println();
}
chiudiportelloPET(); // Chiude portello PET quando si estrae la scheda.
Serial.print("Estrarre la SIMCARD,Grazie...");
Serial.println();
smartcard.PowerOffSC();
//wait smartcard extraction
while(smartcard.IsCardPresent(1)){
delay(500);
}
Serial.println("Operazione conclusa");
Serial.println();
} // Fine LOOP
///////////////////////////////////////////////////////////////////////
void apriportelloPET () // Funzione per l'apertura del portello PET
{
digitalWrite (Rele_PET,HIGH); // pin 9
Serial.print("PREGO CONFERIRE PET");
Serial.println();
}
void chiudiportelloPET () // Funzione per la chiusura del portello PET
{
digitalWrite (Rele_PET,LOW); // pin 9
}
void contaPET() // Funzione che conta i pezzi del materiale PET,rilevati dal sensore
{
Timer = millis(); // Parte il timer
while((millis() - Timer) < Timeout) // Mentre t < timeout
{
distance = Dist.getDistanceCentimeter(); // Acquisisci dati dal sensore
if (distance>=7) // Se la distanza e' maggiore di 7,non contare
{
premuto = false;
}
if ((distance<7) && premuto == false) // Se la distanza e'minore di 7 comincia a contare
{
Contatore_PET ++; // incrementa contatore
Timer = millis(); // timer partito/resettato
premuto = true;
Serial.print("Contatore PET: ");
Serial.println(Contatore_PET);
Scrivi_numero_pezzi(Contatore_PET); // Scrivi il numero di pezzi relativi al materiale PET,su SMARTCARD
}
if (!smartcard.IsCardPresent(1)) // Verifico presenza card <<< Modifica proposta
Timer = millis()+millis(); // Faccio scadere il timeout
if (pulsantePremuto(PS) == true)
{ //inserire e gestire il ritorno
Serial.println("Fine conferimento PET,Selezionato PS");
chiudiportelloPET();
premuto = false;
Contatore_PS=0;
contaPS();
}
}
giaPremuto=false;
}
/* void apriportelloPS () // Funzione per l'apertura del portello PS
{
digitalWrite (Rele_PS,HIGH); // pin 9
Serial.print("PREGO CONFERIRE PS");
Serial.println();
}*
void chiudiportelloPS () // Funzione per la chiusura del portello PS
{
digitalWrite (Rele_PS,LOW); // pin 9
}
*/
void contaPS()
{
Timer = millis(); // Parte il timer
while((millis() - Timer) < Timeout) // Mentre t < timeout
{
distance1 = Dist1.getDistanceCentimeter(); // Acquisisci dati dal sensore
if (distance1>=7) // Se la distanza e' maggiore di 7,non contare
{
premuto = false;
}
if ((distance1<7) && premuto == false) // Se la distanza e'minore di 7 comincia a contare
{
Contatore_PS ++; // incrementa contatore
Timer = millis(); // timer partito/resettato
premuto = true;
Serial.print("Contatore PS: ");
Serial.println(Contatore_PS);
Scrivi_numero_pezzi(Contatore_PS); // Scrivi il numero di pezzi relativi al materiale PS,su SMARTCARD
}
if (!smartcard.IsCardPresent(1)) // Verifico presenza card
Timer = millis()+millis(); // Faccio scadere il timeout
if (pulsantePremuto(PET) == true)
{ // Gestione ritorno
Serial.println ("Hai premuto PET");
Serial.println("Fine conferimento PS,Selezionato PET");
//chiudiportelloPS();
premuto = false;
apriportelloPET();
Contatore_PET=0;
contaPET();
}
}
giaPremuto=false;
}
Se chiami contaPET o contaPS e basta, Scrivi_numero_pezzi scrive senza problemi sulla smartcard.
Se da contaPET passi a contaPS (o viceversa), Scrivi_numero_pezzi scrive solo il conteggio del primo materiale. Giusto ?
Secondo me gestendo così si genera un probabile casino, mi spiego meglio.
Poni che io sia un utente particolarmente bastardo e che non abbia nulla da fare.
Devo inserire 100 pezzi di pet e 100 di ps, ma decido di conferire un pet e poi passare ad un ps, per tornare al pet e passare ancora al ps, e così via ...
Non so se c'è un limite massimo di nidificazioni per le function.