pimoroni-pico/micropython/modules/plasma
Phil Howard 6bf5c7f7b5 Plasma: Swap make_new/print functions for WS2812 module.
Fixes #637
2023-01-19 10:29:30 +00:00
..
README.md update docs 2022-10-18 14:25:02 +01:00
micropython.cmake Renamed plasma mp directory to match module name 2021-08-19 15:25:12 +01:00
plasma.c Plasma: Swap make_new/print functions for WS2812 module. 2023-01-19 10:29:30 +00:00
plasma.cpp Plasma: Use m_new to alloc buffer on gc_heap if not supplied. 2022-10-04 11:39:56 +01:00
plasma.h Plasma/MP: bind update method for #236 2022-01-07 16:04:46 +00:00

README.md

Plasma

The Plasma library is intended to drive APA102 / DotStar™ or WS2812 / NeoPixel™ LEDs on our Plasma 2040 board, though it can also be used with your own custom pins/wiring.

It can also be used to drive WS2812 / NeoPixel™ LEDs from Plasma Stick. Note that APA102 compatibility, user buttons, RGB LED and current sensing functions are not present on Plasma Stick.

Notes On PIO Limitations

The WS2812 and APA102 drivers use the PIO hardware on the RP2040. There are only two PIOs with four state machines each, placing a hard limit on how many separate LED strips you can drive.

In most cases you'll use 0 for PIO and 0 for PIO state-machine, but you should change these if you plan on running different strand types together, or if you're using something else that uses PIO.

WS2812

Getting Started

Construct a new WS2812 instance, specifying the number of LEDs, PIO, PIO state-machine and GPIO pin.

For Plasma 2040:

import plasma
from plasma import plasma2040

LEDS = 30
FPS = 60

led_strip = plasma.WS2812(LEDS, 0, 0, plasma2040.DAT)

For Plasma Stick:

import plasma
from plasma import plasma_stick

LEDS = 30
FPS = 60

led_strip = plasma.WS2812(LEDS, 0, 0, plasma_stick.DAT)

Start the LED strip by calling start. This sets up a timer which tells the RP2040 to DMA the pixel data into the PIO (a fast, asyncronous memory->peripheral copy) at the specified framerate.

led_strip.start(FPS)

RGBW and Setting Colour Order

Some WS2812-style LED strips have varying colour orders and support an additional white element. Two keyword arguments are supplied to configure this:

led_strip = plasma.WS2812(LEDS, 0, 0, plasma2040.DAT, rgbw=True, color_order=plasma.COLOR_ORDER_GRB)

The available orders are defined as constants in plasma:

  • COLOR_ORDER_RGB
  • COLOR_ORDER_RBG
  • COLOR_ORDER_GRB
  • COLOR_ORDER_GBR
  • COLOR_ORDER_BRG
  • COLOR_ORDER_BGR

Set An LED

You can set the colour of an LED in either the RGB colourspace, or HSV (Hue, Saturation, Value). HSV is useful for creating rainbow patterns.

RGB

Set the first LED - 0 - to Purple 255, 0, 255:

led_strip.set_rgb(0, 255, 0, 255)

HSV

Set the first LED - 0 - to Red 0.0:

led_strip.set_hsv(0, 0.0, 1.0, 1.0)

APA102

Getting Started

Construct a new APA102 instance, specifying the number of LEDs, PIO, PIO state-machine and GPIO data/clock pins.

import plasma
from plasma import plasma2040

LEDS = 30
FPS = 60

led_strip = plasma.APA102(LEDS, 0, 0, plasma2040.DAT, plasma2040.CLK)

Start the LED strip by calling start. This sets up a timer which tells the RP2040 to DMA the pixel data into the PIO (a fast, asyncronous memory->peripheral copy) at the specified framerate.

led_strip.start(FPS)

Set An LED

You can set the colour of an LED in either the RGB colourspace, or HSV (Hue, Saturation, Value). HSV is useful for creating rainbow patterns.

RGB

Set the first LED - 0 - to Purple 255, 0, 255:

led_strip.set_rgb(0, 255, 0, 255)

HSV

Set the first LED - 0 - to Red 0.0:

led_strip.set_hsv(0, 0.0, 1.0, 1.0)

Set Brightness

APA102 pixels support global brightness, allowing their brightness to be specified independent of their colour. You can set the overall brightness of your strip by calling:

led_strip.set_brightness(15)

You can set brightness from 0 to 31. This directly maps to the 5-bit brightness value sent to the APA102 LEDs.

Using the Buttons & RGB LED

The pimoroni module contains Button and RGBLED classes to simplify button debounce, auto-repeat and PWM'ing an RGB LED.

Button(button, invert=True, repeat_time=200, hold_time=1000)
RGBLED(r, g, b, invert=True)

The plasma module contains a plasma2040 sub module with constants for the LED and button pins:

  • plasma2040.LED_R = 16
  • plasma2040.LED_G = 17
  • plasma2040.LED_B = 18
  • plasma2040.BUTTON_A = 12
  • plasma2040.BUTTON_B = 13
  • plasma2040.USER_SW = 23

Buttons

Import the Button class from the pimoroni module and the pin constants for the buttons:

from pimoroni import Button
from plasma import plasma2040

Set up an instance of Button for each button:

button_a = Button(plasma2040.BUTTON_A)
button_b = Button(plasma2040.BUTTON_B)

To get the button state, call .read(). If the button is held down, then this will return True at the interval specified by repeat_time until hold_time is reached, at which point it will return True every repeat_time / 3 milliseconds. This is useful for rapidly increasing/decreasing values such as hue:

state = button_a.read()

RGBLED

Import the RGBLED class from pimoroni and the pin constants for the LED:

from pimoroni import RGBLED
from plasma import plasma2040

And set up an instance of RGBLED for the LED:

led = RGBLED(plasma2040.LED_R, plasma2040.LED_G, plasma2040.LED_B)

To set the LED colour, call .set_rgb(r, g, b). Each value should be between 0 and 255:

led.set_rgb(255, 0, 0)  # Full red
led.set_rgb(0, 255, 0)  # Full green
led.set_rgb(0, 0, 255)  # Full blue

Measuring LED Strip Current Draw

Plasma 2040 features low-side current sensing, letting you measure how much current a strip of LEDs is drawing. This could be used just for monitoring, or as a way to reduce the maximum brightness of a strip to keep its current draw within the range of the USB port or power supply being used.

The pimoroni module contains an Analog class to simplify the reading of this current draw.

Analog(pin, amplifier_gain=1, resistor=0)

The plasma module contains a plasma2040 sub module with constants for the current sensing:

  • plasma2040.CURRENT_SENSE = 29
  • plasma2040.ADC_GAIN = 50
  • plasma2040.SHUNT_RESISTOR = 0.015

Analog

Import the Analog class from pimoroni and the pin and gain constants for the current sensing:

from pimoroni import Analog
from plasma import plasma2040

And set up an instance of Analog for the current sensing:

sense = Analog(plasma2040.CURRENT_SENSE, plasma2040.ADC_GAIN, plasma2040.SHUNT_RESISTOR)

To read the current draw, call .read_current(). The returned value will be in amps (A):

print("Current =", sense.read_current(), "A")