Extrait de la note http://www.semiconductors.philips.com/acrobat/applicationnotes/AN10210_2.pdf
To ensure immunity to interference from other IR sources such as the sun, lamps and IR sound trans-missions (to headphones), bi-phase encoding (also called Manchester encoding) is used for RC5 code words. As shown in next figure each bi-phase encoded bit is a symbol comprising two logic levels with a transition in the middle.
As shown in next figure, the bi-phase code words modulate a 36 kHz carrier, before being transmitted via the IR LED. Since the repetition period of the 36 kHz carrier is 27.778 us and the duty factor is 25 %, the carrier pulse duration is 6.944 us. Because the high part of each bit of the RC5 code word contains 32 carrier pulses, 1 bit period is 64 x 27.778 us = 1.778 ms.
A complete RC5 code word contains 14 bits, so it takes 24.889 ms to transmit. Each 14 bit RC5 code word consists of:
Attention, on commencera par rappeler que le signal qui sort du module IR est en logique négative, c'est à dire à zéro lorsqu'une porteuse est détectée.
Méthode par échantillonnage : on attend le premier front descendant, puis on attend 0.75 bits (1333 µs) et on commence à échantillonner tous les 1/2 bit (889 µs), en vérifiant quand même que deux échantillons successifs sont inversés. Si on lit 10, c'est un bit 1, si on lit 01 c'est un bit 0, si c'est 00 ou 11 on sort de la boucle, sinon on s'arrête après le 13ème bit lu. Dans cette méthode, il faut :
On peut raffiner en vérifiant que le premier front n'est pas un parasite et en faisant un triple échantillonnage et un vote majoritaire, mais fondamentalement, c'est un algorithme fragile.
Méthode mesure de durées entres fronts
En travaillant sur les fronts, on sera moins sensible à des dérives d'horloge, et suffisamment pour autoriser un fonctionnement sans quartz. Par exemple, l'horloge interne d'un PIC12C508 est 4.0 MHz +/-10% +8% c'est cette gamme qu'il faut viser (> 10%).
Un simple examen au scope montre qu'au lieu d'avoir un rapport cycle de 50% sur les 2 premiers bits (start) on lit 1190-1220µs état bas et 520-550µs état haut, la période par contre est correcte à 1780ms.
Les algorithmes travaillant sur l'examen des durées positives ou négatives ne marcheront que si les tolérances sont extrêmement larges pour accepter ces écarts. Néanmoins, il en existe, voir par exemple l'algorithme basé sur des machines état de Guy Carpenter avec des tolérances fixes de +/-50% et +/-25%. http://www.clearwater.com.au/pcm-9574/rc5/rc5.html avec un programme en C assez compliqué.
Il vaut mieux travailler sur des durées entre fronts de même signe, soit descendants, soit montants.
Dans les 2 cas, le temps entre 2 fronts de même signe doit être 2ζ(1±α)="2", 3ζ(1±α)="3", 4ζ(1±α)="4", ζ étant la demi durée bit, soit 889 µs, et α l'erreur acceptable. Le non recouvrement de ces plages impose une valeur maximale de 14% pour α ce qui reste acceptable vue la contrainte précédente.
Front |
Mesure |
Décision |
↓ |
2ζ |
le bit suivant vaut le précédent |
↓ |
3ζ |
si le précédent vaut 1 les 2 suivants valent 00, sinon le suivant vaut 1 |
↓ |
4ζ |
si le précédent vaut 1 les 2 suivants valent 01, sinon erreur |
↑ |
2ζ |
le bit suivant vaut le précédent (non testé) |
↑ |
3ζ |
si le précédent vaut 0 les 2 suivants valent 11, sinon le suivant vaut 0 (non testé) |
↑ |
4ζ |
si le précédent vaut 0 les 2 suivants valent 10, sinon erreur (non testé) |
En prenant en compte l'instant où nous sommes au moment du deuxième front mesuré, on en tire plus d'information et on est plus robuste encore.
Front |
Mesure |
Temps de la mesure |
Décision |
↓ |
2ζ (1ζ- et 1ζ+) |
pair |
c'est un bit ZERO (non testé) |
↓ |
2ζ (1ζ- et 1ζ+) |
impair |
c'est un bit UN (non testé) |
↓ |
3ζ (2ζ - et 1ζ+) |
forcément pair |
c'est une paire ZERO,ZERO précédée d'un UN (non testé) |
↓ |
3ζ (1ζ- et 2ζ+ ) |
forcément impair |
c'est un bit UN (précédée d'un ZERO) (non testé) |
↓ |
4ζ (2ζ- et 2ζ+) |
forcément impair |
c'est une paire ZERO, UN (suivi d'un ZERO) (non testé) |
|
|
|
|
↑ |
2ζ (1ζ+ et 1ζ-) |
pair |
c'est un bit UN |
↑ |
2ζ (1ζ+ et 1ζ-) |
impair |
c'est un bit ZERO |
↑ |
3ζ (2ζ+ et 1ζ-) |
forcément pair |
c'est un bit UN (précédée d'un ZERO, suivi d'un UN) |
↑ |
3ζ (1ζ+ et 2ζ- ) |
forcément impair |
c'est une paire UN, ZERO (précédée d'un UN) |
↑ |
4ζ (2ζ+ et 2ζ-) |
forcément impair |
c'est une paire UN, ZERO (suivi d'un UN) |
Méthode front descendants : Le train démarre sur un front négatif, on démarre donc immédiatement , par contre on termine sur un front positif, il faut donc gérer le dernier bit avec un time out.
Méthode front montants : Le train démarre sur un front négatif, on démarre donc sur un biais, en faisant croire à l'algorithme qu'on a mesure une impulsion négative de durée 1ζ. On sort naturellement en fin de boucle, sans besoin de gérer un time out.
En utilisant le timer 0 d'un PIC, alimenté par le prédiviseur et une horloge à 4MHz, il ne faudrait pas dépasser 0xFF pour le plus grand temps à détecter, soit 4ζ(1+α). La fréquence timer doit alors être inférieure à 62.9 kHz, soit <4MHz/63.59, arrondi à 4MHz/64, soit une période de 16µs.
Dans ces conditions les seuils sont :
L'algorithme global est :
DataRecu = 0xFFF8 ; 14 bits à rentrer, avec de voir sortir le premier 0
Attente_front10 ; si time_out, erreur_timeout
Attente_front01 ; si time_out, erreur_timeout
Evaluer la durée entre les 2 fronts
Ntau=2tau, 3tau 4tau
Sinon erreur_mesure
TempsTotal = TempsTotal + Ntau
Si TempsTotal pair
Si Ntau=2 (Durée+=1 et Durée-=1), BitLu=1
Si Ntau=3 (Durée+=2 et Durée-=1), BitLu=1
Si TempsTotal impair
Si Ntau=2 (Durée+=1 et Durée-=1), BitLu=0
Si Ntau=3 (Durée+=1 et Durée-=2), BitLu=1, ShiftBitin, BitLu=0
Si Ntau=4 (Durée+=2 et Durée-=2), BitLu=1, ShiftBitin, BitLu=0
Sinon, erreur_protocole
ShiftBitIn
si Cy=0 goto attente_front10
Réarrange les données reçues
L'attente des fronts se fait simplement, en gérant un time out sur repliement du timer 0. On suppose donc que lorsqu'on rentre dans cette boucle, le timer0 n'est pas nul !!
Attente_front10
[1,2] BTFSS IO_pin
[2,0] GOTO $+5 ; sortie si IO_pin=0
[1] MOVF TMR0,W ; W=timer
[1,2] SKPZ
[2,0] GOTO $-4 ; saut vers attente
[2,0] GOTO Time_out ; TMR0 vient de passer à 0
MOVF TMR0,W ; W=timer
CLRF TMR0 ; reset timer
Comparaison de W par rapport aux seuils 2tau, 3tau ou 4tau
La durée de la boucle d'attente du front est de 6µs @4MHz, c'est la résolution de l'échantillonnage des fronts, c'est moins de la moitié de la résolution du timer 0 (16µs), aucun problème pour capter le passage à zéro. On sort en time-out au bout de 256 / (Fosc/prédiv) = 4096 µs.
A la sortie de l'algorithme, on a les 2 octets suivants :
0 |
0 |
Start |
D6 |
Tog |
A4 |
A3 |
A2 |
|
A1 |
A0 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
Qui sont réarrangés en :
Start |
0 |
0 |
A4 |
A3 |
A2 |
A1 |
A0 |
|
Tog |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
Détail du code disponible ici en assembleur PIC.
Codes RC5 : voir 193.23.168.87/Mikrocontroller/Kohlert/rc5_codes.html
0 |
00 |
TV 1 |
1 |
01 |
TV 2 |
2 |
02 |
Télétext |
5 |
05 |
Magnétoscope 1 |
6 |
06 |
Magnétoscope 2 |
8 |
08 |
Satellite 1 |
10 |
0A |
Satellite 2 |
12 |
0C |
CD vidéo |
14 |
0E |
CD photo |
16 |
10 |
Préampli audio 1 |
17 |
11 |
Tuner |
18 |
12 |
Magnéto-cassette |
19 |
13 |
Préampli audio 2 |
20 |
14 |
Disque Audio Numérique |
21 |
15 |
audio rack, phono |
0 |
00 |
0 |
1 |
01 |
1 |
2 |
02 |
2 |
3 |
03 |
3 |
4 |
04 |
4 |
5 |
05 |
5 |
6 |
06 |
6 |
7 |
07 |
7 |
8 |
08 |
8 |
9 |
09 |
9 |
10 |
0A |
|
11 |
0B |
|
12 |
0C |
standby |
13 |
0D |
mute/demute |
14 |
0E |
P.P. (personal pref.) |
15 |
0F |
display |
16 |
10 |
volume + |
17 |
11 |
volume - |
18 |
12 |
brightness + |
19 |
13 |
brightness - |
20 |
14 |
colour + |
21 |
15 |
colour - |
22 |
16 |
bass + |
23 |
17 |
bass - |
24 |
18 |
treble + |
25 |
19 |
treble - |
26 |
1A |
balance right |
27 |
1B |
balance left |
28 |
1C |
|
29 |
1D |
|
30 |
1E |
|
31 |
1F |
|
32 |
20 |
|
33 |
21 |
|
34 |
22 |
|
35 |
23 |
|
36 |
24 |
|
37 |
25 |
|
38 |
26 |
|
39 |
27 |
|
40 |
28 |
|
41 |
29 |
|
42 |
2A |
|
43 |
2B |
|
44 |
2C |
|
45 |
2D |
|
46 |
2E |
|
47 |
2F |
|
48 |
30 |
pause |
49 |
31 |
erase |
50 |
32 |
rewind |
51 |
33 |
go to |
52 |
34 |
wind |
53 |
35 |
play |
54 |
36 |
stop |
55 |
37 |
recording |
56 |
38 |
external 1 |
57 |
39 |
external 2 |
58 |
3A |
|
59 |
3B |
|
60 |
3C |
|
61 |
3D |
|
62 |
3E |
|
63 |
3F |
system select |
64 |
40 |
|
65 |
41 |
|
66 |
42 |
|
67 |
43 |
|
68 |
44 |
|
69 |
45 |
|
70 |
46 |
|
71 |
47 |
|
72 |
48 |
|
73 |
49 |
|
74 |
4A |
|
75 |
4B |
|
76 |
4C |
|
77 |
4D |
linear function up |
78 |
4E |
linear function down |
79 |
4F |
|
80 |
50 |
cursor step up |
81 |
51 |
cursor step down |
82 |
52 |
menu on |
83 |
53 |
menu off |
84 |
54 |
display A/V status |
85 |
55 |
cursor step left |
86 |
56 |
cursor step right |