IntervalometerThis 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