Monday, June 13, 2011

More coding progress and toys arrived.

First off, a bunch of packages arrived. These were mainly support items for me learning basic electronics. It include things like LEDs, capacitors (well over 1,000), transistors, power supplies, switches, pots, etc... It's like an early Christmas!

The second bit is that I rewrote the code for the microcontroller. Still having a lot of fun with it. I am actually very close to the code being at a truly testable stage. I am going to try and hook it up to a real servo soon to see if I get the results I am hoping for.

In the meantime, a new copy of the code. Main thing missing is a true randomization of the values of the servos.

I will continue to post the code as I develop it. I figure might be useful for someone else playing around with this stuff to have examples. Fun for me to show off as well... :) Here is the code up to this point.

;**********************************************************************
;
; Filename: MouthServos.asm
; Date: 6/14/2001
; File Version: v 0.5
;
;
;**********************************************************************
;
; Files required: P16F877.INC
;
;
;
;**********************************************************************
;
; Purpose:
; Program will drive a set number of servo motors. These servos
; will be moved to random locations for a duration of 1 to 3
; seconds. At that end of that period, they will move to a new
; location and the process repeats.
;
; Additional Info:
; Servo pulse: high pulse 1ms to 2ms in length determining servo position
; with a low pulse of approximately 40ms between high pulses.
;
; Completed:
; Servo array implemented (currently 2 elements but can be easily expanded up to expected 12)
; Init of servo array with preset values for new positions. randomizer not implemented yet.
;
; ToDo:
; Randomize new position and duration.
; Generate pulse based upon values.
;
;
;**********************************************************************

list p=16f887 ; list directive to define processor
#include ; processor specific variable definitions

; '__CONFIG' directive is used to embed configuration data within .asm file.
; The labels following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.

__CONFIG _CONFIG1, _LVP_OFF & _FCMEN_ON & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
__CONFIG _CONFIG2, _WRT_OFF & _BOR21V

SERVOCOUNT EQU D'20'
MINTIMER EQU D'1000' ;smallest pulse for one end of servo positioning
MAXTIMER EQU D'2000' ;largest pulse for other end of servo positioning
TOTALTIMER EQU D'40000' ;max 40ms

; declare servo arrary
VARIABLES UDATA
;***************** Servo array start ****************
servo_start res 0
servo1_cycle res 1
servo1_duration res 1 ;server duration (value * 8) / 1000 = milliseconds
otherservos res 39 ;19 more servos

;***************** Servo array end ******************

temp_fsr res 1 ;used to swap out fsr
loop_count res 1 ;used in looping operations
first_time res 1 ;used to indicate first run through main loop
current_bit res 1 ;indicates current bit on current port to use
current_port res 1 ;indicates current port
debug_port res 1 ;used for debugging port problem, remove for final release

;**********************************************************************
RESET_VECTOR CODE 0x0000 ; processor reset vector
nop
goto start ; go to beginning of program

MAIN_PROG CODE

start
bsf first_time,0

bsf STATUS,RP0 ;move to bank 1
clrf TRISA ;set porta to all output
clrf TRISB ;set portb to all output
clrf TRISC ;set portc to all output
movlw b'00000010' ; configure Timer0. Time factor of x8
movwf OPTION_REG ; Maximum Prescaler

bsf STATUS,RP1 ;move to bank 3
clrf ANSEL ;set to digital instead of analog
clrf ANSELH
bcf STATUS,RP0 ;move to bank 0
bcf STATUS,RP1

BEGIN_PULSE
movlw b'00000001'
movwf current_bit ;set current bit to first bit.
movlw PORTA
movwf current_port ;starting port of A
movlw SERVOCOUNT
movwf loop_count ; loop for the number of servos we are using.
movlw servo_start ; start of the servo array
movwf FSR ; move the address into FSR

clrf T1CON
movlw 0x63 ;setup timer1 to lsat 40ms
movwf TMR1H
movlw 0xC0
movwf TMR1L
bsf T1CON,TMR1ON ;start the timer
bcf PIR1,TMR1IF ;clear the interuppt


BEGIN_SERVO_LOOP ;Do this for each servo
btfsc first_time,0 ;if first time, reset the servos
goto BEGIN_RESET_SERVO
decfsz INDF ;decrement the servo count. if not 0, skip to pulsing
goto BEGIN_PULSE_SERVO_HIGH

BEGIN_RESET_SERVO ;Its either first time or end of cycle, reset the servo to new duration and cycle
movlw d'32' ;set a new servo count TODO: Random value
movwf INDF
incf FSR
movlw d'187' ;move to center position of servo high byte TODO: Random value
movwf INDF
decf FSR
END_RESET_SERVO

BEGIN_PULSE_SERVO_HIGH
movf FSR,W
movwf temp_fsr ;save the fsr
movf current_port,W
movwf FSR ;FSR now has the correct port
movf current_bit,W
movwf INDF ;sets the appropriate bit. since only one servo is high at a time, no need to mask bits
movf temp_fsr,w
movwf FSR ;restore the FSR to point at servos
incf FSR ;move to the duration of the servo
movf INDF,W ;get the duration
sublw 0xFF ;max value of timer0
movwf TMR0 ;set the timer.
bcf INTCON,TMR0IF ;clear the flag interupt flag.
WAIT
btfss INTCON,TMR0IF ;is interupt set yet?
goto WAIT
incf FSR
END_PULSE_SERVO_HIGH

BEGIN_PULSE_SERVO_LOW
movf FSR,W
movwf temp_fsr ;save the fsr
movf current_port,W
movwf FSR ;FSR now has the correct port
clrf INDF ;pulse the port low

BEGIN_UPDATE_CHANNEL
;****** move to next channel (bit/port) for next servo
rlf current_bit
btfss STATUS,0 ;is carry bit set?
goto END_UPDATE_CHANNEL
bcf STATUS,0 ;clear the carry bit
incf current_port ;increment to the next port.
movlw b'00000001'
movwf current_bit ;reset to first bit.
END_UPDATE_CHANNEL

movf temp_fsr,W
movwf FSR ;restore the FSR to point at servos

END_PULSE_SERVO_LOW

decfsz loop_count,1 ;any servos left to process?
goto BEGIN_SERVO_LOOP
END_SERVO_LOOP
WAIT2
btfss PIR1,TMR1IF ;is interupt set yet?
goto WAIT2

bcf first_time,0
goto BEGIN_PULSE
END_PULSE

end

No comments:

Post a Comment