Timer 1 usato due volte in modi diversi

Forse con la pulseIn potresti risolvere. Su che ordine di grandezza di tempi stiamo ragionando? La pulseIn misura da 10 uS in su. Sarebbero sufficienti?
Stavo poi ragionando sul modo con cui usi il timer 1.
Che cosa faresti con CS11? Quel flag è usato per impostare il prescaler, non la modalità di funzionamento del timer

Ho provato con la pulseIn() a misurare la durata dell'impulso, sotto i 10us non ci vado mai, ma ho notato che il codice rallenta molto.

CS11 lo metto a zero per fermare il timer (dato che secondo il prescaler che uso anche gli altri CS sono a zero) che sennò continuerebbe a contare generando un pwm.

ekjk:
Ho provato con la pulseIn() a misurare la durata dell'impulso, sotto i 10us non ci vado mai, ma ho notato che il codice rallenta molto.

Il codice rallenta perché la pulseIn ferma tutto e si mette in attesa dell'impulso, misurandone poi la durata.

CS11 lo metto a zero per fermare il timer (dato che secondo il prescaler che uso anche gli altri CS sono a zero) che sennò continuerebbe a contare generando un pwm.

Ah, ho capito. Togli il segnale di clock al timer.
Ricordati però che quando riattivi il timer dandogli il clock (mettendo CS12 ad 1), il timer potrebbe non ripartire subito, subendo un certo ritardo proporzionale al fattore di prescaler. Tu usi un prescaler di 256, mi pare.
void counterISR da chi viene chiamata?

Ciao,
io uso un prescaler = 8, il tick diventa quindi 0.5us.
void counterISR viene chiamata da attachInterrupt sul pin 3 e su fronte RISING.

ekjk:
Ciao,
io uso un prescaler = 8, il tick diventa quindi 0.5us.

Sì, scusa. Avevo scritto CS12 per sbaglio e su quello mi basavo.

void counterISR viene chiamata da attachInterrupt sul pin 3 e su fronte RISING.

OK.

Comunque continuo a non capire la logica del tuo codice.
Vedendo le prime istruzioni della ISR agganciata all'interrupt di comparazione, tu fermi subito il timer.
Se ho capito è: arriva un segnale su un pin, richiamo un interrupt che fa partire il timer 1. Quando questo arriva al valore impostato da OC1A, fermo il timer. E poi?

Quando il timer arriva al valore OCR1A per prima cosa faccio

if(!NotRun && fire) PORTD = PORTD | B00010000;
  else PORTD =PORTD & B11101111;

Alzo il pin 4.

Dopo di che fermo il timer e calcolo i giri basandomi sul fronte di salita attuale e su quello successivo.

Non so se è chiaro, ma conoscendo la frequenza poi devo applicare un ritardo al segnale di uscita (pin 4) che scriverò in OCR1A e quando il timer arriva a tale valore alzo il pin 4 e fermo il timer.

Sì, ho capito.
Ma non posso aiutarti più di tanto perché per i tempi che servono a te occorrerebbe un oscilloscopio per vedere in quanto reagisce il timer a queste continue attivazioni/disattivazioni, strumento che io non ho. Cambiare valore di OCR1A in corsa non è un problema. Il problema secondo me nasce dall'attivazione/disattivazione del timer. Secondo me il timer riparte (non può non ripartire come dici tu) ma con un certo ritardo, per cui salti delle letture.

Io c'è l'ho l'oscilloscopio...infatti verifico queste cose.
Non c'è un modo per imbrogliare il timer?

Io vorrei che si fermasse...Nella modalità count normale quando va in overflow che succede? Chiama una routine e poi riparte?

ekjk:
Io c'è l'ho l'oscilloscopio...infatti verifico queste cose.
Non c'è un modo per imbrogliare il timer?

Io vorrei che si fermasse...Nella modalità count normale quando va in overflow che succede? Chiama una routine e poi riparte?

Come detto, se lo fermi e lo riattivi, passa un certo lasso di tempo.
Quando il timer manda in overflow il suo contatore, questo semplicemente riparte da zero. Viene chiamata una ISR se è stato attivato il flag per sollevare il corrispondente interrupt.

Non potresti semplicemente salvare il valore del contatore e poi reinserircelo quando ti serve far ripartire il conteggio?

leo72:
Non potresti semplicemente salvare il valore del contatore e poi reinserircelo quando ti serve far ripartire il conteggio?

Si potrei, ma supponiamo di caricare in OCR1A il valore 1000, con un tick di 0.5us il timer impiega 500us a contare per arrivare a 1000 e poi si riazzera e riparte di nuovo, generando una onda quadra.

Io invece necessito solo di un impulso, cioè alzare una uscita quando arriva a 1000 (per es) e poi lui deve star fermo fino al prossimo valore di OCR1A, al prossimo fronte di salita del segnale d'ingresso.

C'è un modo per fare così?

No, che io sappia. Se fermi il timer, incorri nel problema suddetto.
Però forse ti sfugge il fatto che puoi staccare il pin a cui è collegato semplicemente mettendolo come input e poi puoi ricollegarlo mettendolo come output. In questo modo il timer continua a ciclare ma non genera nessun segnale sui pin esterni.

Ecco a questa cosa non ci avevo pensato... Mi hai dato un buon consiglio. Ma nel fare questa operazione genero un ritardo secondo te?

Se metti il pin in input manipolando direttamente i registri del micro il ritardo è minimo, quantificabile nel tempo che serve al micro a decodificare a livello assembly l'operazione. Se usi la funzione pinMode il ritardo è nettamente maggiore.

Ciao' ho appena provato come dici tu ma ho visto con oscilloscopio che l uscita cosi non sta ferma ma si.muove

Disconnetti allora il pin impostando a 0 i flag COM2Ax e COM2Bx (dipende dal pin che stai usando).

Uso il pin 4. Quindi quali registri devo settare a zero?
E poi come li ripristino?

No, aspetta. Io intendevo pin collegati fisicamente al timer.
Ora capisco perché tu, mettendo il pin in input, continuavi a vedere qualcosa con l'oscilloscopio. Perché piloti un pin via software... non ricordavo questo particolare.

Prova usando un flag all'interno della ISR del timer che ti dice se devi pilotare il pin oppure no.

Si ma questo lo faccio già: quando il timer arriva al valore va nella ISR e la prima cosa che faccio è di alzare il pin 4...

Il software così funziona ma mi piacerebbe contare la width dell'impulso prima di alzare quel benedetto pin. Cioè, arriva l'impulso in ingresso, conto la width e dopo metto il valore in OCR1A in base a width (lo prendo da un array), il timer conta e quando ha finito alzo il pin 4.

Ma non puoi suddividere il compito su 2 timer? Hai anche il timer 2. Puoi usare quello come contatore. Vero che usa un contatore ad 8 bit ma nulla ti vieta di implementare un contatore a 32 bit usando una ISR che incrementa una variabile.

PS:
saresti così gentile da spiegarmi un po' più nel dettaglio cosa vuoi fare? Sarò rincogl..., ma ancora non ho capito bene cosa esattamente il tuo codice deve fare. :cold_sweat: