Shop OBEX P1 Docs P2 Docs Learn Events
Make a Fake LED — Parallax Forums

Make a Fake LED

HumanoidoHumanoido Posts: 5,770
edited 2010-08-31 08:33 in Propeller 1
[FONT=&quot]There are 2 methods below for blinking two real LEDs at different rates. I want to change real LEDs to fake LEDs where nothing exists, but the identical timing is maintained. It appears, to accomplish this, the outa statement needs a substitute statement with exactly the same timing. If it's true that statements take 4 cycles, then any other Spin statement could serve as a replacement. Is this true, and which statement could be substituted? Thanks in advance. Humanoido

'

[/FONT][FONT=&quot]PRI task0 ' Private Method - Task 0
case state0 ' Flash LED1 every second
OFF:
if (ms // 500) == 0
outa |= %01 ' Pin 0 on Main Header
state0 := ON
ON:
if (ms // 500) == 0
outa ^= %01 ' Pin 0 on Main Header
state0 := OFF
'

PRI task1 ' Private Method - Task 1
case state1 ' Flash LED2 twice every second
OFF:
if (ms // 250) == 0
outa |= %10 ' Pin 1 on Main Header
state1 := ON
ON:
if (ms // 250) == 0
outa ^= %10 ' Pin 1 on Main Header
state1 := OFF
[/FONT][FONT=&quot]'
[/FONT]

Comments

  • Roger LeeRoger Lee Posts: 339
    edited 2010-08-31 05:18
    [FONT=&quot]outb |= %01
    .
    .
    .
    [/FONT]
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2010-08-31 05:38
    This would be a great application for the fake LED touch sensors!
  • kuronekokuroneko Posts: 3,623
    edited 2010-08-31 05:43
    Humanoido wrote: »
    If it's true that statements take 4 cycles, then any other Spin statement could serve as a replacement.
    (Most) assembler instructions take 4 cycles. Anyway, leave outa statements as they are just don't touch dira for the relevant bits.
  • RinksCustomsRinksCustoms Posts: 531
    edited 2010-08-31 08:33
    From your description, it sounds like you want to utilise a waitcnt command instead.

    waitcnt(value) = Wait until the system counter = value (page 219 in the manual)

    waitcnt(clkfreq + cnt)
    simply waits for exactly 1S, regardless of the system clock value

    waitcnt(clkfreq / 2 + cnt)
    takes current clock frequency, divides it by half then waits until system counter matches the calculated clock ticks of 1/2 clkfreq plus current system counter reg value (0.5 sconds). Also variables can be passed to the equation as well, ie;
    waitcnt(clkfreq / x * a + cnt)

    waitcnt(clkfreq / 1000 * 39 + cnt)
    divide current system clkfreq reg value by 1mS, then multiply the 1mS by 39 to get a binary value for 39mS based on the current clkfreq reg value, then adds that to the system counter value and then proceeds to wait for the 39mS you specified.
    Traps:
    *always specify it as (offset + cnt) not (cnt + offset), the latter does the math (optional) and then activates the wait hardware in the cog.
    *in spin value absolute minimum = 381, the overhead number of clocks it takes the interpreter to evaluate the expression, equation or not.
    Tip:
    *pre calculating those values used often and refrencing them as constants or variables for use in your entire program code or just in a pri block

    **Also note that SPIN commands/programs are many times slower in execution than PASM equivalents and most SPIN commands take many more than 4 clocks to complete, the waitcnt command for example takes at least 381 clocks. Using the counter A/B modules within the cog, you can produce basic square waves/frequencies up to 128MHz using PLL and/or NCO modes but the spin program runs 1,000's of times slower than that. You can even use the special waitvid command to pass the video hardware -after setting the appropriate bits in the vconfig reg- bit patterns to shift out over 4 to 8 i/o such as how the TV and VGA drivers accomplish output.

    If your looking to toggle/pulse an output with optional output disable you can simply do:
    pri task_0( OE, mS, blink_num):ok | val, led
    {
    This pri block does a few things,
    *blink_num =  controls the number of blinks on the output
    *mS        =  desired square wave freq with 50% duty cycle
    *OE        =  Output Enable - enables one of two output pins depending on value passed by mS
    If blink_num or OE is 0 then task_0 will simply wait for mS & return
    }
      val := clkfreq / 2000 * mS    'calculate correct pause time in milliseconds, store result in val
      if(val <> 250 OR val <> 125) 'if mS doesn't equal 500mS OR 250mS then the method quits and does nothing
        ok := false
        return
      if val == 250                 'if mS == 500mS then..
        led := 1                    
      if val == 125                 'if mS == 250mS then..
        led := 2                    
      dira[led] := OE               'enable output = 1, disable = 0
     
      if(blink_num == 0 OR OE == 0) 'if blink_num = 0 OR OE = 0, then wait for mS and return
        repeat 2
          waitcnt(val + cnt)        'pause cog opperation until mS has passed
        ok := true
        return                      
     
      if blink_num                  'if blink_num = true then repeat number of blinks
        repeat blink_num            
          !outa[led]                'toggle logic state of led
          waitcnt(val + cnt)        'pause cog opperation until mS has passed
          !outa[led]                'toggle back to original state
          waitcnt(val + cnt)        'pause cog opperation until mS has passed
        ok := true
    return
    
Sign In or Register to comment.