lettura della quantità di impulsi compiuti in 10 sec

Buongiorno .. è da un po' di tempo che sto lavorando ad un progetto ma sono fermo a causa di un problema nella programmazione.

L'obiettivo è quello di leggere la velocità di una ruota che gira attorno ad un piccolo albero (cioè in un delta t di 10 secondi rilevare il numero di giri) e "nello stesso istante" rilevare il continuo incremento di giri

Ho a disposizione un sensore a forcella(fototransistor, led ir) e arduino uno

Se potete darmi delle dritte su come impostare il programma

La parte di incremento è semplice e l,ho già fatta ma il resto mi da dei valori sbagliati

int po = 7; //porta di lettura
int i = 0;//blocco
int q = 0;//blocco
unsigned int gt; // numero di giri totali
unsigned int gp; // numero di giri ogni 10 secondi
unsigned int x; // variabile per il millis

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

void loop() {

if ( digitalRead(po) == HIGH and i == 0)
{
  gt++;
  i = 1;
}
if ( digitalRead(po) == LOW and i == 1)
{
  i =0;
}
if ( (millis()-x) % 10000 > 0 and (millis()-x) % 10000 < 1000 and q == 0)
{
  x = millis();
  gp = gt - gp;
   
  q = 1;
  Serial.println ("numero giri ogni 10 sec :");
  Serial.println (gp);
  Serial.println ("numero giri totali :");
  Serial.println (gt);
  gt = gp;
}
if ( (millis()-x) % 10000 > 1000 and q == 1)
{
  
  q = 0;
}


}

Ciao, innanzitutto la variabile x la devi definire unsigned long e non int per rispettare il tipo restituito da millis().
Potresti pensare di utilizzare l'interrupt per leggere gli impulsi, ti eviti l'if doppio all'interno del loop e forse è anche più affidabile visto che mentre notifichi il numero di giri vuoi continuare a rilevarli. Impostandolo a RAISING potrebbe fare al caso tuo, nell'isr delle interrupt incrementi sia il contatore parziale che totale dei giri, nel loop non ti resta che verificare se la differenza tra millis() e il valore che hai memorizzato precedentemente nella variabile x è maggiore o uguale al tempo limite (nel tuo caso 10 sec), se si stampi i valori delle variabili e salvi di nuovo in x l'attuale valore di millis()
Per verificare il tempo ti basta una cosa del tipo

if(millis()-x>=10000){
  x=millis();
}

Grazie dell'aiuto, ma dopo aver provato con una piccola prova per usare l'interrupt per creare un semplice contatore di giri non mi da un giusto valore ecco il codice

L'obbiettivo ad ogni volta che da LOW passa a HIGH incrementa (con gli if che avevo fatto funzionava con questo no da delle diverse rilevazioni)

Se puoi correggimi dove ho sbagliato Grazie

unsigned int gt; // numero di giri totali
int po = 2; //porta di lettura
void setup() {
Serial.begin(9600); 
pinMode (po,INPUT);
attachInterrupt(0, incr, RISING); 
}
void loop() {
Serial.println(gt);
}
void incr() {
gt++;
}

Il codice sembra corretto, in che senso ti da valori errati? Ti da più impulsi di quelli effettivi? Se si potresti provare a cambiare leggermente e incrementare sul fronte di discesa in questo modo:

pinMode (po,INPUT_PULLUP);
attachInterrupt(0, incr, FALLING);

e vedere se si risolve, altrimenti potrebbe servirti un debounce hardware (condensatore+resistenza).
In ogni caso non è che non puoi usare il tuo codice che funziona, dovresti cambiare la parte di verifica del tempo come ti ho indicato nel post #2, il dubbio è che la prate di codice che rileva gli impulsi stia simulando un debounce che potrebbe non funzionare correttamente in tutte le condizioni (velocità, frequenza, ecc.) però, ripeto, se funziona puoi usarlo senza problemi

Ciao,
la variabile gt, dato che la usi all'interno di un interrupt, dovrebbe essere dichiarata volatile (cfr.
https://www.arduino.cc/en/Reference/Volatile)

pippettiello:
Ciao,
la variabile gt, dato che la usi all'inetrno di un interrupt, dovrebbe essere dichiarata volatile (cfr.
https://www.arduino.cc/en/Reference/Volatile)

Hai ragione mi è proprio sfuggito, potrebbe essere proprio questa la causa dei valori errati

molto probabilmente i valori errati sono dovuti ai "disturbi elettrici" che un pin impostato come INPUT senza resistenze esterne può ricevere...se si imposta come INPUT_PULLUP si dovrebbe risolvere questo problema (adeguare cablaggi!)...altra cosa è il possibile effetto bouncing .

Ho provato la modifica dello sketch come mi avete consigliato ma la lettura nonostante questo le lettura non corrispondono hai valori reali (cioè interrompo il fascio una volta e nella siriale è present un'altro valore al posto di uno)

Per il debounce hardware non penso ce ne sia bisogno già nel modulo del sensore a farcella l' FC-33 avrà al suo interno delle resistenze di pull down, il condenstore non è presente dici sia questo visto che nonostante abbia cambiao software non cambia

const int po = 2; //porta di lettura


volatile unsigned int gt; // numero di giri totali

void setup() {
Serial.begin(9600); 
pinMode (po,INPUT_PULLUP);
attachInterrupt(0, incr, FALLING); 
}

void loop() {

}




void incr() {

  gt++;
Serial.println(gt);
}

ciao....da un occhio a questo LINK...sopprattutto parte hardware alla fine....

Molto utile questo link grazie

Nonostante abbia messo un condensatore da 82 nF (anche se era indicato 100nF ma con questi condensatori hanno tolleranze di +- 20%) perciò ho pensato vada bene ho provato per l'ennesima volta e non rileva i valori misurati

Non so che fare. Aumento la capacità a 100nF giusti ?

Non so se sia una cosa simile, comunque io ho avuto in passato un problema analogo con un sensore IR a forcella, esattamente un FC-03 (qual è il tuo?).

In pratica ho risolto ma con un escamotage, ossia prendo il segnala output analogico (AO) invece di quello digitale (DO) e con quello sembra funzionare.

Puoi trovare tutto il thread QUI.

No non è quello docdoc, come ho scritto sopra è un fc-33 ha solo un pin digitale a differenza del tuo che ha in più il pin analogico.

Ma in conclusione sei stato in grado di capire il problema

Capire no, credo/temo che fosse il modulo difettoso, ma come puoi leggere nel thread che ti ho linkato, ho risolto usando l'uscita analogica al posto di quella digitale.
Nel tuo caso se hai solo quella digitale non credo che, se il problema è come il mio, si possa fare molto se non acquistare un altro encoder dotato di entrambe le uscite...

ciao va bene

grazie per la disponibilità