Go Down

Topic: Pilotare elettrovalvole Arduino  (Read 1 time) previous topic - next topic

Ziostep

Grazie Claudio,
provo a scrivere lo sketch seguendo questo schema logico, essendo alle prime armi con Arduino non conoscevo queste funzioni, quindi grazie.

Caricherò lo sketch quanto prima, grazie per l momento.

Claudio_FF

#16
Nov 18, 2018, 12:18 pm Last Edit: Nov 18, 2018, 12:25 pm by Claudio_FF
Lo switch è come un if con tante scelte mutuamente esclusive, questo fa la stessa cosa, procedendo dall'alto al basso viene eseguito solo il primo ramo trovato vero (o nessuno se nessuna condizione risulta vera):
Code: [Select]
if(state == IDLE) {
}
else if(state == INFLATE) {
}
else if(state == PAUSE) {
}
else if(state == DEFLATE) {
}
else if(state == WAIT_NO_COMMAND) {
}
* * * * Una domanda ben posta è già mezza risposta * * * *

Ziostep

#17
Nov 18, 2018, 12:37 pm Last Edit: Nov 18, 2018, 12:39 pm by Ziostep
Grazie Claudio,
ti carico lo sketch così mi dici se ho capito quello che volevi dirmi e se sto facendo bene.
Grazie davvero.

P.s.: ho visto solo adesso questo tuo post, perdonami.

Claudio_FF

#18
Nov 18, 2018, 04:33 pm Last Edit: Nov 18, 2018, 04:36 pm by Claudio_FF
Manca sempre la digitalRead per leggere lo switch.

L'else (oltre che scritto sbagliato) non serve: nello stato IDLE non ci interessa sapere se lo switch è disattivo.

Volendo anche per dare dei nomi di comodo ai vari pin si possono usare le define, non serve a niente creare delle variabili a 16 bit da usare come costanti che occupano solo memoria.
* * * * Una domanda ben posta è già mezza risposta * * * *

Ziostep

#19
Nov 18, 2018, 04:51 pm Last Edit: Nov 18, 2018, 07:07 pm by Ziostep
Manca sempre la digitalRead per leggere lo switch.
Questa riga di comando non ho capito dove inserirla.

Non sono sicuro di aver scritto bene, inoltre, ho corretto lo sketch come dici tu.
Ovviamente è da finire lo sketch ma ho carico il file per vedere se scritto così è più corretto.

MatteoDerrico

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
Se una scrivania in disordine è segno di una mente disordinata, di cosa sarà segno allora una scrivania vuota?

Claudio_FF

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.
* * * * Una domanda ben posta è già mezza risposta * * * *

Ziostep

#22
Nov 19, 2018, 10:17 am Last Edit: Nov 19, 2018, 11:13 am by Ziostep
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... :smiley-roll-sweat:  :smiley-roll-sweat:

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.

Claudio_FF

#23
Nov 19, 2018, 11:14 am Last Edit: Nov 19, 2018, 11:20 am by Claudio_FF
Quote from: Ziostep
non riesco a capire bene come funzioni Switch/case in arduino
Come il codice del post #16

Quote
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à.
Code: [Select]
   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.
Code: [Select]
    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.
* * * * Una domanda ben posta è già mezza risposta * * * *

Ziostep

#24
Nov 19, 2018, 11:26 am Last Edit: Nov 19, 2018, 12:16 pm by Ziostep
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.

Claudio_FF

#25
Nov 19, 2018, 12:20 pm Last Edit: Nov 19, 2018, 12:22 pm by Claudio_FF
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.
* * * * Una domanda ben posta è già mezza risposta * * * *

Ziostep

Quindi devo seguire questa logica??

Claudio_FF

#27
Nov 19, 2018, 06:19 pm Last Edit: Nov 19, 2018, 06:26 pm by Claudio_FF
La logica è esattamente come la si descriverebbe in italiano:
Code: [Select]
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.
* * * * Una domanda ben posta è già mezza risposta * * * *

Ziostep

#28
Nov 19, 2018, 06:40 pm Last Edit: Nov 19, 2018, 07:25 pm by Ziostep
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.

Ziostep

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? :smiley-sweat:

Go Up