Inconsistant time using interupts


Closed Thread
Results 1 to 6 of 6
  1. #1
    Join Date
    Dec 2006
    Posts
    32

    Question Inconsistant time using interupts

    Hi guys,

    Im currently using Darrels DT_HID include file to control the USB aspects of my project and it works great and I am also using his DT_INTS-18 include and have setup my PWM routine in an INT_INT interupt and it works but with 1 slight thing that I cant for the life of me figure out.

    Whats happening is that my project can set the pwm down to 1 millisecond and im using both channels for the pwm (its to control 2 DC powerheads for a marine reef tank) and have hooked up 2 LEDS to the pins (RC1 & RC2) and they flash away happily but they dont keep a constant rate, you can see them slow down for any period of time from a fraction of a second to maybe a second.

    I have tried changing to different interupts and either they dont swap over or when I tried TMR0 (I think it was) they ran about 10 times faster than they should and I got errernous twitching on port A 1 & 2.

    Im using an 18F2455 with a 4Mhz xtal and have a dallas DS18S20+ temp probe constantly reading the temp and displaying the info on an LCD screen (Hence why I used the interupt for the pwm routines otherwise because of the LCD and its pauses it needs etc, it ran way too slow)

    Here are my settings for the ports etc.
    Code:
    ADCON0 = 0          'Set ADCON0
    ADCON1 = %00001111  'Set D i/o
    CMCON = 7           'Disable Comparators
    CCP1CON = %00001100 'set pwm
    CCP2CON = %00001100 'set pwm
    TRISA  = %00000000  'set PORTA as all output
    TRISB  = %00000000  'set PORTB as all output
    TRISC  = %00000000  'set PORTC as all output
    PR2 = 63                      
    T2CON = %00000110   ' Start Timer2, Prescaller 1:16
    and here is the interupt setup using Darrels routines.
    Code:
    INCLUDE "DT_INTS-18.bas"     ; Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"
    
    ASM
    INT_LIST  macro    ; IntSource,          Label,  Type, ResetFlag?
            INT_Handler   USB_Handler
            INT_Handler     INT_INT,     _Do_WaveMakers, PBP, yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    endasm
    My wavemaker code is a bit long winded looking but it works (probably an easier way to do it, but this is the way I could figure it out etc, and it dosnt take long to execute because its using case's so it only does 1 section per powerhead at a time)

    Code:
    Do_WaveMakers:    
    
        if PHWAVEBOX = 0 then       'No wavebox mode so we ramp up and down the power   
            select case PH1PHASE
            case 0                                      'Ramp up the powerhead
                PH1TIMER = PH1TIMER +1
                if PH1TIMER >= 100 then                '10th of a second count   
                    PH1TIMER = 0
                    PH1PWR = PH1PWR + (ramp_step/10)    'now add calculated step value
                endif 
                if PH1PWR > PHMAX then 
                    PH1PWR = PHMAX
                    PH1PHASE = 1
                endif
            case 1                                      'At MAX power so hold there for duration
                if PH1TIME < PHSECS then
                    if PH1TIME = (PHSECS/2) -2 and PHOVER = 2 then 
                        PH2PWR = PHMIN
                        PH2PHASE = 0
                        PH2TIME = 0
                    endif
                    PH1TIMER = PH1TIMER + 1
                    if PH1TIMER = 1000 then
                        PH1TIME = PH1TIME + 1
                        PH1TIMER = 0
                    endif
                else
                    PH1TIMER = ramp_step
                    PH1TIME = 0
                    PH1PHASE = 2
                endif
            case 2                                      'Ramp down the power to MIN value
                PH1TIMER = PH1TIMER - 1
                if PH1TIMER <= 0  then    
                    PH1TIMER = 100
                    PH1PWR = PH1PWR - (ramp_step/10)
                endif
                if PH1PWR < PHMIN or PH1PWR > PHMAX then    'Need to have the > PHMAX as it can go below 0 which is higher than the MAX ;)
                    PH1PWR = PHMIN
                    PH1PHASE = 3
                endif
            case 3                                      'At MIN power so hold again
                if PH1TIME < PHSECS AND PHOVER = 1 then 'Unless we are using the together mode (3) then we dont wait
                    PH1TIMER = PH1TIMER + 1
                    if PH1TIMER = 1000 then
                        PH1TIME = PH1TIME + 1
                        PH1TIMER = 0
                    endif
                elseif PH1TIME < PHMSECS and PHOVER = 0 then
                    PH1TIMER = PH1TIMER + 1
                    if PH1TIMER = 1000 then
                        PH1TIME = PH1TIME + 1
                        PH1TIMER = 0
                    endif                
                elseif PH1TIME < PHSECS and PHOVER = 2 then
                    PH1TIMER = PH1TIMER + 1
                    if PH1TIMER = 1000 then
                        PH1TIME = PH1TIME + 1
                        PH1TIMER = 0
                    endif                
                else
                    PH1TIMER = 0
                    PH1TIME = 0
                    PH1PHASE = 0
                endif
            end select
        
            select case PH2PHASE
            case 0                                      'Ramp up the powerhead
                PH2TIMER = PH2TIMER +1
                if PH2TIMER >= 100 then                '10th of a second count   
                    PH2TIMER = 0
                    PH2PWR = PH2PWR + (ramp_step/10)    'now add calculated step value
                endif 
                if PH2PWR > PHMAX then 
                    PH2PWR = PHMAX
                    PH2PHASE = 1
                endif
            case 1                                      'At MAX power so hold there for duration
                if PH2TIME < PHSECS then
                    PH2TIMER = PH2TIMER + 1
                    if PH2TIMER = 1000 then
                        PH2TIME = PH2TIME + 1
                        PH2TIMER = 0
                    endif
                else
                    PH2TIMER = ramp_step
                    PH2TIME = 0
                    PH2PHASE = 2
                endif
            case 2                                      'Ramp down the power to MIN value
                PH2TIMER = PH2TIMER - 1
                if PH2TIMER <= 0  then    
                    PH2TIMER = 100
                    PH2PWR = PH2PWR - (ramp_step/10)
                endif
                if PH2PWR < PHMIN or PH2PWR > PHMAX then    'Need to have the > PHMAX as it can go below 0 which is higher than the MAX ;)
                    PH2PWR = PHMIN
                    PH2PHASE = 3
                    PH2TIME = 0
                endif
            case 3                                      'At MIN power so hold again
                if PHOVER = 2 and PH1PHASE = 3 then
                PH1PWR = PHMIN
                PH1PHASE = 0
                PH1TIME = 0
                endif
                if PH2TIME < PHSECS AND PHOVER = 1 then 'Unless we are using the together mode (3) then we dont wait
                    PH2TIMER = PH2TIMER + 1
                    if PH2TIMER = 1000 then
                        PH2TIME = PH2TIME + 1
                        PH2TIMER = 0
                    endif
                elseif PH2TIME < PHMSECS and PHOVER = 0 then
                    PH2TIMER = PH2TIMER + 1
                    if PH2TIMER = 1000 then
                        PH2TIME = PH2TIME + 1
                        PH2TIMER = 0
                    endif                
                elseif PH2TIME < PHMSECS and PHOVER = 2 then
                    PH2TIMER = PH1TIMER + 1
                    if PH2TIMER = 1000 then
                        PH2TIME = PH2TIME + 1
                        PH2TIMER = 0
                    endif                
                else
                    PH2TIMER = 0
                    PH2TIME = 0
                    PH2PHASE = 0
                endif
            end select
        else                            'Wavebox mode
    
            select case PH1PHASE
            case 0
                if PH1TIME < PHMSECS then
                    PH1TIME = PH1TIME + 1
                else
                    PH1PHASE = 1            
                    PH1TIME = 0
                    PH1PWR = PHMIN
                endif
            case 1
                if PH1TIME < PHMSECS then
                    PH1TIME = PH1TIME + 1
                else
                    PH1PHASE = 0
                    PH1TIME = 0
                    PH1PWR = PHMAX            
                endif
            end select    
    
            select case PH2PHASE
            case 0
                if PH2TIME < PHMSECS then
                    PH2TIME = PH2TIME + 1
                else
                    PH2PHASE = 1            
                    PH2TIME = 0
                    PH2PWR = PHMIN
                endif
            case 1
                if PH2TIME < PHMSECS then
                    PH2TIME = PH2TIME + 1
                else
                    PH2PHASE = 0
                    PH2TIME = 0
                    PH2PWR = PHMAX            
                endif
            end select    
        endif
        CCPR1L = PH1PWR >>2   
        CCP1CON.5 = PH1PWR.1
        CCP1CON.4 = PH1PWR.0
    
        CCPR2L = PH2PWR >>2   
        CCP2CON.5 = PH2PWR.1
        CCP2CON.4 = PH2PWR.0
    
    @    INT_RETURN
    Ive tried using DISABLE and ENABLE at each end, and even INTCON.6 = 0,INTCON = 1 to try to stop anything that could be possibly interferring with the routine when its executed etc, but didnt seem to make any difference.

    The main loop basically just calls the temp sensor to see if its alive, then if it is, reads the temp and sets a couple of pins depending on some settings, displays the temp on the screen, and then if the plugged flag is true using Darrels HID routine calls the USB but only when its plugged in.

    Hope someone can shed some light onto my problem as im out of ideas on what else I can try.

    It couldnt be anything to it been on a breadboard could it? as I remember reading somewhere about breadboards not been brilliant for certain things etc.

    Many thanks in advance,

    Mark.

  2. #2
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Mark,

    I'm thinking that maybe you need to move the USB interrupts to Low Priority, so that it won't interfere with the PWM interrupts.

    Like this ...
    Code:
    DEFINE  USE_LOWPRIORITY  1
    
    INCLUDE "DT_INTS-18.bas"     ; Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"
    
    ASM
    ;----[High Priority Interrupts]-----------------------------------------------
    INT_LIST  macro    ; IntSource,          Label,  Type, ResetFlag?
            INT_Handler     INT_INT,     _Do_WaveMakers, PBP, yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    
    ;----[Low Priority Interrupts]------------------------------------------------
    INT_LIST_L  macro  ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   USB_Handler
        endm
        INT_CREATE_L             ; Creates the Low Priority interrupt processor
    endasm
    And you may need to synchronize loading the CCP registers with Timer2.
    Or, use HPWM10 ... http://www.picbasic.co.uk/forum/show...7805#post37805


    HTH,
    DT

  3. #3
    Join Date
    Dec 2006
    Posts
    32


    Did you find this post helpful? Yes | No

    Default

    Well, after hammering away at this for ages, I tried allsorts, TMR0,TMR1 timers with no avail as it dosnt help when I cant fully follow the datasheets for them etc (maybe one day it'll click! )

    In the end I removed the
    Code:
        CCPR1L = PH1PWR >>2   
        CCP1CON.5 = PH1PWR.1
        CCP1CON.4 = PH1PWR.0
    
        CCPR2L = PH2PWR >>2   
        CCP2CON.5 = PH2PWR.1
        CCP2CON.4 = PH2PWR.0
    from the interupt and as a last ditch attempt simply stuck in 2 HPWM functions in my main loop like this:
    Code:
    HPWM 1,PH1PWR,1000
    HPWM 2,PH2PWR,1000
    and crossed everything I could as it was a total shot in the dark and bingo! it works

    I was getting really fed up with not been able to crack it, but just shows that sometimes going back to simpleton mode works lol!!!

    Was surprised no one could offer any tips though, but in some ways it can help to be out on a limb and forces you to keep hammering away as it can pay off (thankfully while ive still got hair on my head )

    Mark

  4. #4
    Join Date
    Dec 2006
    Posts
    32


    Did you find this post helpful? Yes | No

    Default

    LOL,

    Sorry Darrel, I never saw your post until just now! obviously the time it took me to actually write my last post was when you were writing yours too lol...

    I'm going to bench test the code to triple check its doing what it should do, and if not i'll definately give your low level interupt a try.

    Thats one thing I never thought about to be honest, as I did try to get the low level interupt working when I first was playing with your includes etc, but I never got it working (the usual, download the files, stick in the project and NOT read the instructions fully! Hmmm.. the phrase 'Look before you leap' springs to mind hehe...)

    Mark

  5. #5
    Join Date
    Nov 2007
    Location
    Lake Villa Il.
    Posts
    40


    Did you find this post helpful? Yes | No

    Default

    Hi Mark,
    Just wondering if there was any progress?

    Tnx,

    Sneaky-geek

  6. #6
    Join Date
    Dec 2006
    Posts
    32


    Did you find this post helpful? Yes | No

    Default

    Hi Sneaky,

    sorry its taken a while to reply, but touch wood, it seems to be running ok at the mo! I removed all the PWM calls from the interupt and put them in the main loop and it seems to be working as it should.

    When I get the project finally finished, i'll probably have a play by making the USB interupts low priority like Darrel mentioned previously in the thread.
    If I do and its still fine, i'll pop a reply to let everyone know etc.

    Mark.
    (been having probs hardware side dropping 24v dc to 12v without either having to use a huge heatsink etc, as everything ive tried so far keeps popping lol, but will be trying a step down regulator as soon as funds allow as it needs a few other parts to go with it and a redesign of the PCB, then etch etc etc.)

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts