acquisire parallelamente

Salve!

Ho un problema nell' acquisire degli impulsi che si verificano con una cadenza temporale di 0,5 secondi, il mio target e' un Pic16F627 a cui arrivano 8 segnali proveniente da contapezzi, il problema che mi pongo e' il seguente: fino a che funziona 1 solo contapezzi con il polling degli ingressi del pic riesco a contare senza problemi, se invece i contapezzi in funzione sono due e per pura sfortuna questi dovessero essere sincronizzati vorra' dire che nello stesso istante mi arrivera' un segnale di cambio stato su i relativi ingressi del micro quindi mi perderei uno dei due contapezzi. Attualmente uso una sorta di polling sugli ingressi usando anche un antirimbalzo software di 20ms, esiste una tecnica software o hardware per scongiurare questa problematica?

Reply to
Diego
Loading thread data ...

Usa l'interrupt on change della portab RB4:RB7 Così avresti 4 interrupt che, al cambio di stato di uno di questi pin, abilitano la tua routine di interrupt. Per averne di più prendi esempio da un keypad:

formatting link
Sarà la tua routine a stabilire quale contapezzi ha generato l'interrupt. ciao JohnnyRun

Reply to
JohnnyRun

Basta confrontare un campionamento con quello precedente e vedere se vi sono state variazioni. Poi, il nuovo dato diviene quello vecchio di confronto. Di solito si usa la funzione XOR. In caso di variazioni, si analizza bit per bit l'input e si aggiornano i contatori.

Con tempi cos=EC laschi ti conviene sorvegliare le linee in polling su timer-interrupt.

Piccio.

Reply to
Piccio

"Diego" ha scritto nel messaggio

Dovresti secondo il mio modesto parere vedere quanto tempo dura l'impulso, a questo punto se la tua funzione compresa quella dell'antirimbalzo vengono eseguiti in tempi minori, allora vorra' dire che non dovresti perdere nulla, pero' meglio se segui i consigli degli esperti che qui non mancano.

Reply to
gulp

"JohnnyRun" ha scritto nel messaggio news:

Ti ringrazio, ma non capisco cosa cambierebbe, il problema secondo me dovrebbe rimanere, se due ingressi del pic vanno alti nello stesso istante verra' servito 1 solo interrupt quindi probabilmente mi perdero' l'altro ingresso, cosa succede infatti se si sta eseguendo la routine dell' interrupt ad esempio della RB4 e c'e' anche RB6 che varia il suo stato? interrupt nell'interrupt?

Reply to
Diego

"Piccio" ha scritto nel messaggio:

Quindi tu dici che la strada del polling e' valida con l'aggiunta di eseguirlo con l'interrupt ad esempio del timer0, ad ogni interrupt vado a leggere gli ingressi ed eseguo XOR della lettura precedente.

Reply to
Diego

"gulp" ha scritto nel messaggio:

Effetivamente non avevo pensato a misurare quanto tempo duri l'impulso, dovrebbe e correggimi se sbaglio succedere questo; se la routine del polling di tutti gli ingressi avviene in 5ms mentre l'impulso che arriva all'ingresso del pic dura 200ms vorra dire che sono dentro con i tempi, perche' la routine e' 40 volte piu' veloce dell' evento e dunque non ho problemi a seguire eventi paralleli cioe' che iniziano e finiscono in contemporanea perche' il micro e' piu' veloce?

Reply to
Diego

Diego ha scritto:

Immagino che attualmente fai una cosa sequenziale del tipo:

- leggi ingresso

- se impulso presente fai debouncing 20mS

- se ancora presente incrementa contatore

- leggi successivo ingresso ecc...

...ma chiaramente cosi' non funziona per impulsi contemporanei brevi.

Piuttosto ogni pochi millisecondi:

- acquisire tutti gli ingressi

- su ciascuno applicare il proprio debouncing usando un array di contatori e uno di stati

- per ciascuno se impulso ancora presente aggiornare il relativo contatore finale

A questo punto che sia uno o 100 cambia poco (solo la grandezza degli array e il tempo totale impiegato per elaborare i debouncing).

ciao Claudio_F

Reply to
Claudio_F

Diego:

Quant'è la lunghezza dell'impulso e quale la distanza minima tra gli impulsi? Quanto durano i rimbalzi? Ci sono solo in chiusura, vero?

Io farei un polling ogni (durata rimbalzo) ms.

Associ un contatore ed un contatore contapezzi ad ogni input. Incrementi il contatore se il contatto è chiuso e lo azzeri se è aperto.

Quando il contatore arriva a 2 incrementi il relativo contatore contapezzi, quando arriva a 4 lo decrementi.

--
Ma non si può intendere se prima non s'impara a intender la lingua
Reply to
F. Bertolazzi

E' lo stesso problema che hanno anche le "reti", pero' in questo caso si deve trovare una soluzione semplice. Una potrebbe essere quella di utilizzare 8 ingressi d'interrupt, ma difficilmente sono presenti cosi' tanti ingressi di questo tipo su un micro. L'altra, per usare appunto un solo ingresso d'interrupt, potrebbe usare un multiplexer ad 8 in. commutato dal micro: in sostanza sai ad ogni istante a quale contapezzi sei connesso e se arriva l'interrupt lo pui gestire diversamente a seconda delle tue necessita' .

giorgio

Reply to
Giorgio Padoan

"Diego" ha scritto nel messaggio news:4c9d9ea0$0$30900$ snipped-for-privacy@news.tiscali.it...

io acquisirei in interrupt periodico a 5ms, con tutti gli 8 ingressi sulla stessa porta, poi via software una cosa del genere (scritto in C)

variabili globali byte val_ingressi; byte val_precedente; byte trigger; byte ultimi[4]; int i=0;

funzione_di_interrupt_periodico_5ms () { ultimi[i] = input_porta(); val_ingressi = ultimi[0] & ultimi[1] & ultimi[2] & ultimi[3]; // antirimbalzo 20ms i = (i+1) & 0x3; trigger = trigger | ( val_ingressi & !val_precedente ); // rilevamento fronte salita val_precedente = val_ingressi; }

nel main del programma puoi testare i singoli bit di trigger per sapere se un ingresso e' stato attivato e dopo che lo hai rilevato azzeri il bit, cioe'

if( trigger & 1 ) { trigger = trigger & ~1; funzione_ingresso_0_attivato(); } if( trigger & 2 ) { trigger = trigger & ~2; funzione_ingresso_1_attivato(); } if( trigger & 4 ) { trigger = trigger & ~4; funzione_ingresso_2_attivato(); } eccetera

la funzione di interrupt esegue solo il set dei bit di trigger e la funzione del main in polling esegue solo il reset, cosi' se un ingresso si attiva rimane memorizzato anche se la sua durata e' inferiore alla durata della routine che serve un altro ingresso

non conosco il PIC, quindi non so dirti come devi fare, ma e' importante che l'istruzione "trigger = trigger & ~n", non venga interrotta dall'interrupt periodico.

Reply to
alfio

Salve!

Ringrazio tutti quelli intervenuti, tutti avete contribuito a farmi capire le diverse strade per affrontare e risolvere la problematica del post.

Reply to
Diego

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.