How to blink 8 LEDs at different rates- concurrently?


Closed Thread
Results 1 to 15 of 15

Hybrid View

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


    Did you find this post helpful? Yes | No

    Default

    OUCH!

    After running my loop in the SIM.
    I realized the timing was Waaaayyyyy OFF.
    Fortunately, the other examples were "OFF" too ... just not as far.

    I've always said PAUSE is the worst statement in the BASIC language.
    It got me again.

    Here's a version that should compensate ...
    It uses the CCP module in "Compare" mode to create a precise 10mS interval.
    So when you give a delay value of 50, it actually takes 500mS, on the nose.

    Sorry, it's more than 8 lines now.
    Code:
    DEFINE OSC 4
    DEFINE BLINKYFREQ 100  ; 10mS periods
    
    DATA 50,22,38,75,17,40,62,13  ; default periods for each Output
    ;----------------------------------------------------------------
    CCPR1val  CON EXT      : @CCPR1val = (OSC*1000000/4)/ BLINKYFREQ
    CCPR1     VAR WORD EXT : @CCPR1 = CCPR1L
    Timer1    VAR WORD EXT : @Timer1 = TMR1L
    CCPIF     VAR PIR1.2
    
    LoopLED   VAR BYTE[8]
    LoopCON   VAR BYTE[8]
    x         VAR BYTE
    
    ;----[Initialize]------------------------------------------------
    FOR x = 0 to 7         ; load the periods from EEPROM
        READ x, LoopCON(x)
    NEXT X
    ;-- setup CCP1 and Start Timer1 --
    CCPR1   = CCPR1val     ; set compare value
    CCP1CON = %00001011    ; compare mode, special event 
    Timer1  = 0            ; clear Timer1
    T1CON.0 = 1            ; start Timer1
    
    TRISB = 0              ; PORTB all OUTPUT
    
    ;----[Main Program Loop]----------------------------------------
    Main: 
        x = (x + 1) // 8
        PORTB.0(x) = !(LoopLED(x) < LoopCON(x))
        LoopLED(x) = (LoopLED(x) + 1) // (LoopCON(x) << 1)
        IF x != 7 THEN Main
      Waiting: IF !CCPIF THEN Waiting
        CCPIF = 0
    GOTO Main
    Cheers,
    Last edited by Darrel Taylor; - 26th April 2010 at 03:59. Reason: Minor modifications
    DT

  2. #2
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default

    Darrel, that algorithm is slick!

    Does PBP allow assignments in expressions like C? For example;

    Code:
    while(1)
    { x = (x+1)&7;
      portb ^= ((!(LoopLED[x]=(LoopLED[x]+1)%LoopCON[x])) << x);
      delay_us(2500);
    }

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


    Did you find this post helpful? Yes | No

    Default

    Thanks Mike.
    Quote Originally Posted by Mike, K8LH View Post
    Does PBP allow assignments in expressions like C? ...
    Nope, not even a +=

    However, your x = (x+1)&7 takes much less time than my x = (x + 1) // 8 (Modulus) approach.
    What was I thinking?

    Cool, thanks!
    DT

  4. #4
    Join Date
    Feb 2003
    Posts
    432


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Darrel Taylor View Post
    Thanks Mike.

    Nope, not even a +=

    However, your x = (x+1)&7 takes much less time than my x = (x + 1) // 8 (Modulus) approach.
    What was I thinking?

    Cool, thanks!
    DOH!!! The problem with working with so many different languages is that you can misread code. I took " //8 " to be a comment (Javascript style) that you were going to do it 8 times LOL
    Keith

    www.diyha.co.uk
    www.kat5.tv

  5. #5
    Join Date
    Jan 2006
    Location
    Istanbul
    Posts
    1,185


    Did you find this post helpful? Yes | No

    Default

    If "8 lines" is about the loop part, then here is my code.


    Think like a politician. Is is not less then 8?



    Code:
    <font color="#000080"><b>EEPROM </b></font><font color="#FF0000">0</font>,[<font color="#FF0000">50</font>,<font color="#FF0000">22</font>,<font color="#FF0000">38</font>,<font color="#FF0000">75</font>,<font color="#FF0000">17</font>,<font color="#FF0000">40</font>,<font color="#FF0000">62</font>,<font color="#FF0000">13</font>]
              <font color="#000080"><i>'RB0 - RB7 time intervals
        
    </i></font>Time    <font color="#000080"><b>VAR BYTE</b></font>[<font color="#FF0000">8</font>]
    Timer   <font color="#000080"><b>VAR BYTE</b></font>[<font color="#FF0000">8</font>]
    Temp    <font color="#000080"><b>VAR BYTE
    </b></font>Preload <font color="#000080"><b>VAR WORD
    </b></font>T1CON = <font color="#FF0000">%00000000   </font><font color="#000080"><i>' 1:1 @4Mhz
    </i></font>TMR1IF <font color="#000080"><b>VAR </b></font>PIR1.<font color="#FF0000">0   </font><font color="#000080"><i>' An alias for overflow bit.
    </i></font>TMR1ON <font color="#000080"><b>VAR </b></font>T1CON.<font color="#FF0000">0
    
    
    </font>Begin:
        Preload = <font color="#FF0000">55543 </font><font color="#000080"><i>'Timer1 preload value for excat 10ms. interval.
        </i><b>FOR </b></font>Temp = <font color="#FF0000">0 </font><font color="#000080"><b>TO </b></font><font color="#FF0000">7
            </font><font color="#000080"><b>READ </b></font>Temp ,Time[Temp]  <font color="#000080"><i>'Fill time-intervals.
            </i></font>Timer[Temp] = <font color="#FF0000">0        </font><font color="#000080"><i>'Clear timer array.
        </i><b>NEXT </b></font>Temp
    
    T:
        TMR1IF = <font color="#FF0000">0
        </font>TMR1L = Preload.LowByte
        TMR1H = Preload.HighByte
        TMR1ON = <font color="#FF0000">1
        
    </font>Start:
    
        <font color="#000080"><b>IF </b></font>TMR1IF <font color="#000080"><b>THEN </b></font>INT_TMR       ' 1 line. 
    
        <font color="#000080"><b>GOTO </b></font>Start
        
    
    INT_TMR:
        TMR1ON = <font color="#FF0000">0
        </font><font color="#000080"><b>FOR </b></font>Temp = <font color="#FF0000">0 </font><font color="#000080"><b>TO </b></font><font color="#FF0000">7
            </font><font color="#000080"><b>IF </b></font>Timer[Temp] = Time[Temp] <font color="#000080"><b>THEN 
                </b></font>PORTB.<font color="#FF0000">0</font>[Temp] = PORTB.<font color="#FF0000">0</font>[Temp] ^<font color="#FF0000">1
                </font>Timer[Temp] = <font color="#FF0000">0
            </font><font color="#000080"><b>ENDIF
            </b></font>Timer[Temp] = Timer[Temp] + <font color="#FF0000">1
        </font><font color="#000080"><b>NEXT </b></font>Temp   
        
        <font color="#000080"><b>GOTO </b></font>T    
    
    <font color="#000080"><b>END
    
    
    
    </b></font>
    "If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte

  6. #6
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default

    I am working on the skeleton of a generic task handler that will manage say 16 tasks concurrently. The LEDs are just simulating tasks that occur at set intervals. One of the tasks will be a seconds counter (with an interval of 1000mS) that is the basis of a RTC (good to the accuracy/stability of the HS crystal clock) and accurate timing is therefore an important concern. So using any kind of Pause or Delay function would not work.

    Using a hardware timer is really the only way to do it. However, the timer also has to account for whatever time is used up by instruction cycles - which can vary depending on conditional branches and time spent in each task. DT's method of using a CCP in compare mode solves this problem nicely. Thanks.

  7. #7
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

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