Rain rate?

Salve,
Avevo una domanda da fare... se io ho un pluviometro, senza l'aggiunta di altri componenti esterni, come con il voltmetro che trasforma il rumore del pluviometro in volt come si vede sulle ricerche su google, posso aggiungere il rain rate?

const int pinLed_blink = 6; // led verde che lampeggia
const int pinLed_inter = 7; // led gallo per interrupt
//--------------------------------------------------------------------
// costante contenuto in mm di ogni bascula ( venditore e nostra)
//const float mmGoccia = 0.3; // costante bascula indicata dal venditore
const float mmGoccia = 0.909; // costante bascula ricavata ( vedi blog)
                             // corrisponde ai mm di pioggia per ogni bascula
const int pinInterrupt = 3; // pin interrupt "0"
//-------------------------------------------------------------------------
// variabili usate nella funzione interrupt
//-------------------------------------------------------------------------
volatile unsigned int gocce = 0; // variabile conteggio numero basculate
volatile float mmPioggia = 0.0; // conteggio millimetri di pioggia
volatile boolean statoLed = false; // cambia stato nell'interrupt
//-------------------------------------------------------------------------


// ---------------------------------------------------
// setup
//----------------------------------------------------
void setup()
{
  Serial.begin(9600);
  pinMode(pinLed_blink, OUTPUT);
  pinMode(pinLed_inter, OUTPUT);
  //-------------------------------------------------------------------------
  // Interrupt pluviometro
  //-------------------------------------------------------------------------
  attachInterrupt(1, ContaGocce, FALLING); // modo da HIGH A LOW
  //-------------------------------------------------------------------------
  
 
}
//--------------------------------------------------------------------------
// programma principale
//--------------------------------------------------------------------------
void loop()
{
  // operazioni perdita di tempo
  digitalWrite(pinLed_blink, HIGH); 
  delay(100);
  digitalWrite(pinLed_blink, LOW);
  delay(100);
  //--------------------------------
  
  // stampa letture
 Serial.println(mmPioggia);
   
    //imposta ora della prossima lettura
 
  }

//--------------------------------------------------
// funzione interrupt
//--------------------------------------------------
void ContaGocce()
{
  gocce++; // incrementa numero basculate
  mmPioggia = mmPioggia + mmGoccia; // sommatoria millimetri pioggia
  statoLed = !statoLed;
  digitalWrite(pinLed_inter, statoLed ? HIGH : LOW);
}

Non capisco niente. Sono cosí vecchio che l' elettronica ha fatto passi da gigante e io me lo son perso o é fantascenza? :wink: :wink: :wink:
Ciao Uwe

:slight_smile: Praticamente avevo visto questo progetto

E mi chiedevo c'è un modo avendo solo questo schema (figura: è il WS 2300-16) per calcolare in rain rate tramite programma di arduino? Spero di essere stato chiaro, scrivo pochi dettagli scusate!

Guardi quanti impulsi ricevi entro un certo tempo oppure quanto tempo passa da un impulso all'altro.
Ogni impulso corrisponderá a un certo volume di pioggia caduta.

Ciao Uwe

Aspetta, volendo fare che metti caso: se passano 3 minuti e 15 fino a 2 minuti e 30 da una basculata all'altra il rain rate è 10, come si scrive?... Non so come fare a scrivere con la funzione millis di dirgli che se passa quel tempo quando si verifica un'altra volta una basculata il rain rate è quello...

Per primo converti il tempo da ore, minuti, secondi in secondi.

poi

if (tempo > 150 && tempo <195) rate = 10;
ecc

se é una cosa lineare puoi usare anche la funzione map()
https://www.arduino.cc/en/Reference/Map

Ciao UWe

Grazie per la dritta ma, non basta quell if. Perché devo tipo fare così:
Appena segna una goccia(basculata) faccio partire un conteggio in secondi tipo, se passano tot secondi e accade un'altra basculata, il rain rate è x
Lì si fa riferimento solo al tempo.
Poi come faccio a convertire ore minuti e secondi in secondi? Non ho ben capito

