1NeoPill Firmware and Operation
- Download the code bundle, build, and flash the Blue Pill https://github.com/relwin/NeoPill
- Or download the Hex file and flash using STM32CubeProgrammer.
STM32 Blue Pill Development Environment Used
- STM CubeMX 6.1.1
- Keil uVision 5.26 (Lite version)
- STM32CubeProgrammer v 2.6.0
- With USB cable plugged into the Blue Pill verify no ground loop to target board.
- Both target and Blue Pill powered off (unplug USB.)
- Jumper NeoPixel serial data to PB7 and PB15. These are 5V tolerant inputs.
- Jumper PB6 to PB13.
- Verify common grounds with target, or jumper target GND with Blue Pill G.
- Plug USB cable into PC, powering Blue Pill. Note LED PC13 flashing at 10Hz.
- Power on target. It’s ok if its NeoPixels are operating.
- Start PC python code. LED PC13 flashes at 5Hz if no NeoPixel data present. Once python code syncs LED PC13 flashes at 1Hz.
- Observe graphics display.
Blue Pill Pin
Neopixel serial data
Clock for SPI2 -> PB13
SPI2 clock input <-PB6
Neopixel serial data
Neopixel serial data GND
2Python Code, Stripsym.py
On the PC side a small lump of python code, Stripsym.py, reads a YAML file to configure
- the pygame graphics window,
- number of LEDs,
- and LED format.
The number of LEDs and format must match the target. A strip or matrix configuration is also supported. For a matrix only the progressive scan is supported, or for Adafruit’s NeoMatrix the settings: NEO_MATRIX_TOP+NEO_MATRIX_LEFT+NEO_MATRIX_ROWS+NEO_MATRIX_PROGRESSIVE
- the desired serial port (COM port) is opened,
- a sync command is sent to NeoPill,
- and serial data is read and queued.
Upon receiving a frame of pixel data (number of LEDs * 3 or 4 bytes) the appropriate format is applied, gamma corrected, and displayed in the graphics window.
- python 3.8.1
- pygame 2.0.0
- pyserial 3.5
- pyYAML 5.4.1
YAML file configuration options:
- Strip or matrix configuration
- LED formats: GRB, GRBW
- Number of LEDs: 1..N, where N may be large if your PC is capable.
- Or matrix size, n by m.
- LED display shape: Circle, rectangular
- Intergap size: 1..n
- Graphics window size
- Optional timing adjustment
- Serial port (Windows COM port)
python stripsim.py ledstrip.yaml
python stripsim.py ledmatrix.yaml
- Click the mouse on the display to show data queue stats, FPS, input data rate.
- Up/Dn arrows adjust gamma.
- ‘s’ performs a sync operation with NeoPill, usually needed after the target is restarted.
Received Frame rate
The target’s frame rate may fluctuate greatly. Stripsym displays LED data as fast as possible upon receiving a frame. However, the monitor you’re using typically refreshes at 60Hz so you may not see details such as quick flashes.
FastLED will output high frame rates when dithering. This dithering will go unnoticed on a slow LCD monitor.
If the LED display size is large you’ll have performance issues if updating at higher frame rates and/or number of LEDs. This will cause the input data queue to fill and drop frames. Dragging the window blocks its update while input data gets queued and may overflow.
Frame rate limit
To avoid overflowing the data queue at higher frame rates use fps_limit to restrict display updates to around 60 fps.
Color and Brightness
A typical LCD monitor is no match for NeoPixel brightness. Thus the gamma is adjustable to boost brightness. If your LED graphics are too muddy then boost your target brightness.
GRBW NeoPixel data is converted to RGB by saturate-adding the white value to each RGB component. This works well enough. Color accuracy will be different for every LCD monitor but seems close enough.
NeoPill Timing tweaks:
On the BluePill T1H, RES are adjustable by sending a ‘T’ command string:
“T nnn mmm” where ‘nnn’ is T1H and ‘mmm’ is RES in 13.88ns clocks (1/72MHz).
In Stripsym.py , the YAML config file supports
- timing_T1H num_ns
- timing_RES num_ns
where num_ns are the timings in ns, within 13.88ns.
To force T1H, RES to their default value set them to 0, or reset the BluePill.
Can’t Open USB COM port (Windows10)
- Typically happens after resetting NeoPill.
- Go into Windows DM and "disable/enable" the port.