utilizzo di un flussometro

Buonasera ragazzi :) ho questo flussometro dove ha 3 pin. due di alimentazione e uno, il giallo, quello del segnale.

allora ho trovato in rete questo sketch:

int ingresso = 2;   //Piedino di ingresso del flussostato
double flusso;      //Quantità di acqua che scorre
volatile int count; //Variabile di conteggio

void setup() {
  pinMode (ingresso, INPUT);  //Imposta piedino 2 in ingresso
  attachInterrupt (0, impulso, RISING);  //Configura interrupt 0 pin 2
  Serial.begin (9600);  //Velocità seriale
}

void loop() {
  count = 0;      //Resetta il conteggio
  interrupts();   //Abilita gli interrupt
  delay (1000);   //Pausa di 1 secondo
  noInterrupts(); //Disabilita gli interrupt

  flusso = (count * 2.25);  //2.25mL per ogni impulso
  flusso = flusso * 60;     //Trasforma i secondi in minuti
  flusso = flusso / 1000;   //Trasforma i mL in litri
  Serial.print (flusso);    //Scrive a schermo la variabile flusso
  Serial.println ("L/min");
}

void impulso() {
  count = count + 1;   //Incrementa count di 1
}

E funziona...il punto è: a me non interessa sapere la portata che ha in quel momento, ma quanta acqua passa da quando l'elettrovalvola si attacca fino a quando si spegne. Però non ho idea di come incrementare questo sketch per risolvere il mio problema..

Trovato sempre in rete link

Ho utilizzato l'esempio 1 del tuo link, penso che è quello che mi interessi....online ho trovato le caratteristiche del mio flussometro ovvero:

Features:

Model: YF-S201
Sensor Type: Hall effect
Working Voltage: 5 to 18V DC (min tested working voltage 4.5V)
Max current draw: 15mA @ 5V
Output Type: 5V TTL
Working Flow Rate: 1 to 30 Liters/Minute
Working Temperature range: -25 to +80℃
Working Humidity Range: 35%-80% RH
Accuracy: ±10%
Maximum water pressure: 2.0 MPa
Output duty cycle: 50% +-10%
Output rise time: 0.04us
Output fall time: 0.18us
Flow rate pulse characteristics: Frequency (Hz) = 7.5 * Flow rate (L/min)
Pulses per Liter: 450
Durability: minimum 300,000 cycles
Cable length: 15cm
1/2" nominal pipe connections, 0.78" outer diameter, 1/2" of thread
Size: 2.5" x 1.4" x 1.4"

e questo è lo sketch di cui non ci capisco molto:

byte sensorInterrupt = 0;  // 0 = digital pin 2
#define FlowMeterPulsePerSecondPerLiter 6.9
//#define FlowMeterPulsePerSecondPerLiter 7.5

volatile float PreviousPulseTime;
volatile float PulseDuration;
float LPM;
float averageLPM;
float CumulativeLPM;
float averageCount;
int LPMdecimal;

void setup() 
  {
  Serial.begin(115200);  
  PreviousPulseTime = 0;
  PulseDuration     = 0;
  LPM               = 0;
  averageLPM        = 0;
  averageCount      = 0;
  CumulativeLPM     = 0;
  LPMdecimal        = 2;
  attachInterrupt(sensorInterrupt, pulseCounter, CHANGE);
  }

void loop() 
  {

  CalculateFlow1();

  }

void CalculateFlow1()
  {
  CumulativeLPM = CumulativeLPM + (500/(PulseDuration*FlowMeterPulsePerSecondPerLiter)); 
  averageCount ++; averageLPM = CumulativeLPM/averageCount;
  if (averageCount >10000) 
    { 
    LPM = averageLPM;
    Serial.println(LPM,LPMdecimal);
    averageCount=0;   CumulativeLPM = 0; 
    }  
  }
  
void pulseCounter()
  {
  PulseDuration = millis() - PreviousPulseTime;
  PreviousPulseTime = millis(); 
  }

