contagiri sensore hall (RPM)

Salve sto provando a realizzare un progetto, un contagiri con sensore magnetico da implementare su un kart con motore elettrico trifase. I giri sono letti con un snsore magnetico che rileva gli impulsi dati da un magnete fisso posto su un disco adiacente alla ruota. Il problema che riscontro è dato dalla conversione degli impulsi in RPM, ho provato ad usare l'interrupt per trovare il tempo che intercorre tra i due impulsi ma il programma non funge. Potreste aiutarmi?

Ciao,
essendo il tuo primo post, ti chiederei di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione … possibilmente evitando di scrivere solo una riga di saluto :wink:) e di leggere con attenzione il REGOLAMENTO

… poi, emmm … dato che non abbiamo la palla di vetro … se magari pubblichi il codice (… mi raccomando, racchiuso tra i tag CODE che, in fase di edit, ti inserisce il bottone </> … primo a sinistra) riusciamo anche a dargli un’occhiata :wink:

Guglielmo

Salve,grazie della risposta mi scuso di non essermi presentato.Lo sketch non ho potuto pubblicarlo prima di stamattina.Eccolo,abbiamo preso spunto anche da qualche altro post sul forum ma niente:
</
long T1a;
long T2a;
int RPM

void durata(){
T1a = T2a;
T2a = micros();
}

void setup(){
attachInterrupt(digitalPinToInterrupt(19),durata,RISING);

}

void loop() {if (T2a > T1a)
RPM = 60/ (T2a - T1a);
else
RPM = 0;
T1a = T2a;
lcd.print("RPM= "); //ho escluso nello sketch la configurazione del LCD.
lcd.print(RPM); }>

1. come ti avevo scritto il codice, in conformità al REGOLAMENTO, punto 7, DEVE essere racchiuso tra i tag CODE (… sono quelli che in edit inserisce il bottone fatto così: </>, tutto a sinistra).

2. Non ci hai detto che Arduino stai usando … dato che i pin disponibili per attachInterrupt() cambiano da modello a modello … non possiamo sapere se quanto scrivi è corretto o meno.

Guglielmo

prima di tutto le variabili usate all'interno di un Interrupt vanno dichiarate volatile

volatile unsigned long T1a;
volatile unsigned long T2a;

poi, visto che T1a e T2a rappresentano un valore in microsecondi, come po' questa formuletta dare un valore attendibile

  RPM = 60/ (T2a - T1a);

Rieccomi scusate lo sketch precedente ,ho notato ,anche io ,grazie a voi degli errori,uso un Arduino Mega 2560 ed ho riprovato a calcolarmi il tempo dei due impulsi e ora sembra andare,il problema ora è che gli RPM me li stampa nel monitor seriale sempre uguali a -1 ma raramente me li calcola,non so cos'é che non va :disappointed_relieved: .

volatile unsigned long T1;       //variabile che conta il tempo misurato dalla funzione millis()
volatile unsigned long T2;    
int TT;        //tempo trascorso
int RPM;


void setup(){

attachInterrupt(0,Evento,RISING); 
Serial.begin(9600);              

}


void loop() {                              

T1 = millis();   
RPM = (1000 / T1) * 60 ;    //mille perchè il tempo calcolato è in millisecondi           

}


void Evento(){       

TT = T1 - T2;
Serial.println(RPM);                      
T2 = T1;        //serve a permettere di calcolare il tempo dell iterazione successiva   
                                              

}

All interno di una ISR NON puoi chiamare la Serial.println() ... ... le ISR devono essere le più veloci possibili, aggiornare variabili ed uscire, le stampe le devi fare fuori !

Guglielmo

Ho lo stesso errore mi calcola gli RPM solo i primi 5 6 cicli poi da sempre 0.

Scusa ma la variabile TT dove la usi?

Dato che TT la aggiorni dentro la ISR, come ti ha già spiegato Brunello DEVE essere dichiarata "volatile".

Rimetti il codice aggiornato (... e senza la Serial.println() nella ISR).

Guglielmo

comunque lo sketch iniziale andava bene
erano solo le variabili mal assegnate e il calcolo RPM

volatile unsigned long T1a;
volatile  unsigned long T2a;
long RPM;

void durata() {
  T1a = T2a;
  T2a = micros();
}

void setup() {
  attachInterrupt(digitalPinToInterrupt(19), durata, RISING);
}

void loop() {
  if (T2a > T1a) {
    RPM = 60000000UL / (T2a - T1a);
  }
  else {
    RPM = 0;
  }
  T1a = T2a;
  lcd.print("RPM= ");
  lcd.print(RPM);
}

il programma mandato da brunello non funziona (gli RPM sono sempre uguali a 0) potresti mandarmi un codice funzionante?

su quale pin hai collegato il sensore ?

sul pin 2, come hai scritto dopo attachInterrupt(0,Evento,RISING); // INT 0 = pin2

o sul pin 19, come hai scritto prima attachInterrupt(digitalPinToInterrupt(19), durata, RISING);

Sul pin due ho cambiato anche sul tuo programma il pin da 19 a 0 ma niente

con (digitalPinToInterrupt(19) si specifica il numero del pin, non dell'interrupt quindi dovresti scrivere

attachInterrupt(digitalPinToInterrupt(2), durata, RISING); oppure attachInterrupt(0, durata, RISING);

Ho usato questo ma non va attachInterrupt(0, durata, RISING);

Avete qualche idea per risolvere il problema,non riesco proprio a trovare una soluzione.

a questo punto, visto che le tue conoscenze sono scarse, cominciamo dall'inizio

intanto verifica se l'interrupt viene rilevato

volatile unsigned long T1a;
const byte pin_sens = 2 ;// pin a cui e' collegato il sensore

void durata() {
  T1a++ ;
}

void setup() {
  pinMode(pin_sens , INPUT_PULLUP); // attiva la resistenza di PullUP
// se non serve il pullUp   pinMode(pin_sens, INPUT);
  Serial.begin (115200); // apertura porta seriale. verificare la velocità
  // di seguto l'attivazione dell' Interrupt che puo' essere
  //  RISING = fronte di salita
  //  FALLING = fronte di discesa
  //  CHANGE  == cambio di stato
    attachInterrupt(0, durata, RISING); // collegato al pin 2 ( INT 0 )
  }

void loop() {
  Serial.println(T1a);
}

ti visualizza un numero che si incrementa tutte le volte che c'e' un Interrupt

va incrementato come andava prima il PROBLEMA sono gli RPM.