Shop OBEX P1 Docs P2 Docs Learn Events
Blinking led with counter — Parallax Forums

Blinking led with counter

Don MDon M Posts: 1,652
edited 2014-04-03 08:01 in Propeller 1
I remember that sometime ago there was a discussion about being able to blink an led by only using the counter. I can't find the thread or sample code someone posted.
«1

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2014-02-13 05:43
    You mean something like this?
    CON
      pin = 16
      
    PUB null
    
      outa[pin] := !(dira[pin] := 1)
      ctra := constant(%0_00100_000 << 23 | pin)
      frqa := 500
    
      waitpne(0, 0, 0)
    
  • Don MDon M Posts: 1,652
    edited 2014-02-13 05:47
    I was thinking you may have been the one who posted something about it.

    So I can use this within any cog then?

    I could also make freq a variable to change the blink rate correct?
  • kuronekokuroneko Posts: 3,623
    edited 2014-02-13 05:54
    Don M wrote: »
    So I can use this within any cog then?

    I could also make freq a variable to change the blink rate correct?
    Certainly. Both counters (A & B) can be used for a total of 16 LEDs provided they are not used otherwise (video/audio etc). You can also mis/use the Synth object (PropTool library) if you prefer.
  • Don MDon M Posts: 1,652
    edited 2014-02-13 05:57
    Thanks for your help. I'll try this out later today
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2014-02-13 06:40
    Hi Don;
    Don M wrote: »
    I remember that sometime ago there was a discussion about being able to blink an led by only using the counter. I can't find the thread or sample code someone posted.

    This may be the thread you remember where a bi-colored LED was driven with a pair of Prop pins.
    Flashing a Bi-Colored LED in 7 ways
    My version, written in FemtoBasic, allows the Bi-Colored LED can be controlled with steady state and blinking modes in 3 colors as well as OFF.
    The technique can easily be translated into other languages.

    Duane J
  • D.PD.P Posts: 790
    edited 2014-02-13 12:31

    Now I can't help myself, Peter I will get you!

    In Tachyon
    pub PULSELED ( pin -- )      \ pulse and led smoothly
      DUP            \ dup the pin number on the stack
      A                 \ select CTRA
      APIN           \ assign pin to apin of counter A, still have one pin # on the stack
      #1000 HZ    \ start CTRA in NCO mode at 1000 Hz
      B                 \ select CTRB
      APIN           \ just grabbed the last pin # off the stack, assinged to CTRB
      #1001 HZ    \ start CTRB in NCO mode at 1001 Hz
    
    ;
    
    pub MUTEALL   A MUTE B MUTE ;    \ turn both counters off
    
    / usage     #14 PULSELED   or whatever your pin number is
    
  • Don MDon M Posts: 1,652
    edited 2014-02-13 18:44
    kuroneko,

    Need some help understanding what is happening with your example:
    CON
      pin = 16
      
    PUB null(blink_rate, mode)
    
      outa[pin] := !(dira[pin] := 1)
      ctra := constant(%0_00100_000 << 23 | pin)
      frqa := blink_rate
      waitpne(0, 0, 0)
    
    

    What does the waitpne(0,0,0) do? What do the 0's mean?

    I added this code to my object and it will make the LED blink but it just stops here. If I comment out the waitpne statement then it still blinks but continues on in the code.

    How should this code be used? I want it to blink a x speed for 1 mode then be steady on for another mode. If I change the frqa to 0 then it goes off.

    Thanks.
  • kuronekokuroneko Posts: 3,623
    edited 2014-02-13 18:54
    Don M wrote: »
    What does the waitpne(0,0,0) do? What do the 0's mean?
    If I don't place it there then the method exits and the cog stops. The waitpne is there to keep the cog alive (zero can never be not equal to 0 & ina). For your usage scenarios just ignore it.

    As for steady on I'd simply set outa[pin] high (and reset it for the blink mode), e.g.
    CON
      pin = 16
      
    PUB null(blink_rate, mode)
    
      outa[pin] := mode       ' 1: solid, 0: flashing (depending on frqa)
      dira[pin] := 1
      ctra := constant(%0_00100_000 << 23 | pin)
      frqa := blink_rate
      phsa := 0
    
    Clearing phsa makes sure that the ouput isn't driven (even with frqa == 0).
  • Don MDon M Posts: 1,652
    edited 2014-02-13 18:58
    So you were just using that method only as a test and needed waitpne just to keep it running correct?

    So if I just use it without the waitpne I can use it in an existing cog and just vary the parameters to my liking?

    Sorry for the dumb questions just trying to understand it.

    Thanks.
  • kuronekokuroneko Posts: 3,623
    edited 2014-02-13 19:03
    Correct. Looks like you package it up into a method and call it from anywhere in your program. In this case don't use the waitpne.
  • Don MDon M Posts: 1,652
    edited 2014-02-13 19:10
    OK thanks. I'll play some more.
  • Don MDon M Posts: 1,652
    edited 2014-02-14 10:51
    Can I have a second independent counter using ctrb, frqb, & phsb?
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2014-02-14 11:42
    Can I have a second independent counter using ctrb, frqb, & phsb?

    What do you think? Try it and see!
    kuroneko wrote: »
    Certainly. Both counters (A & B) can be used for a total of 16 LEDs provided they are not used otherwise (video/audio etc). You can also mis/use the Synth object (PropTool library) if you prefer.
  • Don MDon M Posts: 1,652
    edited 2014-02-14 16:07
    @Tracy... It would help if I'd read everthing in detail... thanks for pointing that out.

    On another note however using a Quickstart board I can't get this to work-
    CON
            _clkmode = xtal1 + pll16x                                              
            _xinfreq = 5_000_000
    
    CON
    
      led = 16
    
    pub main
    
      null(200, 0, led)  
      
    PUB null(blink_rate, mode, pin)
    
      outa[pin] := mode       ' 1: solid, 0: flashing (depending on frqa)
      dira[pin] := 1
      ctra := constant(%0_00100_000 << 23 | pin)
      frqa := blink_rate
      waitpne(0, 0, 0)
      
    

    I get an error message on compile- "Expected a constant, unary operator, or "(" "

    But this will work-
    CON
            _clkmode = xtal1 + pll16x                                              
            _xinfreq = 5_000_000
    
    CON
    
      led = 16
    
    pub main
    
      null(200, 0, led)  
      
    PUB null(blink_rate, mode, pin)
    
      outa[pin] := mode       ' 1: solid, 0: flashing (depending on frqa)
      dira[pin] := 1
      ctra := constant(%0_00100_000 << 23 | 16)  ' took out "pin" and put in pin number instead. Why?
      frqa := blink_rate
      waitpne(0, 0, 0)
      
    
    

    Why won't it work?
  • kuronekokuroneko Posts: 3,623
    edited 2014-02-14 16:28
    constant(expr) only works with constants.

    Using a variable pin should read constant(%0_00100_000 << 23) | pin.
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2014-02-14 16:32
    Don,

    That is because the local variable pin can't be resolved as a constant at compile time. But 16 can.

    ctra := constant(%0_00100_000 << 23 | pin)
  • Don MDon M Posts: 1,652
    edited 2014-02-14 16:32
    kuroneko wrote: »
    constant(expr) only works with constants.

    Using a variable pin should read constant(%0_00100_000 << 23) | pin.

    Ok. Thanks for that.

    Here's some code I put your methods to use with. Works pretty neat-
    CON
            _clkmode = xtal1 + pll16x                                              
            _xinfreq = 5_000_000
    
      led  = 16
      led2 = 18
    
    pub main
    
      null(5, 0, led)
      null2(2, 0, led2)
    
      waitpne(0, 0, 0)     
      
    PUB null(blink_rate, mode, pin)
    
      outa[pin] := mode       ' 1: solid, 0: flashing (depending on frqa)
      dira[pin] := 1
      ctra := constant(%0_00100_000 << 23) | pin
      case blink_rate
        1:   
          frqa := 100
        2:   
          frqa := 150
        3:   
          frqa := 200
        4:   
          frqa := 250
        5:   
          frqa := 350
        6:   
          frqa := 500        
    
    PUB null2(blink_rate, mode, pin)
    
      outa[pin] := mode       ' 1: solid, 0: flashing (depending on frqa)
      dira[pin] := 1
      ctrb := constant(%0_00100_000 << 23) | pin
      case blink_rate
        1:   
          frqb := 100
        2:   
          frqb := 150
        3:   
          frqb := 200
        4:   
          frqb := 250
        5:   
          frqb := 350
        6:   
          frqb := 500        
    
    
  • kuronekokuroneko Posts: 3,623
    edited 2014-02-14 16:39
    You can use lookup instead of case. Out of range automatically gives you 0.
    frqa := lookup(blink_rate: 100, 150, 200, 250, 350, 500)
    
  • Don MDon M Posts: 1,652
    edited 2014-02-14 16:49
    Hey thanks! I'm learning a few new neat litte tricks here...
  • Don MDon M Posts: 1,652
    edited 2014-02-14 17:01
    So now I'm thinking of a way to shut it off if I have either had it blinking or on solid. Here is what I came up with. Is there an easier way to do this?
    PUB null(blink_rate, mode, pin)
    
    ''For Mode: 2: off, 1: solid on, 0: flashing (depending on frqa)  
    
      if mode == 2
        mode := 0
        outa[pin] := mode       
        dira[pin] := 1
      else
        outa[pin] := mode       
        dira[pin] := 1   
        ctra := constant(%0_00100_000 << 23) | pin
        frqa := lookup(blink_rate: 100, 150, 200, 250, 350, 500)
        phsa := 0
    
    
  • kuronekokuroneko Posts: 3,623
    edited 2014-02-14 17:06
    I played with this yesterday and came up with this:
    PRI ctrx(pin, ID{0:A|1:B}, blink_rate{0:off|1..6}, mode{0:flash|N:solid})
    
      ID &= 1
      
      spr[$8 + ID{ctrx}] := constant(%0_00100_000 << 23) | pin
      spr[10 + ID{frqx}] := lookup(blink_rate: 100, 150, 200, 250, 350, 500)
      spr[12 + ID{phsx}] := 0
    
      outa[pin] := mode <> 0
      dira[pin] := blink_rate <> 0
    
    A blink_rate of 0 will switch off (not counting) the relevant counter and also release the pin. Whether counter A or B is used depends on ID.

    Note, your mode 2 wouldn't touch the counter so if it's still running it will continue doing so. Did you mean to clear dira[pin] in that mode?

    Alternative version using "A" and "B":
    PRI ctrx(pin, ID{"A"|"B"}, blink_rate{0:off|1..6}, mode{0:flash|N:solid})
    
      ID &= 1
      
      spr[$9 - ID{ctrx}] := constant(%0_00100_000 << 23) | pin
      spr[11 - ID{frqx}] := lookup(blink_rate: 100, 150, 200, 250, 350, 500)
      spr[13 - ID{phsx}] := 0
    
      outa[pin] := mode <> 0
      dira[pin] := blink_rate <> 0
    
  • Don MDon M Posts: 1,652
    edited 2014-02-14 17:14
    Neat! That is very compact.

    Regarding this: mode{0:flash|N:solid} should N be a 1 instead of N ?
  • kuronekokuroneko Posts: 3,623
    edited 2014-02-14 17:18
    Don M wrote: »
    Regarding this: mode{0:flash|N:solid} should N be a 1 instead of N ?
    Doesn't matter as the comparison is mode <> 0. But feel free to use 1.
  • Don MDon M Posts: 1,652
    edited 2014-02-14 17:27
    I get a compile error if I use "N" that is why I asked.

    Here's what works: ctrx(led3, 0{0:A|1:B}, 5{0:off|1..6}, 1{0:flash|1:solid})

    This doesn't work: ctrx(led3, 0{0:A|1:B}, 5{0:off|1..6}, N{0:flash|N:solid})
  • kuronekokuroneko Posts: 3,623
    edited 2014-02-14 17:31
    Don M wrote: »
    This doesn't work: ctrx(led3, 0{0:A|1:B}, 5{0:off|1..6}, N{0:flash|N:solid})
    Ah, I see. This (being an inline comment for PropTool's Summary display mode) just means any number but 0 (just the way I do things). So you can pass anything from e.g. 1..4000 (N sort of stands for Number). Sorry for the confusion.

    That said, "N" would work ...
  • Don MDon M Posts: 1,652
    edited 2014-04-02 15:11
    So I was looking at this code again today and was wondering if there was a way to count the "flashes"? What I am lookiing at doing was to use this method as a way to indicate a condition for troubleshooting. For example we've all seen the instructions that if the red led blinks so many times, then pauses it means one thing etc.

    I like the way that this code piece works in that it doesn't use a cog and works independant of other processes.

    Any idea if this could be done and how to do it?
  • kuronekokuroneko Posts: 3,623
    edited 2014-04-02 17:18
    It can certainly be done but it needs code support (i.e. it's not independent/free anymore).

    Edit: Periodic pulse trains would be OK though, e.g. 10 pulses followed by fixed state (on or off) for the same time then pulses again.
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2014-04-02 21:52
    Don, I'm not sure what you mean by counting the flashes, but as an indicator, you can set up the two cog counters to play against one another.

    For example, if you have a bi-color 2-pin led between two pins,
    '  grnK  -----;------->|-----------;----/\/\-- redK
    '             '-------|<-----------'          &#937;
    
    PUB autoFlash(frqR, frqG, phsG)
      dira[grnK..redK]~~
      ctra := 100_000 << 23 + redK ' NCO mode
      ctrb := 100_000 << 23 + grnK ' NCO mode
      phsb := (posx / 100 * phsG) << 1              '
      frqa := frqR                '
      frqb := frqG
    

    The above PUB with different choices of the parameters generates various alternating patterns of red and green that are easily identifiable (at least for anyone not blind to those colors--always have to consider that possibility when making indicators!)

    examples:
    20,10,0 red, green, pause, repeat
    10,20,0 green, red, pause, repeat
    20, 60,0 red,pause,green,pause, repeat
    20,80,0 red,red,green,green,pause,repeat
    80,20,0 green,green,red,red,pause,repeat
    10,110,00 5 green,5 red, repeat
    10,130,00 6 green,6 red, repeat
    Play with both small integer ratios and as also larger numbers to achieve smooth effects.The third parameter, the starting phase (in percent from 0 to 99%), adds a measure of syncopation.
  • Don MDon M Posts: 1,652
    edited 2014-04-03 03:45
    Don, I'm not sure what you mean by counting the flashes, but as an indicator, you can set up the two cog counters to play against one another.

    For example, if you have a bi-color 2-pin led between two pins,
    '  grnK  -----;------->|-----------;----/\/\-- redK
    '             '-------|<-----------'          &#937;
    
    PUB autoFlash(frqR, frqG, phsG)
      dira[grnK..redK]~~
      ctra := 100_000 << 23 + redK ' NCO mode
      ctrb := 100_000 << 23 + grnK ' NCO mode
      phsb := (posx / 100 * phsG) << 1              '
      frqa := frqR                '
      frqb := frqG
    

    The above PUB with different choices of the parameters generates various alternating patterns of red and green that are easily identifiable (at least for anyone not blind to those colors--always have to consider that possibility when making indicators!)

    examples:
    20,10,0 red, green, pause, repeat
    10,20,0 green, red, pause, repeat
    20, 60,0 red,pause,green,pause, repeat
    20,80,0 red,red,green,green,pause,repeat
    80,20,0 green,green,red,red,pause,repeat
    10,110,00 5 green,5 red, repeat
    10,130,00 6 green,6 red, repeat
    Play with both small integer ratios and as also larger numbers to achieve smooth effects.The third parameter, the starting phase (in percent from 0 to 99%), adds a measure of syncopation.

    Tracy- I tried your method on a Quickstart and couldn't make it work. Now I know that I am not using bi-color led's back to back but thought I'd at least see one of the led's blink.

    If I can use this method only using 1 led and get the patterns you describe with the 1 led then I can use this.

    Here's my code. Maybe it's something I'm doing wrong.
    CON
            _clkmode = xtal1 + pll16x                                               'Standard clock mode * crystal frequency = 80 MHz
            _xinfreq = 5_000_000
    
      
    '  grnK  -----;------->|-----------;----/\/\-- redK
    '             '-------|<-----------'          &#937;
    
      redK = 16
      grnK = 17
    
    PUB Main
    
    ''  examples:
    ''  20,10,0 red, green, pause, repeat
    ''  10,20,0 green, red, pause, repeat
    ''  20, 60,0 red,pause,green,pause, repeat
    ''  20,80,0 red,red,green,green,pause,repeat
    ''  80,20,0 green,green,red,red,pause,repeat
    ''  10,110,00 5 green,5 red, repeat
    ''  10,130,00 6 green,6 red, repeat
    
    ''  Play with both small integer ratios and as also larger numbers to achieve smooth effects.
    ''  The third parameter, the starting phase (in percent from 0 to 99%), adds a measure of syncopation. 
    
      autoFlash(20, 80, 50)
    
    
    PUB autoFlash(frqR, frqG, phsG)
    
      dira[redK..grnK]~~
      
      ctra := 100_000 << 23 + redK ' NCO mode
      ctrb := 100_000 << 23 + grnK ' NCO mode
      phsb := (posx / 100 * phsG) << 1              '
      frqa := frqR                '
      frqb := frqG
      
    

    I tried various numbers for the phase- 0, 50, 99 and none of them blinked.

    Now I noticed in an earlier thread above the code was done like this:
    ctra := constant(%0_00100_000 << 23) | pin 
    
    
Sign In or Register to comment.