Ma il sensore lo devo collegare al pin 2? Da qualche parte ho letto che bisogna collegarlo ad un pin PWM dell'arduino anche perchè nelle caratteristiche trovo un duty cycle.. inoltre trovo questa caratteristica:

Pulses per Liter: 450

Significa che ad ogni impulso misura 0,45L? Grazie :confused:

Gianky00: Pulses per Liter: 450

Significa che ad ogni impulso misura 0,45L? Grazie :confused:

Ciao, secondo me invece significa che ogni 450 impulsi è passato un litro (1 impulso = 1/450 di litro).

pippettiello: Ciao, secondo me invece significa che ogni 450 impulsi è passato un litro (1 impulso = 1/450 di litro).

Ciao e grazie per la risposta...potrebbe darsi, aspetto altri pareri :D

pippettiello: Ciao, secondo me invece significa che ogni 450 impulsi è passato un litro (1 impulso = 1/450 di litro).

+1

... del resto la traduzione esatta è "Impulsi per litro = 450" e quindi direi proprio che sono 450 impulsi ogni litro che passa.

Guglielmo

perfetto, suggerimenti per l'altro mio dubbio cioè su come utilizzare un flussometro non per misurare la portata istantanea bensi' quella totale tra un irrigazione e l'altra..ho trovato solo questo sketch online ma ripeto..non ci capisco granchè:

byte sensorInterrupt = 0;  // 0 = digital pin 2
#define FlowMeterPulsePerSecondPerLiter 6.9
//#define FlowMeterPulsePerSecondPerLiter 7.5

volatile float PreviousPulseTime;
volatile float PulseDuration;
float LPM;
float averageLPM;
float CumulativeLPM;
float averageCount;
int LPMdecimal;

void setup() 
  {
  Serial.begin(115200);  
  PreviousPulseTime = 0;
  PulseDuration     = 0;
  LPM               = 0;
  averageLPM        = 0;
  averageCount      = 0;
  CumulativeLPM     = 0;
  LPMdecimal        = 2;
  attachInterrupt(sensorInterrupt, pulseCounter, CHANGE);
  }

void loop() 
  {

  CalculateFlow1();

  }

void CalculateFlow1()
  {
  CumulativeLPM = CumulativeLPM + (500/(PulseDuration*FlowMeterPulsePerSecondPerLiter)); 
  averageCount ++; averageLPM = CumulativeLPM/averageCount;
  if (averageCount >10000) 
    { 
    LPM = averageLPM;
    Serial.println(LPM,LPMdecimal);
    averageCount=0;   CumulativeLPM = 0; 
    }  
  }
  
void pulseCounter()
  {
  PulseDuration = millis() - PreviousPulseTime;
  PreviousPulseTime = millis(); 
  }

Conti gli impulsi e dividi per 450?

SukkoPera: Conti gli impulsi e dividi per 450?

Oppure (scusa Sukko se mi intrometto) ti inventi una tua unità di misura che sia in 450esimi di litro! Mi spiego: se non ho capito male stai lavorando su una serra, ok? E devi fornire una certa quantità di acqua, giusto? Perché devi lavorare in litri e fare tutti i calcoli (non tu, ovvio, parlo della "povera" MCU) del caso? Fatti i tuoi conti e vedi quanti impulsi (che sono come abbiamo visto 450esimi di litro) ti servono. Conti quelli e che siano 1000 o 5000 o vattelapesca te la cavi con una variabile int o longint senza fare divisioni. Semplice, veloce e pulito. D'altro canto non è che i litri siano una costante fondamentale della natura: ci sono galloni e chissà quante altre unità di misura. Sta a te scegliere la più comoda. In questo caso i 450esimi di litro! :o

Poi mi sento di farti notare che nelle specifiche del tuo sensore il flusso minimo (quello in cui dovrebbe essere garantita una tolleranza del 10 per cento) è di un litro al minuto; cioè 7,5 Hertz

Working Flow Rate: 1 to 30 Liters/Minute
Flow rate pulse characteristics: Frequency (Hz) = 7.5 * Flow rate (L/min)

