Shop OBEX P1 Docs P2 Docs Learn Events
Make an LED pulse (smoothly go on and off) without any code interaction — Parallax Forums

Make an LED pulse (smoothly go on and off) without any code interaction

BeanBean Posts: 8,129
edited 2013-01-30 18:57 in Propeller 1
I needed to make an LED pulse smoothly on and off without any code interaction.
I didn't have a free COG to devote to it.
So I used a COG that wasn't using either of the hardware counters and set them to output slightly different frequencies and connected the LED between the output pins.

It worked very well.
The pulsing time is the difference between the two frequencies (1 Hz for the example code).

Bean
'
' Pulsing (PWM) LED without any code interaction
' Connect LED to pins P0 and P1 (don't forget resistor if needed)
'
' If you connect two LEDs back to back (connections reversed) one will get brighter as the other is getting dimmer
'
' Uses both counters
'
' By Bean, Nov 1, 2012
'
CON
  _clkmode        =  xtal1+ pll16x
  _xinfreq        = 5_000_000


Pub Start
  frqa := 53687                ' 1000 Hz
  ctra := %00100_000 << 23 + 0 ' NCO mode, pin 0
  dira[0]~~                    ' Make pin 0 an output

  frqb := 53740                ' 1001 Hz
  ctrb := %00100_000 << 23 + 1 ' NCO mode, pin 1 
  dira[1]~~                    ' Make pin 1 an output

  repeat                       ' No further actions required
           

