Newsgroup: it.hobby.elettronica.digitale
Titolo: misurare duty cycle con atmega64

 Ciao,
sto riprogettando una schedina di acquisizione dati da usare in auto per 
visualizzare e dataloggare una serie di valori analogici (temperature, 
pressioni, accelerazione) e misurare delle frequenze (giri/velocita'), la 
scelta del micro è caduta su ATMEGA64, la frequenza di campionamento è di 
circa 20 Hz, quindi ogni 50 mS, per i parametri fondamentali.
Per il discorso analogico nessun problema, per le frequenze avrei pensato di 
usare i due capture di cui dispone (TIMER 1 e TIMER3, a 16 bit). Si tratta 
di due segnali che possono andare da zero a circa 500 Hz (giri motore) e da 
zero a 200 Hz (velocita').  Il "problema" è che, per calcolare i consumi e 
verificare le mappature e correzioni, devo misurare anche il duty cycle 
degli iniettori. Purtroppo non posso misurare i giri usando questo segnale 
(altrimenti avrei potuto fare il rapporto tra livello basso ed alto), 
perche' in rilascio l'iniezione è interrotta.
Consigli ? Nella versione dell'acquisizione che sto usando c'e' un piccolo 
PIC ad 8 pin che legge lo stato del pin ogni 200 uS per 1250 volte (250 mS) 
ed incrementa di uno un registro ogniqualvolta il pin è alto, al termine 
trasmette via seriale il risultato al micro principale, azzera e riparte. In 
questo modo ho il dutycycle medio misurato negli ultimi 250 mS. Potrei usare 
il TMR0 in modalita' CTC, un'interruzione ogni 200uS e leggo il pin, ogni 
250 colpi vado a gestire il discorso campionamento (che deve essere ogni 50 
mS precisi in quanto è usato come base tempi per un cronometro e per la 
visualizzazione dei parametri da mettere in sovraimpressione nei cameracar), 
pero' temo che con int timer cosi' ravvicinati  avrei delle sovrapposizioni 
con l'interrupt ADC ( ci sono un bel po' di parametri analogici da leggere) 
ed i capture...
Ciao,
Pier.
www.piergm.com

 degli iniettori.
cut...
Per la velocità ed il numero di giri potresti evitare i capture visto
che le frequenze in gioco sono sufficientemente basse e non ti
interessa una misura interna al periodo.
E' sufficiente usare due pin di interrupt esterni.
Il tempo di risposta all'interrupt deve essere inferiore al minor
intervallo degli eventi che devi misurare, ovvero, 1/500 di secondo =
2 millisecondi, più che abbondanti.
Eventualmente puoi usare un piccolo trucco che io stesso ho adottato
proprio per un contagiri da go-kart: entro poche istruzioni di ogni
subroutine di gestione degli interrupt, riabilitarli immediatamente in
modo da non perdere mai un colpo.
Ovviamente bisogna evitare la ridondanza, cioè impedire che un secondo
evento identico debba essere gestito prima che quello corrente sia
finito (basta un flag, un semaforo oppure un contatore).
I capture li userei per gli iniettori per introdurre minor errore
visto che devi effettuare misure all'interno di un periodo già corto.
Piccio.

 ed i capture...
Per problemi come questo è utilissimo utilizzare il compilatore Codevision,
che ti lascia 12 registri liberi che puoi utilizzare per avere degli
interrupt velocissimi, in quanto non devi pushare e poppare i registri
nello stack.

nello stack.
Oppure usare l'assembler che ti lascia 32 registri liberi   :-P
--
ciao
  Stefano


Cambiare compilatore, possibilmente e visto che si tratta di un qualcosa di 
hobbystico (quel che devo fare, non il compilatore :P), è una cosa che 
vorrei evitare :/
Ciao,
Pier.
www.piergm.com

 Oppure usare l'assembler che ti lascia 32 registri liberi   :-P
Da dove esce 'sto dinosauro? ;-)

Piccio.
Ciao,
Pier.
www.piergm.com


Ho messo troppi 3, diciamo che bisogna moltiplicare per 10 :D
Ciao,
Pier.
www.piergm.com

 giri/minuto, pero' un contagiri che si aggiorna 3 volte al secondo
Buonanotte, moltiplicare per 100, non per 10 o per 30 :)
Ciao,
Pier.
www.piergm.com

 possibile avere un buon refresh alle basse frequenze.
