Merge pull request #536 from pimoroni/hel-plasma

Plasma Stick examples
pull/540/head
Philip Howard 2022-10-19 10:51:27 +01:00 zatwierdzone przez GitHub
commit 3405130820
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
34 zmienionych plików z 1580 dodań i 9 usunięć

Wyświetl plik

@ -50,9 +50,11 @@ namespace pimoroni {
enum BOARD {
BREAKOUT_GARDEN,
PICO_EXPLORER,
PLASMA_STICK,
PLASMA_2040,
INTERSTATE_75,
SERVO_2040
SERVO_2040,
MOTOR_2040
};
enum Rotation {

Wyświetl plik

@ -29,9 +29,15 @@ namespace pimoroni {
scl = I2C_DEFAULT_SCL;
interrupt = I2C_DEFAULT_INT;
break;
case PLASMA_STICK:
sda = I2C_BG_SDA;
scl = I2C_BG_SCL;
interrupt = PIN_UNUSED;
break;
case PLASMA_2040:
case INTERSTATE_75:
case SERVO_2040:
case MOTOR_2040:
sda = I2C_HEADER_SDA;
scl = I2C_HEADER_SCL;
interrupt = I2C_HEADER_INT;

Wyświetl plik

@ -47,6 +47,7 @@ add_subdirectory(inky_pack)
add_subdirectory(inky_frame)
add_subdirectory(automation2040w)
add_subdirectory(plasma_stick)
add_subdirectory(plasma2040)
add_subdirectory(badger2040)
add_subdirectory(tufty2040)

Wyświetl plik

@ -0,0 +1,5 @@
include(plasma_stick_alternating_blinkies.cmake)
include(plasma_stick_encoder.cmake)
include(plasma_stick_fire.cmake)
include(plasma_stick_rainbows.cmake)
include(plasma_stick_temperature_bme280.cmake)

Wyświetl plik

@ -0,0 +1,12 @@
set(OUTPUT_NAME plasma_stick_alternating_blinkies)
add_executable(${OUTPUT_NAME} plasma_stick_alternating_blinkies.cpp)
target_link_libraries(${OUTPUT_NAME}
pico_stdlib
plasma_stick
)
# enable usb output
pico_enable_stdio_usb(${OUTPUT_NAME} 1)
pico_add_extra_outputs(${OUTPUT_NAME})

Wyświetl plik

@ -0,0 +1,54 @@
#include "pico/stdlib.h"
#include "plasma_stick.hpp"
#include "common/pimoroni_common.hpp"
/*
This super simple example sets up two alternating colours, great for festive lights!
*/
using namespace pimoroni;
using namespace plasma;
// Set how many LEDs you have
const uint NUM_LEDS = 50;
// Pick two hues from the colour wheel (from 0-360°, try https://www.cssscript.com/demo/hsv-hsl-color-wheel-picker-reinvented/ )
constexpr float HUE_1 = 40.0f;
constexpr float HUE_2 = 285.0f;
// Set up brightness (between 0 and 1)
constexpr float BRIGHTNESS = 0.5f;
// Set up speed (wait time between colour changes, in seconds)
constexpr float SPEED = 1.0f;
// WS2812 / NeoPixel™ LEDs
WS2812 led_strip(NUM_LEDS, pio0, 0, plasma_stick::DAT);
int main() {
stdio_init_all();
// Start updating the LED strip
led_strip.start();
while(true) {
for(auto i = 0u; i < NUM_LEDS; i++) {
// the if statements below use a modulo operation to identify the even and odd numbered LEDs
if((i % 2) == 0)
led_strip.set_hsv(i, HUE_1 / 360, 1.0, BRIGHTNESS);
else
led_strip.set_hsv(i, HUE_2 / 360, 1.0, BRIGHTNESS);
}
sleep_ms(SPEED * 1000.0f);
for(auto i = 0u; i < NUM_LEDS; i++) {
if((i % 2) == 0)
led_strip.set_hsv(i, HUE_2 / 360, 1.0, BRIGHTNESS);
else
led_strip.set_hsv(i, HUE_1 / 360, 1.0, BRIGHTNESS);
}
sleep_ms(SPEED * 1000.0f);
}
}

Wyświetl plik

@ -0,0 +1,14 @@
set(OUTPUT_NAME plasma_stick_encoder)
add_executable(${OUTPUT_NAME} plasma_stick_encoder.cpp)
target_link_libraries(${OUTPUT_NAME}
pico_stdlib
plasma_stick
breakout_encoder
pimoroni_i2c
)
# enable usb output
pico_enable_stdio_usb(${OUTPUT_NAME} 1)
pico_add_extra_outputs(${OUTPUT_NAME})

Wyświetl plik

@ -0,0 +1,92 @@
#include <stdio.h>
#include "pico/stdlib.h"
#include "plasma_stick.hpp"
#include "common/pimoroni_common.hpp"
#include "breakout_encoder.hpp"
/*
Change the colour of your LEDs easily by hooking up an RGB Encoder Breakout!
*/
using namespace pimoroni;
using namespace plasma;
// Set how many LEDs you have
const uint NUM_LEDS = 50;
// Make this number bigger for more precise colour adjustments
const uint STEPS_PER_REV = 24;
// WS28X-style LEDs with a single signal line. AKA NeoPixel
WS2812 led_strip(NUM_LEDS, pio0, 0, plasma_stick::DAT);
I2C i2c(BOARD::PLASMA_STICK);
BreakoutEncoder enc(&i2c);
// HSV Conversion expects float inputs in the range of 0.00-1.00 for each channel
// Outputs are rgb in the range 0-255 for each channel
void from_hsv(float h, float s, float v, uint8_t &r, uint8_t &g, uint8_t &b) {
float i = floor(h * 6.0f);
float f = h * 6.0f - i;
v *= 255.0f;
uint8_t p = v * (1.0f - s);
uint8_t q = v * (1.0f - f * s);
uint8_t t = v * (1.0f - (1.0f - f) * s);
switch (int(i) % 6) {
case 0: r = v; g = t; b = p; break;
case 1: r = q; g = v; b = p; break;
case 2: r = p; g = v; b = t; break;
case 3: r = p; g = q; b = v; break;
case 4: r = t; g = p; b = v; break;
case 5: r = v; g = p; b = q; break;
}
}
void count_changed(int16_t count) {
printf("Count: %d\n", count);
float h = (count % STEPS_PER_REV) / (float)STEPS_PER_REV;
uint8_t r = 0, g = 0, b = 0;
from_hsv(h, 1.0f, 1.0f, r, g, b);
// set the encoder LED colour
enc.set_led(r, g, b);
for(auto i = 0u; i < NUM_LEDS; i++) {
led_strip.set_rgb(i, r, g, b);
}
}
int main() {
stdio_init_all();
led_strip.start();
if(enc.init()) {
printf("Encoder found...\n");
enc.set_brightness(1.0f);
//enc.set_direction(BreakoutEncoder::DIRECTION_CCW); // Uncomment this to flip the direction
count_changed(0);
enc.clear_interrupt_flag();
while(true) {
if(enc.get_interrupt_flag()) {
int16_t count = enc.read();
enc.clear_interrupt_flag();
while(count < 0) {
count += STEPS_PER_REV;
}
count_changed(count);
}
}
}
else {
printf("Encoder not found :'(\n");
}
return 0;
}

Wyświetl plik

@ -0,0 +1,12 @@
set(OUTPUT_NAME plasma_stick_fire)
add_executable(${OUTPUT_NAME} plasma_stick_fire.cpp)
target_link_libraries(${OUTPUT_NAME}
pico_stdlib
plasma_stick
)
# enable usb output
pico_enable_stdio_usb(${OUTPUT_NAME} 1)
pico_add_extra_outputs(${OUTPUT_NAME})

Wyświetl plik

@ -0,0 +1,38 @@
#include "pico/stdlib.h"
#include "plasma_stick.hpp"
#include "common/pimoroni_common.hpp"
/*
A basic fire effect.
*/
using namespace pimoroni;
using namespace plasma;
// Set how many LEDs you have
const uint NUM_LEDS = 50;
// WS2812 / NeoPixel™ LEDs
WS2812 led_strip(NUM_LEDS, pio0, 0, plasma_stick::DAT);
// Maps a value from one range to another
float map(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
int main() {
stdio_init_all();
// Start updating the LED strip
led_strip.start();
while(true) {
// fire effect! Random red/orange hue, full saturation, random brightness
for(auto i = 0u; i < NUM_LEDS; ++i) {
float hue = map((float)rand(), 0.0f, (float)RAND_MAX, 0.0, 50.0f / 360.0f);
float brightness = map((float)rand(), 0.0f, (float)RAND_MAX, 0.0, 1.0f);
led_strip.set_hsv(i, hue, 1.0, brightness);
}
sleep_ms(100);
}
}

Wyświetl plik

@ -0,0 +1,12 @@
set(OUTPUT_NAME plasma_stick_rainbows)
add_executable(${OUTPUT_NAME} plasma_stick_rainbows.cpp)
target_link_libraries(${OUTPUT_NAME}
pico_stdlib
plasma_stick
)
# enable usb output
pico_enable_stdio_usb(${OUTPUT_NAME} 1)
pico_add_extra_outputs(${OUTPUT_NAME})

Wyświetl plik

@ -0,0 +1,45 @@
#include "pico/stdlib.h"
#include "plasma_stick.hpp"
#include "common/pimoroni_common.hpp"
/*
Make some rainbows!
*/
using namespace pimoroni;
using namespace plasma;
// Set how many LEDs you have
const uint NUM_LEDS = 50;
// The SPEED that the LEDs cycle at (1 - 255)
const uint SPEED = 20;
// How many times the LEDs will be updated per second
const uint UPDATES = 60;
// WS2812 / NeoPixel™ LEDs
WS2812 led_strip(NUM_LEDS, pio0, 0, plasma_stick::DAT);
int main() {
stdio_init_all();
// Start updating the LED strip
led_strip.start(UPDATES);
float offset = 0.0f;
// Make rainbows
while(true) {
offset += float(SPEED) / 2000.0f;
for(auto i = 0u; i < NUM_LEDS; ++i) {
float hue = float(i) / NUM_LEDS;
led_strip.set_hsv(i, hue + offset, 1.0f, 1.0f);
}
sleep_ms(1000 / UPDATES);
}
}

Wyświetl plik

@ -0,0 +1,14 @@
set(OUTPUT_NAME plasma_stick_temperature_bme280)
add_executable(${OUTPUT_NAME} plasma_stick_temperature_bme280.cpp)
target_link_libraries(${OUTPUT_NAME}
pico_stdlib
plasma_stick
bme280
pimoroni_i2c
)
# enable usb output
pico_enable_stdio_usb(${OUTPUT_NAME} 1)
pico_add_extra_outputs(${OUTPUT_NAME})

Wyświetl plik

@ -0,0 +1,64 @@
#include <stdio.h>
#include "pico/stdlib.h"
#include "plasma_stick.hpp"
#include "common/pimoroni_common.hpp"
#include "bme280.hpp"
/*
Reads the temperature from a BME280 breakout...
...and changes the LED strip an appropriate colour.
https://shop.pimoroni.com/products/bme280-breakout
*/
using namespace pimoroni;
using namespace plasma;
// Set how many LEDs you have
const uint NUM_LEDS = 50;
// Set up brightness (between 0 and 1)
constexpr float BRIGHTNESS = 1.0f;
// The range of readings that we want to map to colours
const uint MIN = 10;
const uint MAX = 30;
// Pick what bits of the colour wheel to use (from 0-360°)
// https://www.cssscript.com/demo/hsv-hsl-color-wheel-picker-reinvented/
const uint HUE_START = 230; // blue
const uint HUE_END = 359; // red
// WS28X-style LEDs with a single signal line. AKA NeoPixel
WS2812 led_strip(NUM_LEDS, pio0, 0, plasma_stick::DAT);
I2C i2c(BOARD::PLASMA_STICK);
BME280 bme(&i2c);
int main() {
stdio_init_all();
led_strip.start();
if(bme.init()) {
printf("BME280 found...\n");
while(true) {
BME280::bme280_reading result = bme.read_forced();
printf("%s %0.2lf deg C, %0.2lf hPa, %0.2lf%%\n", result.status == BME280_OK ? "OK" : "ER", result.temperature, result.pressure, result.humidity);
// calculates a colour
float hue = HUE_START + ((float)(result.temperature - MIN) * (float)(HUE_END - HUE_START) / (float)(MAX - MIN));
// set the leds
for(auto i = 0u; i < NUM_LEDS; i++) {
led_strip.set_hsv(i, hue / 360.0f, 1.0, BRIGHTNESS);
}
}
}
else {
printf("BME280 not found :'(\n");
}
return 0;
}

Wyświetl plik

@ -26,6 +26,7 @@ add_subdirectory(pico_motor_shim)
add_subdirectory(pico_rgb_keypad)
add_subdirectory(pico_wireless)
add_subdirectory(automation2040w)
add_subdirectory(plasma_stick)
add_subdirectory(plasma2040)
add_subdirectory(badger2040)
add_subdirectory(tufty2040)

Wyświetl plik

@ -0,0 +1 @@
include(plasma_stick.cmake)

Wyświetl plik

@ -0,0 +1,6 @@
add_library(plasma_stick INTERFACE)
target_include_directories(plasma_stick INTERFACE ${CMAKE_CURRENT_LIST_DIR})
# Pull in pico libraries that we need
target_link_libraries(plasma_stick INTERFACE pico_stdlib plasma)

Wyświetl plik

@ -0,0 +1,10 @@
#pragma once
#include "pico/stdlib.h"
#include "ws2812.hpp"
namespace plasma {
namespace plasma_stick {
const uint DAT = 15; // Used for WS2812
}
}

Wyświetl plik

@ -0,0 +1,35 @@
"""
Drop this function into your code to set your board's time/date from your RV3028 RTC breakout!
"""
def set_pico_time():
# the function sets the Pico's RTC from a RV3028 RTC breakout
# to setup breakout (and set the time) run this first:
# https://github.com/pimoroni/pimoroni-pico/blob/main/micropython/examples/breakout_rtc/set-time.py
from pimoroni_i2c import PimoroniI2C
from breakout_rtc import BreakoutRTC
from machine import RTC
# set up I2C
PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} # i2c pins 4, 5 for Breakout Garden
# for boards that use the alternate I2C pins use the line below instead
# PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} # Default i2c pins for Pico Explorer
i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN)
# for boards that use the alternate I2C pins use the line below instead
# i2c = PimoroniI2C(**PINS_PICO_EXPLORER)
# set up the RTC breakout
RV3028 = BreakoutRTC(i2c)
# set the Pico's RTC from the RTC breakout
RV3028.update_time()
RTC().datetime([RV3028.get_year(), RV3028.get_month(), RV3028.get_date(),
RV3028.get_weekday(), RV3028.get_hours(), RV3028.get_minutes(),
RV3028.get_seconds(), 0])
print(f"Pico RTC set to breakout time: {RV3028.string_date()} {RV3028.string_time()}")
# call the function
set_pico_time()

Wyświetl plik

@ -0,0 +1,152 @@
# Plasma Stick MicroPython Examples <!-- omit in toc -->
- [About Plasma Stick](#about-plasma-stick)
- [Plasma Library](#plasma-library)
- [Using Breakouts](#using-breakouts)
- [Basic Examples](#basic-examples)
- [Alternating Blinkies](#alternating-blinkies)
- [Fire](#fire)
- [Moon](#moon)
- [Rainbows](#rainbows)
- [Thermometer](#thermometer)
- [Advanced Examples](#advanced-examples)
- [CO2](#co2)
- [Encoder](#encoder)
- [Moon (RTC)](#moon-rtc)
- [PIR](#pir)
- [Thermometer (BME280)](#thermometer-bme280)
- [Wireless Examples](#wireless-examples)
- [Cheerlights](#cheerlights)
- [Weather](#weather)
## About Plasma Stick
Plasma Stick 2040 W is a compact controller for WS2812 strip, powered by Raspberry Pi Pico W and perfect for easy, seasonal lighting. It has built in ✨wireless connectivity✨, courtesy of the onboard Pico W.
You can buy one on its own or in a kit:
- [Plasma Stick 2040 W](https://shop.pimoroni.com/products/plasma-stick-2040-w)
- [Wireless Plasma Kit](https://shop.pimoroni.com/products/wireless-plasma-kit)
Plasma Stick ships with MicroPython firmware pre-loaded, but you can download the most recent version at the link below (you'll want the `pimoroni-picow` image).
- [MicroPython releases](https://github.com/pimoroni/pimoroni-pico/releases)
## Plasma Library
You can control your WS2812 / NeoPixel™ strip using our handy MicroPython Plasma library.
- [PicoGraphics MicroPython function reference](../../modules/plasma)
## Using Breakouts
Plasma Stick has a Qw/ST (Qwiic/STEMMA QT) connector. Breakouts with Qw/ST connectors, can be plugged straight in with a [JST-SH to JST-SH cable](https://shop.pimoroni.com/products/jst-sh-cable-qwiic-stemma-qt-compatible?variant=31910609813587). You can connect I2C Breakout Garden breakouts without Qw/ST connectors using a [JST-SH to JST-SH cable](https://shop.pimoroni.com/products/jst-sh-cable-qwiic-stemma-qt-compatible?variant=31910609813587) and a [Qw/ST to Breakout Garden adaptor](https://shop.pimoroni.com/products/stemma-qt-qwiic-to-breakout-garden-adapter).
- [List of breakouts currently supported in our C++/MicroPython build](https://github.com/pimoroni/pimoroni-pico#breakouts)
Plasma Stick uses GP4 and GP5 for its I2C interface. You can use the constants in the shared `pimoroni` module to set up the I2C interface:
```python
from pimoroni_i2c import PimoroniI2C
from pimoroni import PINS_BREAKOUT_GARDEN
i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN)
```
Alternatively, you can specify the pin numbers directly:
```python
from pimoroni_i2c import PimoroniI2C
i2c = PimoroniI2C(sda=(4), scl=(5))
```
## Basic Examples
### Alternating Blinkies
[alternating-blinkies.py](alternating-blinkies.py)
A simple example with two alternating colours, great for festive lights!
### Fire
[fire.py](fire.py)
A simple 🔥 fire effect example 🤘 (warning, flashy).
### Moon
[moon.py](moon.py)
Spooky moon simulator - the LEDs will get brighter as midnight approaches!
Needs to be run from Thonny to get the correct time.
### Rainbows
[rainbows.py](rainbows.py)
Some good old fashioned rainbows!
### Thermometer
[thermometer_pico.py](thermometer_pico.py)
Reads the temperature from the Pico W's internal temperature sensor and changes the LED strip an appropriate colour.
## Advanced Examples
These examples require additional hardware.
### CO2
[co2.py](co2.py)
Reads CO2 level from a [SCD41 CO2 breakout](https://shop.pimoroni.com/products/scd41-co2-sensor-breakout) and turns the LED strip an appropriate colour.
### Encoder
[encoder.py](encoder.py)
Adjust the colour of your LEDs easily with an [RGB Encoder breakout](https://shop.pimoroni.com/products/rgb-encoder-breakout?variant=32236590399571).
### Moon (RTC)
[moon_rtc.py](moon_rtc.py)
Spooky moon simulator - the LEDs will get brighter as midnight approaches!
Gets the time from a [RV3028 RTC breakout](https://shop.pimoroni.com/products/rv3028-real-time-clock-rtc-breakout).
### PIR
[pir.py](pir.py)
Connect a PIR motion sensor and trigger some ominous effects. We like [these ones](https://shop.pimoroni.com/products/micro-pir-motion-sensor-2-pcs) - we connected ours to the QwST connector using [this cable](https://shop.pimoroni.com/products/jst-sh-cable-qwiic-stemma-qt-compatible?variant=31910609846355) and some [socket to socket](https://shop.pimoroni.com/products/jumper-jerky-junior?variant=1076482185) jumper jerky.
### Thermometer (BME280)
[thermometer_bme280.py](thermometer_bme280.py)
Reads the temperature from a [BME280 breakout](https://shop.pimoroni.com/products/bme280-breakout) and changes the LED strip an appropriate colour.
## Wireless Examples
The wireless examples need `network_manager.py` and `WIFI_CONFIG.py` from the `common` directory to be saved to your Pico W. Open up `WIFI_CONFIG.py` in Thonny to add your wifi details (and save it when you're done).
- [micropython/examples/common](../../examples/common)
### Cheerlights
[cheerlights.py](cheerlights.py)
Sets your LED strip to the current #cheerlights colour.
Find out more about the Cheerlights API at [https://cheerlights.com/].
### Weather
[weather.py](weather.py)
This Plasma Stick example connects to Open Meteo to access the current weather conditions.
It then does some cool weather appropriate stuff with LEDs.
Find out more about the Open Meteo API at [https://open-meteo.com].

Wyświetl plik

@ -0,0 +1,42 @@
import plasma
from plasma import plasma_stick
import time
"""
This super simple example sets up two alternating colours, great for festive lights!
"""
# Set how many LEDs you have
NUM_LEDS = 50
# Pick two hues from the colour wheel (from 0-360°, try https://www.cssscript.com/demo/hsv-hsl-color-wheel-picker-reinvented/ )
HUE_1 = 40
HUE_2 = 285
# Set up brightness (between 0 and 1)
BRIGHTNESS = 0.5
# Set up speed (wait time between colour changes, in seconds)
SPEED = 1
# WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma_stick.DAT)
# Start updating the LED strip
led_strip.start()
while True:
for i in range(NUM_LEDS):
# the if statements below use a modulo operation to identify the even and odd numbered LEDs
if (i % 2) == 0:
led_strip.set_hsv(i, HUE_1 / 360, 1.0, BRIGHTNESS)
else:
led_strip.set_hsv(i, HUE_2 / 360, 1.0, BRIGHTNESS)
time.sleep(SPEED)
for i in range(NUM_LEDS):
if (i % 2) == 0:
led_strip.set_hsv(i, HUE_2 / 360, 1.0, BRIGHTNESS)
else:
led_strip.set_hsv(i, HUE_1 / 360, 1.0, BRIGHTNESS)
time.sleep(SPEED)

Wyświetl plik

@ -0,0 +1,119 @@
import WIFI_CONFIG
from network_manager import NetworkManager
import uasyncio
import urequests
import time
import plasma
from plasma import plasma_stick
from machine import Pin
'''
This Plasma Stick example sets your LED strip to the current #cheerlights colour.
Find out more about the Cheerlights API at https://cheerlights.com/
'''
URL = 'http://api.thingspeak.com/channels/1417/field/2/last.json'
UPDATE_INTERVAL = 120 # refresh interval in secs. Be nice to free APIs!
# Set how many LEDs you have
NUM_LEDS = 50
def status_handler(mode, status, ip):
# reports wifi connection status
print(mode, status, ip)
print('Connecting to wifi...')
# flash while connecting
for i in range(NUM_LEDS):
led_strip.set_rgb(i, 255, 255, 255)
time.sleep(0.02)
for i in range(NUM_LEDS):
led_strip.set_rgb(i, 0, 0, 0)
if status is not None:
if status:
print('Wifi connection successful!')
else:
print('Wifi connection failed!')
# if no wifi connection, you get spooky rainbows. Bwahahaha!
spooky_rainbows()
def spooky_rainbows():
print('SPOOKY RAINBOWS!')
HUE_START = 30 # orange
HUE_END = 140 # green
SPEED = 0.3 # bigger = faster (harder, stronger)
distance = 0.0
direction = SPEED
while True:
for i in range(NUM_LEDS):
# generate a triangle wave that moves up and down the LEDs
j = max(0, 1 - abs(distance - i) / (NUM_LEDS / 3))
hue = HUE_START + j * (HUE_END - HUE_START)
led_strip.set_hsv(i, hue / 360, 1.0, 0.8)
# reverse direction at the end of colour segment to avoid an abrupt change
distance += direction
if distance > NUM_LEDS:
direction = - SPEED
if distance < 0:
direction = SPEED
time.sleep(0.01)
def hex_to_rgb(hex):
# converts a hex colour code into RGB
h = hex.lstrip('#')
r, g, b = (int(h[i:i + 2], 16) for i in (0, 2, 4))
return r, g, b
# set up the Pico W's onboard LED
pico_led = Pin('LED', Pin.OUT)
# set up the WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma_stick.DAT)
# start updating the LED strip
led_strip.start()
# set up wifi
try:
network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler)
uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK))
except Exception as e:
print(f'Wifi connection failed! {e}')
# if no wifi, then you get...
spooky_rainbows()
while True:
# open the json file
print(f'Requesting URL: {URL}')
r = urequests.get(URL)
# open the json data
j = r.json()
print('Data obtained!')
r.close()
# flash the onboard LED after getting data
pico_led.value(True)
time.sleep(0.2)
pico_led.value(False)
# extract hex colour from the data
hex = j['field2']
# and convert it to RGB
r, g, b = hex_to_rgb(hex)
# light up the LEDs
for i in range(NUM_LEDS):
led_strip.set_rgb(i, r, g, b)
print(f'LEDs set to {hex}')
# sleep
print(f'Sleeping for {UPDATE_INTERVAL} seconds.')
time.sleep(UPDATE_INTERVAL)

Wyświetl plik

@ -0,0 +1,55 @@
import plasma
from plasma import plasma_stick
import breakout_scd41 as scd
from pimoroni_i2c import PimoroniI2C
"""
Reads CO2 level from an SCD41 breakout...
... and changes the LED strip an appropriate colour.
https://shop.pimoroni.com/products/scd41-co2-sensor-breakout
"""
# set how many LEDs you have
NUM_LEDS = 50
BRIGHTNESS = 1.0
# the range of readings to map to colours
# https://www.kane.co.uk/knowledge-centre/what-are-safe-levels-of-co-and-co2-in-rooms
MIN = 400
MAX = 2000
# pick what bits of the colour wheel to use (from 0-360°)
# https://www.cssscript.com/demo/hsv-hsl-color-wheel-picker-reinvented/
HUE_START = 100 # green
HUE_END = 0 # red
# WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma_stick.DAT)
# Start updating the LED strip
led_strip.start()
# set up I2C
i2c = PimoroniI2C(plasma_stick.SDA, plasma_stick.SCL)
# set up SCD41 breakout
scd.init(i2c)
scd.start()
print("Waiting for SCD41 to be ready")
while True:
if scd.ready():
co2, temperature, humidity = scd.measure()
print(f"""
CO2: {co2} ppm
Temperature: {temperature:.2f} °C
Humidity: {humidity:.2f} %""")
# calculates a colour
hue = HUE_START + ((co2 - MIN) * (HUE_END - HUE_START) / (MAX - MIN))
# set the leds
for i in range(NUM_LEDS):
led_strip.set_hsv(i, hue / 360, 1.0, BRIGHTNESS)

Wyświetl plik

@ -0,0 +1,78 @@
from pimoroni_i2c import PimoroniI2C
from breakout_encoder import BreakoutEncoder
import plasma
from plasma import plasma_stick
"""
Change the colour of your LEDs easily by hooking up an RGB Encoder Breakout!
"""
# set how many LEDs you have
NUM_LEDS = 50
# make this number bigger for more precise colour adjustments
STEPS_PER_REV = 24
i2c = PimoroniI2C(plasma_stick.SDA, plasma_stick.SCL)
enc = BreakoutEncoder(i2c)
enc.set_brightness(1.0)
# enc.set_direction(BreakoutEncoder.DIRECTION_CCW) # Uncomment this to flip the direction
def hsv_to_rgb(h, s, v):
# From CPython Lib/colorsys.py
if s == 0.0:
return v, v, v
i = int(h * 6.0)
f = (h * 6.0) - i
p = v * (1.0 - s)
q = v * (1.0 - s * f)
t = v * (1.0 - s * (1.0 - f))
i = i % 6
if i == 0:
return v, t, p
if i == 1:
return q, v, p
if i == 2:
return p, v, t
if i == 3:
return p, q, v
if i == 4:
return t, p, v
if i == 5:
return v, p, q
def count_changed(count):
print("Count: ", count, sep="")
h = ((count % STEPS_PER_REV) * 360.0) / STEPS_PER_REV # Convert the count to a colour hue
r, g, b = [int(255 * c) for c in hsv_to_rgb(h / 360.0, 1.0, 1.0)] # rainbow magic
# set the encoder LED colour
enc.set_led(r, g, b)
# set the led strip to match
for i in range(NUM_LEDS):
led_strip.set_rgb(i, r, g, b)
# WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma_stick.DAT)
# Start updating the LED strip
led_strip.start()
count = 0
count_changed(count)
enc.clear_interrupt_flag()
while True:
if enc.get_interrupt_flag():
count = enc.read()
enc.clear_interrupt_flag()
while count < 0:
count += STEPS_PER_REV
count_changed(count)

Wyświetl plik

@ -0,0 +1,23 @@
import plasma
from plasma import plasma_stick
import time
from random import random, uniform
"""
A basic fire effect.
"""
# Set how many LEDs you have
NUM_LEDS = 50
# WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma_stick.DAT)
# Start updating the LED strip
led_strip.start()
while True:
# fire effect! Random red/orange hue, full saturation, random brightness
for i in range(NUM_LEDS):
led_strip.set_hsv(i, uniform(0.0, 50 / 360), 1.0, random())
time.sleep(0.1)

Wyświetl plik

@ -0,0 +1,56 @@
import time
import plasma
from plasma import plasma_stick
from machine import RTC
"""
Spooky moon simulator!
The LEDs will get brighter as midnight approaches!
It won't do much in the day...
Needs to be run from Thonny to get the right time.
"""
# Set how many LEDs you have
NUM_LEDS = 50
# pick a hue (0 - 360° on the colour wheel)
# warm white moon - 60, blue moon - 230 , blood moon - 0
HUE = 60
SATURATION = 0.2 # increase this for a more colourful moon (max 1.0)
# when to start counting down from, in seconds before midnight
# eg from 10pm = 2 hours = 2 * 60 * 60 = 7200
COUNT_FROM = 14400
# set up the WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma_stick.DAT)
# start updating the LED strip
led_strip.start()
while True:
# get the time from Pico RTC
year, month, day, _, hour, minute, second, _ = RTC().datetime()
print(f'Time is {hour:02d}:{minute:02d}')
# calculate how long to go until midnight
if hour >= 12:
hours_to_go = 23 - hour
minutes_to_go = 59 - minute
seconds_to_go = 59 - second
total_seconds = hours_to_go * 60 * 60 + minutes_to_go * 60 + seconds_to_go
print(f'{total_seconds} seconds until midnight')
# or, if it's after midnight
else:
hours_since = 0 + hour
minutes_since = 0 + minute
seconds_since = 0 + second
total_seconds = hours_since * 60 * 60 + minutes_since * 60 + seconds_since
print(f'{total_seconds} seconds since midnight')
# gets brighter as witching hour approacheth
brightness = max(0, (COUNT_FROM - total_seconds) / COUNT_FROM)
for i in range(NUM_LEDS):
led_strip.set_hsv(i, HUE / 360.0, SATURATION, brightness)
print(f'Brightness - {brightness * 100} %')
time.sleep(10.0)

Wyświetl plik

@ -0,0 +1,83 @@
import time
import plasma
from plasma import plasma_stick
from machine import RTC
"""
Spooky moon simulator!
The LEDs will get brighter as midnight approaches!
It won't do much in the day...
Gets the time from a connected RV3028 RTC breakout:
https://shop.pimoroni.com/products/rv3028-real-time-clock-rtc-breakout
"""
# Set how many LEDs you have
NUM_LEDS = 50
# pick a hue (0 - 360° on the colour wheel)
# warm white moon - 60, blue moon - 230 , blood moon - 0
HUE = 60
SATURATION = 0.2 # increase this for a more colourful moon (max 1.0)
# when to start counting down from, in seconds before midnight
# eg from 10pm = 2 hours = 2 * 60 * 60 = 7200
COUNT_FROM = 14400
def set_pico_time():
# the function sets the Pico's RTC from a RV3028 RTC breakout
# to setup breakout (and set the time) run this first:
# https://github.com/pimoroni/pimoroni-pico/blob/main/micropython/examples/breakout_rtc/set-time.py
from pimoroni_i2c import PimoroniI2C
from breakout_rtc import BreakoutRTC
from machine import RTC
# set up I2C
i2c = PimoroniI2C(plasma_stick.SDA, plasma_stick.SCL)
# set up the RTC breakout
RV3028 = BreakoutRTC(i2c)
# set the Pico's RTC from the RTC breakout
RV3028.update_time()
RTC().datetime([RV3028.get_year(), RV3028.get_month(), RV3028.get_date(),
RV3028.get_weekday(), RV3028.get_hours(), RV3028.get_minutes(),
RV3028.get_seconds(), 0])
print(f"Pico RTC set to breakout time: {RV3028.string_date()} {RV3028.string_time()}")
# set up the WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma_stick.DAT)
# start updating the LED strip
led_strip.start()
# call our function to set the Pico's RTC
set_pico_time()
while True:
# get the time from Pico RTC
year, month, day, _, hour, minute, second, _ = RTC().datetime()
print(f'Time is {hour:02d}:{minute:02d}')
# calculate how long to go until midnight
if hour >= 12:
hours_to_go = 23 - hour
minutes_to_go = 59 - minute
seconds_to_go = 59 - second
total_seconds = hours_to_go * 60 * 60 + minutes_to_go * 60 + seconds_to_go
print(f'{total_seconds} seconds until midnight')
# or, if it's after midnight
else:
hours_since = 0 + hour
minutes_since = 0 + minute
seconds_since = 0 + second
total_seconds = hours_since * 60 * 60 + minutes_since * 60 + seconds_since
print(f'{total_seconds} seconds since midnight')
# gets brighter as witching hour approacheth
brightness = max(0, (COUNT_FROM - total_seconds) / COUNT_FROM)
for i in range(NUM_LEDS):
led_strip.set_hsv(i, HUE / 360.0, SATURATION, brightness)
print(f'Brightness - {brightness * 100} %')
time.sleep(10.0)

Wyświetl plik

@ -0,0 +1,102 @@
import plasma
from plasma import plasma_stick
from machine import Pin
import time
from random import random, uniform, choice
"""
This example uses a PIR sensor to trigger some spooky effects.
We connected ours up to our QW/ST connector.
"""
# Set how many LEDs you have
NUM_LEDS = 50
BRIGHTNESS = 0.8
HUE = 0.8
# randomly pick a different colour every time an effect fires
RANDOM = True
def spooky_flash():
for i in range(NUM_LEDS):
led_strip.set_hsv(i, HUE, 1.0, BRIGHTNESS / 2)
time.sleep(0.1)
for i in range(NUM_LEDS):
led_strip.set_hsv(i, HUE, 1.0, 0.0)
time.sleep(0.1)
for i in range(NUM_LEDS):
led_strip.set_hsv(i, HUE, 1.0, BRIGHTNESS / 2)
time.sleep(0.1)
for i in range(NUM_LEDS):
led_strip.set_hsv(i, HUE, 1.0, 0.0)
time.sleep(0.1)
for i in range(NUM_LEDS):
led_strip.set_hsv(i, HUE, 1.0, BRIGHTNESS / 2)
time.sleep(0.1)
for i in range(NUM_LEDS):
led_strip.set_hsv(i, HUE, 1.0, 0.0)
time.sleep(0.1)
for i in range(NUM_LEDS):
led_strip.set_hsv(i, HUE, 1.0, BRIGHTNESS)
time.sleep(3)
for i in range(NUM_LEDS):
led_strip.set_hsv(i, HUE, 1.0, BRIGHTNESS / 2)
time.sleep(0.1)
for i in range(NUM_LEDS):
led_strip.set_hsv(i, HUE, 1.0, 0.0)
time.sleep(0.1)
# uncomment next line to increase tension
# time.sleep(randrange(0, 15))
def fire():
while pir.value() == 1:
# fire effect! Random red/orange hue, full saturation, random brightness
for i in range(NUM_LEDS):
led_strip.set_hsv(i, uniform(0.0, 50 / 360), 1.0, random())
time.sleep(0.1)
def all_on():
while pir.value == 1:
# light up a solid colour while movement is detected
for i in range(NUM_LEDS):
led_strip.set_hsv(i, HUE, 1.0, BRIGHTNESS)
time.sleep(0.1)
# set up the hardware
# WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma_stick.DAT)
# the pin the signal line of our PIR sensor is connected to
# if you're using one of our qw/st > DuPont cables the blue wire is SDA (GP4) and the yellow wire is SCL (GP5)
pir = Pin(plasma_stick.SCL, Pin.IN, Pin.PULL_UP)
# Start updating the LED strip
led_strip.start()
while True:
# on movement
if pir.value() == 1:
print("Movement detected!")
# pick a random colour
if RANDOM is True:
HUE = random()
# pick a random effect
effects = [spooky_flash, fire, all_on]
choice(effects)()
# if you want a specific effect, comment the lines above and uncomment one of these:
# spooky_flash()
# fire()
# all_on()
else:
for i in range(NUM_LEDS):
led_strip.set_hsv(i, 1.0, 1.0, 0.0)
time.sleep(0.1)

Wyświetl plik

@ -0,0 +1,36 @@
import plasma
from plasma import plasma_stick
import time
"""
Make some rainbows!
"""
# Set how many LEDs you have
NUM_LEDS = 50
# The SPEED that the LEDs cycle at (1 - 255)
SPEED = 20
# How many times the LEDs will be updated per second
UPDATES = 60
# WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma_stick.DAT)
# Start updating the LED strip
led_strip.start()
offset = 0.0
# Make rainbows
while True:
SPEED = min(255, max(1, SPEED))
offset += float(SPEED) / 2000.0
for i in range(NUM_LEDS):
hue = float(i) / NUM_LEDS
led_strip.set_hsv(i, hue + offset, 1.0, 1.0)
time.sleep(1.0 / UPDATES)

Wyświetl plik

@ -0,0 +1,54 @@
import plasma
from plasma import plasma_stick
import time
from breakout_bme280 import BreakoutBME280
from pimoroni_i2c import PimoroniI2C
"""
Reads the temperature from a BME280 breakout...
...and changes the LED strip an appropriate colour.
https://shop.pimoroni.com/products/bme280-breakout
"""
# Set how many LEDs you have
NUM_LEDS = 50
BRIGHTNESS = 1.0
# The range of readings that we want to map to colours
MIN = 10
MAX = 30
# pick what bits of the colour wheel to use (from 0-360°)
# https://www.cssscript.com/demo/hsv-hsl-color-wheel-picker-reinvented/
HUE_START = 230 # blue
HUE_END = 359 # red
# WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma_stick.DAT)
# Start updating the LED strip
led_strip.start()
# set up I2C
i2c = PimoroniI2C(plasma_stick.SDA, plasma_stick.SCL)
# set up BME280 breakout
bme = BreakoutBME280(i2c)
while True:
temperature, pressure, humidity = bme.read()
print(f"""
Temperature: {temperature:.2f} °C
Humidity: {humidity:.2f} %
Pressure: {pressure / 100:.2f} hPa
""")
# calculates a colour
hue = HUE_START + ((temperature - MIN) * (HUE_END - HUE_START) / (MAX - MIN))
# set the leds
for i in range(NUM_LEDS):
led_strip.set_hsv(i, hue / 360, 1.0, BRIGHTNESS)
time.sleep(0.5)

Wyświetl plik

@ -0,0 +1,64 @@
import plasma
from plasma import plasma_stick
import machine
import time
"""
Reads the internal temperature sensor on the Pico W...
... and changes the LED strip an appropriate colour.
"""
# Set how many LEDs you have
NUM_LEDS = 50
BRIGHTNESS = 1.0
# The range of readings that we want to map to colours
MIN = 10
MAX = 30
# pick what bits of the colour wheel to use (from 0-360°)
# https://www.cssscript.com/demo/hsv-hsl-color-wheel-picker-reinvented/
HUE_START = 230 # blue
HUE_END = 359 # red
# WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma_stick.DAT)
# Start updating the LED strip
led_strip.start()
sensor_temp = machine.ADC(4)
conversion_factor = 3.3 / (65535) # used for calculating a temperature from the raw sensor reading
# The Pico's temperature sensor is not super accurate and readings jump around
# lets do some averaging to avoid annoying flashing
n = 0
temperature = 20 # a dummy value to fill the array
temperature_array = [temperature] * 10 # average over 10 readings (5 secs)
while True:
# read the sensor
# the following two lines do some maths to convert the number from the temp sensor into celsius
reading = sensor_temp.read_u16() * conversion_factor
temperature = 27 - (reading - 0.706) / 0.001721
# add the most recent reading to the array
if n >= len(temperature_array):
n = 0
temperature_array[n] = temperature
n += 1
temperature_average = sum(temperature_array) / len(temperature_array)
print(f"""
Average temperature: {temperature_average:.2f} °C
""")
# calculates a colour
hue = HUE_START + ((temperature_average - MIN) * (HUE_END - HUE_START) / (MAX - MIN))
# set the leds
for i in range(NUM_LEDS):
led_strip.set_hsv(i, hue / 360, 1.0, BRIGHTNESS)
time.sleep(0.5)

Wyświetl plik

@ -0,0 +1,259 @@
import WIFI_CONFIG
from network_manager import NetworkManager
import uasyncio
import urequests
import time
import plasma
from plasma import plasma_stick
# Random functions! randrange is for picking integers from a range, and uniform is for floats.
from random import randrange, uniform
from machine import Timer, Pin
"""
Weather in a bottle!
This Plasma Stick example connects to Open Meteo to access the current weather conditions.
It then does some cool weather appropriate stuff with LEDs.
Find out more about the Open Meteo API at https://open-meteo.com
Based on original code by AxWax <3 https://github.com/axwax/Open-Meteo-Inky-Pack
"""
# Set how many LEDs you have
NUM_LEDS = 50
# Set your latitude/longitude here (find yours by right clicking in Google Maps!)
LAT = 53.38609085276884
LNG = -1.4239983439328177
TIMEZONE = "auto" # determines time zone from lat/long
URL = "https://api.open-meteo.com/v1/forecast?latitude=" + str(LAT) + "&longitude=" + str(LNG) + "&current_weather=true&timezone=" + TIMEZONE
UPDATE_INTERVAL = 900 # refresh interval in secs. Be nice to free APIs!
# Weather codes from https://open-meteo.com/en/docs#:~:text=WMO%20Weather%20interpretation%20codes%20(WW)
WEATHERCODES = {
0: 'clear sky',
1: 'mostly clear',
2: 'partly cloudy',
3: 'cloudy',
45: 'fog and depositing rime',
48: 'fog',
51: 'light drizzle',
53: 'moderate drizzle',
55: 'dense drizzle',
56: 'light freezing drizzle',
57: 'dense freezing drizzle',
61: 'slight rain',
63: 'moderate rain',
65: 'heavy rain',
66: 'light freezing rain',
67: 'heavy freezing rain',
71: 'slight snow',
73: 'moderate snow',
75: 'heavy snow',
77: 'snow grains',
80: 'slight rain showers',
81: 'moderate rain showers',
82: 'violent rain showers',
85: 'slight snow showers',
86: 'heavy snow showers',
95: 'thunderstorm',
96: 'thunderstorm with slight hail',
99: 'thunderstorm with heavy hail'
}
def status_handler(mode, status, ip):
# reports wifi connection status
print(mode, status, ip)
print('Connecting to wifi...')
# flash while connecting
for i in range(NUM_LEDS):
led_strip.set_rgb(i, 255, 255, 255)
time.sleep(0.02)
for i in range(NUM_LEDS):
led_strip.set_rgb(i, 0, 0, 0)
if status is not None:
if status:
print('Connection successful!')
else:
print('Connection failed!')
# light up red if connection fails
for i in range(NUM_LEDS):
led_strip.set_rgb(i, 255, 0, 0)
def get_data():
global weathercode
print(f"Requesting URL: {URL}")
r = urequests.get(URL)
# open the json data
j = r.json()
print("Data obtained!")
r.close()
# parse relevant data from JSON
current = j["current_weather"]
temperature = current["temperature"]
weathercode = current["weathercode"]
datetime_arr = current["time"].split("T")
print(f"""Temperature = {temperature}°C
Conditions = {WEATHERCODES[weathercode]}
Last Open-Meteo update: {datetime_arr[0]}, {datetime_arr[1]}
""")
# flash the onboard LED after getting data
pico_led.value(True)
time.sleep(0.2)
pico_led.value(False)
# the rest of our functions are for animations!
def display_current():
# paint our current LED colours to the strip
for i in range(NUM_LEDS):
led_strip.set_rgb(i, current_leds[i][0], current_leds[i][1], current_leds[i][2])
def move_to_target():
# nudge our current colours closer to the target colours
for i in range(NUM_LEDS):
for c in range(3): # 3 times, for R, G & B channels
if current_leds[i][c] < target_leds[i][c]:
current_leds[i][c] = min(current_leds[i][c] + ANIMATION_SPEED, target_leds[i][c]) # increase current, up to a maximum of target
elif current_leds[i][c] > target_leds[i][c]:
current_leds[i][c] = max(current_leds[i][c] - ANIMATION_SPEED, target_leds[i][c]) # reduce current, down to a minimum of target
def clear():
if weathercode == 0: # clear
# nice sunny yellow
for i in range(NUM_LEDS):
target_leds[i] = [randrange(220, 260), randrange(220, 260), randrange(60, 100)]
if weathercode == 1: # mostly clear
# sky blues
for i in range(NUM_LEDS):
target_leds[i] = [randrange(0, 40), randrange(150, 190), randrange(180, 220)]
def clouds():
# base colours:
if weathercode == 2:
cloud_colour = [165, 168, 138] # partly cloudy
if weathercode == 3:
cloud_colour = [93, 94, 83] # cloudy
if weathercode in (45, 48):
cloud_colour = [186, 185, 182] # foggy
# add highlights and lowlights
for i in range(NUM_LEDS):
if uniform(0, 1) < 0.001: # highlight
target_leds[i] = [x + 20 for x in cloud_colour]
elif uniform(0, 1) < 0.001: # lowlight
target_leds[i] = [x - 20 for x in cloud_colour]
elif uniform(0, 1) < 0.005: # normal
target_leds[i] = cloud_colour
def storm():
# heavy rain, with lightning!
raindrop_chance = 0.01
for i in range(NUM_LEDS):
if raindrop_chance > uniform(0, 1):
# paint a raindrop (use current rather than target, for an abrupt change to the drop colour)
current_leds[i] = [randrange(0, 50), randrange(20, 100), randrange(50, 255)]
else:
# paint backdrop
target_leds[i] = [0, 15, 60]
lightning_chance = 0.001
if lightning_chance > uniform(0, 1):
for i in range(NUM_LEDS):
current_leds[i] = [255, 255, 255]
def rain():
# splodgy blues
# first, work out how many raindrops:
if weathercode in (51, 56, 61, 66, 80): # light rain
raindrop_chance = 0.001
elif weathercode in (53, 63, 81): # moderate rain
raindrop_chance = 0.005
else:
# heavy rain
raindrop_chance = 0.01
for i in range(NUM_LEDS):
if raindrop_chance > uniform(0, 1):
# paint a raindrop (use current rather than target, for an abrupt change to the drop colour)
current_leds[i] = [randrange(0, 50), randrange(20, 100), randrange(50, 255)]
else:
# paint backdrop
target_leds[i] = [0, 15, 60]
def snow():
# splodgy whites
# first, work out how many snowflakes:
if weathercode in (71, 85): # light snow
snowflake_chance = 0.001
elif weathercode in (73, 77): # moderate snow
snowflake_chance = 0.005
else:
# heavy snow
snowflake_chance = 0.01
for i in range(NUM_LEDS):
if snowflake_chance > uniform(0, 1):
# paint a snowflake (use current rather than target, for an abrupt change to the drop colour)
current_leds[i] = [227, 227, 227]
else:
# paint backdrop
target_leds[i] = [54, 54, 54]
# some variables we'll use for animations
ANIMATION_SPEED = 1 # higher number gets from current to target colour faster
# Create an list of [r, g, b] values that will hold current LED colours, for display
current_leds = [[0] * 3 for i in range(NUM_LEDS)]
# Create an list of [r, g, b] values that will hold target LED colours, to move towards
target_leds = [[0] * 3 for i in range(NUM_LEDS)]
# set up the Pico W's onboard LED
pico_led = Pin('LED', Pin.OUT)
# set up the WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma_stick.DAT)
# start updating the LED strip
led_strip.start()
# set up wifi
network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler)
uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK))
# get the first lot of data
get_data()
# start timer (the timer will update our data every UPDATE_INTERVAL)
timer = Timer(-1)
timer.init(period=UPDATE_INTERVAL * 1000, mode=Timer.PERIODIC, callback=lambda t: get_data())
while True:
# do some fancy stuff with the LEDs based on the weather code
if 0 <= weathercode <= 1:
clear()
elif 2 <= weathercode <= 48:
clouds()
elif 51 <= weathercode <= 67 or 80 <= weathercode <= 82:
rain()
elif 71 <= weathercode <= 77 or 85 <= weathercode <= 86:
snow()
elif 95 <= weathercode <= 99:
storm()
else:
print("Unknown weather code :(")
move_to_target() # nudge our current colours closer to the target colours
display_current() # display current colours to strip

Wyświetl plik

@ -1,6 +1,8 @@
# Plasma <!-- omit in toc -->
The Plasma library is intended to drive APA102 / DotStar™ or WS2812 / NeoPixel™ LEDs on the Plasma 2040 board, though it can be used with your own custom pins/wiring.
The Plasma library is intended to drive APA102 / DotStar™ or WS2812 / NeoPixel™ LEDs on our [Plasma 2040](https://shop.pimoroni.com/products/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](https://shop.pimoroni.com/products/plasma-stick-2040-w). Note that APA102 compatibility, user buttons, RGB LED and current sensing functions are not present on Plasma Stick.
- [Notes On PIO Limitations](#notes-on-pio-limitations)
- [WS2812](#ws2812)
@ -33,6 +35,8 @@ In most cases you'll use `0` for PIO and `0` for PIO state-machine, but you shou
Construct a new `WS2812` instance, specifying the number of LEDs, PIO, PIO state-machine and GPIO pin.
For Plasma 2040:
```python
import plasma
from plasma import plasma2040
@ -43,6 +47,18 @@ FPS = 60
led_strip = plasma.WS2812(LEDS, 0, 0, plasma2040.DAT)
```
For Plasma Stick:
```python
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.
```python
@ -54,12 +70,6 @@ led_strip.start(FPS)
Some WS2812-style LED strips have varying colour orders and support an additional white element. Two keyword arguments are supplied to configure this:
```python
import plasma
from plasma import plasma2040
LEDS = 30
FPS = 60
led_strip = plasma.WS2812(LEDS, 0, 0, plasma2040.DAT, rgbw=True, color_order=plasma.COLOR_ORDER_GRB)
```
@ -212,7 +222,7 @@ led.set_rgb(0, 0, 255) # Full blue
## Measuring LED Strip Current Draw
Plasma 2040 feasures 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.
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.

Wyświetl plik

@ -86,16 +86,30 @@ STATIC const mp_map_elem_t plasma2040_globals_table[] = {
};
STATIC MP_DEFINE_CONST_DICT(mp_module_plasma2040_globals, plasma2040_globals_table);
STATIC const mp_map_elem_t plasma_stick_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_plasma_stick) },
{ MP_ROM_QSTR(MP_QSTR_DAT), MP_ROM_INT(15) },
{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_INT(4) },
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_INT(5) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_plasma_stick_globals, plasma_stick_globals_table);
const mp_obj_module_t plasma2040_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_plasma2040_globals,
};
const mp_obj_module_t plasma_stick_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_plasma_stick_globals,
};
STATIC const mp_map_elem_t plasma_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_plasma) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_APA102), (mp_obj_t)&PlasmaAPA102_type },
{ MP_OBJ_NEW_QSTR(MP_QSTR_WS2812), (mp_obj_t)&PlasmaWS2812_type },
{ MP_OBJ_NEW_QSTR(MP_QSTR_plasma2040), (mp_obj_t)&plasma2040_user_cmodule },
{ MP_OBJ_NEW_QSTR(MP_QSTR_plasma_stick), (mp_obj_t)&plasma_stick_user_cmodule },
{ MP_ROM_QSTR(MP_QSTR_COLOR_ORDER_RGB), MP_ROM_INT(0x00) },
{ MP_ROM_QSTR(MP_QSTR_COLOR_ORDER_RBG), MP_ROM_INT(0x01) },