Pilotare elettrovalvole Arduino

Salve ragazzi,
cerco consigli/esempi per realizzare un progetto con Arduino.
Il progetto che vorrei realizzare consiste nel pilotare con Arduino uno un generatore di aria compressa a 12V e due elettrovalvola a solenoide 12V alimentate a 12V (le elettrovaolvola servono per gonfiare e sgonfiare un manicotto).
Ho inserito un regolatore di tensione a 9V per alimentare l'Arduino e uno switch per aprire e chiudere il circuito. Vi allego lo schema elettrico per vedere nel dettaglio la parte hardware.

Ho abbozzato uno sketch dove gonfio e sgonfio un manicotto tramite la pompa e le elettrovalvole, lasciando per il momento da parte il sensore di pressione.
Considerando che è la prima volta che utilizzo Arduino, aspetto vivamente consigli.
Grazie a tutti.

sketch_Prova.ino (696 Bytes)

Nuovo documento 2018-11-16 17.48.07_1.pdf (485 KB)

Ciao

beh lo sketch per adesso è molto semplice, ma già ben impostato :slight_smile:

quanto riguarda l'elettronica... come mai la scelta di non mettere nessun resistenza sulla base del transistor ?:slight_smile:

MD

Ciao Matteo,
essendo il mio primo progetto con Arduino non ho valutato l'inserimento delle resistenze.
Pensi che siano necessarie ed indispensabili?
Grazie

direi di proprio di si...

cerco di spiegarti il perchè :

tu stai cercando di usare (giustamente) il transistor come se fosse un relè... diciamo in modo On/Off...
nel mondo transistor chiamiamo : On-->saturato Off--> interdetto

ok, per saturate il transistor, per farla semplice, dobbiamo avere 2,5 V sulla base Vbe(sat) (dato preso da datasheet) , cosa che senza resistenza ora come ora gli stiamo dando 5 V... il doppio...

perciò dobbiamo "togliere" 2,5V perchè se 5V escono da arduino, 2,5V devono arrivare sulla base del transistor --> 2,5 V devono cadere sulla resistenza :slight_smile:

perciò la nostra resistenza serve per comandare correttamente il nostro transistor...

ti lascio questa guida che spiega come usare questi transistor con arduino :slight_smile:

e come vedi c'è una bella resistenza tra arduino e il tranistor :slight_smile:

Spero di averti chiarito un po' le idee, e di non aver detto troppe cavolate ahaha

MD

Grazie Matteo,
quindi se ho capito bene devo inserire una resistenza da 2.2kohm tra base del tip120 e ll pin di arduino.
Essendo 3 tip120 devo inserire 3 resistenze da 2.2kohm ciascuna? Corretto?

esatto ... ogni cavo che adesso parte da Arduino e va verso la base... gli metti una resistenza ... ogni singolo ramo :slight_smile:

MD

ok perfetto, grazie.

Se volessi aggiungere la funzione millis nello sketch e quindi gonfiar e sgonfiare ogni tot secondi come posso implementare il codice?

se è per fare delle prove, ti consiglio la funzione delay... ma se vuoi usare millis perchè poi ti serve più avanti averlo già implementato :

beh molto semplice.... potresti spulciare negli esempi-> digital -> Blink without Delay

:slight_smile:

se c'è qualcosa che non ti torna o non capisci chiedi pure :slight_smile:

MD

Grazie Matteo,
dovendo inserire il sensore di pressione che monitori appunto la pressione all'interno del manicotto, attraverso cui verranno pilotate le elettrovalvole e la pompa per raggiungere ed eventualmente mantenere una determinata pressione, forse è opportuno utilizzare millis come funzione in quanto utilizziamo tempi piccoli nel processo.
Cosa ne pensi?

dipende tutto da come deve funzionare il sistema... ovvero che funzione ha sto sensore?

conviene che ci spieghi come deve funzionare il tutto per poterti aiutare :slight_smile:

MD

Ziostep:
forse è opportuno utilizzare millis come funzione in quanto utilizziamo tempi piccoli nel processo

Al solito, non si tratta di millis vs delay, ma di struttura: Consiglio su come sostituire delay con millis - #11 by Claudio_FF - Software - Arduino Forum

Usare millis o piccoli delay dipende solo dalla precisione temporale che serve: realizzazione di un ascensore a 3 piani - #16 by Claudio_FF - Generale - Arduino Forum

Qui due esempi, uno con millis e uno con delay che fanno la stessa cosa, entrambi strutturati in modo da non bloccare mai l'esecuzione veloce del ciclo di loop: uso millis() - #31 by Claudio_FF - Software - Arduino Forum

Ragazzi grazie per i consigli e gli interventi, cerco di spiegare al meglio l'intero progetto così da poter chiarire le vostre idee.

