Tutorial on Programming the NeoPixel (WS2812) RGB LEDs and Equipment Giveaway!

NeoPixel

In this episode Shahriar takes a close look at programming the popular NeoPixel RGB LEDs using a PIC microcontroller and C-language. A close-up of the NeoPixel (WS2812) LED is shown with attention to identifying various semiconductor elements inside the package. The principle operation of the LED is the described along with a detailed explanation of the pins and the one-wire communication protocol.

A simple evaluation board for the PIC18F4550 is used to drive a circular array of 60 NeoPixel LEDs from Adafruit. After presenting the difficulties of providing an accurate pulse-shape using the C-language, the measured waveform is shown on a Tektronix MDO4000B. Finally, the code for a circular color rotating pattern is presented and demoed. The code for the experiment can be downloaded here.

There is also equipment giveaway! A TPI Scope Plus 440 and a Tektronix TDS2232 are being given away at no charge! Please leave a comment on the video or on the website. You must be a resident of the USA to receive the giveaway. A winner will be chosen at a later date and notified via email.

65 comments

  1. Dirk de Boer says:

    awesome guide but im having a problem. im porting the code to a tiva c launchpad but need to get the code for the bit test function as thats the only problem im having with it.

  2. Joe Kreidler says:

    Thank you for this video. Your observation about the bit waveform is extremely helpful and will save me time!!!

  3. Michel Jasmin says:

    Thank you for the tutorial. I’ve used your technique to make it work with PicBASIC on a PIC18F25K22 @40MHz:

    http://youtu.be/Fnwh4Fp2dBs

    More infos: http://www.picbasic.co.uk/forum/showthread.php?t=19408&p=128453#post128453

  4. matin says:

    سلام.
    ای کاش امکان ارسال این اسیلوسکوپ ها به ایران هم بود. متاسفانه به دلیل افزایش قیمت دلار و تحریم ها در ایران خرید اسکوپ برای یک دانشجو بیشتر شبیه رویاست…

  5. hans says:

    Hi,

    I hope it’s not to late but i would like to participate on the giveaway. I’m a college student who uses a 6$ multimeter for everything. I’m dreaming of a osilascope or something to measure frequencies.

  6. Kevin R says:

    Perfect I was just looking in to playing around with a PIC controller and was thinking if I could use it to drive rgb pixels. Now if we could get the ring in 12″ circle that would be awesome.

  7. domdomgin@yahoo.com says:

    do u still have the 440 plus oscilloscope..thank you..

  8. JohnO says:

    I enjoyed your video. I went through pretty much the same thing and it’s nice to see a good explanation of what it takes to get hardware working together.

    On the software side, you left a little fairly low-hanging fruit on the tree — try this:

    // PIC16F1459 — at 48 MHz (12 MIPS) because that’s what I had handy.
    // MPLABX v. 2.0
    // Microchip XC8 v. 1.30 – free mode

    #define NEOPIXEL_PIN PORTBbits.RB7

    //
    //
    // — Send RGB values for one NeoPixel
    //
    //

    void sendOnePixel(unsigned char red, unsigned char green, unsigned char blue) {

    // Since time is tight and I’m doing it all in c, help the
    // compiler. Keep the code simple — unroll loops, simplify tests, etc.

    // The delays below were manually tuned after seeing output
    // on an oscilloscope. The delays will probably need to be re-tuned
    // if I ever change compilers. But I can manually retune them several
    // hundred times and still be time ahead of the alternative: learning
    // enough PIC assembler to code it the right way.

    // These delays are tuned for a PIC running at 12 MIPS (48 MHz oscillator).
    // For 16 MIPS (64 MHz) use 12, 2 for SEND_ONE and 5, 10 for SEND_ZERO.

    // one – send high for 0.8 microseconds then low for 0.45 microseconds

    #define SEND_ONE { NEOPIXEL_PIN = 1; _delay(7); NEOPIXEL_PIN = 0; /* _delay(2); */ }

    // zero – send high for 0.4 microseconds then low for 0.85 microseconds

    #define SEND_ZERO { NEOPIXEL_PIN = 1; _delay(2); NEOPIXEL_PIN = 0; _delay(6); }

    // send green, red, blue, each with msb first

    if (green & 0b10000000) SEND_ONE else SEND_ZERO;
    if (green & 0b01000000) SEND_ONE else SEND_ZERO;
    if (green & 0b00100000) SEND_ONE else SEND_ZERO;
    if (green & 0b00010000) SEND_ONE else SEND_ZERO;
    if (green & 0b00001000) SEND_ONE else SEND_ZERO;
    if (green & 0b00000100) SEND_ONE else SEND_ZERO;
    if (green & 0b00000010) SEND_ONE else SEND_ZERO;
    if (green & 0b00000001) SEND_ONE else SEND_ZERO;

    if (red & 0b10000000) SEND_ONE else SEND_ZERO;
    if (red & 0b01000000) SEND_ONE else SEND_ZERO;
    if (red & 0b00100000) SEND_ONE else SEND_ZERO;
    if (red & 0b00010000) SEND_ONE else SEND_ZERO;
    if (red & 0b00001000) SEND_ONE else SEND_ZERO;
    if (red & 0b00000100) SEND_ONE else SEND_ZERO;
    if (red & 0b00000010) SEND_ONE else SEND_ZERO;
    if (red & 0b00000001) SEND_ONE else SEND_ZERO;

    if (blue & 0b10000000) SEND_ONE else SEND_ZERO;
    if (blue & 0b01000000) SEND_ONE else SEND_ZERO;
    if (blue & 0b00100000) SEND_ONE else SEND_ZERO;
    if (blue & 0b00010000) SEND_ONE else SEND_ZERO;
    if (blue & 0b00001000) SEND_ONE else SEND_ZERO;
    if (blue & 0b00000100) SEND_ONE else SEND_ZERO;
    if (blue & 0b00000010) SEND_ONE else SEND_ZERO;
    if (blue & 0b00000001) SEND_ONE else SEND_ZERO;

    return;

    } // end of sendOnePixel()

    //
    // Send pixel data from the stripReds[] … arrays to the strip.
    // Writes out the whole array. At 48 MHz, the delay between
    // individual pixel data is about 4 microseconds. It has to be
    // below about 8 microseconds. So calling sendOnePixel() as a
    // function is fast enough. If speed is really an issue, I can
    // save about a microsecond by putting the code from sendOnePixel()
    // inline here and skip the function call overhead.
    //

    void writeRGBtoStrip(void) {

    int holdGIE = GIE;
    GIE = 0; // disable all interrupts – this is time critical
    for (int j = 0; j < 60; j++) {
    sendOnePixel(stripReds[ j], stripGreens[ j], stripBlues[j]);
    } // end for j
    GIE = holdGIE; // set interrupts back to what they were
    return;

    } // end writeRGBtoStrip

  9. Brett Sutherland says:

    Great tutorial. Thank you for the back to basics approach. I’ve wanted to start programming and have some pics, but have never used them. I’ve looked at the arduino, but didn’t really want a black box solution. Perhaps I have it all wrong, but that is my beginner take. Well done.

  10. josh says:

    The WS2812B chip uses a very simple state machine that does not care about the particulars of the most parts of the data signal timing. It turns out that there are only a couple of timings that actually matter.

    It is no problem to leave the NeoPixel data line low longer than spec’ed as long as you do not leave it low long enough to trigger a reset, which turns out to be in the range of 5us-10us.

    For more info on NeoPixel timing requirements beyond the spec sheets, check out…

    http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/

  11. Mark says:

    I was glad to find your presentation on NeoPixels. It got mentioned on a PIC forum for picBasic Pro (http://www.picbasic.co.uk/forum/showthread.php?t=18431&p=127934#post127934). I especially liked your comments on arduinos. While it is awesome that they open up interest in electronics, they don’t require you understand too much about the inner workings. Thanks for taking the time. Now I need to get to work and play with mine.

  12. Sam Zamora says:

    Commenting for later winning :)
    it would be a dream come true

  13. Luke Gary says:

    This is really cool! What is the smallest PIC that this can run on?

  14. Rob Zazueta says:

    I have been trying to figure out how to play with these LED rings for a while. This tutorial has been tremendously valuable. Thank you so much!

  15. Thomas says:

    Congrats on the Hackaday feature! It’s what led me to your site, and I’ve found a lot of useful things here. I absolutely agree that Arduino can obscure a lot of the inner workings of the micro controller, which can seriously limit the value of the projects produced, but I’m glad that you don’t look down on the platform. Lots of experienced engineers snub Arduino, but I believe it’s an invaluable stepping stone to bigger and better things. I started out with Arduino before being introduced to raw AVR and ARM.

    Some thoughts on the Neopixel’s timing complexities, although I agree that the duration of the high signal is probably the important part. When I was browsing the data sheet, I noticed the WS2812 they use gives a signal frequency of 1.25 us +/- 600 ns. Perhaps this 50% error flexibility is part of what allows the chip to work despite the timing issues. One other thought: won’t the longer signal frequency decrease the refresh rate of the Neopixels? Adafruit’s guide claims a 400 Hz refresh rate, but according to my rough calculations the longer signal frequency coding for 1 would lead to a refresh rate of approx. 350 Hz. Not sure that small difference matters much since they look great and only require one pin, but it’s something to keep in mind.

    Obligatory giveaway note: as a recent college graduate, equipment can be tough to come by. I try to use the scope at my internship when I need it for my projects, but a scope of my own would make a big difference when I’m debugging an idea I had at 1 AM.

  16. Ryan Rose says:

    Hi Shahriar,

    Great video! Hackaday brought me here, and I’m glad it did. I’ll be visiting thesignalpath regularly now to watch all your other videos. As an arduino experimenter, I really appreciate the time you take to explain the low-level fundamentals of your project.

    Cheers!

  17. wouter says:

    Excellent video! Explanation is very detailed and clear. moar of such videos! :)

  18. Jeff Sheldon says:

    I’d love to see this scaled to a hula-hoop. Two color-chase hula hoops on one girl in a nightclub with UV lighting = win (isn’t that why we guys hack things?). Nice work and explanation. Awesome giveaways.

  19. Allie says:

    Thanks for the tutorial. I have been considering a neopixel clock and think this tutorial might be a good starting point – thanks!

  20. Don says:

    Nice video. It was very nicely detailed.

    With regard to NeoPixel Timing, hackaday.com had a link a while back to someone’s analysis. It’s http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/. Not so coincidentally, I found your website through hackaday.com.

    It’s great that you are sharing your knowledge and your old equipment with others. Could you also share a privacy policy? Thanks!

  21. Ian says:

    It would be interesting to see the regenerated signal on the dout of the first module compared to the din (generated by your code)

  22. billthewelder says:

    I like this, it’s something that I would like to try and add to my daughters halloween costume.

  23. Zach Waltz says:

    Nice video. Is 128 the maximum number of addresses for using these neopixel type LEDs?

  24. Frank Alvarez says:

    Great work Shahriar! I just got the 16 LED version and was playing with it using an Arduino and wanted to get into the Adafruit libraries to learn more about what makes them tick but this is way better. Was also thinking about what it would take to create a matrix of these and muxing some video onto them.
    Thanks for your video!

  25. Jeremy says:

    Really enjoyed your video; found you on hackaday. A year and a half ago, I jumped into electronics after many years of wishing I could make the first step. I’ve been pretty successful with Arduino but have always felt like I was cheating a little by not having a better understanding of the fundamentals. I would make good use of the Tektronix oscilloscope in furthering my understanding of electronics and my goal of building a clock from something that’s not based on a development platform.

  26. Rodney King says:

    Simply awesome love the way you explain things. Great detail n all

  27. Eugene says:

    Awesome! I just recently got my hands on some WS2812b leds! Although, not on a ring =[. Individually soldering them has been a pain. Definitely cool seeing this run on a PIC!

  28. AMS says:

    Intersting video, I’m surprised how many people try bitbanging these LED drivers rather than using a serial-port peripheral on their MCU.

  29. Paul Lenhardt says:

    Nice work! I would love to win that scope!

  30. flyingfisch says:

    Looks very cool, I have an arduino but have never really gotten into microcontroller nitty-gritty. Definitely will try this in the near future :)

  31. Neil Benson says:

    Thanks for the tutorial and especially for the code–I learn best by looking at other people’s code!

    Because of my poor internet connection, I have to download the video in several tries; it will take a while to get through all the pieces.

  32. Keathon keane says:

    This is a great video and it’s becoming more and more difficult to find good videos that illustrate the subtle things of building, modifying, or designing the fun little “projects” that exists on the net without using arduinos or other simple kits.

  33. Dennis Meade says:

    It would be interesting to add smaller and smaller rings to the inside of the large ring. Could produce some intertesting effects. I’m currently trying to learn enough about FPGAs to animate one of the 32 x 32 led matrices that Adafruit sells..

  34. J. Peterson says:

    Interesting, thanks for the post. My old Bitscope is getting a bit creaky, could use a new ‘scope : )

  35. Eddy Robinson says:

    Very nice introduction, thank you!
    I’m planning to work with my daughter to create some cool projects for her room with these :)

  36. cBake says:

    Cool! I’ve just gotten into the embedded world through Arduino. I’m doing some projects with multiplexing 7seg displays so this is relevant to me as I look toward getting more into the nitty gritty of microprocessors.

  37. cBaker says:

    Cool! I’ve just gotten into the embedded world through Arduino. I’m doing some projects with multiplexing 7seg displays so this is relevant to me as I look toward getting more into the nitty gritty of microprocessors.

  38. Dale says:

    Awesome. I’ve wanted to do the same for a while.

  39. Irish says:

    Very good tutorial. It’s refreshing to see someone explaining this for people who have not yet gotten into microcontroller usage. Where others are saying use this or that Ardunio ans such and such library, it’s nice to see how to actually program a microcontroller for a specific purpose. Very well done. Thank you.

  40. Lucas says:

    This is actually a really cool experiment! I am in the process of using a PIC18f4550 to drive a bunch of the surface mount equivalents of the NeoPixels for a Tetris board, so this is actually a very useful tool to consider.
    I was having some timing issues with driving these LED’s, but hopefully this can at least sort out that issue.
    Thanks for Posting!
    Lucas

  41. Josh says:

    I’ve been wondering what to do with the PIC18F4550 board that I have laying around…

  42. Greeeg says:

    The timing is examined in more depth here: http://cpldcpu.wordpress.com/2014/01/14/light_ws2812-library-v2-0-part-i-understanding-the-ws2812/

    Internally every LED has a local oscillator which is used in a clocked state machine. You’re right, only the high period matters. As long as the line isn’t low long enough to cause a reset.

  43. Mark Heller says:

    Just starting a makers group here in north Atl and this is the stuff we need to see. Thanks
    Mark

  44. gregg higham says:

    I like this video guide. I’d like to win the Tektronics ‘scope

  45. gregg higham says:

    I like this video guide. I’d like to win the Tektronics ‘scope

  46. Tim says:

    Excellent tutorial, this is exactly what I needed to help me move past Arduino and into the world of PIC! Thanks for taking the time to share the knowledge.

  47. Chris Berg says:

    Was excited about watching this – video won’t play right now though…

  48. Henry says:

    Hey man, grats on making Hackaday and thanks for teaching me more EE in 30 mins than I’ve been able to teach myself in the last month. The Tektronix give-away is awesome; please consider me for it! I have some ideas for a really old KVM switch I found, but I can’t find a local second-hand scope to save my life. I know you’ve done a few reviews, but I wonder if you can let all us wannabe hackers know what kind of specs and features we should be looking for in an oscilloscope? Also, where would be a good place to get a low-cost, second-hand scope? Thanks again!

  49. Chris says:

    Excellent! This would make an awesome halloween dog collar!

  50. Matthew says:

    It’s cool how you got the communication to work with just one I/O pin.

  51. Scott P says:

    Thanks for the video. I’m a computer science / computer engineering background kind of guy but I have a 9 year old boy that is really starting to get interested in electronics so it’s on me to figure things out and get us started together.

    That’s what I’d use the equipment for…..learning for both of us.

  52. Ian says:

    The is an article on josh.com about the timing requirements of neopixels.
    http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/

  53. Alex says:

    Been seen your videos and are of a great interest to me, I’m a hobbist and electronics for me it’s a big step in moving forward, I still need to grow more and learned in this field but looking forward to do so in the future…test equipment it’s in need for me since I’m not sure what’s best to start with. Thanks.

  54. Daniel says:

    I love your videos! So glad you’ve made more! I am a software engineer but have learned tons from your blog. Thanks for sharing your knowledge with the world!

  55. Geir Andersen says:

    Hi Shahriar
    And thank you for another great video! I just love the way you explain things in the realm for electronics so that armatures like me actually can follow along.
    Your video could probably not have come at a better time as I’m developing at PBC based on the WS2812B chip/LED.
    The design is similar to my white LED version http://letsmakerobots.com/node/37574 but this time with RGB to have access to a broader light spectrum.

    My question is really more related to the power supply than the RGB LED. Could you recommend a voltage regulator setup that could supply me with the needed 6A+ current? I would like this to be incorporated into the PCB so I only have a single power source for the complete device.
    I’ll be using a ATMEGA328P-AU as the micro controller running at 5V
    Thanks in advance
    Geir

  56. dicsEE says:

    I really like your educational videos style and almost weekly I refresh the main page hoping to find a new clip.
    Is it too much to ask for a video series about LCD types, functionality, interfacing ?

    PS. Please do not take this comment into account for your giveaway, I have more equipment than I can handle/use already and also I do not live in US

  57. tasweet says:

    hello Shahriar,

    i love the videos. thank you for showing the TPI 440. i might be able to buy one someday. i had been looking for a fluke 196b, but it is like checking the price of a Ferrari for the third time sure that the price on the first two times was wrong. anyone else who requests the tpi deserves it more than me. i just want a significant number viewers to request the giveaway. thank you for all of the effort you put into this site.

  58. Santiago salinas says:

    Thanks for you time and videos

    We are a school of audio and electronics in mexico without lucrative purposes, your videos and use them as teaching material giving your credit

    any help serves to give these low-income students equipment if you so , could send to San Antonio Texas USA and we ship to Mexico

    Colegio de Ingenieros en Audio A.C.
    Phd. Santiago Salinas

  59. Jorge Garcia says:

    Hi Shariar,

    Excellent video. I’m not eligible to receive any of the giveaways, I own a Rigol DS1102E. I wanted to comment that the timing for the Neopixels is not as strict as the datasheet might initially suggest. This link has more information, Josh was able to run a string of 1000+ of these LEDs using the normal Arduino.

    http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/

    Thanks again for the awesome video I enjoy your style and examples very much.

    Best Regards,
    Jorge Garcia

  60. Brian Gabrick says:

    Love the tutorial thanks!

  61. Gregory Bias says:

    I watched the Tutorial on Programming the NeoPixel and found it very interesting and informative.
    The grandkids would love the NeoPixel rings.
    Please consider me for the equipment give away.

    Thanks

  62. Lucas McCauley says:

    Thanks for the great video. I’ve spent a lot of my weekend watching stuff on your blog. As an embedded programmer, I’m all for getting into the low level (well, at least to the C level, though doing this in assembly would have been fun too!) Seeing this video after the RGB LED/RGB detector video makes me want to see some kind of crazy light based data protocol… If only I had the time.

    Keep the videos coming!

    Lucas

    PS. I just thought I’d mention that maybe you meant to do a logical && instead of the bitwise in the NeoInit() ?

  63. Greg Lankford says:

    Great video!

  64. Thomas R says:

    This was super helpful – I’ve been eyeing these LEDs for a while. Came here from r/electronics. Awesome giveaway too – I’d like to enter for the TPI Scope.

  65. Greg says:

    Hi Shahriar,

    I wanted to let you know that I learn heaps from your videos and I really enjoy them. Some of the things that you’ve covered were just at my limits of comprehension, but I always follow along and usually pick it up. You are a great teacher.

    I also wanted to let you know how great I think it is that you are helping others trying to get into electronics with this giveaway. It really is very generous of you.

    Cheers,
    Greg

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>