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.
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
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(); } }