Control remoto RM-1 para Olympus

Las cámaras de fotos Olympus, se pueden controlar a trvaés de un control remoto rm-1. Buscando en google, encontré este blog de alguien que lo hizo con un microcontrolador, yo lo necesitaba para disparar la camara cada 24 segundos, hice unos cambios  para usarlo en un PIC16F876, realizado en c con ccs.

En mi caso el micro es a 20Mhz. Sólo uso el disparo, pero es fácil añadir las otras funciones W y T sirven para usar en manual con el bulb, W inicia el disparo y T lo para (muy útil en astrofotografía), + y – son para el zoom,( no sirve para las camaras reflex). Para que no enfoque en cada disparo poner la camara en enfoque manual.

Para probar el funcionamiento, primero traduje el programa original del blog para usarlo con el Pic16F876  a 4Mhz.  en asm este es el archivo, si no quereis usar el ccs.  El diagrama es el mismo para los dos.

Circuito transmisor infrarojo

Circuito transmisor infrarojo

PortB0 = Led infrarojo. (El led lo saque de un mando de tv antiguo).

PortB1= Led para indicar funcionamiento (Opcional).

Portb4 =Tecla disparo.

Descargar el archivo RM1.c

#include <16f876.h>

#device adc=8
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES PUT                      //Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD
#use delay(clock=20000000)
#BYTE TRISB = 0x86
#BYTE PORTB = 0x06
#BYTE OPTION_REG = 0x81
int16 i=0; //Contador general
int16 pulsos=0;//numero de pulsos para frecuencia de 40Khz.
int estadoFoto=0;
#INT_RB
rb_isr(){
//interrupcion por cambio de estado en PORTB
if (bit_test(PORTB,4)==0){
//Si es el pin 4
disable_interrupts(INT_RB);;//Desactiva interrupcion por puerto b para evitar los rebotes
//La misma tecla inicia y detiene el proceso
if (bit_test(estadoFoto,0)==1){
bit_clear(estadoFoto,0);//Para de hacer fotos
}
else{
bit_set(estadoFoto,0);//hace fotos
}
}
}
void f40KHZ(void){
//Frecuencia comprobada con proteus, si se usa otro oscilador
//estos valores pueden no ser correctos
//debería ser 12.5 milisegundos en nivel bajo y 12.5 alto
for (i=0;i<pulsos;i++){
bit_set(PORTB,0);
delay_us(11);
bit_clear(PORTB,0);
delay_us(10);
}
}
void Envia0(void){
delay_us(500);//500ms a nivel bajo
pulsos=22;//(550us/25us)=22 veces
f40KHZ();
bit_clear(PORTB,0);
}
void Envia1(void){
delay_us(1500);//1500ms a nivel bajo
pulsos=22;//(550us/25us)=22 veces
f40KHZ();
bit_clear(PORTB,0);
}
void cabecera(void){
//Envia la dirección, es la misma para todas las funciones
//Envia 40KZ. durante 8ms. (8000us/25us)=320 veces
pulsos=320;//como pulsos puede ser mayor de 255 se declara int16
f40KHZ();
//4ms a nivel bajo
bit_clear(PORTB,0);
delay_us(4000);
//Envia 40KZ. durante 550ms. (550us/25us)=22 veces
pulsos=22;
f40KHZ();
bit_clear(PORTB,0);
//0110 0001 1101 1100
//Direccion Olympus 0011 1011 1000 0110 (0x3D86)LSB
Envia0();
Envia1();
Envia1();
Envia0();
Envia0();
Envia0();
Envia0();
Envia1();
Envia1();
Envia1();
Envia0();
Envia1();
Envia1();
Envia1();
Envia0();
Envia0();
}
void Disparo(void){
cabecera();
//1000 0000 0111 1111
//8 primeros 1 en LSB 8 siguientes 1 complementado a 2 en LSB
Envia1();
Envia0();
Envia0();
Envia0();
Envia0();
Envia0();
Envia0();
Envia0();
Envia0();
Envia1();
Envia1();
Envia1();
Envia1();
Envia1();
Envia1();
Envia1();
bit_clear(PORTB,0);
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
port_b_pullups(true);
enable_interrupts(INT_RB);//Activa interrupciones por cambio de nivel en portB
bit_clear(OPTION_REG,7); //Activa Pulls Up en PORTB (pines B4-B7)
TRISB=0xF0;//PORTB0-3 Salidas PORTB4-7Entradas
bit_clear(PORTB,0);
enable_interrupts(GLOBAL); //Activa las interrupciones
do {
int n=0;
if (bit_test(estadoFoto,0)==1){
delay_ms(100); //retardo tecla para eliminar rebotes
enable_interrupts(INT_RB); //Vuelve a activar las interrupciones
disparo();//Secuencia de disparo
for(n=0;n<24;n++){
//24 veces 1 segundo
//esto es opcional, se puede poner delay_ms(1000) y eliminar estas lineas
//***OPCIONAL***
delay_ms(500);
bit_set(PORTB,1);//Parpadeo de un led para indicar funcionamiento
delay_ms(500);
bit_clear(PORTB,1);//Parpadeo de un led para indicar funcionamiento
//***OPCIONAL***
//si se pulso la tecla otra vez sale del for
if (bit_test(estadoFoto,0)==0)
break;
}
}
else{
//Inicialmente estadoFoto==0;
//cuando se pulsa el botón por segunda vez
//Tiene que volver a activar las interrucciopnes
delay_ms(100); //retardo tecla para eliminar rebotes
enable_interrupts(INT_RB); //Vuelve a activar las interrupciones
bit_clear(PORTB,1);//Apaga el led Opcional
}
}while (true);
}

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s