Se scendi al di sotto di quello la girante del flussometro non è detto che funzioni e può facilmente bloccarsi. Io date le specifiche resterei entro un +20% dal minimo e -20% dal massimo. Ma queste sono solo considerazioni buttate un po' lì, non ho mai usato questi sensori. Chi ne sa più di me potrà correggermi.

Ciao e buon lavoro!

Buonasera, Grazie per le risposte..in realtà io vorrei solo calcolare quanta acqua scorre in un irrigazione, e non ha una logica temporale ma in base ad un sensore di umidità, quindi, a me non interessa 'a tot litri stacca', ma sapere semplicemente quanta acqua scorre tra l'inizio e la fine di un irrigazione. Inoltre in entrata ho una pressione variabile tra 2 e 4 bar, ma da come vedo dalle caratteristiche posso andare tranquillo visto che sopporta massimo 17,5bar.. la portata la soddisfo. Nessun problema.

Il problema è che non riesco a capire quando dirgli di contare ad arduino..questo dovuto al fatto che non riesco a capire quel benedetto sketch, di cui fa interruput, incrementi ecc..

Gianky00: Il problema è che non riesco a capire quando dirgli di contare ad arduino..questo dovuto al fatto che non riesco a capire quel benedetto sketch, di cui fa interruput, incrementi ecc..

Una premessa e poi ti dico come farei io il programma.

Lascia perdere quello che stai provando: quel programma è complesso perché deve mettere insieme i dati del flusso ricavati dal sensore col tempo. A te non serve. Lascia perdere.

Quello che farei io è: - una variabile dichiarata volatile per contare gli impulsi; - un interrupt che incrementa questa variabile; - Fine!

Eh, troppo semplice, dirai tu. Invece no.

Dato che la pompa la accendi e la spegni tu, sai bene quando accade. Quindi: quando accedi la pompa azzeri la variabile. Da quel momento in poi lei si aggiorna automaticamente (parliamo di interrupt) ed in ogni istante all'interno del loop la puoi leggere e vedere quanta acqua è passata. Quando spegni la pompa puoi anche continuare a leggere la variabile, ma a questo punto sarà fissa e ti darà sempre la quantità dell'ultima irrigazione.

Problema (e soluzione :-): ma questi impulsi cosa mi rappresentano? La variabile è 1230... cosa significa? Facile: abbiamo visto che ogni 450 impulsi sono un litro, quindi 1230/450=2,73 litri. Per far le cose ancora più facili puoi semplicemente dividere per 45 ed hai i decilitri. Ti basta come risoluzione? Spero di si. perché altrimenti le cose si complicano un po'.

ciao.

Esattamente.

SukkoPera:
Esattamente.

Grazie!

Grazie mille pippiettello…seguendo le tue indicazioni(sperando di averle interpretate bene) sono arrivato a fare questo sketch:

volatile int ciclo = 0;
int inPin = 2; //ingresso flussometro
byte pompa 3;
Int statoPompa =0;
void setup() {
  Serial.begin(9600);
  attachInterrupt(inPin, incremento, RISING);
}
statoPompa = digitalRead(pompa);  
if(statoPompa ==HIGH)
ciclo = 0;
void incremento()
 {
  ciclo++;
}
void loop() 
{
  if(ciclo>1)
{
    Serial.print("ciclo: ");
    Serial.println(ciclo);
  }
portata = ciclo / 450;
Serial.print("Portata: ");
Serial.print(portata);
Serial.println(" litri");
}

Non ho ancora avuto modo di provarlo…spero sia giusto!!!

Si, come abbozzo ci siamo, ma un po' di cose son da sistemare (sempre ammesso che vuoi darmi retta :-):

Queste istruzioni:

statoPompa = digitalRead(pompa); 
if(statoPompa ==HIGH)
ciclo = 0;

fuori da setup e loop non hanno senso. Devi metterle nel loop. Inoltre se appena la pompa si spegne azzeri ciclo non riuscirai a leggere la quantità dell'ultima irrigazione perche si azzera appena raggiunto il massimo!

Io metterei una seconda variabile statoPompaPrec per controllare lo stato del sistema. Nel loop e in pseudocodice:

