Shop OBEX P1 Docs P2 Docs Learn Events
C code to work with WS2812 NeoPixel LEDs - Page 3 — Parallax Forums

C code to work with WS2812 NeoPixel LEDs

135

Comments

  • David BetzDavid Betz Posts: 14,516
    edited 2014-09-28 15:01
    JonnyMac wrote: »
    My single-shot version has an execute() method that allows you to pass a pin # and array (via pointer) to use.

    My latest code (auto and single-shot) is available in ObEx (updated 28 SEP 14)
    -- http://obex.parallax.com/object/703

    Reminder: My code is Spin/PASM -- will need translating for those using C.
    I took a look at your single shot version a little closer and I guess it takes commands to send a single burst of colors to an LED chain and then just goes idle waiting for the next command. Is that correct? Did you make this change to allow a single COG to control multiple LED chains?
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-28 16:51
    0,255,0 is red. 255,0,0 is green so those two color codes are reversed. Can I change the header file so it works the way it is suppose to?

    Also, how do I light up the LED's one after the other and have the colors follow each LED instead of the LED going through each color and then going to the next LED?
  • David BetzDavid Betz Posts: 14,516
    edited 2014-09-28 16:59
    NWCCTV wrote: »
    0,255,0 is red. 255,0,0 is green so those two color codes are reversed. Can I change the header file so it works the way it is suppose to?

    Also, how do I light up the LED's one after the other and have the colors follow each LED instead of the LED going through each color and then going to the next LED?
    They are correct for the AdaFruit LED ring. You're certainly free to change yours to match your LEDs though. Maybe I should add a way to indicate which color mapping is in use but I should probably first look at updating to JonnyMac's latest code.
  • David BetzDavid Betz Posts: 14,516
    edited 2014-09-28 18:35
    I just moved the new color swapping code from JonnyMac's new version of his ws2812 driver to mine version and added an option to disable the R/G color swapping. I'll upload a new .zip file as soon as I build SimpleIDE so I can test the new library.
  • David BetzDavid Betz Posts: 14,516
    edited 2014-09-28 19:09
    NWCCTV,

    I just attached a new version to the top post of this thread. In this version, the ws2812_init function takes an additional parameter "swaprg" which can be set for SWAP_RG for the ws2812 and SWAP_NONE for the ws2811. Let me know if this fixes your color problems.

    Thanks,
    David
  • David BetzDavid Betz Posts: 14,516
    edited 2014-09-28 19:13
    By the way, I notice that running the code at the end of my demo that lights the full ring red, green, blue, and then white hangs my PropBOE and even does odd things when I try to reset it. My guess is that 16 LEDs at full white draws too much power. Maybe I need a separate power supply.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-28 19:45
    They are all working in order like I wanted but the first color is green so I do not think that is correct. However, as long as they are all working and changing colors it will be fine. For this one where do I "tune" the colors and if possible add more?
  • David BetzDavid Betz Posts: 14,516
    edited 2014-09-28 19:51
    NWCCTV wrote: »
    They are all working in order like I wanted but the first color is green so I do not think that is correct. However, as long as they are all working and changing colors it will be fine. For this one where do I "tune" the colors and if possible add more?
    You mean even with the new zip file I just posted you are getting green for COLOR(255, 0, 0)? Did you change the last parameter of the call to ws2812_init to SWAP_NONE?

    To get other colors you need to use different values for R, G, and B in the COLOR macro. Either just experiment with different values or use the color picker mentioned in post #59 to find the one you want.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-28 20:21
    Not sure what you mean. Attached is the code that shows up. Where is the color macro?
    #include <stdint.h>
    #include <propeller.h>
    #include "ws2812.h"
    
    
    #define LED_PIN 15
    #define LED_COUNT 16
    
    
    int main(void)
    {
    uint32_t colors[LED_COUNT];
    int cog;
    ws2812_clock_init();
    memset(colors, 0, sizeof(colors));
    if ((cog = ws2812_init(LED_PIN, colors, LED_COUNT, SWAP_RG)) < 0)
    return 1;
    for (;;) {
    ws2812_fill_wheel_continuous_dim(colors, LED_COUNT, LED_COUNT+5, 128, 100);
    //ws2812_fill_wheel_continuous(colors, LED_COUNT, LED_COUNT+5, 100);
    //ws2812_fill_wheel_dim(colors, LED_COUNT, 100, 128);
    ws2812_pause(1000);
    //ws2812_fill(colors, LED_COUNT, COLOR_BLACK);
    }
    cogstop(cog);
    return 0;
    }
    
  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-09-28 20:52
    The single-shot version does not automatically refresh the string. The application does this manually, and in the call to execute() specifies a pin and array pointer (-1 for internal buffer) to use. This allows one to control many strings connected to different IO pins. They can have their own buffers, or buffers can be shared. Note that for smooth color fades the application should call execute() on a regular interval.
    David Betz wrote: »
    What do you mean by "single shot"? How does it differ from your original version.
  • David BetzDavid Betz Posts: 14,516
    edited 2014-09-29 04:19
    NWCCTV wrote: »
    Not sure what you mean. Attached is the code that shows up. Where is the color macro?
    #include <stdint.h>
    #include <propeller.h>
    #include "ws2812.h"
    
    
    #define LED_PIN 15
    #define LED_COUNT 16
    
    
    int main(void)
    {
    uint32_t colors[LED_COUNT];
    int cog;
    ws2812_clock_init();
    memset(colors, 0, sizeof(colors));
    if ((cog = ws2812_init(LED_PIN, colors, LED_COUNT, [COLOR="#FF0000"]SWAP_NONE[/COLOR])) < 0)
    return 1;
    for (;;) {
    ws2812_fill_wheel_continuous_dim(colors, LED_COUNT, LED_COUNT+5, 128, 100);
    //ws2812_fill_wheel_continuous(colors, LED_COUNT, LED_COUNT+5, 100);
    //ws2812_fill_wheel_dim(colors, LED_COUNT, 100, 128);
    ws2812_pause(1000);
    //ws2812_fill(colors, LED_COUNT, COLOR_BLACK);
    }
    cogstop(cog);
    return 0;
    }
    

    Change your code as shown above and you should end up with R, G, B instead of G, R, B.
  • David BetzDavid Betz Posts: 14,516
    edited 2014-09-29 04:22
    JonnyMac wrote: »
    The single-shot version does not automatically refresh the string. The application does this manually, and in the call to execute() specifies a pin and array pointer (-1 for internal buffer) to use. This allows one to control many strings connected to different IO pins. They can have their own buffers, or buffers can be shared. Note that for smooth color fades the application should call execute() on a regular interval.
    I wonder if this could be enhanced by just remembering all of the sets the parameters passed to the COG on the execute call and cycling through them. You'd then need a stop_execution call to remove one of the sets of parameters from the list but at least you wouldn't have to call execute at regular intervals. Seems like it would be pretty easy to do. Maybe I'll try it later.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-29 10:24
    When I run the code in post# 72 I get the error "libws2812.c:16:1: error: too many arguments to function 'ws2812_init'ws2812.h:33:5: note: declared here
    Done. Build Failed!"
  • David BetzDavid Betz Posts: 14,516
    edited 2014-09-29 10:33
    NWCCTV wrote: »
    When I run the code in post# 72 I get the error "libws2812.c:16:1: error: too many arguments to function 'ws2812_init'ws2812.h:33:5: note: declared here
    Done. Build Failed!"
    You need to install the new library that I added to the top post. I added an extra parameter to allow you to use the normal R, G, B order for colors instead of having R and G reversed for your LEDs.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-29 10:43
    You mean by unzipping? I have done that with no luck. The program within the zip file works but not what you posted above.
  • David BetzDavid Betz Posts: 14,516
    edited 2014-09-29 10:49
    NWCCTV wrote: »
    Where can I download PropGCC from?
    I'm not sure what's going wrong. It looks like ws2812.h in that zip file has the added parameter. Are you sure you're unzipping in the right location? SimpleIDE seems to create zip files that don't include a separate directory for the library but it seems to be the convention that a user library should be in a separate directory under "My Libraries". It's a bit of a pain to install the zip file since it requires manually creating the library directory.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-29 10:51
    I am unzipping to the Learn/My Projects/RGB folder.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-29 10:58
    I got it. I re downloaded the zip file and it works now. However, My reds are more orange and greens are more aqua. Blue does not even come up.
  • David BetzDavid Betz Posts: 14,516
    edited 2014-09-29 11:05
    NWCCTV wrote: »
    I got it. I re downloaded the zip file and it works now. However, My reds are more orange and greens are more aqua. Blue does not even come up.
    I'm not sure what's going on. I suppose I need to order some of those devices because it seems to work okay with my AdaFruit LED ring. Sorry you're having trouble.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-29 11:16
    So the attached code works well. However, I would like for each LED to light one at a time instead of all at the same time. Ideas? I tried the other commented out codes but none of them seemed to work properly.
    #include <stdint.h>
    #include <propeller.h>
    #include "ws2812.h"
    
    #define LED_PIN 15
    #define LED_COUNT 16
    
    int main(void)
    {
    uint32_t colors[LED_COUNT];
    int cog;
    ws2812_clock_init();
    memset(colors, 0, sizeof(colors));
    if ((cog = ws2812_init(LED_PIN, colors, LED_COUNT, SWAP_NONE)) < 0)
    return 1;
    for (;;) {
    //ws2812_fill_wheel_continuous_dim(colors, LED_COUNT, LED_COUNT+5, 128, 100);
    //ws2812_fill_wheel_continuous(colors, LED_COUNT, LED_COUNT+5, 100);
    //ws2812_fill_wheel_dim(colors, LED_COUNT, 100, 128);
    ws2812_pause(500);
    ws2812_fill(colors, LED_COUNT, COLOR_WHITE);
    ws2812_pause(500);
    ws2812_fill(colors, LED_COUNT, COLOR_RED);
    ws2812_pause(500);
    ws2812_fill(colors, LED_COUNT, COLOR_GREEN);
    ws2812_pause(500);
    ws2812_fill(colors, LED_COUNT, COLOR_BLUE);
    }
    cogstop(cog);
    return 0;
    }
    
  • David BetzDavid Betz Posts: 14,516
    edited 2014-09-29 11:21
    NWCCTV wrote: »
    So the attached code works well. However, I would like for each LED to light one at a time instead of all at the same time. Ideas? I tried the other commented out codes but none of them seemed to work properly.
    #include <stdint.h>
    #include <propeller.h>
    #include "ws2812.h"
    
    #define LED_PIN 15
    #define LED_COUNT 16
    
    int main(void)
    {
    uint32_t colors[LED_COUNT];
    int cog;
    ws2812_clock_init();
    memset(colors, 0, sizeof(colors));
    if ((cog = ws2812_init(LED_PIN, colors, LED_COUNT, SWAP_NONE)) < 0)
    return 1;
    for (;;) {
    //ws2812_fill_wheel_continuous_dim(colors, LED_COUNT, LED_COUNT+5, 128, 100);
    //ws2812_fill_wheel_continuous(colors, LED_COUNT, LED_COUNT+5, 100);
    //ws2812_fill_wheel_dim(colors, LED_COUNT, 100, 128);
    ws2812_pause(500);
    ws2812_fill(colors, LED_COUNT, COLOR_WHITE);
    ws2812_pause(500);
    ws2812_fill(colors, LED_COUNT, COLOR_RED);
    ws2812_pause(500);
    ws2812_fill(colors, LED_COUNT, COLOR_GREEN);
    ws2812_pause(500);
    ws2812_fill(colors, LED_COUNT, COLOR_BLUE);
    }
    cogstop(cog);
    return 0;
    }
    
    I assume you're indenting the code inside your for and if statements. If so, for some reason that doesn't get reflected in the code you post making it difficult to read. Maybe you need to convert tabs to spaces before posting or something like that? I actually always expand tabs to spaces because of problems like this and also because not everyone has their tab settings set the same.

    In any case, I'm trying to understand the effect you're after. Do you mean that you want one of your LEDs to cycle through WHITE, RED, GREEN, and BLUE and then go black and have the animation switch to the next LED which will then go through the same cycle?
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-29 11:38
    Yes, I am indenting my code. I had this problem before and need to fix it again. As for effect, I want LED 1 to start with a color and then that color to go to LED 2, then 3 and so on and LED 1 would start the next color. Such as a "Chasing" effect.
  • David BetzDavid Betz Posts: 14,516
    edited 2014-09-29 11:46
    NWCCTV wrote: »
    Yes, I am indenting my code. I had this problem before and need to fix it again. As for effect, I want LED 1 to start with a color and then that color to go to LED 2, then 3 and so on and LED 1 would start the next color. Such as a "Chasing" effect.
    Okay, I think I understand. So the second color would not start until the first color had traveled through all of the LEDs, right? So, assuming you have a chain of 4 LEDs, you would have a sequence like this:

    LED0 - red
    LED1 - red
    LED2 - red
    LED3 - red
    LED0 - green
    LED1 - green
    LED2 - green
    LED3 - green
    LED0 - blue
    LED1 - blue
    LED2 - blue
    LED3 - blue
    LED0 - red

    and so on. You would never have more than one LED lit at a time.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-29 12:11
    No. Sorry. Color starts on LED 1, then 2, then 3. When first color goes to LED 2 then second color would light on LED 1. So first would be red on LED 1, then when LED 2 was red, LED 1 would be green. When LED 3 red, LED 2 is Green and LED 1 is blue and so on. I do however like the ease of adding colors to the current code.
  • David BetzDavid Betz Posts: 14,516
    edited 2014-09-29 12:21
    NWCCTV wrote: »
    No. Sorry. Color starts on LED 1, then 2, then 3. When first color goes to LED 2 then second color would light on LED 1. So first would be red on LED 1, then when LED 2 was red, LED 1 would be green. When LED 3 red, LED 2 is Green and LED 1 is blue and so on. I do however like the ease of adding colors to the current code.
    Okay, I see. So eventually all of the LEDs will be lit. I can take a look at this later or maybe tomorrow evening.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-29 12:35
    Exactly. Like a chasing effect. I want to be able to add or remove colors and also the amount of LED's will change. Thanks for the help.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-29 19:46
    This code is suppose to loop continuously, correct? I am using a separate 12V Wall wart connected to a 3.3/5V Bread Board power module set to 5V and when running only 2 or 3 LED's it stops after 2 or 3 loops.
  • David BetzDavid Betz Posts: 14,516
    edited 2014-09-29 19:54
    NWCCTV wrote: »
    This code is suppose to loop continuously, correct? I am using a separate 12V Wall wart connected to a 3.3/5V Bread Board power module set to 5V and when running only 2 or 3 LED's it stops after 2 or 3 loops.
    The driver just sets the color on each LED corresponding to the values in the array. In other words, colors[0] controls the color of the first LED, colors[1] controls the color of the second LED, etc. The rest of the code just sets the color values in the colors array to achieve different patterns. I used to use separate LEDs daisy chained together but had some problems controlling a chain of LEDs probably because of the length of the wires between them. I ended up buying the AdaFruit LED ring and LED strip and they seemed to work okay. Can you describe your setup? I know you said you were using Pololu LEDs. How many do you have in your chain?
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-09-29 20:23
    I have 6 in the chain total but I cut it back to 3 and then to 2 trying to troubleshoot the issue. Next I am going to do 1 and see if that helps. I have a 10uf Cap on + and -. Ron suggested a 22uf in the setup in another thread but I only have a 10 right now. He also used a 10k resistor on the prop DIN but I removed that because it seemed to be causing issues. I am waiting on my Cap delivery from eBay but may go to the shack and get the correct cap to see if that is the issue.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2014-10-10 18:22
    I am once again working on this and I can not seem to figure out why the loop stops after 5 or 6 rotations. I tried a 5V 1.5A wall wart and it still does not work correctly no matter if I have 6 or 2 or 3 LED's connected. I have tried with and without a 10 uf Cap and with and without various resistors. I also tried a Demo Board instead of the BOE board with no luck.
Sign In or Register to comment.