Interactive Fun with NeoPixels

Dive into MicroPython with NeoPixels

With the "Opinionated MicroPython Setup from the previous post, we can now dive into the world of MicroPython on the ESP32.

To build the real-world example, we need the following components:

  • ESP32 board
  • NeoPixel strip, ring,matrix (e.g. WS2812B)
  • optionally a Breadboard

In our example, we use the Wokwi ESP32 board and a NeoPixel ring.

setup

Lightning a NeoPixel in the ring is as simple as:

from machine import Pin
from neopixel import NeoPixel

pin = Pin(23, Pin.OUT)
np = NeoPixel(pin, 16)

np[4] = (255, 0, 0)
np.write()

Check the MicroPython NeoPixel library for more details.

The day's task of the day is to create a simple animation with the NeoPixel ring or matrix.

Tip: You can find inspiration on WOKWI as MicroPython NeoPixel. Play with it, and tune the function parameters to your liking.

Can you implement a two-dimensions random walk on the NeoPixel matrix?

Go ahead, jump into the Python REPL on the microcontroller and try it yourself. Then, check the solution below and pick the best part of both solutions.

In our take on that, we store the state in a variable called matrix, the x,y position of the walker, and the current direction like this:

matrix = [[0 for _ in range(8)] for _ in range(8)]
x,y = 4,4
direction = random.choice(['up', 'down', 'left', 'right'])

In two functions step() and paint() we update the state and display it on the NeoPixel matrix.

Within the step() function, we update the walker position based on the current direction. We also fade out the old positions.

def step():
    global x, y
    global direction
    if direction == 'up':
        x = max(0, x - 1)
    elif direction == 'down':
        x = min(7, x + 1)
    elif direction == 'left':
        y = max(0, y - 1)
    elif direction == 'right':
        y = min(7, y + 1)
    for i in range(8):
        for j in range(8):
            matrix[i][j] = max(0, matrix[i][j] - 1)  # Fade out all positions
    matrix[x][y] = 10  # Mark the new position

The paint() function is straightforward, no surprises here.

def paint():
    for i in range(8):
        for j in range(8):
            value = matrix[i][j]
            np[i * 8 + j] = (0, value, 0)
    np.write() # Update the LED strip

Finally, we can drive the walker by calling the walk() function.

def walk(steps):
    for _ in range(steps):
        step()
        paint()
        sleep(0.1)


walk(256)

Try your solution with different values for the trail length and the sleep time.

Have fun and play with the code!