cut...
No, misurerei il periodo.
Metti un timer 16 bit in free running, espandi da software la
risoluzione se occorre (24 bit).
Ad ogni interrupt esegui la differenza del TCNTx con il campionamento
percedente ed ottieni il periodo che ti interessa dal quale ricaverai
la frequenza.
L'ultimo valore letto diventerà il vecchio del prossimo sample.
La misurazione è in tempo reale, ma io creerei una coda di almeno 4
campionamenti per effettuare una media.
Essendo il timer in free running, si presta a più misurazioni
(velocità, giri).
Puoi cos' usare i capture (hardware) per gli iniettori con la stessa
base dei tempi.
Quindi devi partire dalla risoluzione per gli iniettori e verificare
se devi espandere il contatore a più di 16 bit (credo proprio di sì).
Piccio.

Piccio.
Ciao,
Pier
www.piergm.com

 "congeli" la lettura del TCNT
Hai letto bene la sezione "input capture unit" del datasheet?

"F. Bertolazzi" <TOGL...@MAIUSCOLEtdd.it> ha scritto nel messaggio 
news:1cuqz6o2tqshg.1...@40tude.net...

Lui dice di non usare i capture hardware ma un interrupt qualunque su un pin 
di ingresso e copiare il registro "a mano"....

 di ingresso e copiare il registro "a mano"....
Già, hai ragione, chissà che gli è preso. ;-)
Confesso che non avevo letto il tuo post iniziale.
Se fai partire lo A/D con lo stesso timer con cui misuri gli impulsi avrai
una cosa sincrona al resto, quindi non dovrebbero esserci collisioni (o
essercene sempre...).
Potresti fare una lista precisa degli input che hai e cosa devi misurare?
Una cosa così:
1) Giri motore 0-500 Hz duty cycle 50% misurare frequenza a 20 Hz
2) Velocità 0-500 Hz duty cycle 50% misurare frequenza a 20 Hz
3) Iniettori 0-500 Hz duty cycle variabile misurare periodo a 20 Hz
4) Temperatura acqua 1-3V misurare tensione a 1 Hz
5) Livello carburante 0-4V misurare tensione a 0,1 Hz
Eccetera


Allora, è un po' lunga la faccenda, ma visto che me l'hai chiesto.... :D
Attualmente tutta sta roba, eccetto accelerometro e seconda lambda, la leggo 
con un 16F877, che ha due capture, + 12F675 che misura il duty + 2 grandezze 
analogiche e trasmette via seriale all'877  :
1) Giri motore 0-500 Hz, duty cycle circa 50%, misurare a 20 Hz
2) Velocita', 0-200 Hz, duty cycle 50%, misurare a 20 Hz
3) Iniettori, 0-250Hz  misurare dutycyle a 5 Hz
4) Temp. acqua, mia NTC tra massa ed in analogico, 10k tra in analogico e 
+5, lineariz. con lookup table ogni 5°C, oppure ingresso analogico NTC 
t.acqua su pin centralina, in pratica è la stessa cosa solo che il partitore 
è in centralina e cambia la tabella, frequenza 1-2 Hz
5) Temp. aria, come sopra 1-2 Hz
6) Temp.olio, NTC 1-2 Hz
7) Temp. esterna , NTC 1-2 Hz
8) Pressione olio, sensore resistivo 0/10 bar -> 10-200 ohm, sempre con 
partitore bastano 5 Hz
9) Pressione benzina, come sopra 5-10 Hz
10) Posizione farfalla 0-5V, 20 Hz
11) Tensione batteria, 5 Hz va bene
12) Pressione assoluta alimentazione motore 0-5 V 20 Hz
13) Livello carburante, 0-5V direi 1 Hz e media su 10 campioni almeno.
14) Sonda lambda narrowband 0-1 V, ha un'impedenza molto alta, 20 Hz
15) Sonda lambda wideband 0-5V, il segnale è fornito da un controller 
esterno, 20 Hz
16) Sarebbe bello temperatura gas di scarico con MAX6675 , SCK / CS / DATA 
mi pare, qualche Hz
17) Accelerometro KIONIX KXP5 su SPI (o su rs232) X/Y/Z a 12 bit, 20 Hz
Vari ingressi digitali tra cui :
a) pedale freno, 20 Hz
b) luce cronometro, 20 Hz (il ricevitore, che ha un 12F675+TSOP1738, quando 
riceve il pacchetto trasmesso dalla torretta alza un pin per un secondo, 
siccome mi accontento anche di 1 decimo come errore max, ogni 50 mS 
controllo quel pin).
c) attuatore VTEC
d) boh
e) boh
..
Penso sia tutto.
Visto che non bastano gli ingressi ADC mi sa che conviene tenere il 12F675 e 
fargli leggere, come faccio adesso, oltre al duty cycle, cose di secondaria 
importanza come pressione olio, livello benzina e pressione benzina...
Tra l'altro mancherebbe comunque un ingresso e vorrei evitare un 
multiplexer, bah.
Ah, tutte queste cose vanno spedite sulla seriale a 19200 bps :)
Ciao,
Pier.
www.piergm.com

 multiplexer
