Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

PIC 16F84A e code nec IR

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[1] PIC 16F84A e code nec IR

Messaggioda Foto Utentefloppinoo » 19 lug 2013, 18:42

Ciao vorrei cimentarmi a decodificare un protocollo Nec

tramite un ricevitore ir e un comunissimo PIC 16f84a ...
Ho in pratica comprato un telecomando con ricevitore Ir
di questo modello : HX1838 NEC Code Infrared , che se ne trovano a bizzeffe
su ebay

La parte Hardware lo già fatta (naturalmete non è diffcile).
Il problema è decodificare tramite codice Assembler sul PIC
il segnale proveniente dal IR (vorrei usare assembler come linguaggio)

Ho trovato su internet questo sito
http://www.clinicatv.it/Pages/NEC_IR.aspx

Ad esempio tanto per incomingiare non ho capito se il segnale L corrisponde ai 5 volt o ai 0 volt ??

Per esempio il segnale di start (come è spiegato su questo sito) è composto da 9 MS a livello H e altri 4,5 MS a livello L.
Non ho capito se il piedino di uscita del ricevitore diventa 1 (cioè 5 volt) per 9 MS
e 0 (0 volt per 4,5 MS) o il contrario ...

Perche sembra invece che L corrispondi ai 5 volt mentre H ai 0 volt


Qualcuno ha un codice in assembler da capire e più diretto perche il sudetto sito usa una logica strana di Multitasking .. il che mi rende il codice veramente difficile da capire ... e che ogica usare per decodificare il segnale eliminando possibili errori
Avatar utente
Foto Utentefloppinoo
205 1 3 7
Sostenitore
Sostenitore
 
Messaggi: 508
Iscritto il: 24 lug 2010, 9:26

0
voti

[2] Re: PIC 16f84a e code nec IR

Messaggioda Foto Utentesimo85 » 19 lug 2013, 19:21

floppinoo ha scritto:Perche sembra invece che L corrispondi ai 5 volt mentre H ai 0 volt


No, il contrario. ;-)

H (high) 5V, L (low) 0 V. :-)

Essendo la spiegazione linkata abbastanza chiara, non ho capito cosa non ti è chiaro della spiegazione.

PS: Assembly (linguaggio) non assembler (compilatore assembly). :D
Avatar utente
Foto Utentesimo85
30,8k 7 12 13
Disattivato su sua richiesta
 
Messaggi: 9927
Iscritto il: 30 ago 2010, 4:59

0
voti

[3] Re: PIC 16f84a e code nec IR

Messaggioda Foto Utentefloppinoo » 19 lug 2013, 19:31

Non so perche quando parla dell'altro protocollo RC5 indica on (cioè i 5 volt) sul fronte di discesa

http://www.clinicatv.it/Pages/RC5.aspx

e anche nel codice del ricevitore Nec la parte riguardante il segnale di start fa capire che H corrisponde a 0 volt.
Infatti si vede le due righe (sotto) di codice selezionate, l'istruzione salta al controllo dei 9 MS quando il piedino del ricevitore diventa 1 cioè qunado passa da 0 a 1

cioè 9Ms a 0 volt e 4,5 Ms a 5 volt giusto ?

poi non so forse sto interpretando io male tutto ... :^o ma quelle due istruzione mi hanno confuso
a questo punto :idea:







====================================================================================

;TASK3 relativo alla ricezione e memorizzazione del segnale IR di tipo LG
;{
;fase0 da riposo controllo ingresso IR se passa a stato L (fase1)
IR_IN_LG0
;{
btfsc PORTA,IR_IN ;mantengo STAT1 inalterato fino a quando ingresso rimane a livello H
goto START4 ;passo al TASK4
call CLR_TMR1 ;resetto timer TMR1
movlw 1
movwf STAT3 ;in questo caso porto STAT3=1
goto START4 ;passo al TASK4
;}
;fase1 controllo che al ritorno a livello H ci sian un tempo di 9000 usec valido per passare a fase2
;o cancellare tutto e tornare a fase0
IR_IN_LG1
;{
btfss PORTA,IR_IN ;salto al task successivo finché il livello rimane L
goto START4 ;quindi non cambio nulla
movlw 35 <<-- qui controlla se sono passati i 9Ms
xorwf TMR1H,w ;controllo che il livello rimanga H per 8704/8960 usec
btfss STATUS,Z
goto IR_IN_LG1_ERR ;in caso negativo annullo ricezione
call CLR_TMR1 ;resetto timer TMR1
movlw 2 ;in caso positivo passo STAT3 a 2 per
movwf STAT3 ;proseguire nel task
goto START4 ;ritorno alla routine principale
;}
Avatar utente
Foto Utentefloppinoo
205 1 3 7
Sostenitore
Sostenitore
 
Messaggi: 508
Iscritto il: 24 lug 2010, 9:26

0
voti

[4] Re: PIC 16f84a e code nec IR

Messaggioda Foto Utentesimo85 » 19 lug 2013, 19:54

Non vorrei che facessi confusione tra stato logico e fronte di salita o discesa.



H (o VH) è lo stato logico alto (tipicamente di un valore di 5V).
L (o VL) è lo stato logico basso (tipicamente di un valore di 0V).

Le freccette nello schema rappresentano appunto i fronti (discesa cerchiato in blu e salita cerchiato in rosso)

I fronti di discesa o di salita (falling & rising edges) vengono anche chiamati rispettivamente High to low Transistion THL (da stato logico alto a stato logico basso) o Low to High Transistion TLH (da stato logico basso a stato logico alto) .

floppinoo ha scritto:e anche nel codice del ricevitore Nec la parte riguardante il segnale di start fa capire che H corrisponde a 0
infatti se si vede le due righe di codice selezionate l'istruzione salta al controllo dei 9 MS quando
il piedino del ricevitore diventa 1 cioè qunado passa da 0 a 1


Nella descrizione del primo link (protocollo NEC), appena sotto l'immagine scrive:

"Abbiamo il primo impulso di partenza: un livello H di 9 msec seguito da un livello L di 4.5 msec; questa sequenza mi indica l'inzio della trasmissione."

Secondo la rappresentazione il segnale rimane a stato logico alto appunto per 9 ms ed a stato logico basso per 4.5 ms.

Eviterei di relazionare de due descrizioni e quindi di trattarle separatamente.
Avatar utente
Foto Utentesimo85
30,8k 7 12 13
Disattivato su sua richiesta
 
Messaggi: 9927
Iscritto il: 30 ago 2010, 4:59

1
voti

[5] Re: PIC 16f84a e code nec IR

Messaggioda Foto Utentec1b8 » 19 lug 2013, 20:04

Attenzione che i ricevitori IR tipo TSOP, normalmente utilizzati per ricevere il segnale del telecomando ed interfacciati direttamente con l'ingresso del PIC, hanno l'uscita invertita.
Ossia quando ti dice che il segnale rimane alto per 9ms significa che l'uscita del TSOP diventa a 0 volt per 9ms.
Fabio
Avatar utente
Foto Utentec1b8
3.595 3 8 13
G.Master EY
G.Master EY
 
Messaggi: 1770
Iscritto il: 15 gen 2009, 15:23

0
voti

[6] Re: PIC 16f84a e code nec IR

Messaggioda Foto Utentesimo85 » 19 lug 2013, 20:17

Ecco ora è tutto più chiaro. :)
Avatar utente
Foto Utentesimo85
30,8k 7 12 13
Disattivato su sua richiesta
 
Messaggi: 9927
Iscritto il: 30 ago 2010, 4:59

0
voti

[7] Re: PIC 16f84a e code nec IR

Messaggioda Foto Utentefloppinoo » 19 lug 2013, 20:19

