Ciao a tutti, ho scritto un semplice sketch col quale incremento un contatore "c" ogni volta che il sensore (pluviometro a bascula) mi chiude il circuito.
Ho usato il comando attachinterrupt ma ogni volta che il sensore bascula il contatore viene incrementato due volte.
Qualcuno sa darmi una soluzione?
GRAZIE
int c = 0;
float mm = 0;
void setup() {
pinMode(2,INPUT);
Serial.begin(9600);
attachInterrupt(0,pluviometro, RISING);
}
void pluviometro(){
c++;
delay(100);
}
void loop() {
mm = c*0.5;
Serial.print(c);
Serial.print(", ");
Serial.println(mm);
c = 0;
mm = 0;
delay(5000);
}
tutte le variabili usate nelle ISR DEVONO essere dichiarate volatili, leggi QUI
le ISR debbono essere le più veloci possibili, quindi ... niente delay() al loro interno.
Poi, che tipo di pluviometro stai usando ? Ha un uscita digitale o è un semplice interruttore ? Perché, nel secondo caso, devi applicare un circuito di debouncinghardware sull'ingresso del pin che genera l'interrupt.
Guglielmo
P.S.: Ah ... in conformità al regolamento, punto 7, edita (in basso a destra del post, bottone More -> Modify) il tuo post e racchiudi il codice all'interno dei tag CODE (... sono quelli che in edit inserisce il bottone fatto così: </>, tutto a sinistra). Grazie.
Intanto grazie Guglielmo, ho modificato il post...
Le variabili volatili non riesco a capire cosa siano di preciso. Vengono caricate sulla RAM ma non si capisce se tutti i tipi di variabile possono essere definiti volatile o meno????? e cosa cambia?
Il pluviometro che uso è un semplice pulsante magnetico (reed credo).
Quindi si credo ci voglia un debouncing, ma deve essere per forza hardware o anche a livello software si può aggirare il problema?
"volatile" è un attributo che va dato SOLO alle variabili che sono usare nelle ISR (la routine che viene chiamata dall'interrupt) e che serve al compilatore. Prova a leggere QUI.
Dato che è coinvolto un interrupt il debouncing devi farlo hardware ...
... ti allego alcune possibili configurazioni, vedi quella che ti si adatta meglio.
Grazie mille Guglielmo.
Uwe non posso gestirlo nel loop perché il programma in cui andrò ad inserirlo alla fine gira solo una volta all'ora e non potrei contare le basculate che avvengono durante tutta l'ora.
valdarno8:
... non posso gestirlo nel loop perché il programma in cui andrò ad inserirlo alla fine gira solo una volta all'ora e non potrei contare le basculate che avvengono durante tutta l'ora.
Questo NON ha senso ...
... il loop() gira in continuazione e sei tu, da dentro al loop che decidi QUANDO e COME chiamare funzioni e fare cose, quindi, anche se richiami una funzione solo dopo che sono passati 60 minuti (una volta l'ora), non significa che nel rimanente tempo non puoi fare altre cose, anzi .... hai tutto il tempo che vuoi
Ti consiglio di studiarti come si usa la funzione millis() prima QUI, poi QUI ed infine leggi anche QUI e QUI ... vedrai che ti sarà tutto più chiaro
Ah ok, giusto. Lo potrei mettere dentro il loop ma fuori dal ciclo che gira ogni ora.
Però con quale comando gli posso dire di incrementare in contatore ogni volta che il pluviometro chiude il circuito? Cioè un ciclo che parte all'arrivo di un segnale indipendentemente dal punto in cui sta girando il loop. L'interrupt mi sembrava la scelta migliore.
No, devi far eseguir il loop() frequentemente per riuscire a reagire sul cambio di stato del pluviometro a bascula
nel senso
loop()
{
controllo bascula; stato sensore diverso da quello precedente? piccolo delay, aggiornare stato precedente.
con millis controlli se é passato un ora e esegui quello che deve fare una volta all ora.
}
Ma il controllo dello stato del sensore deve avvenire a frequenze altissime per beccare il momento preciso in cui avviene il contatto. E resta sempre la possibilità che il sensore chiuda in un istante tale che il loop non lo becchi. Per questo secondo me è più preciso l'interrupt.
Com'è fatto il sensore a bascula? Hai un doppio pulsante sullo stesso pin?
Se potessi inserire tre resistenze in modo da creare un doppio partitore resistivo lo puoi leggere come ingresso analogico e sapere da che parte sta.
Altrimenti vai di resistenza e condensatore e continui a usare l'interrupt.