Hallo liebe Forenteilnehmer! Ich habe seit geraumer Zeit eine Olympus E-520 DSLR. Nun möchte ich mir einen Infrarotfernauslöser basteln und bräuchte Infos zum verwendeten Protokoll. Da die Frage "Warum nicht kaufen sind doch billig?" bestimmt kommt, schonmal vornweg die Antwort. Wenn sich keine Infos finde, werde ich das auch tun. Da ich aber Controller und elektronischen Kram hier in Massen zur Verfügung habe, könnte ich mir so ein Teil auch schnell aus ein paar Bauteilen selbst zusammendübeln. Vielleicht hat von euch jemand einen interessanten Link der mir Infos zum IR-Protokoll liefert. Danke schon Mal im Vorraus. Gruß Mandrake
Wenn es die Olympus RM-1 Remote ist dann habe ich das schonmal programmiert. Hier ist eine kleine Seite zum Projekt: http://www.dslr-forum.de/showthread.php?t=435214&highlight=RC-1 Zur Info: Modulation = 40 kHz Logisch 1 = 1,5ms LED aus + 500µs Puls Logisch 0 = 500µs LED aus + 500µs Puls Sequenz wird eingeleitet durch: 3,8ms Puls + 4ms LED aus + 550µs Puls gefolgt von 0110 0001 1101 1100 1000 0000 0111 1111 oder in hex 0x61DC807F. Ergibt als C-Code
1 | /* Macros for IR LED */
|
2 | #define LED_ON() PORTB |= (1<<PB0) | (1<<PB1) | (1<<PB2)
|
3 | #define LED_OFF() PORTB &= ~((1<<PB0) | (1<<PB1) | (1<<PB2))
|
4 | |
5 | #define PULSE_40k() LED_ON(); _delay_us(12.5); LED_OFF(); _delay_us(12.5)
|
6 | |
7 | |
8 | void send_command(){ |
9 | uint8_t i,j; |
10 | /* Code for Shot */
|
11 | uint32_t code=0x61DC807F; |
12 | uint32_t mask=0x80000000; |
13 | |
14 | if((PINB & 1<<PB3) == 0){ |
15 | for(i = 0; i < 152; i++){ |
16 | PULSE_40k(); |
17 | }
|
18 | for(i = 0; i < 22; i++){ |
19 | PULSE_40k(); |
20 | }
|
21 | _delay_ms(4); |
22 | j = 32; |
23 | while(j--){ |
24 | if(code & mask){ |
25 | _delay_ms(1.5); |
26 | for(i=0; i < 20; i++){ |
27 | PULSE_40k(); |
28 | }
|
29 | }
|
30 | else{ |
31 | _delay_us(500); |
32 | for(i=0; i < 20; i++){ |
33 | PULSE_40k(); |
34 | }
|
35 | }
|
36 | mask >>= 1; |
37 | }
|
38 | |
39 | }
|
40 | }
|
Da ich es blind Programmiert habe, weiß ich nicht obs geht. Wäre für eine Rückmeldung dankbar
Hey vielen Dank Timmo! Das ist genau was ich suche! Leider kann ich deinen Quellcode nicht so auf die schnelle ausprobieren. Werde das vermutlich an einem Wochenende auf einem ARM-Controllerboard aus dem Firmenschrott programmieren. Aber auf jedenfall vielen Dank! Gruß Mandrake
Kein Problem. Es gibt übrigens noch mehr Sequenzen (W,T,+,-). Also für Zoom und Fokus soweit ich weiß. W = 0110 0001 1101 1100 0100 0000 1011 1111 T = 0110 0001 1101 1100 1100 0000 0011 1111 - = 0110 0001 1101 1100 0010 0000 1101 1111 + = 0110 0001 1101 1100 1010 0000 0101 1111
Hier ein weiterer link: Nur geht mein "Nachbau" noch nicht http://olyflyer.blogspot.com/2007/07/how-to-make-your-own-rm-1-compatible.html
Interessant. Für was steht W, T, +, - ? Hast du das eigentlich Reverse-Engineered oder gibt es eine Spec dazu? An der ich dann natürlich auch interessiert wäre ;)
W = rauszoomen T = reinzoomen + und - dürfte wie gesagt für den Fokus sein. Ich glaube die IR-Codes habe ich vor einigen Jahren von der Seite die Peter R. genannt hat genommen
Hallo, auch wenn der Thread jetzt nichtmehr aktuell ist poste ich trotzdem mal eine funktionierende Variante für die Fernauslösung einer Olympus E-520. Getestet auf einem Mega8 @ 8mhz externes Quarz. Der Ablauf der Routine steht im Kommentar des Codes: 8ms pulsed, 4ms ruhe, 550us pulsed, dann das Bitmuster.
1 | /*
|
2 | Button codes Olympus:
|
3 | |
4 | Fire 0110 0001 1101 1100 1000 0000 0111 1111
|
5 | W 0110 0001 1101 1100 0100 0000 1011 1111
|
6 | T 0110 0001 1101 1100 1100 0000 0011 1111
|
7 | - 0110 0001 1101 1100 0010 0000 1101 1111
|
8 | + 0110 0001 1101 1100 1010 0000 0101 1111
|
9 | |
10 | Each command starts with 8ms pulsed with 40khz followed by
|
11 | 4ms of low level followed by 550us pulsed with 40khz.
|
12 | After that header sequence the bits above are sent:
|
13 | "Zero" is represented by 559us of low level followed by 559us pulsed.
|
14 | "One" is represented by 1677us of low level followed by 559us pulsed.
|
15 | */
|
16 | |
17 | |
18 | #include <avr/io.h> |
19 | #include <avr/interrupt.h> |
20 | #include <util/delay.h> |
21 | |
22 | |
23 | volatile unsigned int cnt = 0; |
24 | |
25 | // prototypes:
|
26 | void send_0(void); |
27 | void send_1(void); |
28 | void send_header(void); |
29 | void send_cmd(unsigned char cmd); |
30 | |
31 | |
32 | int main(void) |
33 | {
|
34 | DDRC = 0x00; // Buttons at PC5 - PC1 |
35 | PORTC = 0xFF; |
36 | DDRB |= (1<<PB0); // IR-LED at PB0 |
37 | PORTB |= (1<<PB0); |
38 | |
39 | TIMSK |= (1<<OCIE2); // TIMER2 compare match interrupt |
40 | TCCR2 |= ((1<<WGM21) | (1<<CS20)); // TIMER2 CTC; presc = 1 |
41 | OCR2 = 99; |
42 | |
43 | sei(); |
44 | |
45 | |
46 | while(1) |
47 | {
|
48 | if(!(PINC & (1<<PC5))) send_cmd(0); |
49 | if(!(PINC & (1<<PC4))) send_cmd(1); |
50 | if(!(PINC & (1<<PC3))) send_cmd(2); |
51 | if(!(PINC & (1<<PC2))) send_cmd(3); |
52 | if(!(PINC & (1<<PC1))) send_cmd(4); |
53 | }
|
54 | }
|
55 | |
56 | |
57 | |
58 | void send_cmd(unsigned char cmd) |
59 | {
|
60 | unsigned char i = 0; |
61 | // Bytes for Fire, W, T, +, -; bits in reverse order!
|
62 | const unsigned char byte[5] = {0xE1, 0xD2, 0xC3, 0xB4, 0xA5}; |
63 | |
64 | send_header(); |
65 | |
66 | for(i=0; i<4; i++) // first 4 bits |
67 | {
|
68 | if((byte[cmd] >> i) & 0x01) send_1(); |
69 | else send_0(); |
70 | }
|
71 | |
72 | for(i=0; i<4; i++) send_0(); |
73 | |
74 | for(i=4; i<8; i++) // last 4 bits |
75 | {
|
76 | if((byte[cmd] >> i) & 0x01) send_1(); |
77 | else send_0(); |
78 | }
|
79 | |
80 | for(i=0; i<4; i++) send_1(); |
81 | |
82 | _delay_ms(600); // delay before return |
83 | }
|
84 | |
85 | |
86 | |
87 | |
88 | void send_header(void) |
89 | {
|
90 | unsigned char i = 0; |
91 | const unsigned int header = 0x3B86; // first two bytes in reverse bit order |
92 | |
93 | DDRB |= (1<<PB0); // 8ms pulse 40khz |
94 | cnt = 0; |
95 | while(cnt < 641); |
96 | DDRB &= ~(1<<PB0); // 4ms space |
97 | cnt = 0; |
98 | while(cnt < 321); |
99 | DDRB |= (1<<PB0); // 550us pulse 40khz |
100 | cnt = 0; |
101 | while(cnt < 45); |
102 | DDRB &= ~(1<<PB0); |
103 | |
104 | for(i=0; i<16; i++) // send first 16 bits |
105 | {
|
106 | if((header >> i) & 0x01) send_1(); |
107 | else send_0(); |
108 | }
|
109 | }
|
110 | |
111 | |
112 | void send_1(void) |
113 | {
|
114 | DDRB &= ~(1<<PB0); // 1677us space |
115 | cnt = 0; |
116 | while(cnt < 135); |
117 | DDRB |= (1<<PB0); // 559us pulse 40khz |
118 | cnt = 0; |
119 | while(cnt < 46); |
120 | DDRB &= ~(1<<PB0); |
121 | }
|
122 | |
123 | void send_0(void) |
124 | {
|
125 | DDRB &= ~(1<<PB0); // 559us space |
126 | cnt = 0; |
127 | while(cnt < 46); |
128 | DDRB |= (1<<PB0); // 559us pulse 40khz |
129 | cnt = 0; |
130 | while(cnt < 46); |
131 | DDRB &= ~(1<<PB0); |
132 | }
|
133 | |
134 | |
135 | |
136 | |
137 | ISR(TIMER2_COMP_vect) |
138 | {
|
139 | PORTB ^= (1<<PB0); |
140 | cnt++; |
141 | }
|
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.