Comments

  • HumanoidoHumanoido Posts: 5,770
    edited 2012-11-01 07:03
    Thanks for showing this fantastic application of controlling LEDs using deterministic counters. It's a good use of a Cog's 2 counters to gain additional functions on pins freeing up other program activity. It undoubtedly has useful functions that go far beyond just LEDs. I'm experimenting with using counters like small additional processors and objects to gain more functions using their features and did some projects a while back. I think you just provided another example. Keep up the good work!
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2012-11-01 07:10
    Thanks Bean.
    For the longest time I have been attracted to a blinking led as a sign of life in microcontroller projects, but taking a whole cog to manage an led in an endless loop seemed rather wasteful.

    And this really drives home the usefulness of the two timers when used together. The back to back leds can be different colors and I guess that you will have to provide an appropriate resistor to limit current.
  • Mark_TMark_T Posts: 1,981
    edited 2012-11-01 07:12
    Smart thinking - I fear I'd have missed that trick if in the same predicament!

    However I think by adding two diodes to a red-green 3-wire LED you could get the same trick to do colour-fading?
  • Don MDon M Posts: 1,652
    edited 2012-11-01 09:15
    Ok I tried this on a Quickstart and couldn't get it to work. You did mean to connect the led between P0 & P1 correct (one lead to P0 and the other lead to P1)?

    Edit: I'm guessing that this is running at 1Khz? In that case I probably wouldn't see it...

    Edit2: My mistake.. I somehow missed copying the repeat.

    Oops. Sorry.
  • Clock LoopClock Loop Posts: 2,069
    edited 2012-11-01 09:21
    Wait couldn't this be done with a single pin and two counters? Two leds, and two resistors, one pulls up, one down. isuppose theres a few ways to do it(voltage divider) If your leds vf<1.65v

    Technically this could be done with a single led, if you only want to use 1 pin on the prop!
    I use a cog to blink a led all the time for heartbeat, but using a counter (we have so many and mostly don't use them)

    Is a better standard to follow, great idea! And its a simple, oh... right... duh....

    I have had more than a few situations where I really had 1 pin only for the led, and no cogs left, so I just made the heartbeat a "toggle" inbetween code that has pauses for other reasons.

    This really shows how the extra hardware mostly goes unused in the prop and also shows that we have untapped uses for the propeller, even still.

    Having all those counters....that don't rely on any cog or thread(other mcus) really shows that the propeller isn't just another mcu.
  • Heater.Heater. Posts: 21,230
    edited 2012-11-01 09:37
    Loopy,
    For the longest time I have been attracted to a blinking led as a sign of life in microcontroller projects, but taking a whole cog to manage an led in an endless loop seemed rather wasteful.

    Nice idea. Just be aware that if you do things like that the LED will continue blinking even when your application has crashed and died. I once saw a case where an MCU application had crashed but the heartbeat LED was blinking as if everything was OK. Turned out the heart beat LED was driven my an interrupt driven from a timer which continued as normal when the main line had gone off into the weeds.
  • BeanBean Posts: 8,129
    edited 2012-11-01 09:46
    Clock Loop wrote: »
    Wait couldn't this be done with a single pin and two counters?

    YES, You can using a single pin.
    Change the code so that both counters using the same pin and connect the cathode to that pin.
    Connect the anode to +3.3V and you're good to go...
    '
    ' Pulsing (PWM) LED without any code interaction (Single pin version)
    '
    ' Connect LED cathod (-) to pin P0, connect LED anode (+) to +3.3V (don't forget resistor if needed)
    '
    ' Uses both counters
    '
    ' By Bean, Nov 1, 2012
    '
    CON
      _clkmode        =  xtal1+ pll16x
      _xinfreq        = 5_000_000
    
    
    Pub Start
      frqa := 53687                ' 1000 Hz
      ctra := %00100_000 << 23 + 0 ' NCO mode, pin 0
    
      frqb := 53740                ' 1001 Hz
      ctrb := %00100_000 << 23 + 0 ' NCO mode, pin 0 
    
      dira[0]~~                    ' Make pin 0 an output
    
      repeat                       ' No further actions required
    
    

    The code will generate a PWM triangle wave on the output pin that goes from 50% to 100%, which may be handy for other uses too.

    Bean
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2012-11-01 11:05
    Heater. wrote: »
    Nice idea. Just be aware that if you do things like that the LED will continue blinking even when your application has crashed and died. I once saw a case where an MCU application had crashed but the heartbeat LED was blinking as if everything was OK. .

    I've taken advantage of that to indicate what a program is doing when it goes off into the weeds. Before entering a suspect task, the blink pattern is set to a unique pattern. If you come up later and find the system locked up, you know by the pattern where to start debugging. Can be helpful in case of field deployments where you might need someone else to observe the system status. Normal operation is a sequence of flash patterns.

    I use a dual counter arrangement to generate flashes at a programmable rate, color and duration. Program attached is initialized with two pins for r/g led. Then a call to
    flash(whichPin, period_ms, flash_ms)
    causes the selected pin to pulse low autonomously with the selected period and duration in milliseconds. There is a provision to allow the flash to transition into low power RCslow mode.
  • jmgjmg Posts: 15,173
    edited 2012-11-01 13:50
    I've taken advantage of that to indicate what a program is doing when it goes off into the weeds. The before entering a suspect task, the blink pattern is set to a unique pattern. If you come up later and find the system locked up, you know by the pattern where to start debugging. Can be helpful in case of field deployments.

    It is a nifty use of an otherwise spare counter pair. If could also be used for link-traffic indicators, because the cost of updating a value, is a single opcode, or a couple if you want to merge a system variable like a FIFO pointer, with the Pulse value.
    Such 'sign of life' LEDs can be invaluable.

    Expanding the idea, I recall an Infineon device, that uses a time modulation scheme, to lower the edge-count (and thus EMC).
    From memory, they encoded 4 bits of data into 16 possible edge positions, and started with a known width, to Auto-cal.
    Great for low data rate sensor/status links.

    I think a Prop could also allow a 38KHz IR style carrier, and modulate that at ~18.063Hz/bit steps via this dF scheme, or I guess you could use the Pin OR feature to generate 38KHz carrier with one timer, and any lower gating OR modulation you wanted with the other.
  • prof_brainoprof_braino Posts: 4,313
    edited 2012-11-02 18:37
    is there a way to shift the cycle for the next LED, to go the Cyclon scan? Using only the counters, of course :)
    Maybe this is a question for kuroneko?
  • tonyp12tonyp12 Posts: 1,951
    edited 2012-11-03 06:40
    >is there a way to shift the cycle
    Sure, sync the cogs first by init them and have them all wait for a fixed cnt number about 1 second in the future.
    Now set up PHSA and PHSB with slighty higher values in each cog.
    Though I think it will only be scanning in one direction and not in a KnightRider style.
  • T ChapT Chap Posts: 4,223
    edited 2012-11-03 07:00
    Interesting. The difference in frequencies from left to right in headphones is called binaural beats. This is a visual version of audio.
  • Clock LoopClock Loop Posts: 2,069
    edited 2012-11-03 10:01
    re-run the 'counter code' on the same cog., with new values
    thats it. that does mean you must track the cog that launched the spinner in the first place
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2012-11-07 17:00
    I've added a variation of Bean's program to my object for indicating "signs of life" in a multifaceted project,
    "where are we?", or (oh no!)
    "where are we locked up?".
    Low frqa and frqb values generate interesting, humanoid-readable patterns. For example, the following is a modified version of Bean's code. With a bicolor r/g LED and the values as entered in the demo, it autonomously generates a repeating pattern of two red flashes followed by two green flashes with nice pauses in between. Make the second parameter 60 instead of 100 and you get alternating red and green. Make the third (phase) parameter 50 instead of 0 and you get a syncopated pattern of 3 and 2 ... 2 and 3.
    [SIZE=1][FONT=courier new]
    ' Pulsing (PWM) LED without any code interaction
    ' Connect LED to pins redK and grnK (don't forget resistor if needed)
    '
    ' Bicolor LED will flash autonomously in a pattern 
    ' that depends on two frequencies and one phase
    ' Use low frequencies for human readable pattern
    ' Uses both counters ctra and ctrb
    [/FONT][/SIZE][SIZE=1][FONT=courier new]' mod by Tracy Nov 7, 2012 from[/FONT][/SIZE][SIZE=1][FONT=courier new] Bean, Nov 1, 2012
    
    CON
      _clkmode        =  xtal1+ pll16x
      _xinfreq        = 5_000_000
    
      grnK = 6   ' pin # kathode of green LED
    [/FONT][/SIZE][SIZE=1][FONT=courier new]  redK = 7   ' next pin kathode of red LED
    [/FONT][/SIZE]
    [SIZE=1][FONT=courier new] 
    PUB demo
      autoflash(20,100,0)  ' play 2 frqs one phs (0-100%)
      repeat  ' continuation of the program...?
    
    PUB autoFlash(frqR, frqG, phsG)
      dira[grnK..redK]~~     ' assumes neighboring pins
      ctra := %00100_000 << 23 + redK ' NCO mode
      ctrb := %00100_000 << 23 + grnK ' NCO mode
      phsb := (posx / 100 * phsG) << 1              '
      frqa := frqR                '
      frqb := frqG
    [/FONT][/SIZE]
    
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2012-11-09 09:48
    @Tracy Allen
    Only the geeks from Parallax could find such an elegant way to deploy blinking lights and actually save processor resources as well. Congradulations.
  • SRLMSRLM Posts: 5,045
    edited 2013-01-30 12:25
    Bean wrote: »
    I needed to make an LED pulse smoothly on and off without any code interaction.
    ...
    ...
      frqa := 53687                ' 1000 Hz
    ...
      frqb := 53740                ' 1001 Hz
    ...
    

    What is the logic of these two numbers? I'm trying to see if I can get it to pulse at a different rate than 1 hz.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-01-30 12:33
    The observable pulsing occurs at the difference between the two frequencies (i.e. the beat frequency).

    -Phil
  • SRLMSRLM Posts: 5,045
    edited 2013-01-30 13:53
    The observable pulsing occurs at the difference between the two frequencies (i.e. the beat frequency).

    -Phil

    Ok, but how do the numbers 53687 and 53740 correlate to the 1000 Hz and 10001 Hz listed in the code?
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-01-30 14:02
    Those numbers result from the standard formula for an NCO counter:
    FRQx = Fout * 232 / Fclk

    So 1000 * 232 / 80_000_000 = 53687.

    -Phil
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2013-01-30 15:14
    Those numbers result from the standard formula for an NCO counter:
    FRQx = Fout * 232 / Fclk

    So 1000 * 232 / 80_000_000 = 53687.

    -Phil
    Just to add a bit:
    53.6870912 / 1Hz ok call it 54 / Hz.
    So you can either add or subtract 54 to 53687 for the desired beat frequency.
    Adding or subtracting 10 looks real nice at about 5 seconds blink rate.

    BTW, the LED only goes between 50% and 100% brightness but this looks very nice.

    Duane J
  • BeanBean Posts: 8,129
    edited 2013-01-30 15:27
    Duane,
    If you reverse the LED leads it will go from 0% to 50% which is how I use it.

    Bean
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2013-01-30 15:40
    Bean wrote: »
    Duane,
    If you reverse the LED leads it will go from 0% to 50% which is how I use it.

    Bean
    Good point.
    When you say reverse are you actually meaning connecting the LED to 3.3V?

    Duane J
  • BeanBean Posts: 8,129
    edited 2013-01-30 17:38
    Yeah, if you are using the single pin version, then connect the LED with the cathode on the pin and the anode to +3.3V

    Because the counter outputs are OR'd together the pin is high from 50% to 100% and low from 0% to 50%.

    Bean
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-01-30 18:57
    You can also use two pins to get 0-100%, and the polarity is irrelevant.

    -Phi
Sign In or Register to comment.