Contatore volumetrico per liquidi

Ci sono degli errori nello sketch. (che tra l'altro devi scrivere con i tag CODE - vedi punto 7 del regolamento)

const int impulso = 52; // suppongo sia un'Arduino MEGA
int contatore = 0;
int val = 0;  // non è usato nello sketch
int old_counter = 0;

void setup() {
  pinMode(impulso, INPUT);
  Serial.begin(9600);
}

void loop() {
 old_counter = contatore;
   if(digitalRead(impulso) == HIGH){
      contatore ++;
   }
   
   if(contatore > old_counter) {
      Serial.println(contatore);
   }
   // delay(500);

}

Com'è fatto il circuito?
Potrebbe servire una resistenza di pull'up o pull'down, altrimenti legge anche se ci passi la mano vicino.

Si..inizialmente era un arduino mega, poi sono passato ad un arduino due!
Il val=0 hai ragione, era in più, l'avevo utilizzato in precedenza ma poi ho effettuato delle modifiche e lho dimenticato! :smiley:

Mi risulta difficile farti vedere il collegamento, non ho immagini. Comunque ho collegato il tutto su una basetta alimentando anche il sensore di portata in quanto mi richiedeva una certa alimentazione (se non ricordo male max 30v e 0.2 A).

Quindi secondo te il problema dei valori continui è solamente dato dalla mancanza di resistenze??

e se provassi ad utilizzare una funzione pulseIN??
Cosi avrei la portata in litri al secondo che è proprio quella che mi viene richiesta.
Con lo sketch scritto in precedenza invece mi calcolavo solamente i litri (che venivano conteggiati ad ogni impulso) mentre potrei scrivere si i litri, ma anche quanti secondi passano da un impulso ad un altro! Che dite, è fattibile come cosa?

Se l'alimentazione del sensore è separata ricordati di mettere i gnd in comune... Se non usi resistenze di pull-down, puoi usare la pull-up interna invertendo la logica... più o meno così:

const int impulso = 52; // suppongo sia un'Arduino MEGA
int contatore = 0;
// int val = 0;  // non è usato nello sketch
int old_counter = 0;

void setup() {
  pinMode(impulso, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {
 old_counter = contatore;
   if(digitalRead(impulso) == LOW){
      contatore ++;
   }
   
   if(contatore > old_counter) {
      Serial.println(contatore);
   }
   // delay(500);

}

Grazie a tutti per le dritte...domani avrò l'attrezzatura a disposizione e sperando di non fare danni con i collegamenti elettrici, vi saprò dire di più...!! :stuck_out_tongue: :stuck_out_tongue: Spero che riesca a contare qualcosa, poi vi chiederò informazioni in più riguardo alla lettura del tempo! :zipper_mouth_face: :zipper_mouth_face:

Attento che l'Arduino DUE funziona a 3V3. Se gli arriva il segnale diretto del sensore a 30V si brucia.
Qual'è la sigla del sensore? Hai il datasheet?

Per la lettura dei litri al secondo puoi usare gli interrupt ne più ne meno di come si usano per calcolare gli RPM dei motori.
Ci sono tanti esempi sul forum.

attenzione, mi sembra, che dopo un po' (40 giorni circa?)arduino si resetta , ma questo te lo diranno gli specialisti del software, io sono ancora agli inizi.

Non è che Arduino si resetti, se utilizzi la funzione millis() dopo un paio di mesi va in overflow e ritorna a zero, per cui se non gestisci correttamente il confronto, la condizione affinchè la tua funzione periodica venga effettuata viene a mancare, e quindi lo sketch non funziona correttamente. Se cerchi nel forum ci sono diverse discussioni su questo.

I contatori più diffusi sono solitamente a turbina con un reed che chiude il contatto ogni X litri, in base alla caratteristiche descritte nel data sheet. Attenzione perchè se interrompi il flusso mentre il contatto è chiuso, questo resterà in tale stato finchè non ci sarà un ulteriore passaggio di liquido e sposterà il magnete del reed.
Ci sono contatori più costosi che lavorano ad ultrasuoni ed hanno maggiore precisione e non sono soggetti a sporcamenti o blocchi meccanici, ma non credo ci siano queste necessità....

Per Paolo
No, non ho nessuna caratteristica tecnica del sensore. Non ne ho trovate su internet. Comunque ho un foglietto (che è attaccato al connettore digitale) che dice quanto detto in precedenza max 30V e 0,2 A.

Il misuratore è di tipo a turbina, ovvero ogni litro di fluido passato, viene emesso un impulso di +5v (verificato con un alimentatore collegato al sensore stesso). Adesso cercherò sul forum per quanto riguardi il giri del motore con gli interrupt e successivamente farò la prova. Grazie mille a tutti per l'aiuto! :smiley: :wink:

----Ho detto una stro****a...l'impulso è in corrente...circa 0,05 A (molto ballerino)!

Ad esempio --> Arduino Playground - ReadingRPM

Domanda magari stupida: non è che i dati che tu riporti siano i valori massimi accettabili dal reed?
Come lo colleghi il sensore? se è a turbina trovo che l'alimentazione sia superflua, ma magari mi sbaglio.

poi vi chiederò informazioni in più riguardo alla lettura del tempo! :zipper_mouth_face: :zipper_mouth_face:

Prima di pensare al prossimo aiuto da chiedere, potevi anche sistemare il tuo post, includendo il codice nei tag appositi così come ti aveva fatto presente Paolo, eh...

Scusami Leo, non sapevo si potesse fare in "postproduzione", non pratico molto i forum. Starò più attento la prossima volta.

Comunque, ho provato a modificare il mio codice come mi facevate presente, ma nada, nisba, non va. O meglio, quando apro il monitor seriale continua a dare valori crescenti in funzione del delay utilizzato. Conta a priori qualcosa.

Ho provato comunque a modificare un po' il codice utilizzando gli interrupt, però adesso sono senza arduino e quindi non ho la possibilità di testarlo. Vi posto alla fine il risultato. Mi scuso già da adesso se ho scritto qualche castroneria, ma mi sto cimentando da poco con questo linguaggio. :blush:

Per quello che riguarda invece l'alimentazione, collegando un apposito alimentatore che permette di leggere anche dei segnali in ingresso, ho notato che al passaggio del litro di acqua, arriva effettivamente un impulso sotto forma corrente (se non sbaglio un valore variabile intorno a 0.05 A). Questo non vuol dire nulla? cioè devo comunque usare il tutto senza alimentazione??
PS ho trovato su internet uno sketch che legge un segnale in ingresso, tramite un pulsante, accendendo il led sul pin 13 di arduino mega. Essendoci anche lo schema disegnato con fritzing, ho provato a collegare il mio sensore di portata al posto del pulsantino e lanciando lo stesso programma. Mi aspettavo che al passaggio del litro, e quindi all'invio dell'impulso, si accendesse il led, ma anche questa volta non va. Non saprei come risolverlo.

Se posso aggiungere un collegamento ad un link esterno vi faccio vedere come è realizzato il collegamento.

int impulso=52;
long tempo_trascorso;
long durata;
volatile int contatore = LOW ;

   void routine_di_servizio ()
        {
           durata=millis()-tempo_trascorso;
           tempo_trascorso=millis();
        }

    void setup()
    {
         pinMode(impulso, OUTPUT);
         attachInterrupt (0,conta,RISING);
         attachInterrupt (0,routine_di_servizio,RISING);
 
           Serial.begin( 9600 );
           Serial.println( "Misuratore portata: ");
    }

    void loop()
    {
    digitalWrite (impulso,contatore);
    }

     void conta() 
         {
         contatore ++;
         }

:slight_smile: :slight_smile:

Non preoccuparti gold. Come si dice, melius abundare quam deficere!
Proverò subito allora e comunque il disegno è stato semplice, ma veramente esaustivo! XD XD

wardog:
Per Paolo
No, non ho nessuna caratteristica tecnica del sensore. Non ne ho trovate su internet. Comunque ho un foglietto (che è attaccato al connettore digitale) che dice quanto detto in precedenza max 30V e 0,2 A.

Il misuratore è di tipo a turbina, ovvero ogni litro di fluido passato, viene emesso un impulso di +5v (verificato con un alimentatore collegato al sensore stesso). Adesso cercherò sul forum per quanto riguardi il giri del motore con gli interrupt e successivamente farò la prova. Grazie mille a tutti per l'aiuto! :smiley: :wink:

Ciao, occhio che la DUE non può accettare i 5V, anche i segnali analogici devono essere entro i 3,3V dell'alimentazione, così rischi di fare danni! Dovrai implementare un partitore resistivo o usare un chip per la conversione di tensione IN/OUT .

goldx +1 meritatissimo

se dici valori pericolosi sembra salti tutto, invece resta indeterminato lo stato. Per la due circuito identico ma usa il pin 3v al posto di 5v

manuelc:
Guardando un po' in giro... i prezzi vanno da 13 euro a ... parecchie centinaia fino ad arrivare a oltre 1000 euro per caratteristiche simili. A cosa può essere dovuto tale differenza?

La qualità, l'affidabilità, la durata.

lesto:
goldx +1 meritatissimo

se dici valori pericolosi sembra salti tutto, invece resta indeterminato lo stato. Per la due circuito identico ma usa il pin 3v al posto di 5v

credo si riferisse alla resistenza di 1,5 K messa li, serve a limitare la corrente assorbita dal switch, per 5V e 1,5K sarebbero intorno a 3,3 mA se non mi fallisce la memoria della legge di ohm, mentre tu stai indicando la funzione della resistenza da 10K che farebbe da pull down per il switch no? con 10K proteggi molto bene il pin digitale.

Ma prima si parlava che il sensore mandava in uscita 5V, e se usato sulla DUE sarebbe un problema, dovrebbe usare un partitore resistivo per "condizionarlo" a 3,3V della DUE, no? adesso di un switch, forse mi sono perso qualcosa, mmmm...

dallo schema è uno switch, quindi credo che la storia sui 5V sia stato un fraintendimento..

Ciao a tutti. Rieccomi qui. Scusate se non vi ho più risposto, ma sono stato un po' impegnato.
Paolo, ho provato il tuo collegamento. Va una bomba. Grazie mille.

Ho implementato un mio sketch, utilizzando gli interrupt. Nella funzione attachInterrupt, ho utilizzato il RISING, quindi dovrebbe scattare l'interrupt quando il pin passa da LOW ad HIGH.

Nella chiamata dell'interrupt invece, ho utilizzato la seguente dicitura:

void cambia (){
              stato =!stato
              contatore++
            }

In questo modo conta qualcosa, ma quando scatta l'impulso, e quindi si accende il led (ho utilizzato quello del pin 13) la funzione conta due volte, in quanto prima si accende e poi si spegne. Quindi effettivamente legge un cambiamento di stato due volte. Come posso risolvere questo problema? :relaxed: Avevo pensato anche di ingannare il programma facendoli contare solamente i numeri pari o dispari, ma non saprei come fare apparte dividere per due e verificare se il resto è zero! ma non so se in questo caso può andare bene.

Mi affido a voi luminati della programmazione!!! :smiley: :smiley: :smiley:

l'operazione che ritorna il resto di una divisione vienedetta "modulo" e indicata con %, da non confondere con il VERO modulo matematico |x| che ritorna ilvalore di x sempre positivo, e che vine chiamato in programmazione "abs(x)" da absolute value

Però è una operazione lentissima. A me sembra che ti manchi un if

void cambia (){
  stato =!stato; //inverte il valore di stato
  if (stato) //se true
    contatore++; //aumenta il contatore
}

Grazie lesto. Quindi mettendo l'if in quel modo verrà considerato solamente quando il valore di state=TRUE e quindi ad esempio HIGH??

Perchè in precedenza avevo utilizzato un if, in questo modo qui

if(sensorValue<100){  
digitalWrite(Pin,HIGH);
}
else {
digitalWrite(Pin,LOW);
}
digitalWrite(Pin, stato);

e successivamente avevo utilizzato la chiamata dall'interrupt scritta in precedenza.
Al momento non posso provare il tutto, perchè sono lontano dal laboratorio dove sto sperimentando arduino, ma al piu presto proverò! grazie ancora! :wink: