Maybe someone will be optimise code maybe not.
Here is my last test and all my problems wos on my wrong seting of 18F4431
and wrong calc for position counter.
These code only mowe motor CW but I was tested also CCW and is ok.
My best regards to all
/Robert
Code:@ __CONFIG _CONFIG1H, _OSC_HSPLL_1H @ __CONFIG _CONFIG2H, _WDTEN_ON_2H & _WDPS_512_2H @ __CONFIG _CONFIG2L, _BOREN_OFF_2L & _PWRTEN_ON_2L @ __CONFIG _CONFIG3H, _MCLRE_ON_3H @ __CONFIG _CONFIG4L, _LVP_OFF_4L clear define OSC 40 ;define osc speed 10MHz x 4 PLL = 40 MHz ADCON0= %00000000 ANSEL0= %00000000 ANSEL1= %00000000 TRISA = %00011110 TRISB = %00000000 TRISC = %00000000 TRISD = %00000000 TRISE = %00000000 LATA = %00000000 LATB = %00000000 LATC = %00000000 LATD = %00000000 LATE = %00000000 duty var word 'duty variable for PWM CCP1 PosLow VAR BYTE ; Temp variable for Position calc. PosHigh VAR BYTE ; Temp variable for Position calc. PosTemp VAR BYTE ; Temp variable for Position calc. position var word ; Position counter final variable from QEI module direction var bit ; Direction bit for motor CW or CCW setpoint var word ; Setpoint of position variable preset_TMR1 var word ; Timer1 prescaler variable include "PID.pbp" ; Include Henrik PID rutine INCLUDE "DT_INTS-18.bas" ; Base Interrupt System INCLUDE "ReEnterPBP-18.bas" ; Include if using PBP interrupts ;----[High Priority Interrupts]----------------------------------------------- ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler TMR1_INT, _pidloop, PBP, yes endm INT_CREATE ENDASM CCP1CON = %00001111 T2CON = %00000100 T1CON = %10000101 QEICON = %10001000 DFLTCON = %00111010 POSCNTH=0 ; set initial counter for encoder, H bit POSCNTL=0 ; set initial counter for encoder, L bit setpoint = 0 ; set initial for Setpoint duty = 512 ; set initial for PWM 512 = motor no move direction = pid_Out.15 pid_Kp =$0140 pid_Ki =$0020 pid_Kd =$0003 pid_Ti = 8 pid_I_Clamp = 1 pid_Out_Clamp = 511 preset_TMR1 = 65043 TMR1L = preset_TMR1.byte0 TMR1H = preset_TMR1.byte1 @ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts Main: ; main loop IF PORTA.1 = 0 then setpoint = setpoint + 1 ; Increment setpoint from taster on RA1 select case setpoint ; Circular count for Setpoint condition case is >= 65534 ; Circular count for Setpoint condition setpoint = 0 ; reset setpoint POSCNTH=0 ; set counter for encoder, H bit ; reset QEI counter high byte POSCNTL=0 ; set counter for encoder, L bit ; reset QEI counter low byte end select ; End of Circular count for Setpoint condition pid_Error = setpoint - position ; Calculate PID error for PID rutine gosub pid ; go to PID rutine select case direction ; condition determine PWM for locked antiphase case 0 ; condition determine PWM for locked antiphase Duty = abs(512-pid_out) ; condition determine PWM for locked antiphase case 1 ; condition determine PWM for locked antiphase Duty = 512 + pid_Out ; condition determine PWM for locked antiphase end select ; End condition determine PWM for locked antiphase @ INT_DISABLE TMR1_INT ; Prevent disable Timer1 interupt CCPR1L = duty>>2 ; MSB of duty cycle value CCP1CON=%00001111 | (duty<<5) ; set PWM mode and store the @ INT_ENABLE TMR1_INT ; Enable Timer1 interupt goto Main ; do main loop pidloop: ; Interrupt for fast reading QEI and calc position PosHigh = POSCNTH ; reading QEI and calc position PosLow = POSCNTL ; reading QEI and calc position PosTemp = POSCNTL ; reading QEI and calc position If PosLow - PosTemp = 0 then Goto Done ; reading QEI and calc position PosHigh = POSCNTH ; reading QEI and calc position PosLow = POSCNTL ; Done reading QEI and calc position Done: ; Final QEI calc position Position = 256 * POSHIGH + PosLow ; Final QEI calc position TMR1L = preset_TMR1.byte0 ; reset Timer1 to preset TMR1H = preset_TMR1.byte1 ; reset Timer1 to preset @ INT_RETURN ; return from Timer1 interrupt end




Bookmarks