mikrocontroller.net

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


Autor: Mandrake (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht 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&h...

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

/* Macros for IR LED */
#define LED_ON()    PORTB |= (1<<PB0) | (1<<PB1) | (1<<PB2)
#define LED_OFF()    PORTB &= ~((1<<PB0) | (1<<PB1) | (1<<PB2))

#define PULSE_40k()    LED_ON(); _delay_us(12.5);  LED_OFF(); _delay_us(12.5)


void send_command(){
  uint8_t i,j;
  /* Code for Shot */
  uint32_t code=0x61DC807F;
  uint32_t mask=0x80000000;

  if((PINB & 1<<PB3) == 0){
    for(i = 0; i < 152; i++){
      PULSE_40k();
    }
    for(i = 0; i < 22; i++){
      PULSE_40k();
    }
    _delay_ms(4);
    j = 32;
    while(j--){
      if(code & mask){
        _delay_ms(1.5); 
        for(i=0; i < 20; i++){ 
          PULSE_40k();
        }
      }
      else{
        _delay_us(500); 
        for(i=0; i < 20; i++){ 
          PULSE_40k();
        }
      }
      mask >>= 1;
    }

  }
}
Da ich es blind Programmiert habe, weiß ich nicht obs geht. Wäre für 
eine Rückmeldung dankbar

Autor: Mandrake (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter R. (pnu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier ein weiterer link:

Nur geht mein "Nachbau" noch nicht

http://olyflyer.blogspot.com/2007/07/how-to-make-y...

Autor: Mandrake (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ;)

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Markus R. (maggus)
Datum:

Bewertung
0 lesenswert
nicht 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.
/*
Button codes Olympus:

Fire   0110 0001 1101 1100 1000 0000 0111 1111
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

Each command starts with 8ms pulsed with 40khz followed by
4ms of low level followed by 550us pulsed with 40khz.
After that header sequence the bits above are sent:
"Zero" is represented by 559us of low level followed by 559us pulsed.
"One" is represented by 1677us of low level followed by 559us pulsed.
*/


#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>


volatile unsigned int cnt = 0;

// prototypes:
void send_0(void);
void send_1(void);
void send_header(void);
void send_cmd(unsigned char cmd);


int main(void)
{
  DDRC = 0x00;  // Buttons at PC5 - PC1
  PORTC = 0xFF;
  DDRB |= (1<<PB0);  // IR-LED at PB0
  PORTB |= (1<<PB0);

  TIMSK |= (1<<OCIE2);    // TIMER2 compare match interrupt
  TCCR2 |= ((1<<WGM21) | (1<<CS20));    // TIMER2 CTC; presc = 1
  OCR2 = 99;
  
  sei();


  while(1)
  {
    if(!(PINC & (1<<PC5))) send_cmd(0);
    if(!(PINC & (1<<PC4))) send_cmd(1);
    if(!(PINC & (1<<PC3))) send_cmd(2);
    if(!(PINC & (1<<PC2))) send_cmd(3);
    if(!(PINC & (1<<PC1))) send_cmd(4);
  }  
}



void send_cmd(unsigned char cmd)
{
  unsigned char i = 0;
  // Bytes for Fire, W, T, +, -;  bits in reverse order!
  const unsigned char byte[5] = {0xE1, 0xD2, 0xC3, 0xB4, 0xA5}; 

  send_header();
  
  for(i=0; i<4; i++)  // first 4 bits
  {
    if((byte[cmd] >> i) & 0x01) send_1();
    else send_0();
  }

  for(i=0; i<4; i++) send_0();

  for(i=4; i<8; i++)  // last 4 bits
  {
    if((byte[cmd] >> i) & 0x01) send_1();
    else send_0();
  }

  for(i=0; i<4; i++) send_1();

  _delay_ms(600);  // delay before return
}




void send_header(void)
{
  unsigned char i = 0;
  const unsigned int header = 0x3B86;  // first two bytes in reverse bit order

  DDRB |= (1<<PB0);  // 8ms pulse 40khz
  cnt = 0;
  while(cnt < 641);
  DDRB &= ~(1<<PB0);  // 4ms space
  cnt = 0;
  while(cnt < 321);
  DDRB |= (1<<PB0);  // 550us pulse 40khz
  cnt = 0;
  while(cnt < 45);
  DDRB &= ~(1<<PB0);

  for(i=0; i<16; i++)  // send first 16 bits
  {
    if((header >> i) & 0x01) send_1();
    else send_0();
  }
}


void send_1(void) 
{
  DDRB &= ~(1<<PB0);  // 1677us space
  cnt = 0;
  while(cnt < 135);
  DDRB |= (1<<PB0);  // 559us pulse 40khz
  cnt = 0;
  while(cnt < 46);
  DDRB &= ~(1<<PB0);
}

void send_0(void)
{
  DDRB &= ~(1<<PB0);  // 559us space
  cnt = 0;
  while(cnt < 46);
  DDRB |= (1<<PB0);  // 559us pulse 40khz
  cnt = 0;
  while(cnt < 46);
  DDRB &= ~(1<<PB0);
}




ISR(TIMER2_COMP_vect) 
{
  PORTB ^= (1<<PB0);
  cnt++;
}

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.