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

Home