Shop OBEX P1 Docs P2 Docs Learn Events
TIMER (SX/B) for Counting — Parallax Forums

TIMER (SX/B) for Counting

PJAllenPJAllen BannedPosts: 5,065
edited 2007-09-26 18:13 in General Discussion
· OK, the TIMER command was mentioned in another Subject.· So, I read what's available in SX/B Help and... I need more.
· Can these TIMER Configurations set up an SX48 with an edge-triggered input/s?· I want to make a counter, but COUNT and PULSIN have time constraints.· I want to set it running and whenever an event occurs an associated variable should INC.· The events could be a long time in coming, then several in succession, or maybe it'll be·really busy.

Comments

  • BeanBean Posts: 8,129
    edited 2007-08-13 11:29
    Funny thing about the SX48 timers... You cannot read the count register. You must capture the current count into one of the capture registers, then you can read the capture register. This can be done by connecting two pins together. I wrote some code to do this, but I would have to dig it up. The main problem is that if a new pulse comes in while the timer is in capture/compare mode, it will be lost.

    It would be easier to make an edge-triggered interrupt from one of the RB pins and just INC a word variable in the interrupt routine. Don't forget to clear the pending register before ending the interrupt. Plus this method will work on the SX28 too.

    DEVICE SX28, OSC4MHZ, TURBO, STACKX, OPTIONX, PROTECT
    FREQ   4_000_000
     
    PulsePin   PIN RB.0 INPUT INTR_RISE ' Interrupt on rising edge
    
    cntr VAR WORD
    
    INTERRUPT NOPRESERVE
      WKPND_B = 0 ' Clear interrupt pending bit (Do this FIRST)
      INC cntr
    
    RETURNINT
    
    PROGRAM Start
    
    Start:
      DO
        cntr = 0
        PAUSE 1000 ' Count pulses for 1 second
      
        ' Show pulse count in debugger
        WATCH cntr
        BREAK
      LOOP
    END
    
     
    


    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Teacher: What is the difference between ignorance and apathy ?
    Student: I don't know and I don't care
    Teacher: Correct !
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com


    Post Edited (Bean (Hitt Consulting)) : 8/13/2007 1:37:00 PM GMT
  • BenoitBenoit Posts: 47
    edited 2007-08-13 15:43
    This discussion comes at a good time for me too [noparse]:)[/noparse]

    I'm a black and white photography amateur, and I collect and (try to) use old cameras. Many of them have sticky shutters that need to be cleaned because of years of sitting on shelves or stuffed in boxes. After cleaning them, I need to figure out exactly what their shutter speed is when I process the negatives.

    I was thinking of building a simple circuit with a phototransistor placed inside the camera and a light in front of the lens: a SX (48/52?) with a LCD attached would then display the duration the light was caugth by the phototransistor. Do you know if this component have the sufficient resolution/speed for this?

    When the transistor is lit, this could be detected by the SX, which would then count the duration while transistor is getting the light, then display the value on the LCD once it's dark again.

    I would assume that using an interrupt would be much more precise than polling a pin.

    What would be the best way of measuring that interval? The duration would be in the range of milliseconds, and to get any real precision, I would assume microseconds.

    I was thinking of using a sx52 protoboard I have. Would something like this work?

    (Pseudo code)
    Variables:
    ShutterValueReady VAR WORD
    ShutterValue var work
    PIN:
    ShutterPin  RB.0
    
    
    Interrupt routine (?)
    Once RB.0 is triggered, start the TIMER (probably timer1)
    Once RB.0 is released read TIMER value into ShutterValue, set ShutterValueReady =TRUE
      ( not sure if phototransistor goes from to high or low when trigger, doesn't really matter, I guess)
    
    Main program:
    Set ShutterValueReady = FALSE
    Initialize LCD
    Initialize TIMER
    
    Loop forever
    
       if ShutterValueReady then
            Display ShutterValue on LCD
            ShutterValueReady = FALSE   ( reset for another run )
       endif
    end loop
    
    
    



    I would assume that it's relatively easy to start the TIMER with the interrupt, but how would you stop it?
    Would you poll the pin, then once the phototransistor status returns to unlit, stop the timer?

    I've attached a very crude drawing of what I thought might work. Sorry for the child-like artistry, that's pretty much all I can do tongue.gif

    Thanks!
    Benoit

    Post Edited By Moderator (Bean (Hitt Consulting)) : 8/13/2007 5:20:14 PM GMT
  • BeanBean Posts: 8,129
    edited 2007-08-13 16:24
    Bonoit,
    Actual just using PULSIN would be the easiest way to do that. It has 10uSec (0.01mSec) resolution.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Teacher: What is the difference between ignorance and apathy ?
    Student: I don't know and I don't care
    Teacher: Correct !
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • BenoitBenoit Posts: 47
    edited 2007-08-13 16:31
    Great! So, I wouldn't even need to use my SX52 board, then. A SX28 should do the trick.

    Thanks!
    -Benoit
  • Alex41Alex41 Posts: 112
    edited 2007-08-13 16:43
    Bean,

    I have also looked at the TIMER command in the SX/B help file for the SX48. Actually printed out that whole .pdf
    and had it bound for a manual - much easier to reference.
    I'm a bit confused on how it exactly how it it works too, especially how it applies to what I'm trying to do
    See my "Interrupts for Dummies" post.
    I did order two SX48 boards today and hope to have them by the end of the week. Once I get to actually writing code
    and programing the chips·I hope this will make some more sense.

    Thanks,
    Alex
  • BeanBean Posts: 8,129
    edited 2007-08-13 16:56
    Alex,
    The best information about the timers in in Gunther book
    http://www.parallax.com/detail.asp?product_id=70002

    For your application you will be using the timer to generate pulses. So you will use the PWM mode.

    Let's say the SX clock is 4MHz and you want a 1KHz output you would use

    TIMER1 PWM, 2000, 4000

    This means the output pulses will be high for 2000 clocks, and will repeat every 4000 clocks (high for 2000, low for 2000).

    Of course you can use WORD variables instead of the constants to create whatever pulse rate you want.

    If the value go above 65535, then you need to use the prescaler.

    Let's say you wanted a 1 Hz pulse (still with the SX clock at 4MHz). You would use the timer prescaler of 64 and use "TIMER1 PWM 31250, 62500"

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Teacher: What is the difference between ignorance and apathy ?
    Student: I don't know and I don't care
    Teacher: Correct !
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • Alex41Alex41 Posts: 112
    edited 2007-08-13 17:11
    Bean,

    Thanks for that info to get me started. I agree with you - that appears much easier to use that the interrupts - at least
    for a beginner like me.
    My main confusion came from what the prescaler exactly did, but you explained that for me.
    I do have Gunther's book and will read up on the TIMER info in it.

    Thanks,
    Alex
  • JonnyMacJonnyMac Posts: 9,216
    edited 2007-08-13 17:52
    Here's another way to do external counting; it uses a periodic ISR that polls the input (and updates the counter on a 0 -> 1 change). PAUSE is affected by any interrupt, so using the edge triggered interrupt may yield affected results if the delay is long and the input frequency high. PAUSE is replaced by DELAY_MS that uses the ISR to control the delay timing.

    With a 10 uS interrupt period this should theoretically work up to 50 MHz -- I've tested with the PDB and the highest freq from the pulse generator is 1000 Hz.
  • BeanBean Posts: 8,129
    edited 2007-08-13 18:04
    Jon,
    I think you meant to say it will work up to 50 KHz.

    Something that might be useful for that program is that the WKPND_B register gets set even if interrupts are not enabled. So you can use WKPND_B as a latch to tell if a pin changed state while you weren't looking at it. This only works on port RB pins of course.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Teacher: What is the difference between ignorance and apathy ?
    Student: I don't know and I don't care
    Teacher: Correct !
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • JonnyMacJonnyMac Posts: 9,216
    edited 2007-08-13 18:46
    Whoops! -- you're right: 50 kHz (theoretically). You know, I did try the WKPND_B thing -- and it does work -- but it seems (to me, anyway) to take more programming effort.
  • BeanBean Posts: 8,129
    edited 2007-08-15 13:39
    I just realized that the SX48 datasheet does a very good job of explaining the timers too.
    See section 11 Multi-function Timers

    http://www.parallax.com/dl/docs/prod/datast/SX48BD-Data-v1.5.pdf

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Teacher: What is the difference between ignorance and apathy ?
    Student: I don't know and I don't care
    Teacher: Correct !
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • JonnyMacJonnyMac Posts: 9,216
    edited 2007-08-15 14:34
    Well, then, I feel like a dummy, because I haven't been able to make heads or tails of it. What I'm trying to do is use the external pin to drive the counter, get that count to move to the capture register when I decide, then read the capture register. The idea is that I can use the difference between two scans of the capture register to determine the count of external pin events.
  • BeanBean Posts: 8,129
    edited 2007-08-15 16:46
    Jon, you may be a lot of things, but a dummy is NOT one of them.

    The way to get the timer count is to switch the timer to capture mode, then toggle the capture pin. But there is a problem. As soon as you switch to capture mode, the timers starts counting SX clock pulses until the capture pin is toggled.

    It takes a bit of trickery to get the real count from the counter. The bit I found out myself·is that the timer prescaler does NOT effect the external count mode. When using external counter you always get the number of pulses on the pin regardless of the prescaler.

    So you can set the prescaler to 128, put the counter in EXTERNAL mode, clear the counter (which clears the prescaler too), count your pulses (the prescaler will not be advanced), switch to capture mode (now you have 128 SX clocks to toggle the capture pin before the timer gets advanced 1 count).

    Here is a demo program...

    DEVICE SX48, OSCXT1
    FREQ 4_000_000
     
    PulsePin     PIN RC.3 INPUT  ' Connnect to pulse circuit
     
    T2CapturePin PIN RC.0 OUTPUT ' Do not connect to anything
     
    Pulses       VAR WORD
     
    PROGRAM Start
     
    Start:
      TIMER2 R1, $FFFF      ' Allow counter to count to maximum value
      TIMER2 R2, $FFFF      ' Allow counter to count to maximum value
      TIMER2 PRESCALE, 7    ' PRESCALE does NOT affect external clocking
      T2CapturePin = 1      ' Set capture pin high to setup for low edge to capture count
     
      DO
        TIMER2 EXTERNAL     ' Set timer to count external pulses (not affected by prescaler)
        TIMER2 CLEAR        ' Clears counter and the prescaler
        PAUSE 1000          ' Count pulses for 1 second
     
        TIMER2 CAPTURE      ' Switch timer to capture mode so we can get the count
                            '  the timer is now counting SX clock pulses, but since
                            '  the prescaler is set to 128 we have 128 clocks to capture
                            '  the count before it gets incremented.
     
        T2CapturePin = 0   ' Set capture pin low to capture count
        PAUSEUS 1           ' Small delay for capture pin to stay low
        T2CapturePin = 1    ' Set capture pin high
     
        Pulses = T2CPL, T2CPH ' Get count from Timer2 capture registers
     
        WATCH Pulses        ' Show count in DEBUG window
        BREAK                  
     
      LOOP               
    END
    

    Bean.
    ·

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Teacher: What is the difference between ignorance and apathy ?
    Student: I don't know and I don't care
    Teacher: Correct !
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com


    Post Edited (Bean (Hitt Consulting)) : 8/15/2007 5:51:29 PM GMT
  • JonnyMacJonnyMac Posts: 9,216
    edited 2007-08-15 17:44
    Works like a champ. Thanks for the assist, Terry -- it's going into the book! (with proper credit, of course)

    Update: I've attached the "Practical SX/B" version of the program; perhaps PJ and others will find this useful. I expanded the TIMER1 EXTERNAL instruction to assembly so that I can set the edge level for the external event; perhaps this can be added as an option to SX/B.

    Post Edited (JonnyMac) : 8/15/2007 6:32:06 PM GMT
  • BeanBean Posts: 8,129
    edited 2007-08-15 17:51
    Jon, in my experience the maximum input frequency is 1/3 of the SX clock frequency. Seems like an odd ratio, but in my experiments anything over 1/3 starts to give screwy readings.

    [noparse][[/noparse]EDIT] Okay I was wrong, I believe it is 1/2 the SX clock frequency. In my application I'm reading 20MHz clocking the SX at 50MHz.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Teacher: What is the difference between ignorance and apathy ?
    Student: I don't know and I don't care
    Teacher: Correct !
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com


    Post Edited (Bean (Hitt Consulting)) : 8/16/2007 11:16:11 AM GMT
  • pjvpjv Posts: 1,903
    edited 2007-08-16 04:40
    Hi Bean;

    I'm going from memory here..... a project 2 years ago. As best as I can recall, you can count up to the full clock speed, but not beyond.

    Cheers,

    Peter (pjv)
  • BeanBean Posts: 8,129
    edited 2007-08-16 11:15
    Peter,
    I edited my post. From my notes it was a maximum of 1/2 the SX clock frequency. But it seemed I had to be slightly below 1/2 or it would start screwing up (probably a duty cycle problem).

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Teacher: What is the difference between ignorance and apathy ?
    Student: I don't know and I don't care
    Teacher: Correct !
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • pwillardpwillard Posts: 321
    edited 2007-09-26 18:13
    Nyquist Sampling Theorem. ( Learned while studying telecomunications transmission theory regarding T1 digital circuits designed to pass analog voice data. )

    The theorem states that

    “ Exact reconstruction of a continuous-time baseband signal from its samples is possible if the signal is bandlimited and the sampling frequency is greater than *twice* the signal bandwidth.

    In other words... you sample twice to gain precision and therefore the most you can count is 1/2 your clock rate since after that you lose precision (IE; the signal changed and you missed it).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

    There's nothing like a new idea and a warm soldering iron.

    Post Edited (pwillard) : 9/26/2007 6:40:23 PM GMT
Sign In or Register to comment.