Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

PIC e ricezione telecomando infrarossi

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[1] PIC e ricezione telecomando infrarossi

Messaggioda Foto Utentesorecaro » 5 ott 2015, 15:17

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
Avatar utente
Foto Utentesorecaro
36 3 7
Frequentatore
Frequentatore
 
Messaggi: 233
Iscritto il: 26 feb 2013, 19:30

0
voti

[2] Re: PIC e ricezione telecomandoinfrarossi

Messaggioda Foto UtenteRussell » 5 ott 2015, 17:23

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.
Avatar utente
Foto UtenteRussell
3.373 3 5 9
Master
Master
 
Messaggi: 2194
Iscritto il: 4 ott 2009, 10:25

0
voti

[3] Re: PIC e ricezione telecomandoinfrarossi

Messaggioda Foto UtenteWALTERmwp » 5 ott 2015, 20:52

Ciao Foto Utentesorecaro se con questo ...
sorecaro ha scritto:-esegua la somma di tutti i bit del byte
intendi il "peso" di ogni bit(s) penso che quanto elencato sia il minimo da fare.
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.
Avatar utente
Foto UtenteWALTERmwp
22,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6444
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[4] Re: PIC e ricezione telecomandoinfrarossi

Messaggioda Foto Utentesorecaro » 5 ott 2015, 22:27

Buonasera,
intendi il "peso" di ogni bit(s)
intendevo proprio questo, ho sbagliato il termine.
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???
Avatar utente
Foto Utentesorecaro
36 3 7
Frequentatore
Frequentatore
 
Messaggi: 233
Iscritto il: 26 feb 2013, 19:30

1
voti

[5] Re: PIC e ricezione telecomandoinfrarossi

Messaggioda Foto UtenteIlGuru » 5 ott 2015, 23:21

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.
\Gamma\nu\tilde{\omega}\theta\i\ \sigma\epsilon\alpha\upsilon\tau\acute{o}\nu
Avatar utente
Foto UtenteIlGuru
4.129 1 10 13
Master
Master
 
Messaggi: 1372
Iscritto il: 31 lug 2015, 23:32

0
voti

[6] Re: PIC e ricezione telecomandoinfrarossi

Messaggioda Foto Utentesorecaro » 6 ott 2015, 8:53

Buongiorno, Foto UtenteIlGuru il 12f675 se non sbaglio non ha il modulo compare capture PWM
Avatar utente
Foto Utentesorecaro
36 3 7
Frequentatore
Frequentatore
 
Messaggi: 233
Iscritto il: 26 feb 2013, 19:30

0
voti

[7] Re: PIC e ricezione telecomandoinfrarossi

Messaggioda Foto UtenteIlGuru » 6 ott 2015, 11:36

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.
\Gamma\nu\tilde{\omega}\theta\i\ \sigma\epsilon\alpha\upsilon\tau\acute{o}\nu
Avatar utente
Foto UtenteIlGuru
4.129 1 10 13
Master
Master
 
Messaggi: 1372
Iscritto il: 31 lug 2015, 23:32

0
voti

[8] Re: PIC e ricezione telecomandoinfrarossi

Messaggioda Foto Utentesorecaro » 6 ott 2015, 13:07

Foto UtenteIlGuru grazie. Per ora vorrei provare a fare tutto nel main (dovrei esserci con i tempi.
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"
Avatar utente
Foto Utentesorecaro
36 3 7
Frequentatore
Frequentatore
 
Messaggi: 233
Iscritto il: 26 feb 2013, 19:30

0
voti

[9] Re: PIC e ricezione telecomandoinfrarossi

Messaggioda Foto UtenteIlGuru » 6 ott 2015, 14:21

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.
\Gamma\nu\tilde{\omega}\theta\i\ \sigma\epsilon\alpha\upsilon\tau\acute{o}\nu
Avatar utente
Foto UtenteIlGuru
4.129 1 10 13
Master
Master
 
Messaggi: 1372
Iscritto il: 31 lug 2015, 23:32

0
voti

[10] Re: PIC e ricezione telecomandoinfrarossi

Messaggioda Foto UtenteIlGuru » 6 ott 2015, 15:28

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\mu s 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
\Gamma\nu\tilde{\omega}\theta\i\ \sigma\epsilon\alpha\upsilon\tau\acute{o}\nu
Avatar utente
Foto UtenteIlGuru
4.129 1 10 13
Master
Master
 
Messaggi: 1372
Iscritto il: 31 lug 2015, 23:32

Prossimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 3 ospiti