Forum: Mikrocontroller und Digitale Elektronik Infrarotprotokoll von Olympus E-X20 Fernauslöser


von Mandrake (Gast)


Lesenswert?

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

von Timmo H. (masterfx)


Lesenswert?

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

von Mandrake (Gast)


Lesenswert?

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

von Timmo H. (masterfx)


Lesenswert?

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

von Peter R. (pnu)


Lesenswert?

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

von Mandrake (Gast)


Lesenswert?

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 ;)

von Timmo H. (masterfx)


Lesenswert?

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

von Markus R. (maggus)


Lesenswert?

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
Noch kein Account? Hier anmelden.