statoPompa=digitalRead(pompa)
if(statoPompa != statoPompaPrec)/è cambiato qualcosa?
    if(statoPompa==HIGH)/pompa accesa, prima era spenta
         ciclo=0
    end if
end if

poi (per bellezza):

if(statoPompa==HIGH)/pompa accesa
    print("irrigazione in corso: ")
else
    print("ultima irrigazione: ")
end if

A questo punto hai in ciclo il valore che ti serve e lo puoi stampare. Infine:

statoPompaPrec=statoPompa

A te il compito di tradurlo in C e di provarlo. Spero di esserti stato d'aiuto. ciao.

ciao pippettiello, ho avuto modo di controllare il tuo sketch...questo:

volatile int ciclo = 0;
int inPin = 2; //ingresso flussometro
byte pompa = 3;
int statoPompa = 0;
float portata;
unsigned long tempoPrecedente = 0, intervallo = 2000;
int  statoPompaPrec;
void setup()
{
  Serial.begin(9600);
  attachInterrupt(inPin, incremento, RISING);
}
void loop()
{
  unsigned long tempoAttuale = millis();
  if (tempoAttuale - tempoPrecedente >= intervallo)
  {
    tempoPrecedente = tempoAttuale;
    statoPompa = digitalRead(pompa);
#if (statoPompa != statoPompaPrec)
#if (statoPompa == HIGH)
    ciclo = 0;
#endif
#endif
    if (statoPompa == HIGH)
      Serial.print("irrigazione in corso: ");
    else
      Serial.print("ultima irrigazione: ");
    if (ciclo > 1)
    {
      Serial.print("ciclo: ");
      Serial.println(ciclo);
    }
    portata = ciclo / 450;
    Serial.print("Portata: ");
    Serial.print(portata);
    Serial.println(" litri");
    statoPompaPrec = statoPompa;
  }
}
void incremento()
{
  ciclo++;
}

purtroppo mi stampa sempre in seriale:

irrigazione in corso: Portata: 0.00 litri irrigazione in corso: Portata: 0.00 litri etc..

Sempre irrigazione in corso... Poi, ho fatto qualche modifica sul tuo paragrafo:

statoPompa=digitalRead(pompa) if(statoPompa != statoPompaPrec)/è cambiato qualcosa? if(statoPompa==HIGH)/pompa accesa, prima era spenta ciclo=0 end if end if

in:

statoPompa=digitalRead(pompa)

if(statoPompa != statoPompaPrec)/è cambiato qualcosa?

if(statoPompa==HIGH)/pompa accesa, prima era spenta

ciclo=0

endif

endif

Ho dovuto mettere cosi gli #endif e #if se no mi da come errore:

'end' was not declared in this scope

il flussometro l'ho collegato al pin 2 digitale ma anche se non lo collego mi stampa la stessa cosa in seriale..infine, se in setup dichiaro:

pinMode(pompa,OUTPUT);

allora in seriale mi stamperà:

ultima irrigazione: Portata: 0.00 litri ultima irrigazione: Portata: 0.00 litri etc...

se non dichiaro il pinMode allora mi stamperà:

ultima irrigazione: Portata: 0.00 litri ultima irrigazione: Portata: 0.00 litri etc..

Mi sto disperando...non so come uscirne per farlo funzionare!

Ahi, ahi... mi sa che non ci siamo capiti proprio. Quello che ti consigliavo era scritto in pseudocodice, come ho detto. Cioè non in un linguaggio specifico, ma solo in modo da farmi capire. E soprattutto non era inteso per fare un copiaincolla alla meno peggio, ma per darti uno spunto su cui riflettere. Va bo, mi sarò spiegato male. Rifo: Se ti scrivo:

Se (sono le 8)
allora alzati e vai in ufficio
fine se

o:

if ((currentTime.hour==8)&&(currentTime.minute==0)){
WakeUp();
GoToOffice(fast);
}

sto dicendo la stessa cosa in lingue diverse. Per questo alla fine del mio intervento precedente ti dicevo "A te il compito di tradurlo in C e di provarlo."

