Shop OBEX P1 Docs P2 Docs Learn Events
Vixen and the Propeller Christmas lights controller — Parallax Forums

Vixen and the Propeller Christmas lights controller

turbosupraturbosupra Posts: 1,088
edited 2011-11-10 08:09 in Propeller 1
I have written a Propeller plugin for the Vixen Christmas lights software.

I am able to control the LED's on my propeller proto board serially, in real time at 100mS resolution, so it receives 10 "ons" or "offs" or a combination of the two each second telling the LED's whether to be illuminated or not.

I am however not sure how to control the PWM portion of it, in case someone wanted to dim them (I hope I'm over complicating it). I'm pretty sure it'd be easy with 32 cogs :) , but I'm not sure how to with 8. Does anyone have any ideas on how to do this? Take the code example below, how would I incorporate it to fade the LED's if I have an intensity value range I can pass of 0-255? So if I send a value of pin16=1 and pin16On is set to 1, how would I handle a PWM of say 128 (50%) in the time that it is waiting for another serial value command/setting for pin16 (which is currently a 100mS)? All of the methods I can think of (waitcnt) (repeat loops), would hold up the cog, so that it would not be able to do this for the other 27 or 28 pins simultaneously.

I'm using a clock speed of 80mhz in case that matters. Thanks for reading.

   if (pin16On == 1)
      outa[c_pin16] := 1         
    if (pin16On == 0)
      outa[c_pin16] := 0

    if (pin17On == 1)
      outa[c_pin17] := 1
    if (pin17On == 0)
      outa[c_pin17] := 0

    if (pin18On == 1)
      outa[c_pin18] := 1
    if (pin18On == 0)
      outa[c_pin18] := 0

    if (pin19On == 1)
      outa[c_pin19] := 1
    if (pin19On == 0)
      outa[c_pin19] := 0         

    if (pin20On == 1)
      outa[c_pin20] := 1
    if (pin20On == 0)
      outa[c_pin20] := 0 



Thinking out loud, maybe something like ...
    if (pin16On == 1) AND (cnt < (cnt + cntCyclesToBeOn))  ' formula would be something like ((clkfreq/resolution of 10 times per second)) = cycles on, then    ((8,000,000/1000) = 8000)   then 8000 * (pwm/255) = cntCyclesToBeOn and (255-pwm/255) = cntCyclesToBeOff
      outa[c_pin16] := 1         
    if (pin16On == 0)
      outa[c_pin16] := 0

«1

Comments

  • LawsonLawson Posts: 870
    edited 2011-11-07 13:45
    Something like the bit of code below would work if it was run in a tight loop (ie greater than 1000Hz loop rate) and somewhat random PWM was fine. (On_time_1 is a number from 0 to 255 )
    if On_time_1 => (CNT & $FF)
      OUTA(pin_1) := 1
    else
      OUTA(pin_1) := 0
    

    Lawson
  • JonnyMacJonnyMac Posts: 9,198
    edited 2011-11-07 14:08
    What does your packet information look like now? How does the Propeller know how to align the start of the packet with your 1st channel? It would be useful to see the whole program.

    I know Vixen pretty well because KC Oaks is a friend of mine and has written drivers for me (I'm not a .NET programmer). If you're only updating every 100ms you could easily use another cog to monitor the idle time of the serial line; when a proper idle period is detected you could enable serial input. I did this a long time ago with the SX and a driver KC wrote for me. That way you're just expecting N values every 100ms; you should have plenty of time between packets to detect idle time. Just take the packet values and pass them to your dimmer object. I've attached a simple one that I use for LEDs. It will handle eight; use multiple copies if you need more channels.
  • Kevin McCulloughKevin McCullough Posts: 62
    edited 2011-11-07 14:23
    Haven't used this object yet, but it sounds like it would work well in your application for controlling up to 32 PWM channels using only 1 cog: http://obex.parallax.com/objects/467/

    Good luck!
  • turbosupraturbosupra Posts: 1,088
    edited 2011-11-07 15:50
    Hi Jon,

    Thanks for the reply. I have the plugin sending a line of code every time a new resolution period is passed through, so if we use pin16 as an example, it says pin16=1 for each 100ms block that channel 16 is filled in. The prop code segments the delimiter (the equals sign) and then sets outa16 := 1. If the next resolution block comes along and channel 16 is empty inside of Vixen, it sends a pin16=0, the prop parses the information and turns the pin off. If you want an alpha copy of my spin code, I can post that, just let me know.


    JonnyMac wrote: »
    What does your packet information look like now? How does the Propeller know how to align the start of the packet with your 1st channel? It would be useful to see the whole program.

    I know Vixen pretty well because KC Oaks is a friend of mine and has written drivers for me (I'm not a .NET programmer). If you're only updating every 100ms you could easily use another cog to monitor the idle time of the serial line; when a proper idle period is detected you could enable serial input. I did this a long time ago with the SX and a driver KC wrote for me. That way you're just expecting N values every 100ms; you should have plenty of time between packets to detect idle time. Just take the packet values and pass them to your dimmer object. I've attached a simple one that I use for LEDs. It will handle eight; use multiple copies if you need more channels.
  • turbosupraturbosupra Posts: 1,088
    edited 2011-11-07 15:52
    Hi Lawson,

    Thanks for the reply. Can you tell me what $FF signifies, I have see that before and a google search did not yield much.

    Lawson wrote: »
    Something like the bit of code below would work if it was run in a tight loop (ie greater than 1000Hz loop rate) and somewhat random PWM was fine. (On_time_1 is a number from 0 to 255 )
    if On_time_1 => (CNT & $FF)
      OUTA(pin_1) := 1
    else
      OUTA(pin_1) := 0
    

    Lawson
  • Kevin McCulloughKevin McCullough Posts: 62
    edited 2011-11-07 16:38
    The dollar sign ($) in $FF specifies hex. No prefix means the number is decimal, and a percent (%) prefix means binary.
  • Adam WieslerAdam Wiesler Posts: 81
    edited 2011-11-07 17:22
    Hopefully this hasn't already been mentioned, but if you are planning on using this to control AC lights like christmas LEDs or the like, you need to account for the zero cross of the relays to PWM. This is a basic intro: http://www.parallax.com/Portals/0/Downloads/docs/cols/nv/vol8/col/nv146.pdf

    I have been using the prop for x-mas lights for the past 3 years, so if anybody wants it, I might be able to dig up the code I've used.

    EDIT: I just found my dad's code/writeup here: http://www.parallax.com/tabid/711/Default.aspx
  • JonnyMacJonnyMac Posts: 9,198
    edited 2011-11-07 20:50
    Thanks for the reply. I have the plugin sending a line of code every time a new resolution period is passed through, so if we use pin16 as an example, it says pin16=1 for each 100ms block that channel 16 is filled in. The prop code segments the delimiter (the equals sign) and then sets outa16 := 1. If the next resolution block comes along and channel 16 is empty inside of Vixen, it sends a pin16=0, the prop parses the information and turns the pin off.

    Wow... that's very inefficient; you're sending, what?, seven bytes to control a single channel? Then you have to parse all that on the Propeller end?

    There is a driver called Generic Serial (KC added this at my request a few years ago) that just sends the channel values (0 to 255) each event period. If you have eight channels it sends eight bytes every period; if you have 16 channels it sends 16 bytes, etc. You can also append a header and trail with a footer, but I don't use these often.

    What I do is look for the serial line being inactive between events. In the attached demo -- which is happily running on my QuickStart board (see note at end) -- I look for a 5ms idle period on the serial input. Using 57.6K out and a 25ms event period (for smooth fades) Vixen can transmit about 104 bytes in 20ms; probably more channels than you want. And, as indicated above, this is LED dimming. AC lamp dimming requires special circuitry and more complicated software (my article, referenced above, shows how to do it with the SX).

    Note: My version of Vixen (2.5.0.8) only supports COM1 - COM4 with the Generic Serial driver. I used the Advanced properties dialog of the port to reassign my QuickStart board to COM1.
  • turbosupraturbosupra Posts: 1,088
    edited 2011-11-08 05:44
    Thanks Kevin.
    The dollar sign ($) in $FF specifies hex. No prefix means the number is decimal, and a percent (%) prefix means binary.
  • turbosupraturbosupra Posts: 1,088
    edited 2011-11-08 05:45
    Thanks Adam, I will study and learn from this

    Hopefully this hasn't already been mentioned, but if you are planning on using this to control AC lights like christmas LEDs or the like, you need to account for the zero cross of the relays to PWM. This is a basic intro: http://www.parallax.com/Portals/0/Downloads/docs/cols/nv/vol8/col/nv146.pdf

    I have been using the prop for x-mas lights for the past 3 years, so if anybody wants it, I might be able to dig up the code I've used.

    EDIT: I just found my dad's code/writeup here: http://www.parallax.com/tabid/711/Default.aspx
  • turbosupraturbosupra Posts: 1,088
    edited 2011-11-08 06:00
    Hi Jon,

    It probably is inefficient, although I have not run into any bottle necks yet. I did see the generic serial, but since there was no documentation that I could find on it, I wrote my own. I like it because it makes sense to me, but I will try to convert over to something more efficient. I'm using 8N1 and 115200, when do you expect I would see a bottleneck at? It was going to be more inefficient at pin1=1|255, so I'm just trying to gauge this. I really liked using the delimiter concept.

    So if vixen had channels 1-8 set to 100% on for the first event period, the generic serial transmits 8 "255's" in binary and then pauses until the next event period?

    JonnyMac wrote: »
    Wow... that's very inefficient; you're sending, what?, seven bytes to control a single channel? Then you have to parse all that on the Propeller end?

    There is a driver called Generic Serial (KC added this at my request a few years ago) that just sends the channel values (0 to 255) each event period. If you have eight channels it sends eight bytes every period; if you have 16 channels it sends 16 bytes, etc. You can also append a header and trail with a footer, but I don't use these often.

    What I do is look for the serial line being inactive between events. In the attached demo -- which is happily running on my QuickStart board (see note at end) -- I look for a 5ms idle period on the serial input. Using 57.6K out and a 25ms event period (for smooth fades) Vixen can transmit about 104 bytes in 20ms; probably more channels than you want. And, as indicated above, this is LED dimming. AC lamp dimming requires special circuitry and more complicated software (my article, referenced above, shows how to do it with the SX).

    Note: My version of Vixen (2.5.0.8) only supports COM1 - COM4 with the Generic Serial driver. I used the Advanced properties dialog of the port to reassign my QuickStart board to COM1.
  • JonnyMacJonnyMac Posts: 9,198
    edited 2011-11-08 06:31
    So if vixen had channels 1-8 set to 100% on for the first event period, the generic serial transmits 8 "255's" in binary and then pauses until the next event period?

    Yes; it's that easy. If you look at the demo I posted I use the .rxtime() method to wait for the idle period and then grab the next eight bytes (channel values) and move them directly to the dimming object. You get a lighting controller is very few lines of code -- no parsing or decoding of the data is necessary.
    pub main | c, idx 
    
      serial.start(RX1, TX1, %0000, 57_600)                         ' for Vixen Generic Serial driver
      leds1.start(8, LED1)                                          ' LED dimmer(s)
      pause(1)
    
      repeat
        repeat
          c := serial.rxtime(5)                                     ' wait for 5ms idle period
        until (c == -1)
    
        repeat idx from 0 to 7                                      ' rx eight channel levels
          leds1.set(idx, serial.rx)                                 ' move directly to dimmer
    

    I really liked using the delimiter concept.

    Of course that works, but so does using the serial idle line period as a start of frame marker. Note that this is not an original idea by me; MODBUS RTU uses this scheme for industrial data coms. The more channels you have, the more efficient you want your code. And for me, it's important to have a quick event period so that you can do smooth fading; this means even less time to do parsing/data converting.
  • turbosupraturbosupra Posts: 1,088
    edited 2011-11-08 06:57
    Yes, your code worked flawlessly, thank you for that. I thought my limitation was the serial communication of 115200 (far surpassed by my PC's and my prop's clock speed), but you have given me a new perspective and I like the efficiency.

    Where can I find more information about the hardware you used? (if you don't mind sharing) . I was also thinking about Darlingtons and SSR's and being this was the first year for it (if I can even make it by then), I was going to have it all on a breadboard.
  • JonnyMacJonnyMac Posts: 9,198
    edited 2011-11-08 07:12
    Do you want to dim LEDs or AC lamps?
  • turbosupraturbosupra Posts: 1,088
    edited 2011-11-08 07:20
    Well this is a gift for my Dad, and since it is a surprise it would be nice to give him the option of either ... but maybe I should be asking you what you think and then steering him in that direction.

    He has had the following C7 bulbs on his house for 35 years and I think this would be a nice surprise/update. I also do not think these bulbs would fair well with cycling.

    christmasbulb1.png
  • JonnyMacJonnyMac Posts: 9,198
    edited 2011-11-08 07:52
    For AC lamps you have to use phase angle dimming which means that the dimming driver has to monitor the zero-cross point of the AC line and then switch the triacs at some point after that to control brightness (the later the on point, the less bright the output). I've done it with the SX and am in the process of doing it with the Propeller, but until my product (EFX-TEK FC-4+) is ready I can't release my Propeller phase angle code; perhaps someone else has posted a version elsewhere.

    To understand phase angle dimming you can read my article (yes, I am the actor formerly known as Jon Williams), which was referenced earlier:
    -- http://www.parallax.com/Portals/0/Downloads/docs/cols/nv/vol8/col/nv146.pdf

    It's actually easier to do phase angle dimming in the Propeller because the dimmer is running in its own cog (versus using an interrupt). In my version, that cog even times the line frequency when it first starts so that it can work in 50 Hz and 60 Hz systems. Again, once the FC-4+ has been fully tested and is ready for release I will release my phase angle dimming object.

    Now.... if you can live with LEDs, the TIP120 Darlington will switch up to 5A at up to 60V. All you need is a 220-Ohm resistor between the Propeller output pin and the base of the TIP120. The emitter connects to ground and the collector to the cathode side of your LED circuit (with proper current limiter, of course).
  • turbosupraturbosupra Posts: 1,088
    edited 2011-11-08 08:47
    Thanks Jon.

    I believe the phase angle based dimming is probably over my head at this point, but definitely something I'd like to learn when you release your object.

    I just bought a bunch of TIP120's, I think that will be a great start for the first year and allow me to get something going rather quickly I hope, thank you for that.

    What are the advantages of the AC bulb usage ... brightness?
    JonnyMac wrote: »
    For AC lamps you have to use phase angle dimming which means that the dimming driver has to monitor the zero-cross point of the AC line and then switch the triacs at some point after that to control brightness (the later the on point, the less bright the output). I've done it with the SX and am in the process of doing it with the Propeller, but until my product (EFX-TEK FC-4+) is ready I can't release my Propeller phase angle code; perhaps someone else has posted a version elsewhere.

    To understand phase angle dimming you can read my article (yes, I am the actor formerly known as Jon Williams), which was referenced earlier:
    -- http://www.parallax.com/Portals/0/Downloads/docs/cols/nv/vol8/col/nv146.pdf

    It's actually easier to do phase angle dimming in the Propeller because the dimmer is running in its own cog (versus using an interrupt). In my version, that cog even times the line frequency when it first starts so that it can work in 50 Hz and 60 Hz systems. Again, once the FC-4+ has been fully tested and is ready for release I will release my phase angle dimming object.

    Now.... if you can live with LEDs, the TIP120 Darlington will switch up to 5A at up to 60V. All you need is a 220-Ohm resistor between the Propeller output pin and the base of the TIP120. The emitter connects to ground and the collector to the cathode side of your LED circuit (with proper current limiter, of course).
  • Shawn LoweShawn Lowe Posts: 635
    edited 2011-11-08 09:07
    turbosupra wrote: »
    Thanks Jon.

    I believe the phase angle based dimming is probably over my head at this point, but definitely something I'd like to learn when you release your object.

    I just bought a bunch of TIP120's, I think that will be a great start for the first year and allow me to get something going rather quickly I hope, thank you for that.

    What are the advantages of the AC bulb usage ... brightness?

    Maybe in the old days, but with modern LED's I wouldn't think brightness would be a factor.
  • JonnyMacJonnyMac Posts: 9,198
    edited 2011-11-08 09:40
    As Shawn points out there are many more options. Have a look at www.superbrightleds.com. In my opinion, their customer service isn't great, but they do have good products and I frequently purchase (or direct purchases) there for my "Hollywood" lighting projects.

    Here's the latest:

    294044_231658996897138_100001591174583_668685_1949914471_n.jpg

    This is Steve Wang and his crew in front of the Tyrael statue for BlizzCon (I'm not in that photo because I was on my way to a location shoot -- also using Propellers for special FX). The lit portion of Tyrael are eight tendrils that eminate from his back; a couple nearly 20 feet long. Mike Deak (tall guy next to Steve) and I figured out that we needed 1/2" spacing between the LEDs and the diffusion material, and with all his years in the FX business Mike found a way to create that using what I call "calamari rings" of clear vinyl hose (from an aquarium store). The core of the tendrils were wrapped with LED tape from SuperBrightLEDs -- up to seven rolls per tendril. We brought control wires for each roll down through the main (support) tendrils and into the base to three 4-channel DMX controllers (each with their own 12V, 25A supply -- also from SuperBrightLEDs.com). There's a lot of wires and connectors in this dude....

    The "master" controller for the lighting was my Propeller Platform (classic version) and DMX I/O board (both are available from GadgetGangster.com). I do a lot of DMX work with the Propeller so this was pretty easy. The tendrils have an electric shimmer to them and then, every 10 to 15 seconds or so (random), there is a "burst" pulse that starts at his back and moves very quickly to the end of each tendril. It's pretty cool, even if I do say so myself having coded it. The folks at Blizzard loved it -- even though the "burst" thing is not in the game they allowed us to keep it in the display.

    LEDs are fun. Pick up the November issue of Nuts & Volts magazine to read about the dimmer object I've used above and another cool lighting project (for the Red-5 game, FireFall) I did with Steve and his immensely talented crew.

    This is the FireFall display for Red-5 (we built two of these). The characters use Propeller Platforms and TIP125 boards, the audio in the "Thumper" is from a Propeller-powered AP-16+ (that I co-designed and coded):

    301570_10150299732578697_668003696_7874175_1158986995_n.jpg

    This is Jim Raynor from Starcraft II (also for Blizzard) -- my first Propeller-powered prop lighting project for Steve. On the back are "engines" that use RGB LEDs to simulate warm-up and running. The Propeller makes coding these kinds of projects really easy.

    181681407.jpg?key=7681024&Expires=1332955044&Key-Pair-Id=APKAIYVGSUJFNRFZBBTA&Signature=NZQv78yIAYK6oCBTw1~qUoUIMMiIWvQeur4CgQrGZVZ6WFJu3A0rzATSbZk5hmUFoG1tL6YdWWDGzkdHxitfMXwdHacM-EF67FzaX8NEZZ-Le3IpwIP7kaD7hU8Ns4yZSNYlc-MzZ4A5CUWnjGoQx2DSrEXPAlf3bfoEnZmDjbM_

    67714_461597063696_668003696_5474465_4810195_n.jpg


    See... there's more to "Hollywood" than whiney, A-list actors! ;)
  • JonnyMacJonnyMac Posts: 9,198
    edited 2011-11-08 10:07
    This article:
    -- http://www.parallax.com/Portals/0/Downloads/docs/cols/nv/prop/col/nvp9.pdf

    ...describes the 12-channel TIP125 (high side drivers as some RGB LEDs are common-cathode only) board that I mentioned above and also shows how to decode the Renard protocol -- popular with many Christmas lighting enthusiasts -- with the Propeller. You'll see that I used Vixen in the article to test my protocol engine.
  • DynamoBenDynamoBen Posts: 366
    edited 2011-11-08 11:02
    Just over a year ago I designed a controller to do just what you are describing, dim both DC lights and AC. The project is open source and you are welcome to use as much or as little of it as you like. There are two flavors, DMX and Ethernet. The Ethernet side runs sACN but both interfaces are supported by Vixen.

    Project schematics, and code: http://code.google.com/p/propcontroller/
    Project Description (and forum): http://doityourselfchristmas.com/forums/showthread.php?12334-NEW-PropController-Project

    For the DC side check out the BAM driver, it avoids PWM and instead uses Bit Angle Modulation. It's a work in progress but should get you going. For the AC side I use a modified version of the Prop128 code, check out the AC channel driver code (the code drives 32 dimmer output via shift registers, check out the schematic for details).
  • turbosupraturbosupra Posts: 1,088
    edited 2011-11-08 15:34
    Wow you all are far beyond my capabilities :) thank you for the responses!

    I will be reading a lot to even conceptualize what you've done. I'm guessing that as long as I stay below 5A in each of my LED channel strings, I'll be good to go? I'll probably do some shopping tomorrow at superbrightleds while reading up on both projects
  • turbosupraturbosupra Posts: 1,088
    edited 2011-11-08 15:44
    This site is awesome, thank you both!

    So it looks like they even have direct replacement for the C7 bulb base, lol! http://www.superbrightleds.com/cgi-bin/store/index.cgi?action=DispPage&Page2Disp=%2Fspecs%2Fc7.htm#photos

    It doesn't give an amperage rating, but it appears that each replacement LED C7 is less than 0.00833 amps based on volts/watts. So I could have 120 of them before drawing an entire amp. This is great if it is correct.
  • JonnyMacJonnyMac Posts: 9,198
    edited 2011-11-08 15:55
    So it looks like they even have direct replacement for the C7 bulb base, lol! http://www.superbrightleds.com/cgi-b...Fc7.htm#photos

    That "bulb" is designed for a 120V system so it probably won't work with a DC dimmer.
  • turbosupraturbosupra Posts: 1,088
    edited 2011-11-08 17:19
    I thought since it was an LED (3 actually) that it would, but you are probably right, I never thought of it being an AC LED.
  • JonnyMacJonnyMac Posts: 9,198
    edited 2011-11-08 17:49
    Internally it probably has a full-wave rectifier and resistor that is setup for the line voltage. They do have thread in 12v LEDs on the site, but I don't know if they'll fit the sockets you have or are suitable for outdoor use.
  • DynamoBenDynamoBen Posts: 366
    edited 2011-11-08 18:09
    turbosupra wrote: »
    I thought since it was an LED (3 actually) that it would, but you are probably right, I never thought of it being an AC LED.

    JonnyMac is correct the other thing to consider is SCRs need a decent sized load to work correctly. If they are loaded to light they won't dim properly, so if you use these in place of an incandescent be on the look out for this. BTW a quick way around this problem is to add an incandescent bulb/fixture as a "ghost load" somewhere out of sight.

    Also if you live in an area that gets snow incandescent bulbs will quickly melt the snow away, LEDs won't.
  • turbosupraturbosupra Posts: 1,088
    edited 2011-11-08 19:43
    It looks like I will have to scrap the replacement bulb idea, or see if I can get DynamoBen's AC object working in my application.

    I live in MD, so there is plenty of snow. I'd have to take a broom to the snow I guess : ) .

    Jon, what is the theory behind the phase angle dimming. Do you scale the "on" time based on the phase angle and then use an extra piece of hardware to compensate for the crossover?
  • DynamoBenDynamoBen Posts: 366
    edited 2011-11-08 19:53
    turbosupra wrote: »
    Jon, what is the theory behind the phase angle dimming. Do you scale the "on" time based on the phase angle and then use an extra piece of hardware to compensate for the crossover?

    My channel object is doing phase angle dimming (forward phase to be exact). A zero cross sense tells the prop when zero is reached. Once you know that then you can set a timer to turn on the SCR based on how bright you want the light. Go here for some more technical details on this technique.
  • turbosupraturbosupra Posts: 1,088
    edited 2011-11-08 20:20
    That makes sense, thank you. So with each cycle the amount of current is modulated based on phase angle, starting at a certain degree which represents on time, which depends on the intensity?

    I guess resolution is never an issue because the human eye can't see much past 60hz anyway?

    I'm looking at your code and I've never done anything with a DAT portion, so it make take me a while to figure out exactly how it works, thanks for linking to that!



    DynamoBen wrote: »
    My channel object is doing phase angle dimming (forward phase to be exact). A zero cross sense tells the prop when zero is reached. Once you know that then you can set a timer to turn on the SCR based on how bright you want the light. Go here for some more technical details on this technique.
Sign In or Register to comment.