A che punto sei con la ristrutturazione del tutto? Hai già l'ATmega64?
I segnali analogici possono essere ridotti da 0-5V a 0-3.3V?
In questi giorni dovrebbe arrivarmi, oltra ad un Arduino, anche questa:
http://www.sparkfun.com/commerce/product_info.php?products_id=9546
Non mi è chiaro se ho preso un pacco o no, ovvero se comprenda anche il
processore. Che ne dici? Ti consentirebbe di fare tutto con un solo
processore, e ti avanzerebbero ancora un sacco di risorse.


Ci penso :)
ora devo scappare.
Ciao,
Pier
www.piergm.com

 Ci penso :)
Mah, se hai già i 64 (peraltro credo siano sulla strada dell'obsolescenza
anche quelli versione A) e hai segnali 0-5V, sarebbe legittimo usarli.
Anche perché, con quelli e gli altri processori da coordinare, è tutto più
complicato e quindi divertente. :-)

 complicato e quindi divertente. :-)
Si, in effetti... :)
Ah, un'altra cosa : per il discorso ingressi ADC, come potrei fare per 
disturbare il meno possibile la lambda ? Un inseguitore di tensione fatto 
con un OPAMP rail to rail ? Nella centralina dovrebbe esserci un LM2903 
usato come inseguitore di tensione (tra pin lambda ed in analogico del 
micro, un OKI 66507), ed un multiplexer 4051 per le NTC.
Il potenziometro della farfalla entra direttamente, con in serie una R da 
10k.
Comunque, dalla selezione dell'ingresso ADC cambiando i bit MUX4:0 di ADMUX 
quanto mi conviene aspettare prima di far partire la conversione ? Vedo che 
il sample and hold ha capacita' di 14 pF, quindi con un'impedenza di 
ingresso di, diciamo 50k, il condensatore dovrebbe essere carico dopo tau = 
5, ovvero 3.5 uS.
E' corretto ? Posso attendere anche 100uS comunque, tanto ho quasi 50 mS di 
tempo per campionare 12 valori :)
Se posso approfittare della vostra disponibilita' avrei da chiedere un'altra 
cosa sul display che sto usando per il quadretto strumenti, con controller 
T6963C : non riesco in nessun modo a mappare i caratteri personalizzati 
nelle locazioni da 127 a 255, me ne carica circa una quarantina da 205 a 255 
ignorando i precedenti.
Ciao,
Pier.
www.piergm.com

 ignorando i precedenti.
Mi sa che non hai abbastanza RAM o ne hai allocata troppa al display.


Boh, sinceramente non credo sia questo il problema, perche' CG RAM area è 
subito dopo Graphic area, se scrivo nella graphic area si accendono i pixel 
come dovrebbero, se scrivo negli indirizzi successivi non capita nulla, se 
continuo a scrivere ad un certo punto mi compaiono i caratteri non nelle 
prime locazioni riservate ai caratteri speciali ma un bel po' dopo, da 205 o 
215 come detto. Mah...
Il fatto è che disegnare nel layer grafico mi rallenta tantissimo la 
tracciatura perche' devo farlo accendendo un pixel alla volta, per le 
barrette orizzontali alte 8 pixel mi son creato dei font con 1, 2, 3, 4, 5 e 
6 linee verticali ed affiancandoli riesco a disegnare una barra della giusta 
lunghezza in tempo zero o quasi, pero' vorrei fare la stessa cosa per i font 
grandi (4 font 6x8 per ogni font grande), è che non mi basta la memoria 
perche' 0-9 e punto decimale fanno 40 caratteri...
Ciao,
Pier.
www.piergm.com

 tracciatura perche' devo farlo accendendo un pixel alla volta,
Lo fai lasciando un ritardo fisso o leggendo il byte di status?

 Lo fai lasciando un ritardo fisso o leggendo il byte di status?
Leggendo il byte di status, in questi giorni non ho molto tempo, ma appena 
posso approfondisco la cosa.
Intanto grazie,
ciao.

 Credo di si'...
Credi? Prova a settarlo sbagliato, allora.