Ciao a tutti
ho il seguente problema:
devo utilizzare un flussometro,come gestisco gli interrupt,nel senso :
int flussometro=7;
void impulso()
{
count++; //incrementa count di 1
}
void setup()
{
pinMode(flussometro,INPUT);
attachInterrupt(0,impulso,RISING);
}
cosi funziona bene
ma se io volessi aggiungere un altro flussometro come imposto l'interrupt,
come devo riscrivere il codice,posso usare lo stesso piedino ho devo prima dichiarare un altro piedino come interrupt tipo 1,e poi riscrivere:
attachInterrupt(1,impulso,RISING);
(ho letto che le schede hanno diversi piedini dedicati al interrupt) tipo Arduino Uno ha il 2e3
(ma io nello sketch ho usato il 0 ed ha funzionato lo stesso)
allora...nella maggior parte delle schede arduino solo alcuni pin hanno la possibiltà di essere usati per l'interrupts...vedi il reference QUI
in alcune schede invece li puoi utilizzare tutti.
il numero dell'interrupt non è il numero del pin...quindi tu nel tuo attachInterrupt(0,impulso,RISING) non hai indicato il numero del PIN ma il numero dell'interrupt...questo numero, se non sbaglio, ne identifica anche la priorità nel caso di utilizzo di più interrupt diversi in quanto solo uno alla volta può essere eseguito.
come scritto nelle reference la funzione richiamata dall'interrupt deve eseguire solo cose essenziali...nel senso che deve essere più semplice possibile...nel tuo caso aumentare una variabile va benissimo...quello che deve avere questa variabile è la sua dichiarazione come "volatile"...vedi sempre le reference per chiarire di cosa si tratta (allocazione e gestione nella memoria).
se hai due strumenti/sonde che necessitano di un interrupt, tipo conteggio flusso acqua, si devi creare un'altra ISR (interrup service routine...leggasi funzione chiamata) e legarla ad un secondo pin/interrupt.
grazie a tutti per le risposte
ho eseguito diverse prove
1)io collegavo il flussometro al piedino 7(che era sbagliato )nel senso che se volevo collegare un rele che fosse azionato dal segnale del flussometro non ci riuscivo (il segnale variava un po a casaccio tra alto e basso)
2)collegando il flussometro ai piedini 2/3 funzionava tutto ed anche molto stabile
la mia domanda adesso e la seguente
visto che arduino uno ha solo i due piedini come interrupt ,usando questo comando posso impostare ìl un piedino diverso come interrupt
La risposta è contenuta nella tua domanda: Arduino Uno supporta solo 2 external interrupt, sui pin 2 e 3, per cui puoi usare solo quelli con quel comando.
grazie ancora
ho provato la libreria degli interrupt più che macchinosi, lenti direi(visto che mi devono azionare dei relè ho bisogno che il cambio sia quasi istantaneo)
comunque per non farlo troppo complicato ho diviso in due parti, parte controllo generale e parte controllo flussometro, per controllo generale ho usato l'Arduino uno ,invece per il controllo del flussometro ho usato due schede di arduino nano
pero ho riscontrato un problema:
quando metto un solo flussometro funziona tutto bene
invece quando provo ad aggiungerne il secondo diventa instabile...la causa quale potrebbe essere ?
(anche sulla scheda arduino nano uso soltanto i piedini 2 e 3 come interrupt)
il codice che uso e questo :
volatile int contatoreFlussometroFreddo;
volatile int contatoreFlussometroCaldo;
int pinFlussometroFreddo = 2;
int pinFlussometroCaldo = 3;
const int digitalPinRelayTest1 = 4;
const int digitalPinRelayTest2 = 5;
//const int digitalPinRelay8 = 8;
//const int digitalPinRelay9 = 9;
//const int digitalPinRelay10 = 10;
void incrementaContatoreFlussometroFreddo() {
contatoreFlussometroFreddo++; //incrementa contatoreFlussometroFreddo di 1
}
void incrementaContatoreFlussometroCaldo() {
contatoreFlussometroCaldo++; //incrementa contatoreFlussometroCaldo di 1
}
void setup() {
Serial.begin(9600);
pinMode(digitalPinRelayTest1, OUTPUT);
pinMode(digitalPinRelayTest2, OUTPUT);
pinMode(pinFlussometroFreddo, INPUT);
pinMode(pinFlussometroCaldo, INPUT);
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(pinFlussometroFreddo), incrementaContatoreFlussometroFreddo, RISING);
attachInterrupt(digitalPinToInterrupt(pinFlussometroCaldo), incrementaContatoreFlussometroCaldo, RISING);
digitalWrite(digitalPinRelayTest1, LOW);
digitalWrite(digitalPinRelayTest2, LOW);
}
void loop() {
// Reset dei contatori
contatoreFlussometroFreddo = 0;
contatoreFlussometroCaldo = 0;
sei(); //attiva interrupt
delay(1000);
cli(); // disattiva interrupt
/*
equivalente a :
interrupts(); //Abilita gli interrupt
delay (1000); //Pausa di 1 secondo
noInterrupts(); //Disabilita gli interrupt
*/
int flussoFreddo = (contatoreFlussometroFreddo*60/7.5);
int flussoCaldo = (contatoreFlussometroCaldo*60/7.5);
if(flussoFreddo < 250) {
digitalWrite(digitalPinRelayTest1, HIGH);
} else {
digitalWrite(digitalPinRelayTest1, LOW);
}
if(flussoCaldo < 250) {
digitalWrite(digitalPinRelayTest2, HIGH);
} else {
digitalWrite(digitalPinRelayTest2, LOW);
}
Serial.print(flussoFreddo, DEC);
Serial.print("L/hour\r\n");
Serial.print(flussoCaldo, DEC);
Serial.print("L/hour\r\n");
}
ciao...se non ho capito male ogni arduino NANO controlla 2 flussometri (caldo e freddo)...giusto?
nel tuo skecth ad ogni avvio loop() azzeri i due contatori degli impulsi...e metti un delay(1000) per rallentare il loop() con l'intento di farlo ciclare ogni secondo...poi moltiplichi gli impulsi ricevuti *60 dividendo per 7.5...questo dovrebbe darti i litri minuto...giusto!?
io farei...nella ISR...misura del tempo trascorso tra un impulso ed il precedente(benedetto millis())...userei questo per stimare il numero impulsi e calcolare la portata...
si esatto, pero a me non interessa calcolare la quantità,il tot di litri che passano
io ho soltanto bisogno che (ipotizziamo una perdita ) il flusso del liquido va a diminuire ed in quel instante deve dare l'impulso al rele
tutto qui
se ho capito...tu vorresti misurare l'acqua in ingresso, ad una caldaia(?), quindi fredda e verificare quanta ne esce...o meglio quanta ne arriva a destinazione quindi calda!?
ok...dato che, secondo me, non è bene determinare una perdita da una lettura secca di un dato ma questo va "filtrato/mediato" salverei in due array le letture fatte per calda e fredda, e ne determinerei l'andamento considerando un tot% di tolleranza dei flussometri.
no ,il circuito e il seguente:
un circuito chiuso (composto da pompa e flussometro ) fino a quando il flussometro indica un certo valore (ex 100) tutto funziona quando il flussometro arriva a indicare un valore minore a quello da me indicato ex (50) deve dare il segnale
questo,essendo il circuito chiuso si può verificare soltanto quando ce una perdita nel sistema
non ho capito come devo crearmi l ISR
e soprattutto dove devo inserirlo
Io non ho trovato sul reference una informazione tra virgolette importante
la lunghezza dei NOMI delle variabili
ho pensato che se ti va con un solo flussometro ma con due no, la cosa potrebbe essere indotta da una certa confusione sulle variabili
sono ragionevolmente sicuro che attualmente in C le variabili vengono riconosciute dai PRIMI 63 caratteri
ma lo standard è stato rimaneggiato varie volte, non vorrei che lo IDE di arduino, o il suo compilatore, si fermi a meno
è una prova semplice da fare, cambia nome alle variabili con nome lungo, e usa nomi, anche di fantasie, non più lunghi di 10 caratteri, esempio cont1 cont2 flux1 flux2
come vedi tutto viene fatto nella funzione litres(); c'è una flag di primo impulso; la funzione modifica la variabile float litresMin, così hai qualche decimale, calcolando il tempo tra due impulsi...ovviamente essendo un calcolo sulle float devi gestire gli eventuali risultati NaN (not a number) ed inf (infinito)...che si possono generare.
docsavage:
Io non ho trovato sul reference una informazione tra virgolette importante
la lunghezza dei NOMI delle variabili
ho pensato che se ti va con un solo flussometro ma con due no, la cosa potrebbe essere indotta da una certa confusione sulle variabili
sono ragionevolmente sicuro che attualmente in C le variabili vengono riconosciute dai PRIMI 63 caratteri
ma lo standard è stato rimaneggiato varie volte, non vorrei che lo IDE di arduino, o il suo compilatore, si fermi a meno
è una prova semplice da fare, cambia nome alle variabili con nome lungo, e usa nomi, anche di fantasie, non più lunghi di 10 caratteri, esempio cont1 cont2 flux1 flux2
ci metti pochi minuti, e ci togliamo il dubbio
Interessante osservazione, tra l'altro valida per chiunque, non solo nel caso in esame.
Sarebbe da approfondire in un thread separato.
docsavage:
Io non ho trovato sul reference una informazione tra virgolette importante
la lunghezza dei NOMI delle variabili
E non la troverai perché è una cosa che riguarda il livello del compilatore, l'attuale toolchain è C99 compliant, anzi dovrebbe essere C11, pertanto vengono considerati i primi 63 caratteri del nome di una variabile, quelli ulteriori vengono ignorati, se la variabile è external vengono considerati solo i primi 31 caratteri.
In tutti i casi se hai due variabili con lo stesso nome, ovviamente globali o locali nella stessa funzione, il compilatore si ferma e segnala l'errore.
void litres() { // questa è una ISR
if (!firstTime) {
myMillis = millis();
firstTime = true;
}
else {
litresMin = (60000.00 / (millis() - myMillis)) / 7.5;
myMillis = millis();
Serial.println(litresMin);
}
}
come vedi tutto viene fatto nella funzione litres(); c'è una flag di primo impulso; la funzione modifica la variabile float litresMin, così hai qualche decimale, calcolando il tempo tra due impulsi...ovviamente essendo un calcolo sulle float devi gestire gli eventuali risultati NaN (not a number) ed inf (infinito)...che si possono generare.
Buongiorno
grazie mille per l'esempio ,e soprattutto grazie per la spiegazione
provvedo subito a fare delle prove ed ha vedere se funziona
ps:eri guardandomi diversi esempi sono arrivato a scrivere questo
se devo dire la verità non lo fatto seguendo una logica ,ho guardato i vari esempi ed facevo delle prove ed ha funzionato
faccio le prove poi scrivo i risultati
grazie ancora
docsavage:
Io non ho trovato sul reference una informazione tra virgolette importante
la lunghezza dei NOMI delle variabili
ho pensato che se ti va con un solo flussometro ma con due no, la cosa potrebbe essere indotta da una certa confusione sulle variabili
sono ragionevolmente sicuro che attualmente in C le variabili vengono riconosciute dai PRIMI 63 caratteri
ma lo standard è stato rimaneggiato varie volte, non vorrei che lo IDE di arduino, o il suo compilatore, si fermi a meno
è una prova semplice da fare, cambia nome alle variabili con nome lungo, e usa nomi, anche di fantasie, non più lunghi di 10 caratteri, esempio cont1 cont2 flux1 flux2
ci metti pochi minuti, e ci togliamo il dubbio
anche per me vale la stessa cosa di "docsavage" usando nomi troppo lunghi rischio poi di perdermeli durante la scrittura del programma (soprattutto se il programma e molto lungo )
comunque faro delle prove per vedere se cambia qualcosa
cosi almeno ci togliamo il dubbio