Shop OBEX P1 Docs P2 Docs Learn Events
need some expert help :How much pwm PINS are possible — Parallax Forums

need some expert help :How much pwm PINS are possible

AnubisbotAnubisbot Posts: 112
edited 2007-05-18 22:10 in Propeller 1
Hi, since i am verry new to the porpeller and all is a bit difrent then the javelin stamp.

I try to find out how manny cogs i need to dirve 22 PWM pins for led dimming.

I tyed the sevo 32 .spin but dident get it to work..

And with the pwm spin i only get 7-8 pwm pins with the same amount of cogs...

Does some one has i bright idea how to solve that.

I want to mix 2 seperate rgbw leds and some led spots (30leds)..

Anubis bot

Comments

  • Dennis FerronDennis Ferron Posts: 480
    edited 2007-05-18 01:22
    I haven't tested this approach but the way I would do it if I were you would be to make an array of 32-bit longs. The array should hold 100 longs. In each array entry, a bit in the entry corresponds to a low or high on a pwm pin. For instance:

    bit0 <--> pin0
    bit1 <--> pin1
    bit2 <--> pin2

    And so on.

    Now, your table looks like this:

    entry(0) := 0011
    entry(1) := 0010
    entry(2) := 0010
    entry(3) := 0000
    ... and so on

    For simplicity, I haven't shown all the bits. But let's say those four bits represent the states of four pwm control lines. Each entry in the table represents a "snapshot" in time that shows the state of all the output pins at that moment in time. So in the example table I gave, at time t-0, the output lines should be 0011 (turns on pwm0 and pwm1). At time t-1, pwm1 is on but you see pwm0 should be off because there is a 0 in that bit.

    Say you want to make PWM pin 3 be at 25% power. What you would do is go through the table and in the "column" for bit3, you would set bit3 in 25 of the entries, and clear it in 75 of them. You could mix the 25 "on" bits and the 75 "off" bits in any pattern you like, including the "magic sine waves" discussed in a previous post which gives you the best possible power efficiency. As a further example, if you wanted to make PWM pin 2 be at 50% power, you could just go through the 100 entries and set bit2 in half and clear it in half. For any power %, it's just that number of on or off bits in the table.

    Now if you were to take a cog and loop through the entire table continuously, you could write all the bits of each table entry to the OUTA register at once, and that would set all of the PWM pins' states at once. First you say OUTA := entry(0), then you say OUTA := entry(1), and so on, then repeat. That way, it wouldn't take any more processing power to do 22 or even 30 pwm lines than it does to do just one!! (It's still just one variable assignment; you are blasting out the PWM bits in parallel instead of one at a time.) This solution only requires one cog. It is so efficient, you could even code the loop in Spin instead of assembly language, and it would still be fast enough.
  • AnubisbotAnubisbot Posts: 112
    edited 2007-05-18 02:51
    Sound great, but i dont get it a 100 procent,

    can you explain it on a 3 pin exemple, how the code looks like.

    Anubisbot
  • Dennis FerronDennis Ferron Posts: 480
    edited 2007-05-18 08:38
    Forums tend to mess up code formatting, so I'm including the program as an attachment.

    The program (pwm.spin) will flash 3 LEDs. Connect one LED to Pin 0, another to Pin 1, and another to Pin 2. The program will flash the first LED briefly and keep it mostly off. The second LED will flash on and off equal times. The third will stay on most of the time and flash off briefly.

    If you set the Delay value in the program to be smaller, the LEDs should appear dim, medium, and bright.

    You can also change the size of the table. Making the size larger will give you finer control over the PWM values, but take up more memory. Making the table smaller will save memory at the expense of fewer graduations between zero and full power.
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-05-18 10:29
    It rather depends on the granularity of PWM you are prepared to accept and the frequency you want it to run at. You can do it with one cog but I'm not sure what frequency you can get in spin.

    If you have a certain operating frequency and time period you can divide this time period up into parts, the size of the part dictates the resolution you have in your power control. So if you ran your leds at 1khz the time period would be 1ms and you could divide this into 100 time segments giving you 100 power setting.

    Your program has two loops one loops 100 times and inside that loop is a loop that last 1ms/100 you can get the loop to last a certain time by adding a waitcnt instruction at the end of it. In the loop, counters for each of the 22 leds are incremented and then depending on the power settings demanded by the user the new output for the 22 pins is created. Then after the waitcnt is complete the new output state is written to the pins.

    Its pretty basic stuff but coding it elegantly may be tricky.

    Graham
  • AnubisbotAnubisbot Posts: 112
    edited 2007-05-18 16:15
    Looks good, but what i still dont get is how to only use pin 1 to lets say 16 and the rest is totaly unafected like inputs or so.
    And the second part is that how do i change the value of each pin once it is running

    I use the IR spin for a remote control, and i got it so far to start a new cog with your pwm.spin, but how do i update them in the new cog

    Sorry for so manny questions...

    Anubis Bot
  • Dennis FerronDennis Ferron Posts: 480
    edited 2007-05-18 20:06
    In the example program I wrote, think of the array as a two dimensional table of bits (this table shows 3 pins and 4 periods):
      XYZ
    A 000
    B 000
    C 000
    D 000
    
    



    The rows (A, B, C, D) are points in time. The columns (X, Y, Z) are pins. So if you wanted to turn on just X without affecting Y and Z, the table would look like:

      XYZ
    A 100
    B 100
    C 100
    D 100
    
    



    You see, there are ones in the "X" column, but they don't affect Y or Z because those are different columns.

    Basically the program "precalculates" what the outputs should be at each point in time, and just plays the precalculated recording back very quickly. Like drawing a cartoon on the corners of book pages, and then flipping the pages to make the cartoon animate.
  • AnubisbotAnubisbot Posts: 112
    edited 2007-05-18 22:04
    I got that, but i dont get how i make my input pin 15 to stay a input, and 30 -31 to be able to debug. the pwm code changes the state.
  • Dennis FerronDennis Ferron Posts: 480
    edited 2007-05-18 22:10
    You might be able to make it work by specifying a range of pins in spin; instead of:

    dira := something

    it would be:

    dira[noparse][[/noparse]7..0] := something

    where 7 and 0 are whatever range of pins you want to set at once. If you have to have a gap in your range, you would need to do a shift, like this:

    dira[noparse][[/noparse]14..0] := something
    dira[noparse][[/noparse]23..16] := (something << 16)

    That skips pin 15. You have to shift 16 so that you get bits 16 through 23 of the value, instead of repeating the lower bits over again.
Sign In or Register to comment.