Ir pultelis fotoaparatui

Kartais fotografuojant prireikia aparatą valdyti nestovint prie jo paties. Kai kada gali pagelbėti foto aparate esantis taimeris. Bet jis tinka nevisada. Žiemą, į prie lango pakabintą lesyklą, atskrenda įvairių paukščių. Kilo noras juos nufotografuoti. Pats normalaus teleobjektyvo neturiu, arčiau prieiti negaliu, nubaidau paukščius. Fotoaparatas turi jungtį laidiniam užrakto paleidimui ir IR imtuvą distanciniam pulteliui. Kaip patogesnis variantas pasirodė IR pultelis. Pirkti originalų pasirodė perdidelė prabanga, todėl sumaniau pasidaryti pats.

apacia

virsus
Nuotraukos matomas pultelis nėra pilnai baigtas, Užliejant viršutinį plokštės paviršių pritrūkau epoksidinės dervos, taip pat dar nebaigti šlifuoti pultelio kraštai ir apačia.

Pultelio sudedamosios dalys

Pagrindinė pultelio detalė Atmel ATTINY13 procesorius.

EAGLE Version 5.12.0 Copyright (c) 1988-2011 CadSoft

Part     Value          Device          Package      Library                 Sheet

C1       100n           C-EUC0805       C0805        rcl                     1
C3       4,7u           CPOL-EUSMCB     SMC_B        rcl                     1
IC1      TINY13-20SU    TINY13-20SU     8S2          atmel                   1
LED1     IR             LED5MM          LED5MM       led                     1
LED2                    LEDCHIPLED_0805 CHIPLED_0805 led                     1
R3                      R-EU_R0805      R0805        rcl                     1
R5                      R-EU_R0805      R0805        rcl                     1
S2       SKHMPSE010     SKHMPSE010      SKHMPXE010   switch                  1
T1       BSS123         BSS123          SOT23        transistor-small-signal 1

Schema

schema (2)

Valdanti programa

Pradėjęs rašyti programą pamačiau, kad į mikrokontrolerio turimą 1024 baitų atmintį Nikon impulsų seką generuojanti programa laisvai telpa užimdama kiek daugiau negu 1/4 visos atminties. Kilo mintis padaryti universalų pultelį tinkantį ir kitiems, populiaresniems aparatams. Taip pavyko sutalpinti kodus generuojančius impulsus šių gamintojų aparatams: Nikon, Pentax, Canon ir Sony. Pats pultelis turi tik vieną mygtuką, todėl užrakto paleidimas ir režimo keitimas atliekamas vienu ir tuo pačiu mygtuku. Jei mygtuko paspaudimas trumpalaikis aktyvuojamas fotoaparato užraktas, jei ilgesnis – keičiamas pultelio režimas.

/* Pultelis Pentax, Canon, Sony ir Nikon fotoaparatų valdymui. 
Naudojama attiny13, vidinis 9.6 MHz taktinis generatorius. 
Jungiklis jungiamas prie PORTB2 išvado. 940 nm IR diodas 
jungiamas prie PORTB0 išvado, indikacinis šviesos diodas prie PORTB3.

      +--------xxxx----------+----------o +3V
      |         R1           |
     ---                     |
     \ / IR 940nm            |
     ---                     |
      |                      +-------------+
      |                      |             |
      |                      |             |
      |                      |             |
      \ |              ------+-----        |
   T1  /|--------------+ PB0  Vcc |        |
      v |    +---xxx---+ PB3      |        |
      |      | R2=1000 |          |        |  10nF
      |  RED |         | attiny13 |      --+--
      |     ---        |          |      --+--
      |     \ /     On |          |        |
      |     ---      / |          |        |
      |      |    +-  -+ PB2      |        |
      +------+    |    |   GND    |        |
             |    |    ------+-----        |
             |    |          |             |
             +----+----------+-------------+
                             |
                            ---
                             -

Trumalaikis mygtuko paspaudimas (iki 3s) siunčia IR komandą.
Ilgalaikis mygtuko paspaudimas keičia pultelio režimą. Režimo 
perjungimas indikuojamas atitinkamu kiekiu indikacinio diodo
blykstelėjimų:

1. Nikon,
2. Pentax,
3. Canon,
4. Canon +2s.
5. Sony
6. Nikon + Canon + Pentax

Norint perjungi atitinkamą režimą nuspaudę mygtuką laikome tol,
kol indikacinis diodas nemirktels tiek kartų kokio mums režimo 
reikia, po to paleidžiame mygtuką. 

--- nikon ---

2000us on (38khz modulated) 
28000us off (no signal)
400us on
1600us off
400us on
3600us off
500us on
-- repeated a second time after 63ms

--- canon ---
Parameter     Original RC-1    Tolerance
Num. of pulses 16  9 - 22
Burst frequency  32700 Hz  29800 - 35500 Hz
Delay for immediate trigger  7.33 ms  7.0 - 7.7 ms
Delay for 2 s delayed trigger  5.36 ms  5.1 - 5.7 ms 
Num. of pulses  16 9 - 22

-- Pentax ---
The remote control generates a series of IR pulses as shown below. The 'on'-
pulses are modulated at 38kHz.
              |||||||||||||         |||   |||   |||   |||   |||   |||   |||
   38kHz ---> |||||||||||||         |||   |||   |||   |||   |||   |||   |||
 modulation  _|||||||||||||_________|||___|||___|||___|||___|||___|||___|||_
duration [ms] |    13     |    3    |1| 1 |1| 1 |1| 1 |1| 1 |1| 1 |1| 1 |1|
*/