Grazie raga, per le risposte :D, non so se il mio ricevitore è un TSOP l'unica cosa che so che il piedino di uscita va collegato con una resitenza di pull-up con il piedino di ingresso del PIC ... il modulo da me comprato è questo :
http://www.ebay.it/itm/160996608282?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l2649


E anche questa è stata una cosa che mi ha fatto venire il dubbio perche se l'uscita del ricevitore è impostata inizialmente a 1 con il pull-up significa che lo start da 9 Ms dev'essere per forza iniziare con uno 0, giusto ??

Simo anche io ho capito a primo archito che H fosse riferito a 1 .. ma poi vedendo il codice
Assembly e quelle due istruzioni da me indicate sembra che come dice c1b8
la cosa sia invertita.

Il pezzo di codice da me mostrato sopra risale al protocollo NEC e al codice postato dallo stesso autore del sito
volevo aver conferma almeo di questa cosa. Altrimenti inutile partire a scrivere un po di codice ..
purtroppo il codice dell'autore fa uso di multitasking e io volevo ripulilo da cio visto che non devo fare un decodificatore di diversi tipi di protocolli Ir come in quel progetto ... ma per farlo, devo capirne un po
le basi ... del protocollo NEC xd xd e di possibili cose che non potrei sapere come in questo caso per i TSOP

Se la decodifica mi funziona poi postero sia il codice che il circuito promesso -- :ok:

Se qualcuno ha qualche drita su come procedere per la decodifica e per la logica, i cosigli sono ben accetti
Ultima modifica di Foto Utentefloppinoo il 19 lug 2013, 20:41, modificato 1 volta in totale.
Avatar utente
Foto Utentefloppinoo
205 1 3 7
Sostenitore
Sostenitore
 
Messaggi: 508
Iscritto il: 24 lug 2010, 9:26

0
voti

[8] Re: PIC 16f84a e code nec IR

Messaggioda Foto Utentec1b8 » 19 lug 2013, 20:41

floppinoo ha scritto:E anche questa è stata una cosa che mi ha fatto venire il dubbio perche se l'uscita del ricevitore è impostata inizialmente a 1 con il pull-up significa che lo start da 9 Ms dev'essere per forza 0 giusto ??

Giusto, il tuo non è un TSOP ma funziona praticamente allo stesso modo.

Aspetto di vedere il tuo progetto pubblicato.
Fabio
Avatar utente
Foto Utentec1b8
3.595 3 8 13
G.Master EY
G.Master EY
 
Messaggi: 1770
Iscritto il: 15 gen 2009, 15:23

0
voti

[9] Re: PIC 16f84a e code nec IR

Messaggioda Foto Utentefloppinoo » 19 lug 2013, 20:43

Ok c1b8 .. r ci mettero un pochino a risolvere, comunque promesso mi faro attendere ma postero :ok:
Avatar utente
Foto Utentefloppinoo
205 1 3 7
Sostenitore
Sostenitore
 
Messaggi: 508
Iscritto il: 24 lug 2010, 9:26

1
voti

[10] Re: PIC 16F84A e code nec IR

Messaggioda Foto Utentefloppinoo » 21 lug 2013, 16:16

Finalmente ci sono riuscito :D. In pratica ho dovuto cambiare il codice ASM dell’autore eliminando il multitasking e rendendo il codice più lineare e di facile utilizzo.

L’autore nel suo codice controlla i singoli cambiamenti 0 e 1, e valuta ogni volta il valore del TMR0. Io invece ho considerato intera sequenza 0 e 1 prima di valutare il TMR0 ottenendo 4 possibili condizioni :


Start 13,5 MS (9Ms (0) + 4,5 Ms (1))
Repeat 11,81 US (9Ms + 2,25 Ms)
Bit 1 2246 US (560 us + 1686 uS)
Bit 0 1120 US (560 uS + 560 uS)

 la logica è invertita perché il mio ricevitore è simile a un TSOP, con resistenza di pull-up di 10 k
