add examples

This commit is contained in:
helgibbons 2022-10-04 19:17:09 +01:00
parent 675de25985
commit dd6d0a23ea
4 changed files with 444 additions and 0 deletions

View File

@ -0,0 +1,79 @@
import WIFI_CONFIG
from network_manager import NetworkManager
import uasyncio
from urequests import get
import time
import ujson
import plasma
from plasma import plasma2040
"""
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('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 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 WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma2040.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))
while True:
# open the json file
print(f"Requesting URL: {URL}")
data = get(URL).json()
print("Data obtained!")
# extract hex colour from the data
hex = data['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)

View File

@ -0,0 +1,81 @@
from pimoroni_i2c import PimoroniI2C
from breakout_encoder import BreakoutEncoder
import plasma
from plasma import plasma2040
"""
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
PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5}
i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN)
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, plasma2040.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)

View File

@ -0,0 +1,47 @@
import plasma
from plasma import plasma2040
from pimoroni import RGBLED
from pimoroni_i2c import PimoroniI2C
import machine
import time
"""
Reads the internal temperature sensor on the Pico and changes the LED strip an appropriate colour.
"""
# Set how many LEDs you have
NUM_LEDS = 50
BRIGHTNESS = 1.0
MIN = 15
MAX = 30
# What you want your MIN colour to be - a hue between 0 and 360 degrees.
# Green is 120!
START_HUE = 120
# WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma2040.DAT, rgbw=False)
# 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
while True:
# 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
print(f"""
Temperature: {temperature:0.2f} * C
""")
# calculates a colour
hue = max(0, START_HUE / 360 * (1 - (temperature - MIN) / MAX))
for i in range(NUM_LEDS):
led_strip.set_hsv(i, hue, 1.0, BRIGHTNESS)
time.sleep(0.5)

View File

@ -0,0 +1,237 @@
import WIFI_CONFIG
from network_manager import NetworkManager
import uasyncio
from urequests import get
import time
import ujson
import plasma
from plasma import plasma2040
# Random functions! randrange is for picking integers from a range, and uniform is for floats.
from random import randrange, uniform
from machine import Timer
import gc
"""
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 = 500 # 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
# open the json file
print(f"Requesting URL: {URL}")
j = get(URL).json()
print("Data obtained!")
# 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]}
""")
gc.collect()
# 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():
# nice sunny yellow
for i in range(NUM_LEDS):
target_leds[i] = [242, 237,80]
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 = 2 # higher number gets from current to target colour faster
current_leds = [ [0] * 3 for i in range(NUM_LEDS)] # Create an list of [r, g, b] values that will hold current LED colours, for display
target_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
# set up the WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma2040.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