#define F_CPU 9600000UL
#include <avr/sleep.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <avr/sfr_defs.h>
#include <avr/portpins.h>
#include <avr/common.h>
#include <avr/version.h>

#define IRLED  0
#define IRCANON  0
#define StatusLED  3

#define mygt  2

#define adresas  1

void irasom( uint8_t n ) {
    eeprom_busy_wait();
    __EEPUT( adresas, n );
}

uint8_t skaitom( void ) {
    uint8_t rez;
    eeprom_busy_wait();
    __EEGET( rez, adresas );
    return rez;
}

void rezimas( uint8_t n ) {
    for( uint8_t i = 0; i < n; i++) {
      PORTB |= _BV(StatusLED);
      _delay_ms( 100 );
      PORTB &=~ _BV(StatusLED);
     _delay_ms( 100 );
    }
}

void sleep_powerdown ( void ) {
    MCUCR |= _BV(SM1);
    __asm__ __volatile__( "sleep" );
    MCUCR &= ~ _BV(SM1);
}

__attribute__((signal,naked))
void SIG_OUTPUT_COMPARE0A ( void ) {
    __asm__ __volatile__( "reti" );
}

__attribute__((signal,naked))
void SIG_PIN_CHANGE0 ( void ) {
    __asm__ __volatile__( "reti" );
}

__attribute__((signal,naked))
void SIG_WATCHDOG_TIMEOUT ( void ) {
    __asm__ __volatile__( "reti" );
}

extern _Bool button ( void ) {
    uint8_t i;
    for( i = 0; i < 20; i++ ) {
      if( PINB & _BV(mygt) ) return 0;
    }
    return 1;
}

void ir_on( uint16_t n ) {
    for( uint16_t i = 0; i < n; i++) {
        PORTB |= _BV(IRLED);
        _delay_us( 13.02 );
        PORTB &= ~ _BV(IRLED);
        _delay_us( 13.02 );
    }
}

void ir_on_canon( uint16_t n ) { 
    for( uint16_t i = 0; i < n; i++) {
        PORTB |= _BV(IRCANON);
        _delay_us( 15 );
        PORTB &= ~ _BV(IRCANON);
        _delay_us( 15 );
    }
}

void canon2( void ) { 
    ir_on_canon( 16 );
    _delay_us( 5500 );
    ir_on_canon( 16 );
}

void canon( void ) { 
    ir_on_canon( 16 );
    _delay_us( 7500 );
    ir_on_canon( 16 );
}

void nikon( void ) {
    for( uint8_t i=0; i 5) irasom( 0 );
    DDRB |= _BV(StatusLED);
    DDRB |= _BV(IRLED);
    DDRB |= _BV(IRCANON);
    PINB |= _BV(StatusLED);
    PINB |= _BV(IRLED);
    PINB |= _BV(IRCANON);
    PORTB &= ~ _BV(mygt);
    PORTB &= ~ _BV(IRLED);
    PORTB &= ~ _BV(IRCANON);
    PORTB &= ~ _BV(StatusLED);
    MCUSR &= ~ _BV(WDRF);
    WDTCR |= _BV(WDCE);
    WDTCR = 0;
    CLKPR = _BV(CLKPCE);
    CLKPR = 0;
    PCMSK = _BV(mygt);
    GIMSK |= _BV(PCIE);
    TCCR0A = 0x02;
    TCCR0B = 0x01;
    OCR0A  = 120;
    TIMSK0 |= _BV(OCIE0A);
    MCUCR  |= _BV(SE);
    sei();
    cli();
    WDTCR |= _BV(WDCE);
    WDTCR = _BV(WDP0);
    sei();
    for (;;) {
      while( ! (PINB & _BV(mygt)) ) {
        PORTB &= ~ _BV(mygt);
        sleep_powerdown();
        PORTB |= _BV(mygt);
      }
      WDTCR &= ~ _BV(WDTIE);
      while( ! button() ) {
        sleep_powerdown();
      }
      cli();
      MCUCR &= ~ _BV(SE);
      PORTB |= _BV(mygt);
      laik = 0;
      rez = 0;
      pp = 0;
      while (!(PINB & _BV(mygt))) {
        pp = 1;
        _delay_ms( 50 );
        laik++;
        if (laik == 180) {
          rez = 0;
          laik = 60;
        }
        if ((laik == 60)||
            (laik == 80)||
            (laik == 100)||
            (laik == 120)||
            (laik == 140)||
            (laik == 160)) {
          rez++;
          rezimas( rez );
        }
   }
   if (pp == 1) {
     if (laik < 60) kodas();      
     if (laik >= 60) irasom( rez-1 );
   }
   PORTB &= ~ _BV(mygt);
   _delay_ms(30);
   sei();
   sleep_powerdown();
  }
}

Parašykite komentarą

El. pašto adresas nebus skelbiamas. Būtini laukeliai pažymėti *