#include <Time.h>
#include <Wire.h>
const int pinLed_blink = 6; // led verde che lampeggia
const int pinLed_inter = 7; // led gallo per interrupt
const float mmGoccia = 0.518; // costante bascula ricavata ( vedi blog)
const int pinInterrupt = 3; 
volatile unsigned int gocce = 0; // variabile conteggio numero basculate
volatile float mmPioggia = 0.0; // conteggio millimetri di pioggia
volatile boolean statoLed = false;
float rainrate=0;//
int time;

void setup()
{
  Serial.begin(9600);
  pinMode(pinLed_blink, OUTPUT);
  pinMode(pinLed_inter, OUTPUT);

  attachInterrupt(1, ContaGocce, FALLING); // modo da LOW ad HIGH
  
 
}

void loop()
{
  
  digitalWrite(pinLed_blink, HIGH); 
  delay(100);
  digitalWrite(pinLed_blink, LOW);
  delay(100);
  
 Serial.println(mmPioggia);
   Serial.println(rainrate);
   
 
  }
void ContaGocce()
{
   gocce++; // incrementa numero basculate
if (gocce>1)
{ 
  mmPioggia =mmPioggia + 0.518;
}
else
{
 mmPioggia = mmPioggia + mmGoccia; // sommatoria millimetri pioggia
}

statoLed = !statoLed;
  digitalWrite(pinLed_inter, statoLed ? HIGH : LOW);
  }

Si può fare con quella funzione map che per esempio più si ci avvina a un certo tempo più il rain rate aumenta? Perché con gli if verrebbe tipo a scatti, ovvero che devo fare non si quanti if, perché devo dirgli per esempio, sia il rain rate di 15mm/h sia di un 1mm/h sia di 2 mm/h, 3mm/h ect...

Ho trovato questo sketch in rete in cui c'è pure il rain rate, ma ci sono un mucchio di cose che non mi servono, forse questo svolge proprio quello che voglio con il rain rate, ma è difficile interpretarlo per me
http://forum.micasaverde.com/index.php?topic=25587.0

rainrate.ino (8.33 KB)

Allora, io ho provato qualcosa ma non riesco a venirne a capo, ho usato la funzione map con il time, però non riesco a trovare un modo per far partire un conteggio millis solo appena avviene una basculata e poi quando viene un'altra basculata calcola il rain rate tramite la funzione map e poi vorrei che ripartisse da capo con il millis
io ho pensato tipo di fare un if esterno che quando la goccia è uguale a 1 parte il conteggio con millis e poi quando la goccia è maggiore di uno che calcola il rain rate e azzera il millis, però ritorna a uno visto quel "gocce--" e quindi siccome è a uno riparte un'altra volta il conteggio e così via, però non so come farlo con il programma...

Qui le parti importanti:

const int pinLed_blink = 6; // led verde che lampeggia
const int pinLed_inter = 7;
const float mmGoccia = 0.518;
const int pinInterrupt = 3;
volatile unsigned int gocce = 0;
volatile float mmPioggia = 0.0; // conteggio millimetri di pioggia
volatile boolean statoLed = false;
unsigned long time;
float dewPoint;
float windchill;
float temperaturaf;
float heatindexf;
float heatindexc;
float pressionelivellodelmarehPa;
float pressionelivellodelmare;
float rafficamax=0;
byte giornoSalvato;
float maxeeprom=0.0;
float mineeprom=100.0;
float rainrate=0;
void setup() {
  Serial.begin(9600);
  tft.initR(INITR_BLACKTAB);
  tft.fillScreen(ST7735_BLUE);
  tft.setCursor (0,20);
  tft.setTextSize(2);
  tft.setTextColor (ST7735_GREEN);
  tft.print (" STAZIONE");
 tft.setCursor (10,40);
  tft.print ("  METEO:");
  delay (2000);
  tft.setTextColor (ST7735_YELLOW);
  tft.setCursor (4,80);
  tft.print ("SITUAZIONE  ATTUALE");
    pinMode(pinLed_blink, OUTPUT);
  pinMode(pinLed_inter, OUTPUT);
  attachInterrupt(1, ContaGocce, FALLING); // modo da HIGH a LOW
  if (gocce>1)
  {
    gocce--;
    rainrate= map(time,780000,2000,2.5,1000);
   }
   if ((rainrate!=0)&(time>=780000))
   {
    rainrate=0;
   }
void ContaGocce()
{
   gocce++; // incrementa numero basculate
   if (gocce>1)
{ 
  mmPioggia =mmPioggia + 0.518;
}
else
{
 mmPioggia = mmPioggia + mmGoccia; // sommatoria millimetri pioggia
}
statoLed = !statoLed;
digitalWrite(pinLed_inter, statoLed ? HIGH : LOW);
time=millis();
EEPROM.put (eeAddress4, mmPioggia);
}

Ho messo unsigned long su time che mi ero sbagliato

Insomma non so come fare un paragone di tempo tra una goccia(basculata) e l'altra....

As_Needed:
Insomma non so come fare un paragone di tempo tra una goccia(basculata) e l'altra....

Non capisco;
Fai la differenza dei millis tra le 2 bascolate. Piú corto é il tempo piú pioggia viene giú.

Ciao Uwe

Si ma praticamente voglio: quando succede una basculata parte un millis e quando accade un' altra basculata, fa quel if che ho messo con map dentro, che a seconda di quanto tempo é passato c é un certo rr
o magari se c é un altro metodo efficace potrei avere un piccolo esempio di sketch, magari modificando delle parti di quello che ho messo? mi faresti un grande favore, perché mi serve anche questo dato per averla completa al cento per cento la stazione meteo...

Niente, nessuno puó aiutarmi con un piccolo esempio? Uwe almeno con un esempio di sketch, così mi chiarisco le idee... sempre se puoi o vuoi sia chiaro! :wink: mi manca solo questo, gli altri tanti valori sono riuscito a fare tutto xd

Millis non misura il tempo.
Millis rende un numero che sono i millisecondi dall'accensione dell'Arduino.

Memorizzi al primmo basculamento i millis in una veriabile e al sucessivo basculamento sottrai dai millis attuali il valore precedente. cosí trovi il tempo tra 2 basculamenti. Dopo memorizzi i millis nella variabile per il sucessivo intervallo.
Ciao Uwe

Ti posto il codice di tutto lo sketch al volo, spero possa essere utile

// - - - PLUVIOMETRO - - - //
// - - - - - Variabili di servizio - - - - - //
int PluvioDigit = 3;       //input for REED PluvioDigit
int PluvioVal = 0;         //used to store input PluvioPluvioValue
int PluvioCont = 0;        //PluvioConta gli scatti
int PluvioInitCont = 0;    // scatti da inizio temporale
int PluvioFlag = 0;        //tiene memoria dello scatto
int PluvioRefresh = 5000;  //Valore che indica ogni quanto aggiornare lo schermo
int PluvioScanTime = 500; //Valore che evita che venga contato due volte uno scatto
float PluvioAdattatore = 0.254;  // Valore di ogni scatto di pluvio
// - - - - - Variabili di Output - - - - - //
float PluvioRate = 0;      //per il calcolo del rainPluvioRate
float PluvioMm = 0;        //Tiene conto dei mm
float PluvioMmStorm = 0;       //Tiene conto dei mm del temporale
// - - - FINE PLUVIOMETRO - - - //

unsigned long PluvioStep = 0; // tiene memoria di quando è stato effettuato l'ultimo scatto
unsigned long PluvioOldStep = 0; // tiene memoria di quando è stato effettuato il penultimo scatto
unsigned long time = 0; // tempo globale
unsigned long printtime = 0; //tiene conto di quando è stata effettuata l'ultima volta la stampa

void setup() {
  delay(1000);
  digitalWrite (PluvioDigit, HIGH);  // internal pull-up resistor
  attachInterrupt (1, PluvioDataScan, FALLING);  // attach interrupt handler
  Serial.begin(9600);
  time = millis();
}

void PluvioDataEngine() {
  PluvioMm = PluvioCont * PluvioAdattatore;
  PluvioMmStorm  = PluvioInitCont * PluvioAdattatore;
  if (((PluvioStep - PluvioOldStep) != 0) && (PluvioInitCont >= 2)) {
    if ((time - PluvioStep) > (PluvioStep - PluvioOldStep)) {
      PluvioRate = 3600 / (((time - PluvioStep) / 1000)) * PluvioAdattatore;
      if (PluvioRate < 1) {
        PluvioInitCont = 0;
        PluvioRate = 0;
      }
    } else {
      PluvioRate = 3600 / (((PluvioStep - PluvioOldStep) / 1000)) * PluvioAdattatore;
    }
  } else {
    PluvioRate = 0.0;
  }
}

void PluvioDataScan() {

  noInterrupts();             // disable global interrupts
  //PluvioVal=digitalRead(PluvioDigit);

  if ((time - PluvioStep) >= PluvioScanTime) { //con questo PluvioContatore evitiamo che uno scatto venga Conteggiato per due volte
    //if (PluvioVal==LOW) {
    PluvioFlag = 1;
    //}
  }

  //if ((PluvioVal==HIGH) and (PluvioFlag==1)) {
  if ((PluvioFlag == 1)) {
    PluvioFlag = 0;
    PluvioOldStep = PluvioStep;
    PluvioStep = time;
    PluvioCont++;
    PluvioInitCont++;
  }
  interrupts();              // Re-enable Interrupts
}

void loop() {
  time = millis();
  //PluvioDataScan();

  if ((time - printtime) >= PluvioRefresh) { //aggiornamento PluvioContinuo
    printtime = time;
    PluvioDataEngine();
    Serial.print("Scatti: ");
    Serial.print(PluvioCont, DEC);
    Serial.print(" - Totale: ");
    Serial.print(PluvioMm, 1);
    Serial.print(" mm - Temporale: ");
    Serial.print(PluvioMmStorm, 1);
    Serial.print(" mm - Rate: ");
    Serial.print(PluvioRate, 1);
    Serial.println(" mm/h ");
  }
}

Gianfranco

Editato da un moderatore - gpb01

@GianfrancoPa: Cortesemente, quando postate il codice, seguite quanto scritto nel REGOLAMENTO, punto 7, ed usate gli appositi tag CODE (... sono quelli che in edit inserisce il bottone fatto così: </>, tutto a sinistra) e NON i tag QUOTE ! Grazie.

Guglielmo

Ringrazio tutti per la pazienza e sopratutto grazie mille a Gianfranco per l'esempio!!! Ci sono riuscito finalmente! La logica che hai usato è praticamente quella di uwe, però perché mi sapeva difficile capire dove mettere ogni pezzo, grazie tante! Finalmente ho tutti i valori che volevo, grazie grazie grazie :wink:

Cerchiamo di evitare soluzioni pronte e cerchiamo di indicare la via giusta perchè chi chiede faccia il lavoro di capire la cosa e in questo modo lo impara bene.
Ciao Uwe

Sono d'accordo, peró a volte se magari non si riesce senza studiarci molto una cosa a farla, poi ci si blocca solo su una cosa e si tralasciano delle altre. Io ti ringrazio ovviamente anche a te, perché anche senza la risposta di gianfranco già avevo escogitato un metodo grazie alle tue ulteriori parole, che poi ho rivisto nel suo sketch e l ho adattato al mio. L importante che si vada avanti e di sicuro serve anche impegnarcisi per farlo!