ciao ti consiglio di cambiare nome a IDLE, perchè come vedi si colora di blu da solo, ciò vuol dire che è un qualcosa di già utilizzato all'interno del core di Arduino.
Lascio la parola ai più esperti, però nel dubbio io cambierei il nome ![]()
MD
ciao ti consiglio di cambiare nome a IDLE, perchè come vedi si colora di blu da solo, ciò vuol dire che è un qualcosa di già utilizzato all'interno del core di Arduino.
Lascio la parola ai più esperti, però nel dubbio io cambierei il nome ![]()
MD
Ah, vero, c'è sempre il rischio di scrivere qualche nome già predefinito.
Si potrebbe cambiare in ONIDLE.
A parte un ; svista il resto è tutto corretto.
Grazie ragazzi,
ulteriore dubbio.
Nel passare dallo stato ONILDE --> INFLATE (INFLATE-->PAUSE ECC) non so scrivere il codice in quanto non riesco a capire bene come funzioni Switch/case in arduino...
![]()
Scusate ma sto facendo il massimo per capire il linguaggio nel più breve tempo possibile.
Grazie ancora.
P.s.: ho caricato lo sketch dove ho provato ad implementare lo stato WAIT_NO_COMMAND, non sono sicuro di aver fatto bene.
sketch_Prova.ino (2.63 KB)
Ziostep:
non riesco a capire bene come funzioni Switch/case in arduino
Come il codice del post #16
ho provato ad implementare lo stato WAIT_NO_COMMAND, non sono sicuro di aver fatto bene
Il caso WAIT_NO_COMMAND serve solo ad attendere che l'interruttore sia portato nello stato non attivo se per caso non lo è già.
case WAIT_NO_COMMAND:
if (digitalRead(SWITCHPIN) == LOW) state = ONIDLE;
break;
IL commento "stato che memorizza il case eseguito" sarebbe più corretto: "variabile che memorizza lo stato corrente", di fatto lo stato corrente corrisponde al case eseguito.
Se durante la pausa serve anche mantenere la pressione tramite "rabbocchi" allora bisogna aggiungere uno stato REFILL, e si potrà andare avanti e indietro diverse volte tra i due stati PAUSA e REFILL a seconda del valore letto della pressione.
Con la logica ci sei quasi, in ogni case un if corrisponde a un evento che si vuole gestire, e il contenuto dell'if alle azioni in risposta all'evento. Lo stop sgonfiaggio va dentro il caso DEFLATE, non dentro il WAIT_NO_COMMAND.
case DEFLATE:
if(raggiunta la pressione minima nel manicotto) { // <----EVENTO
digitalWrite(INTELVALVEPIN, LOW); // <----AZIONI
digitalWrite(PUMPPIN, LOW);
digitalWrite(EXAUSTVALVEPIN, LOW);
digitalWrite(LED, LOW);
state = WAIT_NO_COMMAND;
}
break;
Non serve (anzi non si deve) usare delay da nessuna parte, altrimenti l'esecuzione dei casi si blocca.
Grazie Claudio,
adesso il codice inizia ad essere più chiaro.
Inizio, finalmente, a comprendere anche la logica dello switch/case.
Continuo e cerco di inserire anche il codice per il sensore di pressione.
Grazie per il momento.
P.s.: Nel DEFLATE
digitalwrite(EXHASTVALVEPIN, HIGH); e non LOW altrimenti l'aria non esce e si blocca a quella pressione il tutto.
sketch_Prova.ino (2.83 KB)
Ziostep:
P.s.: Nel DEFLATE
digitalwrite(EXHASTVALVEPIN, HIGH); e non LOW altrimenti l'aria non esce e si blocca a quella pressione il tutto.
Nel DEFLATE le azioni vengono eseguite a sgonfiaggio già terminato (evento pressione zero).
L'avvio dello sgonfiaggio avviene quando nel PAUSE si rileva l'evento timeout.
Quindi devo seguire questa logica??
sketch_Prova.ino (3.09 KB)
La logica è esattamente come la si descriverebbe in italiano:
Quando sono in attesa (ONIDLE)
se comando attivo -> avvia gonfiaggio -> INFLATE
Quando sto gonfiando (INFLATE)
se pressione massima -> ferma gonfiaggio e
annota tempo attuale -> PAUSE
Quando sono in pausa (PAUSE)
se trascorsi N secondi -> avvia sgonfiaggio -> DEFLATE
altrimenti se pressione bassa -> avvia gonfiaggio -> REFILL
Quando sto rabboccando (REFILL)
se trascorsi N secondi -> avvia sgonfiaggio -> DEFLATE
altrimenti se pressione massima -> ferma gonfiaggio -> PAUSE
Quando sto sgonfiando (DEFLATE)
se pressione minima -> ferma sgonfiaggio -> WAIT_NO_COMMAND
Quando sto attendendo nessun comando (WAIT_NO_COMMAND)
se comando disattivo -> ONIDLE
Poi questa è una logica di partenza, su un sistema reale io vorrei poter interrompere il processo in qualsiasi momento, e far fronte ai guasti della sonda pressione (ad esempio aggiungendo dei timeout). Ma queste modifiche sono solo altre semplici righe descrittive da aggiungere ai "quando" (gli stati/situazioni), o altre situazioni, ad esempio uno stato ERROR.
Ovviamente devo aggiungere il sensore di pressione collegandolo al pin analogico.
Saranno modifiche che dovrò apportare in quanto deve funzionare in real-time il sistema e deve poter essere adattato alle situazioni.
Comunque grazie Claudio, essendo alle prime armi con Arduino devo prendere un po la mano.
Ciao Claudio,
seguendo la tua guida sto scrivendo così lo sketch ( in allegato).
Riscontro un bel problema sul come inserire il codice per il sensore e quindi mettere la condizione nello stato dell'if facente riferimento sempre al sensore.
Hai ulteriori direttive in merito? ![]()
sketch_Prova.ino (3.66 KB)
Usando nel programma parole italiane come attesa, gonfia, sgonfia, pausa non si correrebbe il rischio di creare conflitti con parole "proibite". Un francese non si sognerebbe nemmeno di scrivere parole in inglese! ![]()
Ciao DATMAN,
grazie per la direttiva, ma sembra che non ci siano parole proibite all'interno del codice...
Ma ho sostituito gli stati in italiano e anche il resto.
Allora si può scrivere proprio tutto in italiano, così la logica è perfettamente leggibile:
switch(stato)
{
case RIPOSO:
if (comando_attivo()) {
avvia_gonfiaggio();
stato = GONFIAGGIO;
}
break;
case GONFIAGGIO:
if(pressione_massima()) {
fermo();
annota_tempo();
stato = PAUSA;
}
break;
case PAUSA:
if(trascorsi(10000)) {
avvia_sgonfiaggio();
stato = SGONFIAGGIO;
}
else if(pressione_bassa()){
avvia_gonfiaggio();
stato = RABBOCCA;
}
break;
case RABBOCCA:
if(trascorsi(10000)) {
avvia_sgonfiaggio();
stato = SGONFIAGGIO;
}
else if(pressione_massima()){
fermo();
stato = PAUSA;
}
break;
case SGONFIAGGIO:
if(pressione_minima()) {
fermo();
stato = ATTENDI_NO_COMANDO;
}
break;
case ATTENDI_NO_COMANDO:
if (!comando_attivo()) stato = RIPOSO;
break;
}
Dopo di che restano da scrivere le brevi funzioncine che vengono richiamate (per quasi tutte credo basti una sola riga).
Sto facendo bene così???
sketch_Prova.ino (3.77 KB)
Devi mettere le condizioni pressione bassa, pressione massima, ...
Si lo so DATMAN,
volevo sapere se il resto era tutto corretto.
Inoltre, non avendo acquistato ancora il sensore il codice lo posso scrivere oppure devo tenere a mente casi particolari??
Ovviamente ho il datasheet del sensore che voglio usare, quindi so la Vcc,Vout e il range di pressioni in mmhg di utilizzo.
Grazie
Che cos'è:
sensorValue = analogRead (AnalogInPin); //annota pressione attuale
??
Da leggersi come:
quando sto gonfiando
se pressione massima
spegni valvole
annota pressione attuale
passa a pausa
Scusa Claudio non mi sono spiegato bene,
nello sketch è stato definito lo switch/case con i vari stati, fin qui tutto perfetto.
Devo dichiarare il sensore di pressione all'interno del codice ( non è stato ancora acquistato, mi serve un consiglio sull'acquisto). Vorrei acquistare un sensore con un buon range di misura, spendendo poco se possibile, tenendo a mente che le elettrovalvole hanno range di 0-350 mmhg.
Ti allego il link di quello che vorrei prendere ' Sensore di pressione Relativa MPX5700GP, pressione massima 700kPa '. Volutamente voglio prendere un sensore con un range maggiore dell' elettrovalvole oggi utilizzate per poter fare un UPGRADE futuro cambiando solo le elettrovalvole.
Negli STATI devo leggere la pressione presente all'interno del manicotto, tramite lettura del sensore di pressione, e passare da uno stato all'altro in funzione della pressione letta.
Se la pressione nello STATO è nel RangeMax allora si ferma il gonfiaggio, il RangeMax deve essere mantenuto per tot secondi e la pressione deve essere stampata sul computer.
Adesso posso passare allo STATO successivo.
Stavo cercando di scrivere proprio questo, pensavo che con " sensorValue = analogRead (AnalogInPin);" andavo a leggere il valore del sensore.
Spero di aver chiarito le idee
![]()
Ziostep:
Stavo cercando di scrivere proprio questo, pensavo che con " sensorValue = analogRead (AnalogInPin);" andavo a leggere il valore del sensore.
Si, la lettura è giusta, quello che chiedevo era il significato di metterla quel punto li, cioè in un punto dove significa: "quando è stata rilevata la pressione massima allora annoto la pressione". Mi domandavo se quella "annotazione" (ben diversa da quella che ho scritto io nelle spiegazioni precedenti) avesse uno scopo in previsione di qualcosa da implementare.
Per il resto la pressione basta leggerla prima dello switch (saranno da fare delle calibrazioni per far corrispondere le scale).
Se ho capito bene quello che vuoi dire è:
case GONFIAGGIO:
if(analogRead (AnalogInPin)>=Pmax) { // leggo la pressione e la confronto con il valore
digitalWrite(INTELVALEPIN, LOW); //smetto di gonfiare
digitalWrite(PUMPPIN, LOW);
stato = PAUSA; //passo allo stato successivo
}
break;
Ovviamente io vorrei sapere se la pressione è di 302/310/306, vorrei stamparla a video sul computer ma non so scrivere il codice, inoltre, la lettura della pressione non ho capito se va fatta in PAUSA.
Non so se sia giusto quello che ho scritto sopra.
grazie Claudio