Interrupt won't execute.


Closed Thread
Results 1 to 24 of 24
  1. #1
    Join Date
    Mar 2010
    Posts
    12

    Default Interrupt won't execute.

    Hey all, another newbie question.

    I'm trying to run a servo (later to be expanded to 2 servos) with timer1 interrupts. The program compiles nicely, but never gets to the interrupt routine. I've never used interrupts or the timer before, but I've read all that I can, and just can't figure it out.

    I'm running on the 16F690

    Here's my code:

    Code:
    define OSC 4
    ON INTERRUPT GOTO INTCODE
    
    
    DEFINE HSER_TXSTA 20h       'SET THE TRANSMIT REGISTER TO TRANSMITTER ENABLED
    DEFINE HSER_BAUD 2400       'SET BAUD RATE
                                'DEFINE ADCIN PARAMETERS
    Define ADC_BITS	10          'SET NUMBER OF BITS IN RESULT
    Define ADC_CLOCK 3          'SET CLOCK SOURCE (3=RC)
    Define ADC_SAMPLEUS 50	    'SET SAMPLEING TIME IN uS
    define LOADER_USED 1
    
    SELECTOR    VAR BYTE        'SELECTS PROGRAM TYPE
    TEMP        VAR WORD        'TEMPORY VARIABLE FOR ANY USE
    POSITION    VAR WORD        'POSITION OF SERVO1 1250 - 2500
    OFFWIDTH    VAR WORD        'HOW LONG THE PULSE NEEDS TO BE OFF FOR
    FREQ        VAR WORD        'FREQUENCY TO RUN THE SERVOS AT
    PICOSC      VAR BYTE BANK0  'TO STORE OSCILLATOR FREQUENCY IN
    PERIOD      VAR WORD        'TEMPORY VARIABLE TO DISPLAY THE PERIOD OF PULSE
    PRESCALER   VAR WORD        'STORES THE TIMER1 PRESCALER VALUE
    TMROFF      VAR WORD        'STORES THE TIME THAT THE SERVO1 PULSE WILL BE LOW
    RUN         VAR BIT         'IS THE PROGRAM RUNNING
    
    SERVO1      var PORTA.0     'OUTPUT PIN FOR SERVO1
    STARTSTOP   VAR PORTB.6     'INPUT PIN FOR PUSHBUTTON
    TRISB.4 = 1                 'INPUT FOR SELECTOR SWITCH PIN 13
    TRISA.0 = 0                 'MAKES PIN 19 AN OUTPUT FOR SERVO1
    TRISB.6 = 1                 'MAKES PIN 11 AN INPUT FOR PUSHBUTTON
    
    PRESCALER = 8               'DEFINES THE TIMER1 PRESCALER AS 18
    FREQ = 50                   'CONSTANT FREQUENCY FOR THE SERVOS
    RUN = 0                     'TEMPORARY VARIABLE FOR SERVO RUNNING
    
    T1CON  = %00110000          'SETS THE TIMER1 VALUES - PRESCALER = 8
    GIE         var INTCON.7
    PEIE        var INTCON.6
    TMR1IE      var PIE1.0
    TMR1ON      var T1CON.0
      
    ADCON1 = %10000010          'SET PORTA ANALOGUE AND RIGHT JUSTIFY THE RESULT
    
    GOSUB GETOSC 
    
    MAINLOOP
            GOSUB FINDPROGRAM
            GOSUB STARTPULSE
            'GOSUB STOPPULSE
    GOTO MAINLOOP
    
    FINDPROGRAM                'SELECTS BETWEEN SEVERAL TYPES OF MOTION
        ADCIN 10, TEMP          'READ CHANNEL 10 TO TEMP
        IF TEMP = 15000 THEN POSITION = 125                    'USES VOLTAGE DIVIDER TO
        IF TEMP  15000 AND TEMP = 22000 THEN POSITION = 150   'VARY THE VOLTAGE ON CH10.
        IF TEMP  22000 AND TEMP = 35000 THEN POSITION = 175   'THIS CONVERTS AND STORES
        IF TEMP  35000 AND TEMP = 47000 THEN POSITION = 200   'TO 'TEMP'.
        IF TEMP  47000 AND TEMP = 60000 THEN POSITION = 225   
        IF TEMP  60000 THEN POSITION = 250
        GOSUB SETPULSE   
    RETURN
    
    DISABLE INTERRUPT
    INTCODE
        IF SERVO1 = 0 THEN
            TMR1H = ((65535 - POSITION)256)            'EXTRACT HIGH BYTE INTO TIMER1
            TMR1L = ((65535 - POSITION)-(TMR1H256))    'EXTRACT LOW BYTE
            HSEROUT [HIGH , DEC TMR1H, LOW , DEC TMR1L,10,10,13]
            HIGH SERVO1
        ENDIF
        
        IF SERVO1 = 1 THEN
            TMR1H = ((65535 - TMROFF)256)              'EXTRACT HIGH BYTE INTO TIMER1
            TMR1L = ((65535 - TMROFF)-(TMR1H256))      'EXTRACT LOW BYTE
            HSEROUT [HIGH , DEC TMR1H, LOW , DEC TMR1L,10,10,13]
            LOW SERVO1
        ENDIF
    RESUME
    ENABLE INTERRUPT
    
    SETPULSE
        POSITION = POSITION MIN 250  'MIN POSITION LIMITED TO 0 DEGREES
        POSITION = POSITION MAX 125  'MAX POSITION LIMITED TO 180 DEGREES
        HSEROUT [POSITION = ,DEC POSITION,10,13]
        TMROFF = (((((10000  FREQ)  10)  PRESCALER)10) - POSITION)
        'HSEROUT [TMROFF = ,DEC TMROFF,10,10]
        'PERIOD = TMROFF + POSITION
        'HSEROUT [PERIOD = ,DEC PERIOD,10,10]
        
    RETURN
    
    STARTPULSE
        HSEROUT [PULSE STARTED,10,10]
        LOW SERVO1
        GIE = 1             'GLOBAL INTERRUPT ENABLE
        PEIE = 1            'PERIPHRIAL INTERRUPT ENABLE
        TMR1H = 255         'SETS TIMER1 TO 65535 
        TMR1L = 255         'NEXT TICK WILL INTERRUPT
        TMR1ON = 1
    RETURN
    
    STOPPULSE
        HSEROUT [PULSE STOPPED,10,10]
        LOW SERVO1
        PEIE =0
    RETURN
    
    GETOSC
    
    asm
        ifdef OSC
           MOVECB   OSC, _PICOSC
        else
           MOVECB   4, _PICOSC
        endif
    endasm
    RETURN
    
    END
    Thanks for any help, the learning curve seems steep at times.

  2. #2
    Join Date
    Oct 2009
    Location
    Utah, USA
    Posts
    427


    Did you find this post helpful? Yes | No

    Default

    Hey Bison,

    Yes, very steep learning curve... but the pay off is worth it.

    Not sure if this is your real problem or not... but on the program I have that works with a 12F683...

    Instead of using "DISABLE INTERRUPT" AND "ENABLE INTERRUPT"...

    I just use "DISABLE" and "ENABLE".

    Again, this is for the 12F683, but I also needed this...

    Code:
    INTCON     = %11001000     'now enable GIE,PEIE,x,x,GPIE,x,x,x
    I then use this bit of code when interrupted to see if the int. was caused by the timer1 overflow or because one of the inputs (button) went low...

    Code:
    disable
    
    MyInt:
      
      inttype = PIR1 & %00000001  'check if timer1 overflow occured
      if inttype = 1 then goto TimerInt
      
      goto buttonint  'interrupt was gpio.3
    I do not have the time to examine your code in detail right now but there are a couple of things to check.

    good luck
    Dwight

  3. #3
    Join Date
    Mar 2010
    Posts
    12


    Did you find this post helpful? Yes | No

    Unhappy Thanks, but no go.

    Thanks Dwight, I tried that, but it didn't help. The interrupt isn't happening at all.

  4. #4
    Join Date
    Oct 2009
    Location
    Utah, USA
    Posts
    427


    Did you find this post helpful? Yes | No

    Smile

    Just thinking out loud now...

    some possibilities:
    What is the source for the timer clock?
    What is the prescaler value?
    Did you properly enable the timer interrupt?
    (with the 12f683 it is the PIE1 reg)
    INTCON reg setup correctly?

    I can't remember exactly why right now... but at the end of my timer interrupt service routine I had these two lines, which clears bit 0 of these two registers. I think it clears the interupt flags so that when the "ENABLE" statement is hit(at then end of the interrupt handler code), it does not immediatly, falsely, re-interrupt.

    Code:
    intcon.0 = 0
       PIR1.0 = 0
    These are just my musings and I too am a newbie at this stuff
    If all else fails then write a small snippet of code that just tests one portion of your code to try and narrow the problem down.

    Do not forget to make the chip .pdf manual your best friend... you must, must, must read it! (a section at a time) go to the section on timers and on interupts and see what it tells you.

    That, in my opinion, is really the BIG difference between the versatility of the PIC micros and of something like the basic stamp. The PIC has much to offer and therefore much to configure correctly.

    Good luck
    Dwight

  5. #5
    Join Date
    Mar 2010
    Posts
    12


    Did you find this post helpful? Yes | No

    Question Need more info.

    What is the source for the timer clock?
    Internal oscillator, I think I've selected this properly, but I'm not sure.

    What is the prescaler value?
    It should be 8 - I hope.

    Did you properly enable the timer interrupt?
    I tried to. I suspect this is where I need the help.

    INTCON reg setup correctly?
    Once again, I'm not sure. I tried to.

    Do not forget to make the chip .pdf manual your best friend... you must, must, must read it!
    I've read this, and other sections many times, but I really am starting from scratch here. I've nutted out quite a few things, but so much of the terminology is unfamiliar to me that it's not always clear.

  6. #6
    Join Date
    Oct 2009
    Location
    Utah, USA
    Posts
    427


    Did you find this post helpful? Yes | No

    Default

    Below is text copied from the 16f690 docs...

    Section 6.7 Timer1 Interrupt
    The Timer1 register pair (TMR1H:TMR1L) increments
    to FFFFh and rolls over to 0000h. When Timer1 rolls
    over, the Timer1 interrupt flag bit of the PIR1 register is
    set. To enable the interrupt on rollover, you must set
    these bits:
    • TMR1ON bit of the T1CON register
    • TMR1IE bit of the PIE1 register
    • PEIE bit of the INTCON register
    • GIE bit of the INTCON register
    The interrupt is cleared by clearing the TMR1IF bit in
    the Interrupt Service Routine.

    Note: The TMR1H:TTMR1L register pair and the
    TMR1IF bit should be cleared before
    enabling interrupts.

    I feel your pain!

    Dwight

  7. #7
    Join Date
    Nov 2007
    Location
    West Covina, CA
    Posts
    219


    Did you find this post helpful? Yes | No

    Default Something for later

    Can't help with the interupts for now but will offer a suggestion for your A/D part. I'm not sure how you got the numbers to compare and set the servo output values. Your variable "temp" will only get a value somewhere between 0 and 1023 due to the 10bit A/D.
    Code:
    FINDPROGRAM                'SELECTS BETWEEN SEVERAL TYPES OF MOTION
        ADCIN 10, TEMP          'READ CHANNEL 10 TO TEMP
        IF TEMP = 15000 THEN POSITION = 125                    'USES VOLTAGE DIVIDER TO
        IF TEMP  15000 AND TEMP = 22000 THEN POSITION = 150   'VARY THE VOLTAGE ON CH10.
        IF TEMP  22000 AND TEMP = 35000 THEN POSITION = 175   'THIS CONVERTS AND STORES
        IF TEMP  35000 AND TEMP = 47000 THEN POSITION = 200   'TO 'TEMP'.
        IF TEMP  47000 AND TEMP = 60000 THEN POSITION = 225   
        IF TEMP  60000 THEN POSITION = 250
        GOSUB SETPULSE   
    RETURN
    I would suggest using the SELECT CASE to compare your 6 A/D value possibilities. List the "Values" in ascending order and this will set your "POSITION" value as needed.
    Code:
    FINDPROGRAM                'SELECTS BETWEEN SEVERAL TYPES OF MOTION
        ADCIN 10, TEMP   ' Note: Value returned will be anywhere from 0 to 1023
        SELECT CASE TEMP
            CASE Value1: POSITION = 125         'TEMP = Value1, lowest value 
            CASE is <= Value2: POSITION = 150   'TEMP <= Value2
            CASE IS <= Value3: POSITION = 175   'TEMP <= Value3
            CASE IS <= Value4: POSITION = 200   'TEMP <= Value4
            CASE IS <= Value5: POSITION = 225   'TEMP <= Value5
            CASE Value6: POSITION = 250         'TEMP = Value6, highest value
        END SELECT        
        GOSUB SETPULSE   
    RETURN
    Louie

  8. #8
    Join Date
    Mar 2010
    Posts
    12


    Did you find this post helpful? Yes | No

    Red face ADCON code

    Thanks for the input Link, I'll have to have a look at that code, it looks smaller than mine.

    The way I've done it works currently though. When I cut and pasted code it seems some characters didn't come across for some reason. the individual lines should look more like:

    Code:
    IF TEMP > 22000 AND TEMP <= 35000 THEN POSITION = 175
    I don't know why, but the ADC values do come out between those values; they go all the way up to 65535 with full voltage. I tried to calculate how they'd come out before I coded it, but ended up just adjusting them after seeing the output. If anyone knows why that'd be interesting.

    Still need help with the interrupts though.

    I've since added every single registry setting I could find in, and i got it off the ground, but it's giving me very strange results. I'll post more details once the kids are in bed.

  9. #9
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,648


    Did you find this post helpful? Yes | No

    Unhappy

    Hi, BB

    your code doesn't compile at all ...

    from MCS ...

    FATAL ERROR: Too many errors. (21)
    ERROR Line 53: Bad expression or missing THEN. (AdCServo.pbp)
    ERROR Line 53: Syntax error. (AdCServo.pbp)
    ERROR Line 54: Bad expression or missing THEN. (AdCServo.pbp)
    ERROR Line 54: Syntax error. (AdCServo.pbp)
    ERROR Line 55: Bad expression or missing THEN. (AdCServo.pbp)
    ERROR Line 55: Syntax error. (AdCServo.pbp)
    ERROR Line 56: Bad expression or missing THEN. (AdCServo.pbp)
    ERROR Line 56: Syntax error. (AdCServo.pbp)
    ERROR Line 57: Bad expression or missing THEN. (AdCServo.pbp)
    ERROR Line 64: Bad expression. (AdCServo.pbp)
    ERROR Line 65: Bad expression. (AdCServo.pbp)
    ERROR Line 66: Bad expression. (AdCServo.pbp)
    ERROR Line 71: Bad expression. (AdCServo.pbp)
    ERROR Line 72: Bad expression. (AdCServo.pbp)
    ERROR Line 73: Bad expression. (AdCServo.pbp)
    ERROR Line 82: Bad expression. (AdCServo.pbp)
    ERROR Line 83: Bad expression. (AdCServo.pbp)
    ERROR Line 91: Bad expression. (AdCServo.pbp)
    ERROR Line 101: Bad expression. (AdCServo.pbp)
    add to that most of the operators and tokens are missing, your TMR1 calculations are false ( Where's the prescaler you've set to 8, gone ??? ), TMROFF calculations also false, your HSEROUT command syntax is not correct ...
    and the servo pulse values do not match 0 and 180° positions !

    Ok, I stop here ...

    You'd better rewrite your PROJECT on a white sheet from very start ...

    Would be much better ( and quicker ) than trying to correct what you've done ...

    AND I did forget last, but not least ... do not use " ON INTERRUPT " as timing is critical here ... only ASM interrupts will fit here ... IF you insist on using interrupts - that are not at all compulsory in such a project -


    Alain
    Last edited by Acetronics2; - 25th March 2010 at 09:51.
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  10. #10
    Join Date
    Mar 2010
    Posts
    12


    Did you find this post helpful? Yes | No

    Default Half working now.

    As mentioned above, I've added every single register entry that I could find that was related to timer1.

    The interrupt now executes, but I'm getting weird results.

    Firstly here's the code for the registry entrys I've added:

    Code:
    T1CON  = %00110001          'ENABLE X,X,PRESCALER = 8,X,X,X,TMR1ON 
    INTCON     = %11001000      'ENABLE GIE,PEIE,x,x,GPIE,x,x,x
    GIE         var INTCON.7
    PEIE        var INTCON.6
    TMR1IE      var PIE1.0
    TMR1ON      var T1CON.0
    TMR1IE = 1                  '
    PEIE = 1                    'WHO KNOWS
    GIE = 1                     'WHAT ALL OF 
    PIR1.0 = 0                  'THESE DO, BUT IT 
    TMR1H = 0                   'DIDN'T START 
    TMR1L = 0                   'WITHOUT THEM.
    I'm thinking I've added too many, but I don't really know how they work - even after reading the datasheet several times. If anyone has any comments to make about these I'd be most grateful, I really am trying to learn.

    Here's the interrupt routine again:

    Code:
    DISABLE' INTERRUPT
    INTCODE:
        IF SERVO1 = 0 THEN
            HSEROUT ["FIRST IF - POSITION: ",DEC POSITION,10]
            TMR1H = ((65535 - POSITION)/256)            'EXTRACT HIGH BYTE INTO TIMER1
            TMR1L = ((65535 - POSITION)-(TMR1H*256))    'EXTRACT LOW BYTE
            HSEROUT ["HIGH: ", DEC TMR1H," LOW: ", DEC TMR1L,10]
            SERVO1 = 1
            HSEROUT ["SERVO1: ",DEC SERVO1,10,10]
        ENDIF
        
        IF SERVO1 = 1 THEN
            HSEROUT ["SECOND IF - TMROFF: ",DEC TMROFF,10]
            TMR1H = ((65535 - TMROFF)/256)              'EXTRACT HIGH BYTE INTO TIMER1
            TMR1L = ((65535 - TMROFF)-(TMR1H*256))      'EXTRACT LOW BYTE
            HSEROUT ["HIGH: ", DEC TMR1H," LOW: ", DEC TMR1L,10,10,13]
            SERVO1 = 0
            HSEROUT ["SERVO1: ",DEC SERVO1,10,10]
        ENDIF
        INTCON.0 = 0
        PIR1.0 = 0
    RESUME
    ENABLE' INTERRUPT
    and here's the results on the serial port:

    FIRST IF - POSITION: 225
    HIGH: 12 LOW: 64
    SERVO1: 0

    This is where it gets weird. I'm trying to extract the high and low bits for timer1, ie. I want the timer to countdown for the amount of time stored in 'position'. So the timer has to equal 65535 - Position. I need to break this down into the high and low bits for tmr1H and tmr1L. So tmr1H = 65535 - position / 256 etc. (much thanks to Aratti for helping me with that).

    The strange thing is the value that the PIC has calculated for high and low.

    high should equal (65535 - 225(value for position is shown in serout))/256 = 255.11 (I know we'll lose the .11)

    Low should equal ((65535 - 225)-(255*256) = 30
    of course this last value won't be correct until the first one comes out right, but even with the first incorrect value from formula one in place it's still all wrong.

    I can't figure it out. Why so far out?
    It looks too simple to go wrong. I'm missing something.

    Can hair be glued back in?

    I can't find a smilie for crying desperately...

  11. #11
    Join Date
    Mar 2010
    Posts
    12


    Did you find this post helpful? Yes | No

    Default Re submitting code.

    Hey Ace, thanks for looking it over.

    As mentioned briefly above, when I cut and pasted my code, it seems a lot of the symbols didn't come across. I'll repost here:

    Code:
    define OSC 4
    ON INTERRUPT GOTO INTCODE
    
    
    DEFINE HSER_TXSTA 20h       'SET THE TRANSMIT REGISTER TO TRANSMITTER ENABLED
    DEFINE HSER_BAUD 2400       'SET BAUD RATE
                                'DEFINE ADCIN PARAMETERS
    Define ADC_BITS	10          'SET NUMBER OF BITS IN RESULT
    Define ADC_CLOCK 3          'SET CLOCK SOURCE (3=RC)
    Define ADC_SAMPLEUS 50	    'SET SAMPLEING TIME IN uS
    define LOADER_USED 1
    
    SELECTOR    VAR BYTE        'SELECTS PROGRAM TYPE
    TEMP        VAR WORD        'TEMPORY VARIABLE FOR ANY USE
    POSITION    VAR WORD        'POSITION OF SERVO1 1250 - 2500
    OFFWIDTH    VAR WORD        'HOW LONG THE PULSE NEEDS TO BE OFF FOR
    FREQ        VAR WORD        'FREQUENCY TO RUN THE SERVOS AT
    PICOSC      VAR BYTE BANK0  'TO STORE OSCILLATOR FREQUENCY IN
    PERIOD      VAR WORD        'TEMPORY VARIABLE TO DISPLAY THE PERIOD OF PULSE
    PRESCALER   VAR WORD        'STORES THE TIMER1 PRESCALER VALUE
    TMROFF      VAR WORD        'STORES THE TIME THAT THE SERVO1 PULSE WILL BE LOW
    RUN         VAR BIT         'IS THE PROGRAM RUNNING?
    
    ADCON1 = %10000010          'SET PORTA ANALOGUE AND RIGHT JUSTIFY THE RESULT
    
    SERVO1      var PORTA.0     'OUTPUT PIN FOR SERVO1
    PUSHBUTT    VAR PORTA.2     'INPUT PIN FOR PUSHBUTTON
    TRISB.4 = 1                 'INPUT FOR SELECTOR SWITCH PIN 13
    TRISA.0 = 0                 'MAKES PIN 19 AN OUTPUT FOR SERVO1
    TRISA.2 = 1                 'MAKES PIN 17 AN INPUT FOR PUSHBUTTON
    
    PRESCALER = 8               'DEFINES THE TIMER1 PRESCALER AS 1:8
    FREQ = 50                   'CONSTANT FREQUENCY FOR THE SERVOS
    RUN = 0                     'TEMPORARY VARIABLE FOR SERVO RUNNING
    
    T1CON  = %00110001          'ENABLE X,X,PRESCALER = 8,X,X,X,TMR1ON 
    INTCON     = %11001000      'ENABLE GIE,PEIE,x,x,GPIE,x,x,x
    GIE         var INTCON.7
    PEIE        var INTCON.6
    TMR1IE      var PIE1.0
    TMR1ON      var T1CON.0
    TMR1IE = 1                  '
    PEIE = 1                    'WHO KNOWS
    GIE = 1                     'WHAT ALL OF 
    PIR1.0 = 0                  'THESE DO, BUT IT 
    TMR1H = 0                   'DIDN'T START 
    TMR1L = 0                   'WITHOUT THEM.
    
    GOSUB GETOSC 
    
    MAINLOOP:
            IF PUSHBUTT = 1 THEN 
                HSEROUT ["HIGH.",13,10]
            ELSE 
                HSEROUT ["LOW",13,10]
            ENDIF
            GOSUB FINDPROGRAM
            GOSUB STARTPULSE
            'GOSUB STOPPULSE
    GOTO MAINLOOP
    
    FINDPROGRAM:                'SELECTS BETWEEN SEVERAL TYPES OF MOTION
        ADCIN 10, TEMP          'READ CHANNEL 10 TO TEMP
        IF TEMP <= 15000 THEN POSITION = 125                    'USES VOLTAGE DIVIDER TO
        IF TEMP > 15000 AND TEMP <= 22000 THEN POSITION = 150   'VARY THE VOLTAGE ON CH10.
        IF TEMP > 22000 AND TEMP <= 35000 THEN POSITION = 175   'THIS CONVERTS AND STORES
        IF TEMP > 35000 AND TEMP <= 47000 THEN POSITION = 200   'TO 'TEMP'.
        IF TEMP > 47000 AND TEMP <= 60000 THEN POSITION = 225   
        IF TEMP > 60000 THEN POSITION = 250
        GOSUB SETPULSE   
    RETURN
    
    DISABLE' INTERRUPT
    INTCODE:
        IF SERVO1 = 0 THEN
            HSEROUT ["FIRST IF - POSITION: ",DEC POSITION,10]
            TMR1H = ((65535 - POSITION)/256)            'EXTRACT HIGH BYTE INTO TIMER1
            TMR1L = ((65535 - POSITION)-(TMR1H*256))    'EXTRACT LOW BYTE
            HSEROUT ["HIGH: ", DEC TMR1H," LOW: ", DEC TMR1L,10]
            SERVO1 = 1
            HSEROUT ["SERVO1: ",DEC SERVO1,10,10]
        ENDIF
        
        IF SERVO1 = 1 THEN
            HSEROUT ["SECOND IF - TMROFF: ",DEC TMROFF,10]
            TMR1H = ((65535 - TMROFF)/256)              'EXTRACT HIGH BYTE INTO TIMER1
            TMR1L = ((65535 - TMROFF)-(TMR1H*256))      'EXTRACT LOW BYTE
            HSEROUT ["HIGH: ", DEC TMR1H," LOW: ", DEC TMR1L,10,10,13]
            SERVO1 = 0
            HSEROUT ["SERVO1: ",DEC SERVO1,10,10]
        ENDIF
        INTCON.0 = 0
        PIR1.0 = 0
    RESUME
    ENABLE' INTERRUPT
    
    SETPULSE:
        POSITION = POSITION MIN 250  'MIN POSITION LIMITED TO 0 DEGREES
        POSITION = POSITION MAX 125  'MAX POSITION LIMITED TO 180 DEGREES
        HSEROUT ["POSITION = ",DEC POSITION,10,13]
        TMROFF = (((((10000 / FREQ) * 10) / PRESCALER)*10) - POSITION)
        'HSEROUT ["TMROFF = ",DEC TMROFF,10,10]
        'PERIOD = TMROFF + POSITION
        'HSEROUT ["PERIOD = ",DEC PERIOD,10,10]
        
    RETURN
    
    STARTPULSE:
        HSEROUT ["PULSE STARTED",10,10]
        LOW SERVO1
        'GIE = 1             'GLOBAL INTERRUPT ENABLE
        'PEIE = 1            'PERIPHRIAL INTERRUPT ENABLE
        TMR1H = 255         'SETS TIMER1 TO 65535 
        TMR1L = 255         'NEXT TICK WILL INTERRUPT
        TMR1ON = 1
    RETURN
    
    STOPPULSE:
        HSEROUT ["PULSE STOPPED",10,10]
        LOW SERVO1
        PEIE =0
    RETURN
    
    GETOSC:
    
    asm
        ifdef OSC
           MOVE?CB   OSC, _PICOSC
        else
           MOVE?CB   4, _PICOSC
        endif
    endasm
    RETURN
    
    END
    I hope it worked this time, dunno what went wrong the first time.

  12. #12
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,648


    Did you find this post helpful? Yes | No

    Exclamation

    Sorry to insist, but " ON INTERRUPT " can't make things work nicely ...

    latency can be much over the positionning pulse length ...

    so, no hope this way ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  13. #13
    Join Date
    Mar 2010
    Posts
    12


    Did you find this post helpful? Yes | No

    Default Ok.

    Fair enough Ace, I guess I'll have to nut out some ASM.

    IF you insist on using interrupts - that are not at all compulsory in such a project -
    Does this mean there's another way of doing this without interrupts?

    Bear in mind that I need to expand this to running two servos at once.

    your TMR1 calculations are false ( Where's the prescaler you've set to 8, gone ??? ),
    Are you saying that my timer1 calcs are wrong because I don't have a prescaler? All the calcs were done with the idea that if you multiplied them by 8 they would come out right.

    I thought T1CON = %00110001, would make the prescaler 8, have I done that wrong too?

    Sorry for all the mistakes, I'm just trying to figure it out.

  14. #14
    Join Date
    Mar 2006
    Location
    China
    Posts
    266


    Did you find this post helpful? Yes | No

    Default We all know the answer .... again...

    If you have not looked at AND REJECTED the instant interupts that is made by DT (DT´s instant interupts) you should really look into that now.
    It is a way to solve all problems without even knowing how to spell to ASM.

    /me

  15. #15
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,648


    Did you find this post helpful? Yes | No

    Thumbs down

    Hi, Jumper

    DT Basic Interrupts are wayyy too slow, here ... and overall their execution time is not predictable for timing corrections ...

    so, no joy nor !

    You do have to deal with ASM ... or write the program in pure PBP, without any interrupts ...

    Alain

    PS: and do not forget DT Bas ints consume a lot of RAM ...

    @ BB

    Does this mean there's another way of doing this without interrupts?

    Bear in mind that I need to expand this to running two servos at once.
    I alredy built a 4 channels fail-safe in pure PBP ... 4 Channels to read and 4 channels to output ... so, your project looks quite doable.
    Writing a neat timechart ... of course.
    Last edited by Acetronics2; - 25th March 2010 at 10:33.
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  16. #16
    Join Date
    Mar 2010
    Posts
    12


    Did you find this post helpful? Yes | No

    Unhappy One last question.

    alright Ace, I give in, you've got me in dispair with this project, I'll look for a totally different way.

    I alredy built a 4 channels fail-safe in pure PBP ... 4 Channels to read and 4 channels to output ... so, your project looks quite doable.
    Writing a neat timechart ... of course.
    Is this something you've released that I can learn from or even adapt?

    If I can't see the code, can you give me some hints about the way forward?

    I don't mind all the time charts in the world, but what's it for?

    I'll stop bothering you now, time for bed.

    Either way, thanks for the help, it's good to know when the idea you've got is impossible, that way you can move on; even if it is disheartening. Sniff...

    I'll check out DT's interrupts anyway - always learning.

  17. #17
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,648


    Did you find this post helpful? Yes | No

    Wink

    Ok BB

    First of all ...

    explain with clear words what your device has to do :

    from which inputs (w/ details ) to which outputs ( w/details ) ...

    50% of the work is here ...

    Alain

    PS: and stop thinking " C " ... you must think " Basic " now ! ( ROFL)
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

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


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Acetronics View Post
    DT Basic Interrupts are wayyy too slow, here ... and overall their execution time is not predictable for timing corrections ...
    Too Slow???
    For a Servo??? Get real.
    I've run 16 servo's simultaneously with DT_INTS.

    Timing not predictable??? What???
    It's extremely predictable. What are you talking about?

    PS: and do not forget DT Bas ints consume a lot of RAM ...
    oooo, ~50 bytes to have super easy interrupts, yeah too much RAM.

    Quote Originally Posted by bison_bloke
    alright Ace, I give in, you've got me in dispair with this project, I'll look for a totally different way.
    Don't listen to Alain.
    He's just being obstinate.
    DT

  19. #19
    Join Date
    Mar 2010
    Posts
    12


    Did you find this post helpful? Yes | No

    Default Ok, let's see if we can make something of this mess...

    I've run 16 servo's simultaneously with DT_INTS.
    Does this mean there's code out there that I can directly adapt?

    Where would I find this?

    explain with clear words what your device has to do :

    from which inputs (w/ details ) to which outputs ( w/details ) ...
    I have two inputs: start/stop button and a 'selector switch' which I already have working with that if statement you see above.

    I have three outputs: two servos that I need to 'bounce' independently of each other. I need them to simulate the somewhat random movements that a passenger in a car would experience whilst driving. The third input is for vibration, this is just an unbalanced DC motor - np.

    I also want to run a countdown timer so that it gets turned of after 20mins.

    50% of the work is here ...
    So now that my project is exactly half done, which way do I head?

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


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by bison_bloke View Post
    Does this mean there's code out there that I can directly adapt?

    Where would I find this?
    Well, that program is extensive ... each channel has it's own Center Trim, Gain and 10-bit positions, with stored programmed movements.
    Never released it. Because I'd have to support it.

    But since you don't seem to mind ON INTERRUPT ... there's a sample at meLabs for the LAB-X1 board.
    It drives 2 servos using interrupts.
    Has buttons, an LCD ... sounds just like what you wanted.

    servosx.bas
    http://melabs.com/resources/samples.htm
    <br>
    DT

  21. #21
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,648


    Did you find this post helpful? Yes | No

    Question

    Quote Originally Posted by bison_bloke View Post
    I have two inputs: start/stop button and a 'selector switch' which I already have working with that if statement you see above.

    I have three outputs: two servos that I need to 'bounce' independently of each other. I need them to simulate the somewhat random movements that a passenger in a car would experience whilst driving. The third input is for vibration, this is just an unbalanced DC motor - np.

    I also want to run a countdown timer so that it gets turned of after 20mins.



    So now that my project is exactly half done, which way do I head?
    Hi, BB

    Just missing : is both servos position given by a unique " selector pot " ( 6 positions , if I have correctly understood ) , so both servos receive same driving pulse ???

    Alain

    For the Heading ...

    I'd propose you a " system clock " @ 50 Hz ... with a timer interrupt ( very, very simple kind of interrupt ). And as 20 mins = 60000 " ticks " @ 50 Hz ... it's done

    If you think to it, tasks are done in a linear way and the whole sequence is repeated @ 50 Hz ...

    so, just let me an hour to open the '690 Datasheet ( never worked with this chip to the day ) ...
    Last edited by Acetronics2; - 26th March 2010 at 08:28.
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  22. #22
    Join Date
    Mar 2010
    Posts
    12


    Did you find this post helpful? Yes | No

    Default

    Both servos will run on different signals. There will be no pots involved.

    The user selects a 'program' from the selector switch, hit's start, and a predefined program controls everything from there. The servos will almost always be in different positions to each other.

  23. #23
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,648


    Did you find this post helpful? Yes | No

    Default

    Hi,

    Have a look to your PMs ... and enjoy

    @ Darrel : Do not look at it ... you won't like at all ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  24. #24
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,648


    Did you find this post helpful? Yes | No

    Talking

    Hi,

    Here it is for Everyone ...

    a running version with a 16F877a and EasyPic 5 .

    still something to debug with HSEROUT, probably a timing issue ...

    Code:
    '****************************************************************
    '*  Name    : AdcServo2 : the ultimate vibrator ...             *
    '*  Author  : [select VIEW...EDITOR OPTIONS]                    *
    '*  Notice  : Copyright (c) 2008 [select VIEW...EDITOR OPTIONS] *
    '*          : All Rights Reserved                               *
    '*  Date    : 01/10/2008                                        *
    '*  Process.: 16F877a / EasyPic5                                *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          :                                                   *
    '****************************************************************' 
    
    '******************************************************************************
    ' Config
     @ device HS_OSC , WDT_ON , PWRT_ON , BOD_ON , LVP_OFF , protect_OFF
    
    '******************************************************************************
    'Defines
    
    DEFINE OSC 8
    
    DEFINE INTHAND _MAINLOOP
    
    DEFINE HSER_TXSTA 20h       'SET THE TRANSMIT REGISTER TO TRANSMITTER ENABLED
    DEFINE HSER_BAUD 9600       'SET BAUD RATE
                                'DEFINE ADCIN PARAMETERS
    DEFINE ADC_BITS	10          'SET NUMBER OF BITS IN RESULT
    DEFINE ADC_CLOCK 3          'SET CLOCK SOURCE (3=RC)
    DEFINE ADC_SAMPLEUS 50	    'SET SAMPLEING TIME IN uS
    
    DEFINE LCD_DREG PORTB               ' I/O port where LCD is connected
    DEFINE LCD_DBIT 0					' 0, 1, 2, 3
    DEFINE LCD_RSREG PORTB
    DEFINE LCD_RSBIT 4                  ' Register select pin
    DEFINE LCD_EREG PORTB
    DEFINE LCD_EBIT 5                   ' Enable pin
    DEFINE LCD_BITS 4                   ' 4-bit data bus
    DEFINE LCD_LINES 2                  ' LCD has 2 character lines
        
    '******************************************************************************
    ' Comparator Config  
    
    CMCON       = %00000111
    
    '******************************************************************************
    ' Adc Config
    
     ADCON0     = %11000001     'SET PORTA ANALOGUE AND RIGHT JUSTIFY THE RESULT
     ADCON1     = %10001110     
      
    '******************************************************************************
    ' TMR1 Config : Preset = 45543  - Prescaler 1 
    ' 
    T1CON       = %00000000          'SETS THE TIMER1 VALUES - PRESCALER = 1
    
    '******************************************************************************
    ' Interupts config
    
     INTCON     = %11000000         ' GIE + PIE
     PIE1       = %00000001         ' TMR1IE
     PIR1       = 0
     PIE2       = 0
     PIR2       = 0
     
    '******************************************************************************
    'Variables
    
    wsave       var byte $20   system   ' just to avoid a compilator error ...
    wsave1      var byte $a0   system
    wsave2      var byte $120  system
    wsave3      var byte $1a0  system
    
    ssave       var byte Bank0 system
    psave       var byte Bank0 system
    
    
    
    POSITION    VAR WORD        'POSITION OF SERVO1 1250 - 2500
    TEMP        var word
    PLOW        var word        'low part of the servo signal
    COUNTER     var word        'Timeout counter
    PRESET      var word
    
    Delay       var BYTE
    RUN         VAR BIT         'IS THE PROGRAM RUNNING
    
     
    '******************************************************************************
    'Aliases
    
    GIE         var INTCON.7
    PEIE        var INTCON.6 
    TMR1IE      var PIE1.0
    TMR1IF      var PIR1.0
    TMR1ON      var T1CON.0
    
    '******************************************************************************
    ' Variable presets
    
    
    RUN         = 0                     'TEMPORARY VARIABLE FOR SERVO RUNNING
    POSition    = 150                   ' Servo @ RestPositon.   
    counter     = 0                     ' timeout counter
    PRESET      = 25555
    TMR1H       = Preset.Highbyte       ' Must be initialized ...
    TMR1L       = Preset.Lowbyte
    
    '******************************************************************************
    ' Constants
    
    SELECTOR    CON 0                   'Assign selector ADC Input to AN0
    
    '******************************************************************************
    ' I/Os
    
    SERVO1      var PORTC.0             'OUTPUT PIN FOR SERVO1
    STARTSTOP   VAR PORTA.4             'INPUT PIN FOR PUSHBUTTON
    
    PORTA = %00010111
    PORTB = 0
    PORTC = 0
    PORTD = 0
    PORTE = 0
    
    TRISA = %00000011
    TRISB = 0
    TRISC = 0
    TRISD = 0
    TRISE = 0
    
    Pause 500
    LCDOUT $FE, 1        ' Clear display, cursor off
                   
    '******************************************************************************
    '******************************************************************************
    
    MAINLOOP: ' Here we start a cycle ...
    
    TMR1on      = 0                     ' Reload the timer ...
    TMR1H       = PRESET.Highbyte
    TMR1L       = PRESET.Lowbyte
    TMR1IF      = 0
    TMR1ON      = 1                     ' Restart the timer
    GIE         = 1                     ' Interrupts authorized
    
    IF run THEN                         ' Run Button has to be pushed for first move
    
    FINDPROGRAM:                        'SELECTS BETWEEN SEVERAL TYPES OF MOTION
    
        ADCIN Selector , TEMP          'READ CHANNEL 10 TO TEMP
        
        SELECT CASE TEMP
        
        	Case is <  250  
        	 	POSITION = 125
    
            Case is <= 366 
         		POSITION = 150
         		    
        	Case is <= 583
        	 	POSITION = 175
        	 	  
        	Case is <= 783
        		POSITION = 200
        		    
        	Case is <= 1000  
         		POSITION = 225
         		   
        	Case is >  1000  
         		POSITION = 250
         		
         End Select
        
        low servo1
        Pulsout Servo1, position
        
        PLOW = 20000-POSITION
        
            
        IF COUNTER.5 OR ! COUNTER THEN
            'HSEROUT ["HIGH =" , DEC POSITION, " LOW =", DEC PLOW, 10,10,13]
            LCDOUT $FE,2 ,"Position = ",dec position,"    ", $FE,$C0,"TEMP = ", dec TEMP,"     "                                       
        Endif
    else
    
         
        IF COUNTER.5 OR ! COUNTER THEN
            'HSEROUT ["Waiting for RUN", 10,10,13,"HIGH =" , DEC POSITION, " LOW =", DEC PLOW, 10,10,13]
            LCDOUT $FE,2 ,"Waiting for RUN", $FE,$C0,"Position = ", dec position
        ENDIF
    endif
    
    '******************************************************************************   
    TESTINPUTS:
    
    Delay = 0
    Button Startstop,1,255,0,Delay,0,jump    ' Button active LOW !!!
    
    IF RUN THEN COUNTER = counter + 1
    IF counter => 60000 then counter = 0 :goto jump
    
    stop                                     ' Stop here and wait for interrupt
                                                ' to launch a new cycle
    JUMP:
    WHILE STARTSTOP = 0 : wend  
    RUN = ~run
    stop                                     ' Stop here and wait for interrupt
                                                ' to launch a new cycle
    END
    enjoy ...

    Alain
    Last edited by Acetronics2; - 26th March 2010 at 15:55.
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

Members who have read this thread : 0

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