Electronics

Projects
  Kodak DC20 Controller

PIC Microcontrollers
  Getting Started
  16F84

Reference
  Resistor Color Codes
  Resistance Calculator
  Ohm's Law

 

 

Kodak DC20 Digital Camera Controller

Software
 DC20 Controller

DC20 Controller Home

Parts List
The Circuit
Software
Construction

Related Links

The software for controlling the DC20 is shown below. This .ASM code was written for the PIC 16F84 microcontroller, but can be easily modified for other PIC processors.

The code below has been divided into several sections to accomodate the narrative text.

Click here to remove the narrative text.

.ASM Code

The first block of code contains a few lines of comments describing the I/O port assignments. The LIST directive instructs the assembler to build HEX code for the 16F84. The INCLUDE directive instructs the assembler to include the contents of the p16f84.inc file, which contains equates for common CPU registers and other commonly used values.

;
; PORTA,0 = rx
; PORTA,1 = tx
; PORTA,2 = LED
; PORTA,3 = not used
; PORTA,4 = not used
; PORTB,0-7 = input

	LIST P=16F84
	INCLUDE "p16f84.inc"

The next block contains equates that assign meaningful names to the memory addresses used by the program.


txreg	equ	0x0c
rxreg	equ	0x0d
bits	equ	0x0e
aloft	equ	0x0f
photos	equ	0x10
dcnta	equ	0x11
dcntb	equ	0x12
dparo	equ	0x13
dparm	equ	0x14
dpari	equ	0x15
dcnto	equ	0x16
dcntm	equ	0x17
dcnti	equ	0x18
parity	equ	0x19

A goto instruction that forces execution to jump to the main label is placed at address 0x00. This causes the CPU to skip over the routines that are placed ahead of the main program code.


	org	0x00
	goto	main


The init routine is called once at the beginning of the code. It sets Port A up for input on bit 0, output on bits 1 and 2, and inputs on 3 and 4. Bits 5, 6 and 7 are not implemented in the PIC 16F84 so therefore it doesn't matter which direction they are set to. All eight bits on Port B are set as inputs. The option register is configured to enable the internal pull-ups on Port B.


init
	movlw	B'00011001'
	tris	PORTA

	movlw	B'11111111'
	tris	PORTB ; RB0-7 input

	movlw	B'01111111' ; enable portb pull-ups
	option

	return


The keepalive routine is called once at the beginning of the code, then again periodically to keep the camera from going to sleep. It sends a series of 8 bytes to the camera that define the serial communications speed to use, which is 9600 in this case.


keepalive
; Init to 9600 baud
	movlw 0x41
	call tx
	movlw 0x00
	call tx
	movlw 0x96
	call tx
	movlw 0x00
	call tx
	movlw 0x00
	call tx
	movlw 0x00
	call tx
	movlw 0x00
	call tx
	movlw 0x1A
	call tx
	return


tx is called to trasmit a byte to the camera. Register w should be loaded with the value to be transmitted before calling tx.


; transmit a byte passed in w to PORTB, 7.
; (1 start bit, 8 data bits, 1 parity bit, 1 stop bit)
tx
	movwf	txreg
	comf	txreg,f
	movlw	0x00
	movwf	parity
	bsf	PORTA,1 ; start bit
	call	delbit
	movlw	0x08
	movwf	bits
tx1
	rrf	txreg,f
	btfsc	STATUS,C
	goto	tx2
	bcf	PORTA,1
	incf	parity,f
	goto	tx3
tx2
	bsf	PORTA,1
tx3
	call	delbit
	decfsz	bits, f
	goto	tx1

	btfsc	parity,0 ; parity bit
	bcf	PORTA,1 ; send another 'high' to make it even
	goto	txpsent
	bsf	PORTA,1
txpsent
	call	delbit ; pause after parity bit

	bcf	PORTA,1 ; stop bit
	call	delbit ; pause after stop bit
	retlw	0



; delay one full bit length for 9600 baud
delbit	movlw	d'1'
	movwf	dcntb
delbit0	movlw	d'27'
	movwf	dcnta
delbit1	decfsz	dcnta, f
	goto	delbit1
	decfsz	dcntb, f
	goto	delbit0
	retlw	0


vdelay is a 3 level delay routine. 3 levels are required to achieve delays of several seconds or more. Before calling, set dparo, dparm and dpari with the most signifcant (outer), middle significant (middle) and least significant (inner) delay values, respectively.


; variable delay routine - 3 levels
vdelay	movf	dparo,w
	movwf	dcnto
delay0	movf	dparm,w
	movwf	dcntm
delay1	movf	dpari,w
	movwf	dcnti
delay2	decfsz	dcnti,f
	goto	delay2
	decfsz	dcntm,f
	goto	delay1
	decfsz	dcnto,f
	goto	delay0
	retlw	0


wait30s calls vdelay with values appropriate for a delay of about 30 seconds.


; 30 second delay
wait30s
	movlw	d'150'
	movwf	dparo
	movlw	d'250'
	movwf	dparm
	movlw	d'250'
	movwf	dpari
	call	vdelay
	retlw	0


wait10s calls vdelay with values appropriate for a delay of about 10 seconds.


; 10 second delay
wait10s
	movlw	d'50'
	movwf	dparo
	movlw	d'250'
	movwf	dparm
	movlw	d'250'
	movwf	dpari
	call	vdelay
	retlw	0


wait5s calls vdelay with values appropriate for a delay of about 5 seconds.


; 5 second delay
wait5s
	movlw	d'25'
	movwf	dparo
	movlw	d'250'
	movwf	dparm
	movlw	d'250'
	movwf	dpari
	call	vdelay
	retlw	0


wait1s calls vdelay with values appropriate for a delay of about 1 second.


; 1 second delay
wait1s
	movlw	d'5'
	movwf	dparo
	movlw	d'250'
	movwf	dparm
	movlw	d'250'
	movwf	dpari
	call	vdelay
	retlw	0


Execution begins at the label main. The init routine is called first. This sets up the I/O ports and the option register on the CPU.


main
	call	init

After the init routine, the main program blinks the LED indicator three times. This is partly for show, and partly to provide feedback to the operator confirming the CPU is functioning correctly. The LED is connected to bit 2 of Port A. Blinking the LED involves setting bit 2 which turns on the LED, waiting a suitable amount of time (1 second in this case), then clearing bit 2 which turns the LED off. This process is repeated 3 times with a 1 second delay in between.


; Blink 3 times.
	bsf	PORTA,2
	call	wait1s
	bcf	PORTA,2
	call	wait1s
	bsf	PORTA,2
	call	wait1s
	bcf	PORTA,2
	call	wait1s
	bsf	PORTA,2
	call	wait1s
	bcf	PORTA,2
	call	wait1s

Once initialization is complete and the operator is suitable impressed with the blinking indicator, the CPU pauses for a preset amount of time. This allows the operator to get the kite-cam aloft before it starts snapping photos. The length of the delay is determined by reading the inputs on Port B, which is directly connected to an 8 bit DIP switch.


; Wait 30 seconds inside a loop that executes
; a number of times as determined by the
; value present on the Port B input lines.
; Call the keepalive routine once for each
; iteration of the loop to keep the camera
; from going to sleep.
	movf	PORTB,w
	movwf	aloft
aloft0
	call	keepalive
	call	wait30s
	decfsz	aloft,f
	goto	aloft0

The DC20 is capable of taking up to 8 photos. Start a loop that will execute 8 times. For each iteration, send a 'take photo' command to the camera. Turn the LED on before the command is sent, and turn it off again after about 5 seconds. An additional delay of about 10 seconds is forced after each photo to allow the camera to write the photo to its memory.


; Aloft time is up.
; Start snapping photos.
	movlw	0x08
	movwf	photos
photo
; turn on LED
	bsf	PORTA,2

; take a photo
	movlw 0x77
	call tx
	movlw 0x00
	call tx
	movlw 0x00
	call tx
	movlw 0x00
	call tx
	movlw 0x00
	call tx
	movlw 0x00
	call tx
	movlw 0x00
	call tx
	movlw 0x1A
	call tx

	call	wait5s

; turn off LED
	bcf	PORTA,2

	call	wait10s

	decfsz	photos,f
	goto	photo

When the 8-cycle photo loop completes, the CPU's job is done. Send it into an infinite loop to keep it from executing random instructions that may exist beyond the end of the program. The end statement tells the assembler where the block of code terminates. It is not an instruction to the CPU.


loop
	goto loop

	end

I/O Port Usage

Port A, bit 0 is the serial receive line connected to the camera's transmit line. The software does nothing with this I/O line, but it is connected to the camera to facilitate future enhancements. Port A, bit 1 is the serial transmit line connected to the camera's receive line. It is through this line that all commands are sent to the camera. Port A, bit 2 is connected to the LED on the controller. The LED is used to indicate status. The remaining bits on Port A are not used. These two lines are connected to +5V through 10KΩ pull-up resistors. This is necessary on any unused pins to prevent them from floating.

All eight I/O lines on Port B are connected to the 8 position DIP switch. Pull-up resistors are not needed on Port B pins since the 16F84 has internal pull-up resistors. The internal resistors do need to be activated by clearing the MSB of the option register. This is done in the init routine.

 

Tell me what you think