Algoritmo decodifica protocollo infrarosso sony SIRC

Aug 18, 2009 7 Replies

Ciao a tutti di nuovo Più vado avanti e più mi rendo conto di essere un mediocre! determinate cose non riesco a capirle... credo di non avere una mente abbastanza "reattiva"... delle volte accetto la situazione e vado avanti altre...come in questo caso... la "tigna/testardaggine" non mi permette di accettare la mia ignoranza... ed eccomi qui a chiedere spiegazioni poichè su internet la miriade di siti che ho trovato sui decoder ir non riuscivano a spiegarmi la questione nel modo compatibile alla mia mediocrità ;)



il punto in cui mi blocco è alla radice del problema... mi riferisco al protocollo sirc ad esempio...

formatting link



come diamine faccio a capire quando sono passati 600us...(presumo siano 0,6 ms) ok..uso il timer... l'interrupt...ma poi?!?! come dovrei configurarlo...con che frequenza....



è più forte di me...non c'arrivo....

qualche anima pia .... può/riesce a spiegarmi...


il medriocre....saluta Contrario


"Contrario" ha scritto nel messaggio news:4a8a4c00$0$40015$ snipped-for-privacy@reader3.news.tin.it...

Visto il caldo, non vorrei sparare mostruosità, ma non mi sembra estremamente difficoltoso. Se riesci a discriminare in hw la presenza della portante a 40KHz (un semplice rc, es 1K + 33nF) avrai sull'ingresso direttamente i bit da decodificare. Ti serve un ingresso con possibilità di capture. Inizializzi l'hw per la generazione dell'interrupt + capture nello stato cambio fronte del segnale ('portante assente' e 'portante presente'). Andando a leggere il timer associato al capture, riesci facilmente a discriminare i bit di START, 0 e 1 e relativa durata. Una volta identificato l'inizio del messaggio con i relativi bit, si tratta solo di memorizzarli in un buffer per poi gestirlo come comando completo.

Contrario ha scritto:

Supponendo di usare un ricevitore IR che demoduli per conto suo (che sono troppo stracomodi) io farei molto banalmente così:

aspetti il fronte di salita

attendi un millisecondo (non è critico... in realtà qualunque valore più lungo di 600uS ma più corto di 1200uS... dipende da quanto tempo ti serve per le operazioni successive... da 800uS a 1000uS dovrebbe essere OK... eventualmente metodo galileiano e via :D )

leggi lo stato del segnale (sarà il valore del tuo bit letto)

aspetti fino a quando il segnale non è basso

ripeti fino a quando non hai letto tutti i bit

Sempre che tu possa permetterti funzioni bloccanti, questa lo è.

Dovrai inoltre prevedere un timeout di qualche tipo che ti faccia uscire dai loop di attesa se per caso la ricezione si interrompe.

Preferirei utilizzare un rivelatore di picco, in quanto non vorrei che la V in uscita dall'RC fosse troppo bassa. Per cui un diodo al germanio (ma va bene anche al silicio 1n4148) collegato col catodo all'RC, per questo userei una costante un po' piu' alta, mettendoci una R=10K invece che 1K, ed usa un pin ingresso triggerato. Per il resto ti basta misurare il periodo T tra una salita e l'altra e confrontarlo con 0,9ms per capire se e' uno 0 o un 1. Il capture sul fronte di salita ti permette di misurare T. Il clock del capture non sceglierlo troppo alto, possibilmente da evitare un overflow del suo registro, il che ti semplifica i calcoli per avere T.

ciao giorgio

On 18 Ago, 08:36, "Contrario" wrote: [cut]

,6

Immagino che tu abbia la possibilit=E0 di fare un capture del segnale (tra l'altro deve essere "pulito", quindi senza la portante da 40KHz); in tal caso devi solo discriminare gli zeri dagli uni e il bit di start effettuando un conteggio tra il fronte di salita dell'impulso ed il successivo insomma...una cosa tipo quella che ti ho scritto sotto in pseudo codice.

####### .... boolean START; // imposto quando rilevo il bit di start int16 dato_tmp;//variabile tempranea per memorizzare il dato int16 dato // varabile che conterr=E0 il dato valido int8 contatore_timer=3D0;

#DEFINE DATA_LENGTH 12 // lunghezza totale di 12 bit int8 i;//variabile usata per per lo shift

setup_timer( timer programmato per generare un interrupt di 100us)

ISR timer //interrupt ogni 100us { contataore_timer=3Dcontataore_timer+1; //incremento di 1 unit=E0=3D100us }

int8 count=3D0; //variabile contenente il conteggio del timer

ISR segnale //interrupt al fronte di salita del segnale { count=3Dcontatore_timer; //memorizzo il n=B0 di impulsi rilevati nel ciclo precedente start timer;//sincronizzo il timer con l'impulso ricevuto contatore_timer=3D0;//faccio partire il contatore del timer da zero

switch (count) { case (12+5): //ho rilevato un 1 case (12+6): //ho rilevato un 1 {se START=3D=3D1 {dato_tmp=3D 1

"Hexfet13" ha scritto nel messaggio news: snipped-for-privacy@b14g2000yqd.googlegroups.com... On 18 Ago, 08:36, "Contrario" wrote: [cut] Immagino che tu abbia la possibilità di fare un capture del segnale (tra l'altro deve essere "pulito", quindi senza la portante da 40KHz); in tal caso devi solo discriminare gli zeri dagli uni e il bit di start effettuando un conteggio tra il fronte di salita dell'impulso ed il successivo insomma...una cosa tipo quella che ti ho scritto sotto in pseudo codice.

Non si tiene impegnata cosi' tanto la CPU semplicemente per risparmiare tre componenti, mi dissocio completamente. Faccio presente che in questo modo durante l'arrivo degli impulsi a 40KHz hai una cadenza d'interrupts di 25microsec!

ciao giorgio

"Contrario" ha scritto:

Che uC usi? Comunque è molto semplice (su internet trovi molti esempi), quando passi dallo stato basso a quello alto fai partire un timer, idem per il contrario (e stopperai il primo timer), in questo modo sai se è uno 0 o 1. Una volta ricevuto il codice, bhe puoi fare quello che ti pare :-)

Consiglio: "usa un demodulatore tipo i vari TMFS1836 (se non erro), evita di farti un filtro R-C, tanto al massimo ti costa 1-2E"

Mi correggo: " il periodo T tra una salita e la discesa"

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required