Sto cercando di realizzare un manicotto dalla circonferenza di 16/20cm (simile allo sfigmomanometro della pressione arteriosa) da posizionare attorno al polso. Il manicotto tramite insufflazione di aria prodotta dalla pompa e fatta passare attraverso la prima elettrovalvola (range da 0-350 mmhg), fa espandere il manicotto esercitando una pressione attorno al polso (non devo misurare la pressione sanguigna, devo solo effettuare una compressione attorno al polso). Quindi la massima pressione attorno al polso è di 350mmhg.

Prima operazione da fare attraverso il sensore di pressione è conoscere la pressione all'interno del manicotto tale da poterla tenere costante per un top di tempo. Ovviamente non essendo tutti uguali i polsi il sensore deve lavorare in un range. Il sensore ancora non è stato scelto in quanto non so quale prendere.

Dopo aver raggiunto la pressione desiderata e mantenuta per un top di secondi, la seconda elettovalvola fa uscire l'aria dal manicotto inibendo la pompa.
In linea di massima il progetto è questo.

Grazie a tutti.

Ziostep:
cerco di spiegare al meglio l'intero progetto così da poter chiarire le vostre idee

Ok, hai descritto il tutto nei termini del dominio applicativo, ora riesci (in base a quanto hai descritto) a sintetizzare le diverse situazioni in cui si può venire a trovare il sistema con dei semplici nomi che le descrivono? Questi saranno gli stati del sistema (io ne vedo almeno cinque, il primo sicuramente è RIPOSO/IDLE).

Dopo di che ti basta decidere a quali eventi/condizioni prestare attenzione in ogni stato, e cosa fare quando l'evento accade (compreso eventualmente quale nuovo stato diventa attivo).

Ad esempio nello stato RIPOSO interessa solo avvertire il comando di avvio (pulsante/switch), e nel caso di comando attivato dare inizio al gonfiaggio rendendo attivo lo stato successivo (che sicuramente sarà GONFIA/INFLATE).

Ciao Claudio,
guarda nel mio primo post ho caricato già lo sketch riferito al gonfiare/sgonfiare considerando la posizione dello switch. E' semplice come codice ma son partito da li.

Non ho capito bene cosa intendi per suddividere per stati tutto il processo. Penso tu ti stia riferendo ad:
1 stato: riposo
Verificare la posizione dello switch

2 stato: Se lo switch si trova in alto
Allora attiva la pompa e gonfia

Ti riferisci ad un suddivisione degli eventi di questo tipo?

Ziostep:
guarda nel mio primo post ho caricato già lo sketch riferito al gonfiare/sgonfiare considerando la posizione dello switch. E' semplice come codice ma son partito da li.

Manca la lettura dello switch.

Non ho capito bene cosa intendi per suddividere per stati tutto il processo. Penso tu ti stia riferendo ad:
1 stato: riposo
Verificare la posizione dello switch

2 stato: Se lo switch si trova in alto
Allora attiva la pompa e gonfia

Ti riferisci ad un suddivisione degli eventi di questo tipo?

Quasi, il tuo codice è stateless e reattivo, quello che fa dipende direttamente e solo dall'ingresso, e non ha memoria di quello che eventualmente è stato fatto prima (le situazioni attraversate).

Per me gli stati che hai elencato nella descrizione sono:

  • IDLE (attesa comando)
  • INFLATE (gonfiaggio, attesa pressione alta)
  • PAUSE (pausa tot secondi, non so se serve fare anche un REFILL se la pressione scende)
  • DEFLATE (sgonfiaggio, attesa pressione bassa)

ed eventualmente un ulteriore stato di attesa WAIT_NO_COMMAND per aspettare che lo switch sia riportato in posizione disattiva e non ripartire subito con un nuovo gonfiaggio.

Si possono definire delle etichette di comodo:

#define   IDLE            0
#define   INFLATE         1
#define   PAUSE           2
#define   DEFLATE         3
#define   WAIT_NO_COMMAND 4

Una variabile globale per memorizzare lo stato, che parte da IDLE

byte state = IDLE;

E nel loop una struttura decisionale che elabora solo lo stato attivo in quel momento. È come avere diversi programmi (i casi) di cui uno solo alla volta viene eseguito, quello corrispondente alla situazione attuale del sistema indicata dalla variabile 'state':

switch(state)
{
    case IDLE:
        break;

    case INFLATE:
        break;

    case PAUSE:
        break;

    case DEFLATE:
        break;

    case WAIT_NO_COMMAND:
        break;
}

Quando siamo in IDLE l'unica cosa che interessa è sentire il comando di avvio:

   case IDLE:
        if(...lettura pin switch... == ...livello attivo...) {
            ...avvia gonfiaggio...
            state = INFLATE; // <--- nuovo stato attivo
            }
        break;

eccetera...

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.

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):

if(state == IDLE) {
}
else if(state == INFLATE) {
}
else if(state == PAUSE) {
}
else if(state == DEFLATE) {
}
else if(state == WAIT_NO_COMMAND) {
}

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.

sketch_Prova.ino (868 Bytes)

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.

Claudio_FF:
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.

sketch_Prova.ino (971 Bytes)