Ciao a tutti,
vi presento il progetto su cui sto lavorando: gassificare un motore a benzina.
Tralasciando tutta la parte teorica sul funzionamento del motore e della miscelazione, per ora mi sto concentrando sull'interpretazione del segnale di crank proveniente dalla ruota fonica tramite un sensore magnetico.
La parte hw è già definita e funzionante, tramite un MAX9924 converto gli impulsi del sensore magnetico in onda quadra TTL compatibile: il treno d'impulsi corrispondente ai 60-2 denti della ruota fonica viene replicato dall'integrato come un segnale alto durante il passaggio del dente davanti al sensore e un segnale basso durante il passaggio della gola davanti al sensore.
Quando si hanno i "denti mancanti", l'integrato solleva a Vcc l'uscita grazie al pullup, quindi si ha un segnale alto di durata t multiplo dei denti mancanti.
Bene.. sperando di aver chiarito, ora vi posterei il codice da me scritto con l'intento di avere in uscita da Arduino UNO un'impulso corrispondente ai "denti mancanti".
Inutile dire che non è funzionante...
const int led = 13;
volatile unsigned long trif=0; //tempo corrente
volatile unsigned long trif_1=0; //tempo precedente
void setup()
{
pinMode(led, OUTPUT);
attachInterrupt(0,conteggio,FALLING);
}
void loop()
{
}
void conteggio()
{
trif=pulseIn(2,HIGH);
if (trif > trif_1)
{
digitalWrite(led,HIGH);
delay(trif);
trif_1=trif;
}
else
{
digitalWrite(led,LOW);
trif=0;
}
}
Vi ringrazio anticipatamente per l'aiuto... Attualmente in uscita ottengo un segnale costante a livello logico basso.
Grazie dell'attenzione.
Aldo
Rileggendo ho già trovato un errore: non posso porre trif_1=trif alla fine dell'if senno come tempo precedente avrò sempre il periodo massimo dell'impulso.
Ho modificato in questo modo e ora ottengo un segnale sempre alto:
In teoria la sto già usando, applico il segnale sul pin dell'interrupt 0 e poi abilito la funzione "conteggio" ogni fronte di discesa.
Poi dentro alla funzione "conteggio" misuro la durata dell'impulso alto e la confronto con la durata del precedente impulso alto.
Se la durata dell'impulso corrente è maggiore della durata dell'impulso precedente, allora sono in presenza del dente mancante. Quindi genero un impulso in uscita con Delay(durata impulso corrente).
Quindi dovrei usare un millis() tra 2 interrupt diversi, uno sul fronte di salita e uno sul fronte di discesa, per sapere quanto tempo è passato tra i 2 eventi?
Perché mi sembra di aver capito dalle faq che all'interno di una isr non si possa usare millis()
Nel frattempo ho scoperto che, scritto come l'ultima versione da me postata, trif=0 sempre in ogni caso, guardando il monitor seriale.
Tra l'altro effettua 3 letture e poi si interrompe.
Di eliminare i delay ci avevo già pensato, ma non sapevo come fare.
....the use of delay() in a sketch has significant drawbacks. No other reading of sensors, mathematical calculations, or pin manipulation can go on during the delay function, so in effect, it brings most other activity to a halt.
Sempre o solo quando inserisci il serial print all'interno dell'interrupt?
Perché ho letto più di una volta che il serial print all'interno degli interrupt genera problemi..
Kafer:
Sempre o solo quando inserisci il serial print all'interno dell'interrupt?
Perché ho letto più di una volta che il serial print all'interno degli interrupt genera problemi..
Hai ragione, mettendo tutto nel loop() stampa correttamente
L'interrupt si attiva ogni cambiamento del segnale.
Noto che ogni tanto la variabile tempo assume un valore sensato, però rimangono dei dubbi:
1_ teoricamente la variabile tempo dovrebbe stamparmi il valore del periodo del segnale corrispondente al dente mancante
2_ il loop e l'interrupt sono sincronizzati? Nel senso, l'interrupt si attiva ogni cambiamento del segnale ma il loop ogni quanto si attiva? Ogni colpo di clock o comunque con una frequenza relativa al colpo di clock?