Quindi è verificato che se IR prevede una resistenza di pull’up, la logica del protocollo e invertita
Ad esempio sarà (0Volt) sui 9 MS mentre avrà 5 volt sui 4,5 Ms per lo start ecc ecc

Quando faccio i confronti e controllo il TMR0, non controllo che il tmr0 cada precisamente
all’interno di un singolo ciclo come fa l’autore del sito con queste:

movlw 35
xorwf TMR1H,w btfss STATUS,Z
goto IR_IN_LG1_ERR call CLR_TMR1


Io uso invece un intervallo più ambio, verificando il TMR0, con questo doppio confronto

movlw 103
subwf TMR0,W
btfss STATUS,C
goto $+7
movlw 107
subwf TMR0,W
btfsc STATUS,C
goto $+3
call start

Insomma con queste istruzioni dico che se dopo il ciclo 1 0 il TMR0 cade tra il valore di 103 e 107, allora si ha uno Start, cioè più o meno cerco di tenermi 200 US sopra e rispettivamente 200 US sotto il valore di riferimento, che nel mio caso è 13,5 MS (103*128 = 13184) (107 * 128 = 13696)
(attenzione autore usa un prescaler a 256) .
Tutto questo non per fare originale ma per il semplice fatto che
i telecomandi, come quelli comprati da me dalla Cina per pochi euro non hanno una
precisione ottimale per essere decodificato correttamente dal ricevitore IR.


Infatti i controlli cosi come definiti dall’autore, li ho personalmente provati su telecomandi delle mie tv e vanno bene (tutto funziona) ma sui telecomandi presi dalla Cina gli stessi confronti non vanno bene… Il mio codice invece garantisce una sensibilità inferiore,
in quanto aumento gli intervalli di riferimento, senza naturalmente pregiudicare il funzionamento del protocollo stesso … (volutamente ho posto il prescaler più basso per distanziare il valore del TMR0 nei miei confronti)
Il mio codice in pratica funziona sia per i telecomandi buoni che per quelli scadenti
Inoltre col mio codice è possibile adattare la sensibilità del ricevitore a piacimento restringendo o allargando a piacere gli intervalli per ognuno dei 4 casi

Come pattern di programmazione ho usato o meglio ho simulato un pool

Iinfine uso due Flag
sia per i registri comands che per i registri andress. Cioè se il flag è 1 allora il dato nei registi passa il controllo di negazione se 0 cancello tutto e occorre rischiacciare fisicamente il tasto … (ma ho visto che quest’evvenienza non me mai successo anche se si opera a una distanza di 4 5 metri usando questo telecomandino preso dalla cina
Per 3 euri)

Buon divertimento


Questo è lo schema elettrico :
- (*) nota MOD: riferimento immagini su sito esterno eliminato perché non più disponibili


Questo e il diagramma di flusso :
- (*)


Questo è il codice ASM in assembly :
Codice: Seleziona tutto
;Programma per PIC 16f84a e Ir con codice Nec  Francesco Marangi 2013    
;In configurazione XT con quarzo da 4MHZ e due capacita da 22pf

   PROCESSOR   16F84A
   RADIX   DEC
   include   "P16F84A.INC"
    ERRORLEVEL      -302
   __CONFIG   _PWRTE_ON & _CP_OFF & _WDT_OFF & _XT_OSC


    ;PORTB
    #define         Rb0 0
    #define         Rb1 1
    #define         Rb2 2
    #define         Rb3 3
    #define         Rb4 4
    #define         Rb5 5
    #define         Rb6 6
    #define         Rb7 7
   




   #define         TOIF 2
   #define         TOIE 5

    ;PORTa
    #define         IR_IN 1
    #define         PROVA_START 0
    #define         PROVA_REPEAT 2
    #define         PROVA 3


   #define         FLAG_ANDRESS  0
   #define         FLAG_COMMAND  1

  ORG     0CH
      ;Delay
      Tsecondi                EQU 14h
      Tminuti                 EQU 15h
      cnt0                   EQU 16h
      cnt1                   EQU 17h
      cnt2                   EQU 18h
      cnt3                   EQU 19h


;Variabili per TMR0
      CountMS                 EQU 1Ah
      CountS                 EQU 1Bh
      CountM                 EQU 1Ch

      lenghtByte                EQU 1Eh
      temp                    EQU 20h
      resByte                   EQU 21h



      andress                   EQU 22h ;60
      andressNot                EQU 23h ;61
      command                   EQU 24h ;62
      commandNot                EQU 25h ;63

      flagS                   EQU 26h ;63


  ORG     00H 
goto inizio
 

  ORG 04H
  retfie   


   
;====================== MACRO ==================================================
minutiDiAttesaM
      movwf Tminuti
      movf Tminuti,F
      btfsc STATUS,Z
      goto $+2
      call delay_n_minuti
      return

secondiDiAttesaM
      movwf Tsecondi
      movf Tsecondi,F
      btfsc STATUS,Z
      goto $+2
      call delay_n_secondi
      return


minutiDiAttesa macro XM
      movf         XM,w
        call        minutiDiAttesaM
      endm

minutiDiAttesaL macro XM
      movlw        XM
        call          minutiDiAttesaM
      endm

secondiDiAttesa macro XS
      movf         XS,w
        call         secondiDiAttesaM
      endm

secondiDiAttesaL macro XS
      movlw         XS
        call         secondiDiAttesaM
      endm




inizio 
     bsf STATUS, RP0
     movlw 00000010B
     movwf TRISA
     movlw 00000000B
     movwf TRISB


     ;PRESCALER 64 & inoltre non metto in pull up b4 - b7
     movlw B'11010110' ;Imposto il prescaler a 128
     movwf OPTION_REG
     bcf STATUS, RP0
     clrf PORTA
     clrf PORTB      
     ;IMPOSTO LA COSTANTE CHE USO PER IMPOSTARE DA DOVE DEVE PARTIRE TMR0


main
      call   cancellaTutto
      call   poolNec
      ;Se FLAG_COMMAND ==1 OR FLAG_ANDRESS == 1
      ;Allora c'è un messaggio nei registri Andress e Command da consumare
      ;Naturalmente se  Andress non ci serve basta  controllare solo FLAG_COMMAND == 1
   


      btfss flagS,FLAG_COMMAND
      goto  endMain

      movf   command,W
      movwf   PORTB
      secondiDiAttesaL 3
      clrf    PORTB
  endMain      
goto main






;Trova le azioni di Start e di Reapet del protocollo Nec
;Se repeat i registi sono già pieni ...
;Se start invece viene eseguita la costruzione di Andress e Command e delle loro negazioni
;Riempiendo i rispettivi registri
poolNec
      btfsc   PORTA, IR_IN;Vede il primo 0, se legge uno 0 passa al controllo del messaggio di start
      goto       $-1


      clrf   TMR0

      btfss      PORTA,IR_IN
      goto       $-1
      btfsc      PORTA,IR_IN
      goto       $-1


      movlw 103
      subwf TMR0,W
      btfss STATUS,C
      goto $+7
      movlw 107
      subwf TMR0,W
      btfsc STATUS,C
      goto  $+3
      call start
      goto okStart ;Non eseguo il controllo per repeat visto che ormai il comando è start


      movlw 85
      subwf TMR0,W
      btfss STATUS,C
      call errorNec
      movlw 89
      subwf TMR0,W
      btfsc STATUS,C
      call errorNec       
      call repeat
okStart
return






start
      call costruisciProtocolloNec
      ;Procedura per lo start
      bsf PORTA,PROVA_START
      secondiDiAttesaL 1
      bcf PORTA,PROVA_START
return



repeat
      ;Procedura per il repeat
      bsf PORTA,PROVA_REPEAT
      secondiDiAttesaL 1
      bcf PORTA,PROVA_REPEAT
return




;Per ogni byte del protocollo Nec Chiamo byteLoop e memorizzo il risusltato nei rispettvi 4 registrirotocolloNec
costruisciProtocolloNec
      clrf   resByte
      call   byteLoop
      movf   resByte,W
      movwf   andress
   
      clrf   resByte
      call   byteLoop
      movf   resByte,W
      movwf   andressNot
   
   
      clrf   resByte
      call   byteLoop
      movf   resByte,W
      movwf   command
   
      clrf   resByte
      call   byteLoop
      movf   resByte,W
      movwf   commandNot

      call   convalidaProtocollo
return



; Questo ciclo mi costruisce nella variabile temporanea ResByte un byte del protocollo
byteLoop
      movlw 8
      movwf lenghtByte

byteLoopDec
      clrf   TMR0

      btfss   PORTA,IR_IN
      goto    $-1
      btfsc   PORTA,IR_IN
      goto    $-1




      movlw    16 ;Si verifica 1
      subwf    TMR0,W
      btfss    STATUS,C
      goto    $+8
      movlw    20
      subwf    TMR0,W
      btfsc    STATUS,C
      goto     $+4      
      bsf      STATUS,C
      rlf      resByte,f
      goto   okUno ;Non eseguo il controllo per 0 visto che ormai il bit è 1

      movlw    6 ;Si verifica 0
      subwf    TMR0,W
      btfss    STATUS,C
      goto    errorNec
      movlw    10
      subwf    TMR0,W
      btfsc    STATUS,C
      goto    errorNec
      bcf      STATUS,C
      rlf      resByte,f

okUno
      decfsz lenghtByte,f
      goto byteLoopDec
return



;Convalido i registi ottenuti con la loro negazione, se la convalida è positiva setto a 1 il rispettivo Flag
convalidaProtocollo
      comf   andressNot,W
      subwf   andress,W
      btfss   STATUS, Z
      goto    $+1
      bsf      flagS,FLAG_ANDRESS
      
      comf   commandNot,W
      subwf   command,W
      btfss   STATUS, Z
      goto    $+1
      bsf      flagS,FLAG_COMMAND


      ;btfsc    flagS,FLAG_COMMAND
      ;bsf      PORTA,PROVA
return



cancellaTutto
      clrf   resByte
       clrf   andress
       clrf   andressNot
       clrf   command
       clrf   commandNot
      bcf      flagS,FLAG_ANDRESS
      bcf      flagS,FLAG_COMMAND
return


errorNec
      call   main
return




;================== PROCEDURE PER ATTENDERE 1 SECONDO O 1 MINUTO PRECISO usando TMR0 ==================
;Attese di n minuti o n secondi
delay_n_minuti
      loop_x_minuti
      movlw 60
      movwf Tsecondi
      call delay_n_secondi
      decfsz Tminuti,f
      goto loop_x_minuti
      return

delay_n_secondi
      Loop_delay_n
      call Delay
      decfsz Tsecondi,1
      goto Loop_delay_n
      return

Delay
      Movlw 100
      Movwf cnt2
      Loop2
      Movlw 100
      Movwf cnt0
      Loop1
      Movlw 32
      Movwf cnt1
      Loop0
      Decfsz cnt1,1
      Goto Loop0
      Decfsz cnt0,1
      Goto Loop1
      Decfsz cnt2,1
      Goto Loop2
      Retlw 0

END


Questo è il video che ne prova il funzionamento :
http://www.youtube.com/audio?v=TqtokYevJhk&video_referrer=watch

Buon divertimento
Devo ringraziare c1b8, perché senza il suo intervento a voglia a cimentarmi
Quella sera non ne uscivo dal bandolo della matassa ma dopo i chiarimenti nel forum tutto è proseguito abbastanza agevolmente. GRAZIE !!!
O_/
Avatar utente
Foto Utentefloppinoo
205 1 3 7
Sostenitore
Sostenitore
 
Messaggi: 508
Iscritto il: 24 lug 2010, 9:26

Prossimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 6 ospiti