Buonasera, ho in mente un piccolo progetto dove un PIC riceve degl'impulsi da un telecomando(IR) ed in base al tasto premuto esegue un azione.Il telecomando in questione non ha marca ne modello, però con l'oscilloscopio ed il suo ricevitore sono riuscito a vedere la sequenza di bit che dovrei mandare in pasto al PIC.
Questa è la sequenza di un tasto:
Avete qualche idea su come cominciare?? Io avrei pensato di fare cosi:
-memorizzo in un array la sequenza del byte che ricevo.
-se l'impulso dura 0.6ms è 0
-se l'impulso dura 1.6ms e 1
-esegua la somma di tutti i bit del byte
-se il byte ha un valore x eseguo x1, se il byte ha valore y eseguo y1
Cosa ne pensate?
Come PIC vorrei usare un 12F675, ambiente MikroC PRO
PIC e ricezione telecomando infrarossi
Moderatore:
Paolino
35 messaggi
• Pagina 1 di 4 • 1, 2, 3, 4
0
voti
sei libero di utilizzare il segnale come meglio credi
ci saranno modi piu' o meno efficienti, anche se non emuli perfettamente il sistema del tuo telecomando/TV non importa.
l'unica difficoltà puo' essere la tua sincronizzazione del clock del treno, quindi dovrai campionare il segnale un po piu' velocemente, in modo da avere almeno qualche campione durante quei 0.6ms, altrimenti rischi di perdere il sincronismo. Forse per semplicità devi campionare almeno a 0.2ms.
appena noti (in ogni periodo) la transizione in alto iniziale fai scattare il cronometro... e poi fai come descrivi tu (se torni giu' dopo 0.6ms è uno 0, altrimenti se avviene dopo 1.6ms è un 1)
dovrai sfruttare quel periodo iniziale di 9+4ms per capire che devi resettarti e metterti in ascolto del nuovo treno in arrivo.
ci saranno modi piu' o meno efficienti, anche se non emuli perfettamente il sistema del tuo telecomando/TV non importa.
l'unica difficoltà puo' essere la tua sincronizzazione del clock del treno, quindi dovrai campionare il segnale un po piu' velocemente, in modo da avere almeno qualche campione durante quei 0.6ms, altrimenti rischi di perdere il sincronismo. Forse per semplicità devi campionare almeno a 0.2ms.
appena noti (in ogni periodo) la transizione in alto iniziale fai scattare il cronometro... e poi fai come descrivi tu (se torni giu' dopo 0.6ms è uno 0, altrimenti se avviene dopo 1.6ms è un 1)
dovrai sfruttare quel periodo iniziale di 9+4ms per capire che devi resettarti e metterti in ascolto del nuovo treno in arrivo.
0
voti
Ciao
sorecaro se con questo ...
Dovresti però decidere come gestire il rilevamento delle tempistiche e strutturare in modo "pulito" il codice, per evitare di perdersi.
In via preventiva, bisognerebbe anche controllare la forma d'onda una volta collegati ricevitore e PIC.
Quale la frequenza del quarzo applicato ?
Saluti
intendi il "peso" di ogni bit(s) penso che quanto elencato sia il minimo da fare.sorecaro ha scritto:-esegua la somma di tutti i bit del byte
Dovresti però decidere come gestire il rilevamento delle tempistiche e strutturare in modo "pulito" il codice, per evitare di perdersi.
In via preventiva, bisognerebbe anche controllare la forma d'onda una volta collegati ricevitore e PIC.
Quale la frequenza del quarzo applicato ?
Saluti
W - U.H.F.
-

WALTERmwp
30,2k 4 8 13 - G.Master EY

- Messaggi: 8982
- Iscritto il: 17 lug 2010, 18:42
- Località: le 4 del mattino
0
voti
Buonasera,
Per quanto riguarda il quarzo pensavo di usare un 12f675 con quarzo interno da 4MHz, ma se questo può causare dei problemi posso cambiare sia PIC che quarzo, il progetto è in fase di "studio".
Ora provo a scrivere uno pseudo-codice in C per farvi comprendere quello che ho in mente.
Questo è quello che avevo pensato, che ne dite???
intendevo proprio questo, ho sbagliato il termine.intendi il "peso" di ogni bit(s)
Per quanto riguarda il quarzo pensavo di usare un 12f675 con quarzo interno da 4MHz, ma se questo può causare dei problemi posso cambiare sia PIC che quarzo, il progetto è in fase di "studio".
Ora provo a scrivere uno pseudo-codice in C per farvi comprendere quello che ho in mente.
- Codice: Seleziona tutto
void interrupt()
reset tmr0;
fine interrupt
main:
-----
----
----
while(1)
if(gpio.f3==0)
fronte_discesa=1;
abilito timer0;
tmr0=0;
if(gpio.f3==1)
fronte_salita=1;
if(gpio.f3)&&(fronte_salita==1)
tempo_passato=tmr0;
if(tempo_passato>12ms)
inizio ricezione=1;
while(inizio ricezione)
for(impulso=31; impulso==0; impulso--)
if(gpio.f3==0)
tmr0=0;
flag_discesa=1
if(gpio.f3==1)&&(flag_discesa==1)
flag_salita=1;
if(gpio.f3==0)&&(flag_salita==1)
tempo_impulso=tmr0;
if(tempo_impulso<0,7ms)
array byte ricezione=0
else
array byte ricezione =1
reset variabili usate sopra
valore array= array byte ricezione bit.0 + array byte ricezione bit.1*2+ e cosi via fino a 31
switch(valore array)
case xxxxxxx;
gpio.f2=1;
case yyyyyyy;
gpio.f3=1
e cosi via
Questo è quello che avevo pensato, che ne dite???
1
voti
Visto che tiri in ballo la interrupt service routine, usa il modulo compare capture PWM per misurare la larghezza degli impulsi, invece che il ciclo nel main. È piú veloce ed è fatto apposta.

0
voti
Hai ragione, il CCP sul PIC12F675 non c'è, ma c'è il modulo Comparator che lavora con segnali analogici, che può utilizzare una tensione VRef generata da un modulo interno per discriminare i livelli alti e bassi e che genera un interrupt settando il flag CMIF ogni volta che l'uscita del comparatore cambia di stato.
Con questo fai partire e stoppare il contatore di TMR0.
In pratica quello che fai nal main, ma usando gli interrupt.
Con questo fai partire e stoppare il contatore di TMR0.
In pratica quello che fai nal main, ma usando gli interrupt.

0
voti
Sto provando queste poche righe ma purtroppo non fanno quello che dovrebbero.
- Codice: Seleziona tutto
unsigned short ricevo[32]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned bit flag_discesa; flag_salita; inizio_ricezione; alto; basso;
unsigned bit stop_tempo;
unsigned short tempo_trascorso;
unsigned short incremento_byte;
void interrupt(void){
if(intcon.t0if)
{
intcon.t0if=0;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main() {
incremento_byte=0;
stop_tempo=0;
alto=0;
basso=0;
flag_discesa=0;
flag_salita=0;
inizio_ricezione=0;
tempo_trascorso=0;
CMCON = 7; //Disabilita comparatore
ADCON0 = 0b000000000; //Disabilita convertitore A/D
ANSEL = 0b00000000; //Tutte le porte in digitale
TRISIO = 0b00010000; //Tutti i pin in OUT tranne gpio3
OPTION_REG=0b00000101; //abilita presaler 1:64 in modo da avere un incremento del tmr0 ogni 64uS
INTCON.GPIE =1; //abilita interrupt generale
gpio.f5=0;
gpio.f3=0;
gpio.f2=0;
gpio.f1=0;
gpio.f0=0;
while(1){
////////////////////////////controlla impulso start di 13ms////////////////////////////////////////////////////////////
if(gpio.f4==0)
{
INTCON.T0IE=1;
tmr0=0;
flag_discesa=1;
}
if((gpio.f4==1)&&(flag_discesa==1))
{
flag_salita=1;
}
if((gpio.f4==0)&&(flag_salita==1))
{
tempo_trascorso=tmr0;
}
if(tempo_trascorso>200)
{
inizio_ricezione=1;
flag_salita=0;
flag_discesa=0;
tempo_trascorso=0;
}
////////////////se c'è stato impulso di start memorizza bit in array ricevo//////////////////////////////
while(inizio_ricezione==1)
{
for(incremento_byte=0; incremento_byte<32; incremento_byte++)
{
///se è iniziato l'impulso di ricezione del dato
if((gpio.f4)&&(alto==0))
{
stop_tempo=0;
tempo_trascorso=0;
tmr0=0;
alto=1;
}
///se l'impulso di ricezione è completato allora copia il valore del tmr0
///nella varibile tempo_trscorso
if((gpio.f4==0)&&(alto==1))
{
tempo_trascorso=tmr0;
stop_tempo=1;
alto=0;
}
///confronta il valore del tmr0 con 10 (640us) e 20(1280us)
//se l'impulso è stato minore di 640us allora imposta il bit a 0
if((tempo_trascorso<10)&&(stop_tempo==1))
{
ricevo[incremento_byte]=0;
gpio.f5=1; //flag per controllo
}
//se l'impulso è stato maggiore di 1280us allora imposta il bit a 1
if((tempo_trascorso>20)&&(stop_tempo==1))
{
ricevo[incremento_byte]=1;
gpio.f1=1; //flag per controllo
}
}
}
}
}
Il problema che ho è il seguente.
Se premo un qualsiasi tasto del telecomando si attiva il flag di controllo gpio.f1, se ripremo nuovamente il tasto si attiva anche il secondo flag di controllo, gpio.f5, penso che si debbano attivare insieme visto che il dato che trasmetto con il telecomando è composto da impulsi "lunghi" e "corti"
0
voti
Mi sembra che così il main viene eseguito una sola volta, a meno che non abbia letto male.
Inoltre azzerare tmr0 così non basta, perché il datasheet nel paragrafo 4.4 "Prescaler" recita:
When assigned to the Timer0 module, all instructions writing to the TMR0 register (e.g., CLRF 1, MOVWF 1, BSF 1, x....etc.) will clear the prescaler.
Quindi quando lo azzeri le impostazioni del prescaler vanno ripristinate.
Inoltre azzerare tmr0 così non basta, perché il datasheet nel paragrafo 4.4 "Prescaler" recita:
When assigned to the Timer0 module, all instructions writing to the TMR0 register (e.g., CLRF 1, MOVWF 1, BSF 1, x....etc.) will clear the prescaler.
Quindi quando lo azzeri le impostazioni del prescaler vanno ripristinate.

0
voti
Non è nemmeno necessario azzerare il valore di tmr0, quello è un byte, basta che ti salvi il valore del timer quando devi iniziare a misurare un tempo e poi lavori sempre per differenza.
Anche quando tmr0 va in rollover, non esistendo i numeri negativi, la differenza sarà sempre il numero di 64
tra i due istanti:
t1 -> timer1 = tmr0 (es 250)
t2 -> timer2 = tmr0 (es 10) -> timer2-timer1 = 10-250 = -240 = 16
Se il compilatore rogna puoi sempre mettere un if per valutare le due situazioni in cui timer1 è maggiore o minore di timer2.
Se è maggiore basta fare timer2+(256-timer1)
Così non devi nemmeno ri impostare il prescaler
Anche quando tmr0 va in rollover, non esistendo i numeri negativi, la differenza sarà sempre il numero di 64
tra i due istanti:t1 -> timer1 = tmr0 (es 250)
t2 -> timer2 = tmr0 (es 10) -> timer2-timer1 = 10-250 = -240 = 16
Se il compilatore rogna puoi sempre mettere un if per valutare le due situazioni in cui timer1 è maggiore o minore di timer2.
Se è maggiore basta fare timer2+(256-timer1)
Così non devi nemmeno ri impostare il prescaler

35 messaggi
• Pagina 1 di 4 • 1, 2, 3, 4
Torna a Firmware e programmazione
Chi c’è in linea
Visitano il forum: Nessuno e 6 ospiti

Elettrotecnica e non solo (admin)
Un gatto tra gli elettroni (IsidoroKZ)
Esperienza e simulazioni (g.schgor)
Moleskine di un idraulico (RenzoDF)
Il Blog di ElectroYou (webmaster)
Idee microcontrollate (TardoFreak)
PICcoli grandi PICMicro (Paolino)
Il blog elettrico di carloc (carloc)
DirtEYblooog (dirtydeeds)
Di tutto... un po' (jordan20)
AK47 (lillo)
Esperienze elettroniche (marco438)
Telecomunicazioni musicali (clavicordo)
Automazione ed Elettronica (gustavo)
Direttive per la sicurezza (ErnestoCappelletti)
EYnfo dall'Alaska (mir)
Apriamo il quadro! (attilio)
H7-25 (asdf)
Passione Elettrica (massimob)
Elettroni a spasso (guidob)
Bloguerra (guerra)




