12_neopixel_led_strip
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| 12_neopixel_led_strip [2026/08/01 16:17] – [Using NeoPixel Strip for Traffic Lights] walkeradmin | 12_neopixel_led_strip [2026/08/02 13:48] (current) – [Knight Rider Lights] walkeradmin | ||
|---|---|---|---|
| Line 10: | Line 10: | ||
| Strips of NeoPixels are very cool to use. You might have heard of them being referred to as Addressable RGBs (aRGB) LEDs. While neopixels look a bit like Xmas tree lights, they are in fact individually addressable, | Strips of NeoPixels are very cool to use. You might have heard of them being referred to as Addressable RGBs (aRGB) LEDs. While neopixels look a bit like Xmas tree lights, they are in fact individually addressable, | ||
| + | \\ | ||
| + | \\ | ||
| + | Please note. The first part of this wiki page is about the NeoPixels and the code required to run them. It seems quite long, but this is only because the code has loads of useful comments in it. It is quite simple code, and when you remove all the comments, it is also rather short. | ||
| + | \\ | ||
| + | \\ | ||
| + | After this, there is some other projects you can follow along with about the different ways you could use the NeoPixel LEDs, they all use exactly the same wiring, so trying them out is simply a case of running a new piece of code, enjoy :) | ||
| \\ | \\ | ||
| \\ | \\ | ||
| Line 197: | Line 203: | ||
| # color is a built in python variable that holds an RGB value. | # color is a built in python variable that holds an RGB value. | ||
| # when you call the fill function (fill(color)) you have to set the value of color. | # when you call the fill function (fill(color)) you have to set the value of color. | ||
| + | # Ex: fill((255, 0, 0)) will set all LEDs red. ' | ||
| def fill(color): | def fill(color): | ||
| """ | """ | ||
| Line 316: | Line 323: | ||
| </ | </ | ||
| + | So if you set this up correctly, you should have something resembling the video below: | ||
| + | \\ | ||
| + | \\ | ||
| + | {{ : | ||
| + | \\ | ||
| + | I cannot wait to build this in to an actual traffic light ;) | ||
| + | \\ | ||
| + | \\ | ||
| + | Here is the NeoPixel Traffic Light project built in the Wokwi simulator. | ||
| + | \\ | ||
| + | \\ | ||
| + | {{ : | ||
| + | \\ | ||
| + | The NeoPixel in Wokwi isn't perfect, but it illustrates that the project will function as expected. | ||
| + | \\ | ||
| + | \\ | ||
| + | ---- | ||
| + | ==== NeoPixel LED Chase Sequence ==== | ||
| + | This next code scrolls down the line of NeoPixels. The most important line of code in this example is this: | ||
| + | |||
| + | * for i in range(NUM_LEDS): | ||
| + | |||
| + | What this does is creates a range of numbers from the value of the NUM_LEDS (12 in our example) and this looks like this: | ||
| + | |||
| + | * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 | ||
| + | |||
| + | So this for loop starts at ' | ||
| + | < | ||
| + | for i in range(NUM_LEDS): | ||
| + | clear() | ||
| + | np[i] = color # set the color of first LED | ||
| + | np.write() | ||
| + | time.sleep(delay) | ||
| + | | ||
| + | # now the loop will do the same but for LED2, 3, 4 etc. | ||
| + | # we clear the LEDs each time so that only 1 LED is ever illuminated. | ||
| + | </ | ||
| + | We call this chase function 3 times: | ||
| + | |||
| + | < | ||
| + | # Chase effect | ||
| + | chase((255, 0, 0), 0.08) | ||
| + | chase((0, 255, 0), 0.08) | ||
| + | chase((0, 0, 255), 0.08) | ||
| + | </ | ||
| + | |||
| + | First we set LEDs to Red, then second time it's Green then lastly we set Blue. | ||
| + | |||
| + | Here is the full code: | ||
| + | < | ||
| + | # WS2812 / NeoPixel Example | ||
| + | # Raspberry Pi Pico + MicroPython | ||
| + | # | ||
| + | # Controls a strip of 12 LEDs connected to GP0. | ||
| + | |||
| + | from machine import Pin | ||
| + | import neopixel | ||
| + | import time | ||
| + | |||
| + | # ------------------------------- | ||
| + | # Configuration | ||
| + | # ------------------------------- | ||
| + | |||
| + | LED_PIN = 8 # GPIO connected to DIN | ||
| + | NUM_LEDS = 12 # Number of LEDs, 0-11 is used, not 1-12 | ||
| + | |||
| + | # Create the NeoPixel object | ||
| + | np = neopixel.NeoPixel(Pin(LED_PIN), | ||
| + | |||
| + | # ------------------------------- | ||
| + | # Helper Functions | ||
| + | # ------------------------------- | ||
| + | |||
| + | def clear(): | ||
| + | """ | ||
| + | for i in range(NUM_LEDS): | ||
| + | np[i] = (0, 0, 0) | ||
| + | np.write() | ||
| + | |||
| + | def chase(color, | ||
| + | """ | ||
| + | clear() | ||
| + | |||
| + | for i in range(NUM_LEDS): | ||
| + | clear() | ||
| + | np[i] = color | ||
| + | np.write() | ||
| + | time.sleep(delay) | ||
| + | |||
| + | # ------------------------------- | ||
| + | # Main Program | ||
| + | # ------------------------------- | ||
| + | |||
| + | while True: | ||
| + | |||
| + | # Chase effect | ||
| + | chase((255, 0, 0), 0.08) | ||
| + | chase((0, 255, 0), 0.08) | ||
| + | chase((0, 0, 255), 0.08) | ||
| + | </ | ||
| + | |||
| + | Here is a short video showing the sequence. | ||
| + | \\ | ||
| + | \\ | ||
| + | {{ : | ||
| + | \\ | ||
| + | It's a nice effect to see the LEDs chasing like this. | ||
| + | \\ | ||
| + | \\ | ||
| + | ---- | ||
| + | ==== Knight Rider Lights ==== | ||
| + | |||
| + | Who remembers these? | ||
| + | \\ | ||
| + | \\ | ||
| + | {{ : | ||
| + | \\ | ||
| + | Well I do :) and we can replicate this effect with our Pico and NeoPixel LEDs. The code for this is almost identical to the previous project where we have the running LEDs. | ||
| + | \\ | ||
| + | \\ | ||
| + | The major change is the addition of this part: | ||
| + | < | ||
| + | # Backward direction | ||
| + | for i in range(NUM_LEDS - 2, 0, -1): | ||
| + | clear() | ||
| + | np[i] = color | ||
| + | np.write() | ||
| + | time.sleep(delay) | ||
| + | </ | ||
| + | |||
| + | In our previous project, the LEDs ran forward, then cycled colour, in this project we are not cycling the colour and the additional code runs the LEDs in reverse. | ||
| + | \\ | ||
| + | \\ | ||
| + | Here is the full code, explanation for how this works is at the end of this wiki page. | ||
| + | |||
| + | < | ||
| + | # WS2812 / NeoPixel Example | ||
| + | # Raspberry Pi Pico + MicroPython | ||
| + | # | ||
| + | # Controls a strip of 12 LEDs connected to GP8. | ||
| + | |||
| + | from machine import Pin | ||
| + | import neopixel | ||
| + | import time | ||
| + | |||
| + | # ------------------------------- | ||
| + | # Configuration | ||
| + | # ------------------------------- | ||
| + | |||
| + | LED_PIN = 8 # GPIO connected to DIN | ||
| + | NUM_LEDS = 12 # Number of LEDs, 0-11 is used, not 1-12 | ||
| + | |||
| + | # Create the NeoPixel object | ||
| + | np = neopixel.NeoPixel(Pin(LED_PIN), | ||
| + | |||
| + | # ------------------------------- | ||
| + | # Helper Functions | ||
| + | # ------------------------------- | ||
| + | |||
| + | def clear(): | ||
| + | """ | ||
| + | for i in range(NUM_LEDS): | ||
| + | np[i] = (0, 0, 0) | ||
| + | np.write() | ||
| + | |||
| + | def chase_bounce(color, | ||
| + | """ | ||
| + | # Forward direction | ||
| + | for i in range(NUM_LEDS): | ||
| + | clear() | ||
| + | np[i] = color | ||
| + | np.write() | ||
| + | time.sleep(delay) | ||
| + | |||
| + | # Backward direction | ||
| + | for i in range(NUM_LEDS - 2, 0, -1): | ||
| + | clear() | ||
| + | np[i] = color | ||
| + | np.write() | ||
| + | time.sleep(delay) | ||
| + | |||
| + | # ------------------------------- | ||
| + | # Main Program | ||
| + | # ------------------------------- | ||
| + | |||
| + | while True: | ||
| + | |||
| + | # Chase effect | ||
| + | chase_bounce((255, | ||
| + | </ | ||
| + | |||
| + | So, what does this extra code do? and how? | ||
| + | \\ | ||
| + | \\ | ||
| + | Here is an explanation of the reverse code block in general. | ||
| + | |||
| + | < | ||
| + | # Backward direction (move the lit LED from right to left) | ||
| + | # range(NUM_LEDS - 2, 0, -1) generates: | ||
| + | # For 12 LEDs → 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 | ||
| + | # - Start at LED 10 (second-to-last) | ||
| + | # - Stop at LED 1 (LED 0 is skipped to avoid repeating the end LED) | ||
| + | # - Step backwards by -1 each time | ||
| + | for i in range(NUM_LEDS - 2, 0, -1): | ||
| + | |||
| + | clear() | ||
| + | |||
| + | np[i] = color # Light the current LED at position i | ||
| + | |||
| + | np.write() | ||
| + | |||
| + | time.sleep(delay) | ||
| + | </ | ||
| + | |||
| + | And this is what the line that makes the count to backwards actually does. | ||
| + | |||
| + | < | ||
| + | range(NUM_LEDS - 2, 0, -1) | ||
| + | #Breakdown for NUM_LEDS = 12: | ||
| + | |||
| + | Start: NUM_LEDS - 2 → 10 | ||
| + | #(LED 11 was already lit in the forward chase) | ||
| + | |||
| + | Stop: 0 | ||
| + | #(but Python stops before 0, so last value is 1) | ||
| + | |||
| + | Step: -1 | ||
| + | #(count backwards) | ||
| + | </ | ||
| + | |||
| + | For the reverse sequence, we don't need to worry about the first (0) or last (11) LEDs as these are already set by the forward sequence. | ||
| + | \\ | ||
| + | \\ | ||
| + | That's it! Oh, and don't worry, I won't be fitting these to my car :) | ||
| + | \\ | ||
| + | \\ | ||
| + | ---- | ||
12_neopixel_led_strip.1785601077.txt.gz · Last modified: by walkeradmin
