How to use WS2812 “NeoPixel” LEDs with a PIC microcontroller

Sdílet
Vložit
  • čas přidán 24. 07. 2024
  • Do you want to step up your LED game? Then look no further! The WS2812 "NeoPixel" RGB LEDs are intelligent, individually addressable LED modules. And the best part: Besides two wires for power they only require one data line for as many LEDs as you could want. And today we will learn how to use the WS2812 LED with a PIC microcontroller.
    Thanks for watching, and let me know in the comments if you have any questions!
    Companion article: www.friendlywire.com/tutorials...
    Email list: www.friendlywire.com/email
    Website: www.friendlywire.com
    Twitter: / friendlywire
    Reddit: / friendlywire
    Facebook: / friendlywire
    Instagram: / friendlywire
    Timestamps:
    00:00 Introduction & Overview
    01:11 What you need
    01:43 WS2812 NeoPixel LEDs in a nutshell
    02:26 WS2823 data protocol
    04:14 Schematic
    04:51 Building the circuit
    05:45 Programming the PIC16F1455
    06:04 Setting up the MPLAB X IDE and IPE
    07:47 Main idea of the program
    11:37 Binary clock and electronic dice with the WS2812
    12:02 Summary

Komentáře • 89

  • @FriendlyWire
    @FriendlyWire  Před 3 lety +3

    If you're new to PIC microcontrollers and want to learn some more of the basics then check out my PIC introduction video :) czcams.com/video/e4Q2dYVedPY/video.html

    • @philipgbullas
      @philipgbullas Před 2 lety +1

      thats what i want to learn ☺️ thank you sir!

    • @FriendlyWire
      @FriendlyWire  Před 2 lety

      @@philipgbullas Hey Phil, thank you for interest and for being here! Have a great day!

  • @dima22061985
    @dima22061985 Před 8 měsíci +2

    your explanation is better than others in my native language ) Thank u ☺

    • @FriendlyWire
      @FriendlyWire  Před 8 měsíci

      Thank you, Dima, glad you like it! :)

  • @jerril42
    @jerril42 Před 3 lety +1

    That explains a lot about how the WS2812s work. I also like the frequency checking solution. Thanks Jens

  • @ScottWalshWoodworking
    @ScottWalshWoodworking Před 3 lety +2

    Excellent. I've always wondered how this was done. Good explanation! Hopefully I'll get around to working with these types of LEDs once day.

    • @FriendlyWire
      @FriendlyWire  Před 3 lety

      Thank you so much, Scott, glad you like it! :)

  • @EderJPires
    @EderJPires Před 2 lety +2

    Excellent video, thank you! I'll be trying this with my 12 years old son. hope you don't mind the questions coming ahead!

    • @FriendlyWire
      @FriendlyWire  Před 2 lety

      That's fantastic, and no worries, I am happy to help! :)

  • @orides5976
    @orides5976 Před 5 měsíci +1

    You are brilliant in the art of teaching! Please keep the amazing work you are doing! Long life to PICs all over the world! 🙂

    • @FriendlyWire
      @FriendlyWire  Před 5 měsíci +1

      Thanks so much, it really means a lot! I am already working on the next video scripts, but I just moved to a different country and I am waiting for my electronics stuff to arrive. Should be here in a month!

  • @DiegoTheWolf
    @DiegoTheWolf Před 5 měsíci +1

    Nice, never saw your channel in the past years (developing Arduino and ESP), but this is gold! Really nicely explained, i can skip parts i'm familiar with and the the PIC integration (watched the whole video nevertheless :D).

    • @FriendlyWire
      @FriendlyWire  Před 5 měsíci

      Thank you so much, glad you like the video! And yes, I always try to explain the concepts separately from the implementation for PICs (even though I hope I can also inspire people to use a PIC).

  • @user-gi6re4ls2z
    @user-gi6re4ls2z Před rokem +1

    Amazing Thank you

  • @DavidKHill
    @DavidKHill Před 6 měsíci +1

    Hi Jens, I am not quite sure if you'll get my comment, but wanted to say I've joined this thread a bit late. I've build the circuit you illustrated and I was able to get it compiled, flashed and running right out of the box. It's working great! I've connected it to a 4.5Vdc Bench Supply and have been running it 24/7 the past 3 weeks. It hasn't skipped a beat. So, I'm ready to add that Adafruit 8 LED strip to the circuit as depicted in the video (11:09), however, I'm a bit at a loss as to how this strip is wired to the breadboard and existing WS2812B Breakout boards. The pins for the strip is GND/Din/5Vdc/GND. But the WS2812B break board (output side) is 5Vdc/Dout/GND. Your wiring on the bread board doesn't quite make sense. How are you accomplishing this, or did I get the wrong Adafruit WS2812B strip?
    Thanks!!

    • @FriendlyWire
      @FriendlyWire  Před 6 měsíci +1

      Hey David, glad it's working for the first steps already, perfect! I am sure you can use the Adafruit LED strip, too, sometimes the wires are placed differently. All you need to remember is this: there is one data line, that sends the signal from the PIC to the LED strip. In your case, you need to connect the PIC data-pin to the Din of your LED strip. Then, connect GND to the negative power rail of your breadboard, and 5Vdc to the positive 5V power rail, and it should work.
      If it's too difficult to talk here (without the possibility to share pictures), please feel free to also send me an email. You can find my email address at the bottom of my website, www.friendlywire.com, and I will do my best to get back to you there.
      Thanks again for your interest, David, and best of luck!

    • @DavidKHill
      @DavidKHill Před 6 měsíci +1

      That is exactly what I did after I posted that last comment. I tried a couple of arrangements.
      1. I placed the strip in parallel to the breakout led boards. The first three lighted exactly like the 3 break out boards but the remaining five changed random colors. I understand this behavior.
      2. Then I put the data in ton the last of the 3 breakout boards (series) and noticed all 8 LEDs on the stick were random. This also makes total sense. only the first 3 are addressed anything after that appears to be noise.
      Now to revamp the code to address all 11 LEDs. This is most intriguing Jens! I'm developing a whole new appreciation for the PIC family. Sure would like to see more PIC-AS coding if you got anything. I know that Microchip deprecated the PIC-ASM to PIC-AS (part of the xc8 compiler).
      Thanks for the quick reply!
      -d

    • @FriendlyWire
      @FriendlyWire  Před 6 měsíci +1

      @@DavidKHill So glad it's working now, David, and thank you for your kind words! I am not sure if I will cover assembly for the PIC anytime soon (since it's more advanced and perhaps not the first thing to learn for beginners) but perhaps in the future! Thanks again, and have a great week!

    • @DavidKHill
      @DavidKHill Před 6 měsíci +1

      Yes, you are right. Still good info in these videos. Keep up the great work, I've got you subscribed and on notification should you put out any new videos.
      Thanks again and take care
      -D

    • @FriendlyWire
      @FriendlyWire  Před 6 měsíci

      @@DavidKHill Thank you so much, David, and best wishes!

  • @kumarg8432
    @kumarg8432 Před 3 lety +1

    Thanks, Really helpful..
    Kindly explain the PWM, timer and working of registers in microcontroller...

    • @FriendlyWire
      @FriendlyWire  Před 3 lety +1

      Thank you, Kumar, glad you like the video :) I have the electronic candle video which explains some basics of PWM: czcams.com/video/pCvCan2yGZg/video.html . I think a tutorial on timers would be a great idea for a future video!

  • @gustavoheenriquee
    @gustavoheenriquee Před 2 lety +1

    Very, very, very, gooooood!

    • @FriendlyWire
      @FriendlyWire  Před 2 lety

      Thanks, Gustavo, glad you find it useful! :)

  • @Westimation
    @Westimation Před 2 lety +1

    A great explanation, one of the best I have seen.
    I notice at 3:35 you say that the protocol resets... and the data sheets refer to the long pulse >50us as a reset. This is partially true, but it is also a "load" to output command.
    Once the 24 bit data is stored on the first LED's internal controller it switches through its DI pin to the DO pin to the next LED's DI pin and so on through all the LEDs.
    It is only when the "Load" pulse of >50uS does the LED internal controller switch the received bits to drive the LEDs. (via internal drive circuits). The >50uS pulse also resets the serial drive chain.
    You can observe this on long chains of LEDs loaded with say the same colour notice the LEDs only change after all the serial data has been passed through the LEDs and the >50us pulse is sent the LEDs will change.
    Another thing to keep in mind is that there is no need to continuously update the LEDs. My latest code updates my 16 WS2812 LEDs once every 16 mS thus the load and reset pulse is 16mS long. (Held low at end of load sequence, until next 16mS interrupt). This leaves plenty of processor time to deal with all the other code handling I require. I have also tried 30 second updates with no problems, you only need to update the LED string when required, something that seems to be missing from some coding I have seen.

    • @FriendlyWire
      @FriendlyWire  Před 2 lety

      Thank you for the comment, yes! You are right, of course, in the context of the protocol I thought it'd be best to think of it as a "reset" of sorts, but what you write about the switching of the data directionality is more accurate. Regarding the refreshing that's also a helpful piece of advice. In this case I was concerned with driving around 10 LEDs, so it's not all that resource intensive to update them every single loop cycle, but with larger displays/arrays that surely becomes a concern :) Thanks for the great feedback and improvements, much appreciated!

    • @Westimation
      @Westimation Před 2 lety +1

      I'm using a PIC16F1823 running a 32Mhz clock, with tight assembler code.
      I'm using the User RAM to store the colour data starting at FSR 0x20 and going up to FSR 0x70, 64 bytes to give me maximum of 21 "GRB" LEDs (63 bytes).
      For transmitting a 0 my "1" pulse is 400nS long followed by a 980nS "0" total 1380nS.
      For transmitting a 1 my "1" pulse is 760nS long followed by a 620nS "0" total 1380nS again.
      Both figures are well within the data sheet specs. of a total transfer time of 1.25uS+- 600nS.
      However at the end of each byte when I need to increment and check the FSR for overflow, the transmission time for a "0" time expands out to 1840nS, well beyond the data sheet specs for a "0" transmission time of 850+-140nS.
      On my current project I am using 16 LEDs but don't change the routine and the remaining bytes are just "spat" out the Do line of the 16th LED, and the long "0" at the end transfers the data to the LED drivers.
      Everything works as it should and I have also tried the code on the WS6812 RGBW LEDs and a few other WS2812 protocol LEDs (2.2mm versions etc).
      My conclusion is that it is the "1" time that does all the hard work.
      I hope this helps with any ones future WS2812 project.

    • @FriendlyWire
      @FriendlyWire  Před 2 lety

      @@Westimation Nice idea to send it out directly from the user RAM :) At that point it may be worthwhile to think about using external RAM that can be clocked out much faster, but then we're basically building a graphics card :D

    • @Westimation
      @Westimation Před 2 lety +1

      @@FriendlyWire Using an external RAM would affect the "Reset/Load" timing. However using the FSR/ to read program memory into the INDF registers is a possibility.
      As an example the PIC16F1823 has 2K of program memory, and 1K could be reserved for the LED string data. Other PICs have 4K or greater program memory and would a lot more data combinations would be possible for character displays.
      By the way my project is a model railway mimic panel and the LEDs are used for block occupancy and signals on the panel. The current panel I'm working on has 14 LEDs.

    • @FriendlyWire
      @FriendlyWire  Před 2 lety

      @@Westimation Definitely a good idea. Nice, do you have a photo of your project?

  • @whizzjb
    @whizzjb Před 2 lety +1

    Great Video!! @FriendlyWire I have multiple strings of WS2812B leds that the last led has a chopped data out pin, I was wanting to know if its possible to use an pic chip to receive the data from the WS2812b controller (that thinks the sting has 300 leds) and skip X number of leds and send the rest of the data out from that point. Allowing me to make up multiple strings using the same effect but without duplicating strings.

    • @FriendlyWire
      @FriendlyWire  Před 2 lety

      Thanks, Jon, so glad you like it! I am sure you can do this with a microcontroller, but you have to be very fast. It might be easier to try and salvage the existing last WS2812B LED and replace it with a new one where you can access the data out pin. Do you have a picture of your LED string? You can share it with me on Twitter or Instagram @FriendlyWire :)

  • @bogest76
    @bogest76 Před 2 lety +1

    Hi! Great video.
    Can i use an Atmel 24c64 for controling this led too?

    • @FriendlyWire
      @FriendlyWire  Před 2 lety

      Thank you for your kind words! I am not an expert on AVR's, so I cannot be sure unfortunately. What you should check is the instruction clock on your chip, it has to be fast enough for the 400ns that he WS2812B's protocol needs.

  • @s1nister688
    @s1nister688 Před 3 lety +1

    Hey, thanks for the video. Would be really awesome if you had a discord server for the channel where beginners like me could discuss with others.

    • @FriendlyWire
      @FriendlyWire  Před 3 lety +1

      Thanks for the kind words! Yeah that's actually a great idea. I know it's not exactly the same but there is a subreddit: www.reddit.com/r/FriendlyWire/ :) I will look into the Discord idea too. Thanks again, and have a great day!

  • @jayashreek2939
    @jayashreek2939 Před rokem +1

    Very nice,
    Is it possible 20mz pic16f72
    To run ws2812.or ws2811.

    • @FriendlyWire
      @FriendlyWire  Před rokem

      Glad you like it! May be a tiny bit too slow, since the operating speed is 20mHz/4 = 5MHz, which is 200 nanoseconds per instruction cycle. The WS2812 could be just OK with it (see also the companion article here: www.friendlywire.com/tutorials/ws2812/#ch2 ) so I would say it's worth a try. But it is a bit tight.

    • @jayashreek2939
      @jayashreek2939 Před rokem +1

      @@FriendlyWire thanks

    • @FriendlyWire
      @FriendlyWire  Před rokem

      @@jayashreek2939 Happy to help! You can give this a try with 20MHz, it may still work, the WS2812 tolerances are pretty large. :)

  • @DavidKHill
    @DavidKHill Před 6 měsíci +1

    New Question regarding the code. There are two variables in the code that I'm attempting to understand.
    unsigned char brt = 1;
    unsigned char dir = 1;

    • @FriendlyWire
      @FriendlyWire  Před 6 měsíci +1

      Had to look it up myself. These variables are for the brightness of the LEDs. brt stores a value between 0 and 255. 0 is dark, and 255 is full brightness. dir is the "direction" in which we change the brightness when the pushbutton is pressed. If "dir" is equal to 1, then we increase the brightness when the button is pressed. When we reach 255, dir changes from +1 to -1. Then, if we press the button again, it instead reduces the brightness from 255 to 254, and so on. When we reach absolute darkness (brt = 0), dir gets set to +1 again, so we can increase the brightness again.
      If you look at the source code in the companion article (www.friendlywire.com/tutorials/ws2812/), it's lines 102-113 that implement this functionality.

    • @DavidKHill
      @DavidKHill Před 6 měsíci +1

      @@FriendlyWire Thanks Jens, that was most helpful, at first glance I assumed that what brt and dir were. But wasn't sure.
      Now to figure out how to control the 8 additional LEDs in the Adafruite Strip. :)
      Cheers!

    • @FriendlyWire
      @FriendlyWire  Před 6 měsíci

      @@DavidKHill That's fantastic, I am so glad it's working now, David! Thank you for sharing.

  • @juanfra1997
    @juanfra1997 Před rokem +1

    It is a Good video but maybe a video with mcc would be useful for various pics

    • @FriendlyWire
      @FriendlyWire  Před rokem

      Thank you, Juan, I am always interested in making my videos more helpful to others, so I really appreciate your comment. Can you explain a bit more what you mean? :)

    • @juanfra1997
      @juanfra1997 Před rokem +1

      @@FriendlyWire microchip has a beautiful tool called mcc (microchip code configurator) wich you don't have to configure all the registers via code just thought the tool etc also it helps to configure more things is just too long to xplain in a comment

    • @FriendlyWire
      @FriendlyWire  Před rokem

      @@juanfra1997 Oh I think I know what you mean. You basically configure the functionality and then it generates the relevant code for you. I actually enjoy searching the commands for registers etc to get it to working, but I certainly see the appeal of other approaches :) Thanks for sharing, Juan!

  • @Christian-fj9vh
    @Christian-fj9vh Před 2 lety +1

    Excellent content with high learning value. For my level of understanding (and age, maybe) you speak a little bit too fast. Looking forward to your next tutorial!

    • @FriendlyWire
      @FriendlyWire  Před 2 lety

      Thank you, Christian, for your kind feedback, it means a lot! Was there a specific moment where the content was moving too fast? I am always looking for possible improvements :)

  • @ilkeraykut7064
    @ilkeraykut7064 Před 2 lety +1

    Thanks for the video. i have a question .sendRGB(0,0,brt) what does it mean exactly? is it for a single led ,right? you have 11 sendRGB(0,0,brt) function in if condition ,that means you have 11 led,right? and another question let 's say brt=255 does it mean the color of led is brightest blue? so brt decreases means blue brightness decreases ,right?

    • @FriendlyWire
      @FriendlyWire  Před 2 lety +1

      Yes, exactly, it's for a single LED! sendRGB(0,0,255) sends the full blue value, sendRGB(0,0,127) would be "half blue", and so on.

    • @ilkeraykut7064
      @ilkeraykut7064 Před 2 lety +1

      @@FriendlyWire did you Check adafruit neo pixel library ?in that library there are color function and brigtness function .why is like that?

    • @FriendlyWire
      @FriendlyWire  Před 2 lety

      @@ilkeraykut7064 I am not sure how this is done for other microcontrollers. This project here is independent of other libraries and code, so I just programmed it the way I thought it would be useful :) If you need additional functions, you can always add them to the existing code, and if you do, please let me know, I am always curious to see how viewers improve the tutorials and projects on this channel!

    • @ilkeraykut7064
      @ilkeraykut7064 Před 2 lety +1

      @@FriendlyWire int i=0;
      for(;i

    • @FriendlyWire
      @FriendlyWire  Před 2 lety

      @@ilkeraykut7064 Because the for-command takes too much time to evaluate, I think. Copy & paste sendRGB(0,0,255); fifteen times and then it should work as intended. Timing is very critical with those LEDs, the loop makes it take too long so that the protocol resets in between. Does that help?

  • @TheUnofficialMaker
    @TheUnofficialMaker Před 2 lety +1

    how to build green blinky thing on lower left below scope?

    • @FriendlyWire
      @FriendlyWire  Před 2 lety

      What part of the video are you referring to? :) I see the scope at 10:27 but I am not sure what you mean :)

    • @TheUnofficialMaker
      @TheUnofficialMaker Před 2 lety +1

      @@FriendlyWire old mac monitor running some sort of screensaver?

    • @FriendlyWire
      @FriendlyWire  Před 2 lety +1

      @@TheUnofficialMaker Ohh, I see! That's actually an Apple ][ monitor hooked up to a Raspberry Pi that plays back a video on loop, nothing too fancy :)

    • @TheUnofficialMaker
      @TheUnofficialMaker Před 2 lety +1

      @@FriendlyWire that would make a cool video

    • @FriendlyWire
      @FriendlyWire  Před 2 lety

      @@TheUnofficialMaker Thanks! :) I was thinking of building a simple PIC-based video card one day, let's see... :)

  • @1dakikadakarakalem
    @1dakikadakarakalem Před 2 lety +1

    can you control argb led strib ?

    • @FriendlyWire
      @FriendlyWire  Před 2 lety +1

      Thank you for the question! Can you send me a link to the LED strip, and I will let you know! :)

    • @1dakikadakarakalem
      @1dakikadakarakalem Před 2 lety +1

      @@FriendlyWire WS2812B led strip

    • @FriendlyWire
      @FriendlyWire  Před 2 lety +1

      @@1dakikadakarakalem Yes, that works with this circuit!

  • @GadgetoidUK
    @GadgetoidUK Před 3 lety +1

    Love your PIC series, really takes me back to our PIC16-on-everything days.
    From some PIC16F1503 firmware circa 2016:
    ```
    for(pixel = REG_WS2812; pixel < NUM_ELEMENTS+REG_WS2812; pixel++){
    for(j = 0b10000000; j != 0; j>>=1){
    if(_i2c_slave_get_regs(pixel) & j){
    LATAbits.LATA4 = 1;
    LATAbits.LATA4 = 1;
    LATAbits.LATA4 = 0;
    } else {
    LATAbits.LATA4 = 1;
    LATAbits.LATA4 = 0;
    }
    }
    }
    ```
    I don't quite recall how I got away with such brazen disregard for timing, but I think it just worked out. The code is interleaved with servo updates using a state-machine in an ISR, while the main loop handles I2C comms. It's a wonder what you can get working on these things.

    • @FriendlyWire
      @FriendlyWire  Před 3 lety

      Thank you for your kind words, glad you like the videos! :)
      Wow, that looks miraculous that it works out. I tried to get it as tight as possible with the timing. And ISR (interrupt service routine) would definitely screw this up, so it's probably better to place the update cycle inside the ISR as well, and do peripheral stuff outside. Do you remember what clock speed you used?

    • @GadgetoidUK
      @GadgetoidUK Před 3 lety +1

      @@FriendlyWire I suspect it was whatever is stock on the PIC16F1503. Looks like 16MHz:
      OSCCONbits.SCS = 0b10;
      OSCCONbits.IRCF = OSC_16MHZ;
      Definitely code that I'm not going to touch again... just in case it figures out it's defying the laws of physics and stops working or something.

    • @FriendlyWire
      @FriendlyWire  Před 3 lety

      @@GadgetoidUK Thanks for checking :-) What compiler did you use? The code in my tutorial is for 48MHz, so lots of extra room in there for extra features later on, but it is a bit overkill just for LEDs :)

    • @GadgetoidUK
      @GadgetoidUK Před 3 lety +1

      @@FriendlyWire IIRC it was XC8

    • @FriendlyWire
      @FriendlyWire  Před 3 lety

      @@GadgetoidUK Oh, nice, same in this video :)

  • @user-tb8nq2wg5e
    @user-tb8nq2wg5e Před měsícem +1

    I want to source code

    • @FriendlyWire
      @FriendlyWire  Před měsícem

      Sure! It's in the companion article: www.friendlywire.com/tutorials/ws2812/#appendix

  • @thediamondnightingales9623

    What have you got lined up for your next lesson?

    • @FriendlyWire
      @FriendlyWire  Před 2 lety +1

      Hopefully a multiplex tutorial using the MAX7219! :)

    • @thediamondnightingales9623
      @thediamondnightingales9623 Před 2 lety +1

      @@FriendlyWire that sounds awesome, ive always wondered how multiplexing works, im looking forward to seeing it!!

    • @FriendlyWire
      @FriendlyWire  Před 2 lety +1

      @@thediamondnightingales9623 Glad you like it! It'll be a while, though, it takes a lot of time (for me) to make these tutorials, and I want them to be as good as possible :)

    • @thediamondnightingales9623
      @thediamondnightingales9623 Před 2 lety +1

      @@FriendlyWire its better to take the time to verify your information, build a narrative and craft an excellent tutorial, it makes your videos engaging and worth the wait, you take your time with it brother, we can wait lol

    • @FriendlyWire
      @FriendlyWire  Před 2 lety

      @@thediamondnightingales9623 Thank you for your kind words, it means a lot! And have a great weekend! :)

  • @sparky8823
    @sparky8823 Před 2 lety +1

    Dang!!!
    Why not just simply use an arduino?

    • @FriendlyWire
      @FriendlyWire  Před 2 lety +1

      Of course you can use an Arduino, but this tutorial is for PIC microcontrollers :)

    • @sparky8823
      @sparky8823 Před 2 lety +1

      @@FriendlyWire OK. My bad. Still was interesting video!

    • @FriendlyWire
      @FriendlyWire  Před 2 lety

      @@sparky8823 I am glad you like it! I like to use PIC controllers, but you can also use Arduinos of course. I think there are always many different ways to achieve your goals :)