Shop OBEX P1 Docs P2 Docs Learn Events
LEDs brightness with pwm at various frequencies. — Parallax Forums

LEDs brightness with pwm at various frequencies.

lyassalyassa Posts: 52
edited 2012-01-27 00:46 in Propeller 1
I wanted to control the brightness of 3 LEDs, red, green and blue, so I thought to write a pwm routine in Spin. I know I can use counters, and some objects already exist, but I wanted the learning experience, and I ended with an effect I am not able to understand, so hopefully you can explain it for me.

Well, I wrote the routine below. I tell it how much percent of the duty cycle I want each LED to be on, as well as the frequency. The visual effect looks good at low frequencies, around 100Hz. However, the LEDs start to appear brighter and of the same intensity at higher frequncies, around 5000Hz. I thought the freq should not matter much as long the percent periods they are on and off does not change!!

' for this test, and to compare brightness visually, the three LEDs are red color, connected to the Propeller pins with 100 ohms resistors.
pub main
   pwm3(5,5,90,100)    ' led1 5% of the duty cycle, led2 5%, led3 90%, freq 100Hz - brightness easily distinguishable by eye.
   ' pwm3(5,5,90,5000)  ' same duty cycles percentages, freq 5000Hz - all three leds appear the same brightness.

' uses pins 20, 21 and 22
pub pwm3 (r,g,b, f)  | i, w
    dira[20..22] := %111
    w := clkfreq / 100
    w := w /f
    'show(r,g,b, cnt, w)
    repeat  
       repeat i from 0 to 99  '
          if i < r                    ' on for 5 loop then off for the rest
              outa[20] := 1
          else
              outa[20] := 0

          if i < g                ' on for 5 loop then off for the rest
              outa[21] := 1
          else
              outa[21] := 0

          if i < b        ' on for 90 loop then off for the rest
              outa[22] := 1
          else
              outa[22] := 0
        
          waitcnt(w + cnt)

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2012-01-27 00:10
    What's your clock setup? Anyway, assuming 80M you'll end up with w = 80M/100/5000 = 160. This is too small for waitcnt in SPIN (min is 381, see manual rev 1.2, page 219). With an 80M setup 2099 is the best you can do with your code as is.
  • lyassalyassa Posts: 52
    edited 2012-01-27 00:29
    Kuroneko, u r d man.
    Yes, I am using 80Mhz. You are right, I set the freq to 3000Hz and the brightness is messed up. At 2099Hz is as goos as at 100Hz. Thanks for your help and for figuring that out so quickly. The reason I devide by 100 is because the inner loop repeats 100 times to cover one cycle. E.g. If the freq to 1 Hz, then the inner loop need to wait for 1/100th of second by 100 loops to get 1 second.

    By the way, the lengthy if...else ... could by replaced by

    outa[20] := ||(r > i) ' true = -1, false = 0, || = absolute
    outa[21] := ||(g > i)
    outa[22] := ||(b > i)

    Thanks again for your help.
  • kuronekokuroneko Posts: 3,623
    edited 2012-01-27 00:46
    lyassa wrote: »
    outa[20] := ||(r > i) ' true = -1, false = 0, || = absolute
    outa[21] := ||(g > i)
    outa[22] := ||(b > i)
    You can even get rid of the || operator. When you assign a number to a single bit you get the equivalent of e.g. outa[n] := value & 1. TRUE & 1 is 1 so doesn't require any post processing.
Sign In or Register to comment.