This application is designed to trigger a camera shutter using one of three methods on a periodic basis. This devices allows for the creation of a very low weight high perfomance Kite Aerial Photography Rig. There is a 8-position dip switch on Port B that configures the device on power-up. Port RA.0 is connected to a three pin header that is configured to connect to a standard remote control servo. A future modification of the code will also allow this port to trigger an Epic Stylus camera using a infrared remote trigger instead of a mechanical one. Port RA.1 is connected to a small relay that is configured to trigger a Pentax ZX-M 35mm camera using its remote electronic trigger port. The remaining pins of Port A are tied to ground and can be used in future revisions to the design.
I designed a simple pc board for the prototype circuit. I used the ExpressPC Board service. They provide a free package to design the circuits and they offer a prototype board service for about $60 (3 boards). My prototype board can be downloaded. The source code, including a hex file suitable for programming, is available for download.
' Program: intervalometer.bas ' Programmer: Walter E Anderson ' Copyright ' Notice: Copyright (c) 2002 by Walter E Anderson ' Chip: PIC 16F84 ' Clock: 4 MHz ' Date Created: 29 May 2002 ' Last Revised: 30 May 2002 ' ' ' Revision History: ' ' ' Purpose: ' This application is designed to trigger a camera shutter using one of ' three methods on a periodic basis. There is a 8-position dip switch on Port ' B that configures the device on power-up. Port RA.0 is connected to a three ' pin header that is configured to connect to a standard remote control servo. ' A future modification of the code will also allow this port to trigger an ' Epic Stylus camera using a infrared remote trigger instead of a mechanical ' one. Port RA.1 is connected to a small relay that is configured to trigger ' a Pentax ZX-M 35mm camera using its remote electronic trigger port. The ' remaining pins of Port A are tied to ground and can be used in future ' revisions to the design. ' ' As stated above the configuration of the application is controlled by the ' settings of an 8-position dip switch on port B. The settings are as follows: ' ' Interval ' RB2 RB1 RB0 Value Description ' --- --- --- ----- ------------------ ' 0 0 0 0 2 second interval ' 0 0 1 1 5 second interval ' 0 1 0 2 15 second interval ' 0 1 1 3 30 second interval ' 1 0 0 4 1 minute interval ' 1 0 1 5 2 minute interval ' 1 1 0 6 5 minute interval ' 1 1 1 7 10 minute interval ' ' Film capacity ' RB3: 0 - 24 exposure roll, 1 - 36 exposure roll ' ' Start-up delay ' RB4: 0 - 2 minute delay, 1 - 5 minute delay ' ' Output selection ' RB5: 0 - relay port (RA.1), 1 - servo port (RA.0) ' ' The following settings are only used if servo port selected. ' ' Signal type for servo port ' RB6: 0 - standard servo, 1 - infrared pulse stream ' ' Servo direction, only applicable if RB5=1 and RB6=0 ' RB7: 0 - 1 millisecond, 1 - 2 millisecond ' ' @ __config _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF ' ----------------------------------------------------------------- ' VARIABLE and CONSTANT DEFINITION ' FilmCount var word ' Variable to hold picture count TimerInterval var word Seconds var word ServoTime var word TempByte var byte ClockTicks var byte Trigger var bit ' Variable to determine if trigger ' ' ' ----------------------------------------------------------------- ' Microcontroller Set-up ' ' Set PORTA.0, PORTA.1, and PORTA.2 for output TRISA = %11111000 LOW PORTA.0 LOW PORTA.1 HIGH PORTA.2 ' Set PORTB for input TRISB = %11111111 ' Set TMR0 to trigger interrupt once every 16.384ms (61 ticks ' per second) 4MHz crystal, 1:64 prescaler, initialize TMR0 ' to 0 OPTION_REG = %10000101 INTCON = %10100000 ClockTicks = 0 Seconds = 0 TempByte = PORTB & %00000111 ' Based upon switch selection for SELECT CASE TempByte ' RB0..RB2 set the timer interval CASE 0 ' to the number of seconds TimerInterval = 2 ' described above. CASE 1 TimerInterval = 5 CASE 2 TimerInterval = 15 CASE 3 TimerInterval = 30 CASE 4 TimerInterval = 60 CASE 5 TimerInterval = 120 CASE 6 TimerInterval = 300 CASE 7 TimerInterval = 600 END SELECT IF (PORTB.3 = 1) THEN FilmCount = 37 ' 37 exposures ELSE FilmCount = 25 ' 25 exposures ENDIF PAUSE 1000 LOW PORTA.2 IF (PORTB.4 = 0) THEN ' Wait for 2 minutes on start-up FOR TempByte = 0 TO 119 PAUSE 1000 ' Ok to use long pause since no Interupts yet NEXT TempByte ELSE ' Wait for 5 minutes on start-up FOR TempByte = 0 TO 299 PAUSE 1000 NEXT TempByte ENDIF Trigger = 0 TMR0 = 0 ON INTERRUPT GOTO IntHandler GOTO Main ' ----------------------------------------------------------------- ' Interrupt Handler ' IntHandler: DISABLE ' Prevent any new interrupts during interrupt handler ClockTicks = ClockTicks + 1 IF (ClockTicks < 61) THEN IntExit ClockTicks = 0 Seconds = Seconds + 1 IF (Seconds < TimerInterval) THEN IntExit Seconds = 0 Trigger = 1 IntExit: INTCON = %10100000 ' Clear the event flags ENABLE ' Re-enable interrupts RESUME ' ' ----------------------------------------------------------------- ' Main program loop ' Main: ' This is the standard 'center' pulse for a servo ServoTime = 1500 ' Test to see if TimerInterval has expired IF (Trigger = 1) THEN IF (PORTB.5 = 0) THEN ' Use Relay Port HIGH PORTA.1 HIGH PORTA.2 FOR TempByte = 0 TO 29 ' 0.3 second delay total while PAUSE 5 ' still allowing the timer NEXT TempByte ' interrupt to be serviced LOW PORTA.1 LOW PORTA.2 ELSE ' Use Servo Port IF (PORTB.6 = 0) THEN ' Standard servo signals ' This code only adjust the pulse length. ' It does not actually send the pulse to the servo IF (PORTB.7 = 0) THEN 'Send 1 millisecond pulse ServoTime = 1000 ELSE 'Send 2 millisecond pulse ServoTime = 2000 ENDIF ELSE ' Send EPIC Pulse stream ENDIF ENDIF ' Decrement Film Counter FilmCount = FilmCount - 1 IF (FilmCount <= 0) THEN 'Shutdown the circuit DISABLE ' Turn off interrupts HIGH PORTA.2 PAUSE 30000 LOW PORTA.2 END ' Stop execution and place PIC in sleep mode ENDIF Trigger = 0 ENDIF ' The following code tests to see if the servo output port is ' selected and if so send the pulse stream to maintain position IF ((PORTB.5 = 1) AND (PORTB.6 = 0)) THEN HIGH PORTA.0 PAUSEUS ServoTime LOW PORTA.0 IF (ServoTime <> 1500) THEN HIGH PORTA.2 FOR TempByte = 0 TO 29 ' 0.3 second delay total while PAUSE 10 ' still allowing the timer HIGH PORTA.0 PAUSEUS ServoTime LOW PORTA.0 NEXT TempByte ' interrupt to be serviced LOW PORTA.2 ServoTime = 1500 ELSE PAUSE 10 ' This delay results in a XX update frequency ENDIF ENDIF GOTO Main
This page and all of its contents are Copyright © 2002 by Walter Anderson
Home Page