​ ​ ​ ​ Minor problem with interrupt timing
Results 1 to 4 of 4

Thread: Minor problem with interrupt timing

  1. #1
    Member
    Join Date
    Mar 2014
    Location
    United Kingdom
    Posts
    67

    Default Minor problem with interrupt timing

    I have a circuit which generates 600Ás negative pulses which I want to count with interrupts (incrementing dcl_in), because I don't want to miss any pulses while other things might be happening.

    Being unfamiliar with PicAxe interrupts I followed the example in the manual and generated this:
    Code:
    interrupt:
    SETFREQ m16
    LET int_timer = int_timer + 1
    IF pinC.3 = 0 THEN interrupt
    SETFREQ m4
    LET dcl_in = dcl_in + 1
    SERTXD ("Interrupt length ",#int_timer," cycles",LF,CR)
    int_timer = 0
    ; more stuff
    SETINT %00000000 , %00001000
    RETURN
    This consistently returns
    Interrupt length 1 cycles
    which it did before I added the "SETFREQ m16" and also did when I only had a 200Ás interrupt pulse, which I thought might not be long enough, but probably was.

    So the question is, what's wrong with
    Code:
    LET int_timer = int_timer + 1
    which I added to give me a rough idea of how many machine cycles the processor goes through while waiting for the interrupt condition to go away?

    The variable "int_timer" is a word variable by the way, in case it ends up as a big number. It's running on an 08M2+ for the record.

    Thanks.

  2. #2
    Technical Support
    Join Date
    Jan 1970
    Location
    UK
    Posts
    23,879

    Default

    Quote Originally Posted by Hairy Animal View Post
    I have a circuit which generates 600Ás negative pulses which I want to count with interrupts (incrementing dcl_in), because I don't want to miss any pulses while other things might be happening.
    Do you want to count pulses or measure their length as your code seems to do ?

    Your problem is ...

    Code:
    interrupt:
    SETFREQ m16
    LET int_timer = int_timer + 1
    IF pinC.3 = 0 THEN interrupt
    That's about 10 tokens worth of PICAXE code being executed. It takes roughly, I recall, 125us per token at 4MHz so, in total, 1250us at 4MHz, 625us at 8MHz, 312us at 16MHz.

    It will also take time getting into the interrupt routine so if you are lucky the count may sometimes reach two. You can take the SETFREQ M16 out of the counting loop to speed it up slightly, but I wouldn't expect any great improvement.

    I am somewhat surprised it even worked at all, that you are seeing any interrupts. I guess the looping code waiting for interrupts is quite short.

    Bottom line is you aren't going to measure the length of 600uS pulses with a PICAXE accurately by interrupting and you are likely going to miss a few. One would normally use HINTSETUP to not miss any.

    If you want to persevere with SETINT I would recommend putting the SETFREQ M16 before looping for interrupts and timing this way. I can't vouch for how much better it will be but you never know -

    Code:
    Symbol IRQ_PIN = pinC.3
    Symbol IRQ_MSK = %00001000
    
    Gosub Interrupt_Enable
    Do
    Loop
    
    Interrupt:
      If IRQ_PIN = 1 Then x0
      If IRQ_PIN = 1 Then x1
      If IRQ_PIN = 1 Then x2
      If IRQ_PIN = 1 Then x3
      If IRQ_PIN = 1 Then x4
      
      ; More of the same here
    
      Do : Loop Until IRQ_PIN = 1
    
      x4: w0 = w0 + 1
      x3: w0 = w0 + 1
      x2: w0 = w0 + 1
      x1: w0 = w0 + 1
      x0:
    
      SetFreq M4
      SerTxd( "Pulse length = ", #w0, CR, LF )
    
    Interrupt_Enable:
      SetFreq M16
      w0 = 0
      SetInt %00000000, IRQ_MSK
      Return
    The best solution, if you are generating the pulses, is not to produce pulses but toggle the output, have the counter count changes from high to low and from low to high.

    The chance of spotting and counting meteorites is small on a normal night, blink and you'll miss one. Now if the sky toggled light and dark every time one arrived you would probably be able to count them all :-)

  3. #3
    Member
    Join Date
    Mar 2014
    Location
    United Kingdom
    Posts
    67

    Default

    Many thanks for the quick reply Hippy.

    It's only the pulses themselves I want to count, but there might be anything from one a day to five a second (possibly more), so I decided to use an interrupt in case my inefficient code is busy doing other things when a pulse arrives, then I know it will always update the dcl_in count without fail. I appreciate that COUNT for instance could probably do the job perfectly well, but I was worried that I might miss pulses in between the measurement periods while I was updating other things.
    10n100k.jpg
    The attached picture (horizontal scale is millisecs) is from the useful little PCB scope; sufficiently accurate to show me what's happening, so I know the hardware's generating this 600Ás pulse reliably (on Ch1), but I wanted to make sure that it would be long enough to always ensure that the code got into the interrupt routine okay, hence the
    Code:
    LET int_timer = int_timer + 1
    to just see if it was actually looping back to the start of the interrupt before the interrupt went away. If it wasn't, then I might have lengthened the pulse a bit. From what you say about 125Ás per token, I shouldn't miss anything, even if I leave the clock speed at 4MHz.

    Thanks for the suggested interrupt code as well, as always there are so many ways of doing things and that gives me lots of useful hints on how to improve the code.

  4. #4
    Technical Support
    Join Date
    Jan 1970
    Location
    UK
    Posts
    23,879

    Default

    If you just want to count pulses and not miss any there are three main options -

    1) Use an internal counter driven by an external source. Easy with X2, you have to jump through some POKESFR hoops for the M2 but does work.

    2) use HINT pins which will spot and remember any pulse down to microseconds and less. As long as you clear the 'has been seen' flag before the next arrives you won't miss any, and you can poll or use use interrupts to handle counting. You can also use more POKESFR magic to have seen pulses remembered even if HINT pins are not supported, though you will have to poll those with PEEKSFR to get at them.

    3) Use output toggling rather than pulse generation. That's my favoured solution.

Bookmarks

Posting Permissions

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