WeAct F411 + MicroPython + NeoPixels

Further to the Canaduino STM32 boards with MicroPython writeup, I thought I’d start showing how you’d interface common electronics to the WeAct F411 boards. First off, NeoPixels!

Rather than use the Adafruit trade name, these are more properly called WS2812 LEDs. Each one contains a tiny microcontroller and it only takes three connections to drive a long chain of addressable colour LEDs. The downside is that the protocol to drive these is a bit of a bear, and really needs an accurate, fast clock signal to be reliable.

The STM32F411 chip does have just such a clock, and the generic micropython-ws2812 library slightly misuses the SPI bus to handle the signalling. The wiring’s simple:

  • F411 GND to WS2812 GND;
  • F411 3V3 to WS2812 5V;
  • F411 PA7 (SPI1_MOSI) PB15 (SPI2_MOSI) to WS2812 DIn

Next, copy ws2812.py into the WeAct F411’s flash. Now create a script to drive the LEDs. Here’s one to drive 8 LEDs, modified from the library’s advanced example:

# -*- coding: utf-8 -*-

import time
import math

from ws2812 import WS2812

ring = WS2812(spi_bus=2, led_count=8, intensity=0.1)

def data_generator(led_count):
    data = [(0, 0, 0) for i in range(led_count)]
    step = 0
    while True:
        red = int((1 + math.sin(step * 0.1324)) * 127)
        green = int((1 + math.sin(step * 0.1654)) * 127)
        blue = int((1 + math.sin(step * 0.1)) * 127)
        data[step % led_count] = (red, green, blue)
        yield data
        step += 1

for data in data_generator(ring.led_count):
    ring.show(data)
    time.sleep_ms(100)

Previously I said you’d see your WS2812s flicker and shimmer from the SPI bus noise. I thought it was cool, but I suspect it was also why the external flash on my F411 board just died. By pumping data into PA7, I was also hammering the flash chip’s DI line …