Imperdonabile il tentativo raffazzonato di aggiungere "#" prima di if e endif! Ma sai cosa significa quel simbolo a inizio riga? E se non lo sai (ne son certo) non puoi certo sapere perché facendo così gli errori spariscono. Tanto vale cancellare le righe di codice che ti danno noia, no? Certo che a far così non si va da nessuna parte. Un po' di studio e un po' d'impegno, dai!

Ok. Dopo il cazziatone :) un aiutone:

volatile int ciclo = 0;
int cicloPrec = 0;
int inPin = 2; //ingresso flussometro
int pompa = 3;
int statoPompa = 0;
float portata;
int  statoPompaPrec = 0;

void setup()
{
 Serial.begin(9600);
 Serial.println("Avvio del sistema...");
 pinMode(inPin, INPUT);
 pinMode(pompa, INPUT);
 attachInterrupt(digitalPinToInterrupt(inPin), incremento, RISING);
}

void loop()
{
 statoPompa = digitalRead(pompa);
 if (statoPompa != statoPompaPrec) {
   if (statoPompa == HIGH) {
     ciclo = 0;
   }
 }
 if (ciclo != cicloPrec) {
   if (statoPompa == HIGH)
     Serial.print("irrigazione in corso: ");
   else
     Serial.print("ultima irrigazione: ");
   portata = ciclo / 450;
   Serial.print("Portata: ");
   Serial.print(portata);
   Serial.println(" litri");
 }
 cicloPrec = ciclo;
 statoPompaPrec = statoPompa;
}

void incremento()
{
 ciclo++;
}

Non l'ho provato e non garantisco. È solo un abbozzo. provalo e poi ne riparliamo (però questa volta puoi fare copiaincolla :smiling_imp: ).

In particolare: sul pin 2 hai collegato il flussometro, e stando a quello che dicevi nel primo post funziona. Al limite rimetti quel programma e rifai il test. Occhio che nell'istruzione attachInterrupt NON devi indicare il pin! https://www.arduino.cc/en/Reference/attachInterrupt ma l'interrupt. Sul pin 3 invece leggi lo stato della pompa (acceso/spento - HIGH=acceso).

Ah, il cancelletto ("#") serve a dare istruzioni al compilatore: quelle righe quindi non sono di programma. Approfondisci l'argomento, se vuoi.

Dai, prova e poi fammi sapere. Ce la possiamo fare.

P.S. Purtroppo MIT Appinventor ed anche lo stesso LEGO Mindstorm sono stati creati per avvicinare all'informatica e facilitare il cammino, cosa lodevole, ma dai risultati direi che hanno l'effetto opposto: dopo aver pensato che con tre click e quattro icone si sia diventati programmatori senza studiare è molto duro tornare alla realtà: bisogna studiare e farsi il mazzo. punto. (Considerazione generale... niente di personale)

Ciao.

Ciao pippettielo, intanto perdonami se rispondo solo adesso, purtroppo il tempo è davvero poco e prima o poi rispondo a tutti e ringraziare a chi mi aiuta e facilita non di poco il mio studio. Grazie a te, ho ultimato il mio sketch che stasera pubblicherò qui… è migliorato per quello che serve a me. Grazie ancora!!

EDIT:
Per chi potrà interessare, ecco qui lo sketch finito:

volatile int ciclo = 0;
int cicloPrec = 0, flussometro = 2, pompa = 3, statoPompa = 0, inputSize = 0, statoPompaPrec = 0, cronometro;
float portata;
char myCmd[128];
unsigned long tempoPrecedente = 0, intervallo = 1000;
void setup()
{
  Serial.begin(9600);
  pinMode(flussometro, INPUT);
  pinMode(pompa, INPUT);
  attachInterrupt(digitalPinToInterrupt(flussometro), incremento, RISING);
  Serial.println("|-----------------------------------------|");
  Serial.println("|        AVVIO SOFTWARE FLUSSOMETRO       |");
  Serial.println("|      premi 'comandi' per iniziare       |");
  Serial.println("|-----------------------------------------|");
}

void loop()
{
  unsigned long tempoAttuale = millis();
  if (tempoAttuale - tempoPrecedente >= intervallo)
  {
    tempoPrecedente = tempoAttuale;
    if (ciclo != 0)
      cronometro++;
    else cronometro = 0;
    statoPompa = digitalRead(pompa);
    Serial.print("consumo idrico: ");
    portata = ciclo / 4.5 / 100;
    Serial.print(portata);
    Serial.print(" litri");
    Serial.print ("  -  secondo: ");
    Serial.println(cronometro);
    statoPompaPrec = statoPompa;
  }
  if (Serial.available())
  {
    delay(100);
    inputSize = Serial.available();
    for (int i = 0; i < inputSize; i++)
      myCmd[i] = Serial.read();
    if (myCmd[0] == 'o') if (myCmd[1] == 'n')
      {
        digitalWrite(pompa, HIGH);
        Serial.print("la pompa è: ");
        if (statoPompa == HIGH)
          Serial.println(F("ACCESA"));
        else Serial.println(F("SPENTA"));
        myCmd[0] = 0; myCmd[1] = 0;
      }
    if (myCmd[0] == 'o') if (myCmd[1] == 'f')
      {
        digitalWrite(pompa, LOW);
        Serial.print("la pompa è: ");
        if (statoPompa == HIGH)
          Serial.println(F("ACCESA"));
        else Serial.println(F("SPENTA"));
        myCmd[0] = 0; myCmd[1] = 0;
      }
    if (myCmd[0] == 'o') if (myCmd[1] == 'n')
      {
        digitalWrite(pompa, HIGH);
        statoPompa = digitalRead(pompa);
        Serial.print("la valvola è: ");
        if (statoPompa == HIGH)
          Serial.println(F("APERTA"));
        else Serial.println(F("CHIUSA"));
        myCmd[0] = 0; myCmd[1] = 0;
      }
    if (myCmd[0] == 'o') if (myCmd[1] == 'f')
      {
        digitalWrite(pompa, LOW);
        statoPompa = digitalRead(pompa);
        Serial.print("la valvola è: ");
        if (statoPompa == HIGH)
          Serial.println(F("APERTA"));
        else Serial.println(F("CHIUSA"));
        myCmd[0] = 0; myCmd[1] = 0;
      }
    if (myCmd[0] == 'r') if (myCmd[1] == 'e') if (myCmd[2] == 's')if (myCmd[3] == 'e') if (myCmd[4] == 't')
            {
              ciclo = 0;
              cronometro = 0;
              if (ciclo == 0)
                Serial.println("Consumo idrico resettato");
              else Serial.print("fallimento RESET");
              if (cronometro == 0)
                Serial.println("Cronometro resettato");
              else Serial.print("fallimento RESET");
              myCmd[0] = 0; myCmd[1] = 0; myCmd[2] = 0; myCmd[3] = 0; myCmd[4] = 0;
            }
    if (myCmd[0] == 'c') if (myCmd[1] == 'o') if (myCmd[2] == 'm') if (myCmd[3] == 'a') if (myCmd[4] == 'n')  if (myCmd[5] == 'd')  if (myCmd[6] == 'i')
                {
                  Serial.println(F("premi   'on'   accendere pompa"));
                  Serial.println(F("premi   'off'  spegnere pompa"));
                  Serial.println(F("premi    '?'   sapere stato della pompa"));
                  Serial.println(F("premi  'reset' resettare portata"));
                  myCmd[0] = 0; myCmd[1] = 0; myCmd[2] = 0; myCmd[3] = 0;  myCmd[4] = 0;  myCmd[5] = 0;  myCmd[6] = 0;
                }
  }
}
void incremento()
{
  ciclo++;
}

Gianky00: Ciao pippettielo, intanto perdonami se rispondo solo adesso, purtroppo il tempo è davvero poco e prima o poi rispondo a tutti e ringraziare a chi mi aiuta e facilita non di poco il mio studio. Grazie a te, ho ultimato il mio sketch che stasera pubblicherò qui.. è migliorato per quello che serve a me. Grazie ancora!!

Figurati! Lieto di esserti stato d'aiuto.