Project Weekly Progress Report
Project Title:
Microcontroller Implementation of a Small Robot Arm Controller
Week of: February 8th, 2000
Engineers:
Megan Bern and Ritesh Patel
=================================================================
Objective:
For the week of February 8th, 2000, our objective was to finish writing code for the digital filter.
Progress:
Software:
In the previous week, the pole for our digital filter was located at 53.45 Hz. The desired pole is 20 Hz. We used the following theory to change our code.
When trying to implement (1) on a microcontroller, the remainders must be added into the output.
(1)
If all of the remainders are added together and divided by 4, they can be added into the final output. The additional remainder created when dividing the original remainders by 4 must also be considered.
After the code was
revised, it was found that the pole was moved from 53.45 Hz to approximately
40 Hz. There was still something major that we were missing.
Simulink was evaluated again using the block diagram shown in Figure 1.
The output of the scope is shown in Figure 2. The output reaches
0.689mV and the input, which is not shown reaches 0.9543mV. The output
is 0.721 of the input. This is very close to 0.707, or the desired
pole location. This means that something else is wrong with the digital
filter code.
Figure 1: Block Diagram used in Simulink
Figure 2: Scope Output
After several hours of troubleshooting, it was realized that the interrupt signal was deceiving. Figure 3 shows the 200 Hz interrupt signal that was being used .
Figure 3:
200 Hz Interrupt Signal
This signal was sampling
every 2.5ms instead of the desired 5ms. By changing the 200Hz signal
to a 100Hz signal as shown in Figure 4, the signal will be sampled every
5ms.
Figure 4:
100 Hz Interrupt Signal
The final code that is attached to this report was then simulated. The code output a signal that was 0.707 of the input signal at 20Hz. This proves that the code for the digital filter is working. The output is shown in Figure 5.
For comparison, the old code was changed so that the interrupt signal was 100 Hz. This code was ran and the output of the digital filter was displayed on the oscilloscope with an input signal of 20 Hz. The output was only 0.68 of the input signal. This indicates that the pole is not at 20 Hz. Improving the old code also improved the accuracy of the pole location as well as changing the interrupt signal. The output of the old code with an input of 20 Hz is shown in Figure 6.
The input of the digital
filter using the old code was adjusted until the pole location was found.
This is shown in Figure 7. The pole was found to be located at 18.19
Hz. This is very close to 20 Hz, but the changing of the digital
filter code improved the output even more.
Figure 5: Digital Filter Output @ 20 Hz with New Code
Figure 6: Digital Filter Output @ 20 Hz with Old Code
Figure 7: Digital Filter Output @ 18.19 Hz with Old Code
Conclusion:
Overall, the problem
was obvious, but hard to find. There was a lot of time wasted trying
to find the problem. We are still on schedule. Next week will
be used to learn the new debugging tool.
;Ritesh Patel & Megan Bern
;Program1
;02/08/00
;generates 100Hz square wave
;A/D and D/A conversion
;Digital Filter [Yn=.25Rn + .25(Rn-1)+.50(Yn-1)]
;include(mod515)
$INCLUDE(mod515)
;include(digital)
$INCLUDE(digital.asm)
STARD EQU 8000H ;start address for program
ORG
stard
JMP
SETUP
;Interrupt Jump Table
org
stard+2BH
;TF2 + EXF2 interrupt
AJMP TMR2SRV
; Jump to timer 1 interrupt
;-----------------------------------------------------------------
TMR2SRV: ;timer 2 service every 5 ms
MOV
A,#2
; load ACC for channel 2
CALL
adcin
; call converter subroutine
; value in ACC
CALL
da_out ; write to
D/A converter, Chn 0
CPL
p4.1
;generate pulse
CLR
TF2
; clear interrupt flag
RETI
; ADCIN subroutine
; Return ACC with the 8 bit A/D conversion from the channel
selected by ACC
;
ADCIN:
ANL A,#00000111B
; ONLY 8 CHANNELS
ANL ADCON,#11000000B
; MODE FOR A/D CONVERSION: SINGLE
ORL ADCON,A
; "OR" IN THE CHANNEL
MOV DAPR,#0
; START CONV W/NO REF VOLTAGE
JB
BSY,$
; LOOP TILL CONVERTED
MOV
acc,ADDAT
; ACC = CONVERSION
LOOP:
MOV
IP_1,IP
;MOVE Rn INTO Rn-1
MOV
IP,a ;MOVE Rn INTO a
MOV
b,#4h ;MOVE 4 INTO b
DIV
ab ;DIVIDE Rn BY 4
MOV
R7,b ;MOVE REMAINDER 1 INTO R7
MOV
R2,a ;MOVE Rn(1/4) INTO R2
MOV
a,IP_1 ;MOVE Rn-1 INTO a
MOV
b,#4h ;MOVE 4 INTO b
DIV
ab ;DIVIDE Rn-1 BY 4
MOV
R3,a ;MOVE Rn-1(1/4) INTO R3
MOV
a,b ;MOVE REMAINDER 2 INTO a
ADD
a,R7 ;ADD REMAINDER 1 TO REMAINDER 2
MOV
R7,a ;MOVE SUM OF REMAINDERS 1 AND 2 INTO R7
MOV
OP_1,OP ;MOVE Yn INTO Yn-1
MOV
a,OP_1 ;MOVE Yn-1 INTO a
MOV
b,#2h ;MOVE 2 INTO b
DIV
ab ;DIVIDE Yn-1 BY 2
MOV
R4,a ;MOVE Yn-1(1/2) INTO R4
MOV
a,b ;MOVE REMAINDER 3 INTO a
MOV
b,#2h ;MOVE 2 INTO b
MUL
ab ;MULTIPLY REMAINDER 3 BY 2
ADD
a,R7 ;ADD (2)REMAINDER 3 TO REMAINDERS 1 AND 2
MOV
b,#4h ;MOVE 4 INTO b
DIV
ab ;DIVIDE TOTAL REMAINDERS BY 4
ADD
a,R2 ;ADD (1/4)Rn TO REMAINDERS
ADD
a,R3 ;ADD (1/4)Rn-1 TO REMAINDERS AND (1/4)Rn
ADD
a,R4 ;ADD (1/2)Yn-1 TO REMAINDERS, (1/4)Rn, AND (1/4)Rn-1
MOV
R5,a ;MOVE TOTAL, Yn, INTO R5
MOV a,b
;MOVE REMAINDER OF TOTAL REMAINDERS INTO a
CLR
C ;CLEAR CARRY FLAG
SUBB a,#2
;SUBTRACT 2 FROM REMAINDER OF REMAINDERS
JC
HERE
JZ
THERE
JNZ
THERE
THERE:
MOV a,R5
;MOVE Yn INTO a
ADD a,#1
;ADD 1 TO Yn
MOV OP,a
;MOVE TOTAL, Yn, INTO CURRENT OUTPUT
HERE: MOV a,R5
MOV OP,a ;MOVE TOTAL, Yn, INTO CURRENT OUTPUT
RET
; da_out subrountine
; write value in ACC to D/A channel specified below
da_out: MOV P2,#DA_0 ; point to D/A channel
0
MOVX @R1,a ; write data
RET
;***********************************************
;
;
Intialization Code
;
;***********************************************
SETUP:
MOV IEN0,#0 ;Disable ALL INTS
MOV SP,#70H ;Initialize STACK
SETB P5.5 ;Do a reset
CLR P5.5 ;bring it low
SETB P5.0 ;make A16 of 128K Ram, high
SETB P5.2 ;disable EEPROM
CLR P5.1 ;new port 5.1 for D/A
;END 80535 Stuff
MOV R0,#7FH ;CLEAR 128 BYTES OF RAM
clr_ram: MOV @R0,#0
DJNZ R0,clr_ram
SETB T2CON.0 ; timer 2: 16 bit operation
SETB T2CON.4 ; and auto-reload mode
MOV TH2,#0EDH ; load timer 2 registers
MOV TL2,#0E4H
MOV CRCH,#0EDH ; load capture registers
MOV CRCL,#0E4H ; timer 2
SETB ET2
;enable timer 2 ovf int
SETB EAL
; enable all interrupts
Digital:
MOV IP,#0 ;Initialize IP
MOV IP_1,#0 ;Initialize IP_1
MOV OP,#0 ;Initialize OP
MOV OP_1,#0 ;Initialize OP_1
main: jmp main
END