Created
April 24, 2023 12:02
-
-
Save dgrnbrg/1f0e1e7d3b37c00e8edd985110deb989 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
####### | |
####### In your python env, make sure you've installed pyartnet (`pip install pyartnet`) | |
####### | |
####### To run, you do: `python3 artnet.py` or `python3 artnet.py 2` | |
####### The numeric argument is the index of the pixel's color channel that we're animating | |
####### | |
####### This does a chaser effect up & down a 288 pixel strand on each port. | |
####### | |
####### You can run with an environment variable to change the universe. I run 12 copies in 12 terminals, | |
####### because the python I wrote isn't fast enough to run single-threaded, but even an older multicore | |
####### laptop can run 12 copies: e.g. `START_UNIVERSE=25 python artnet.py 3` | |
####### | |
import asyncio | |
import logging | |
from pyartnet import SacnNode, ArtNetNode | |
import sys | |
import os | |
import math | |
####### | |
####### IP Address | |
####### | |
IP_ADDR = '192.168.20.119' | |
####### | |
####### Mode should be `sacn` or `artnet` only | |
####### | |
THE_MODE = 'artnet' | |
####### | |
####### You want this 3 for RGB or 4 for RGBW pixels | |
####### | |
NUM_CHANNELS_PER_LED = 4 | |
####### | |
####### This is how many pixels there are per led strand connector | |
####### | |
NUM_PIXEL_PER_STRAND = 288 | |
####### | |
####### This is how many strands there are per dx connector | |
####### | |
STRANDS_PER_CONNECTOR = 4 | |
####### | |
####### This is how many connectors are in use | |
####### | |
NUM_CONNECTORS = 1 | |
####### | |
####### Uncomment the line below to see packets' bytes as they hit the wire | |
####### | |
#logging.basicConfig(level=logging.DEBUG) | |
async def main(): | |
if len(sys.argv) >= 2: | |
i = int(sys.argv[1]) | |
else: | |
i = 0 | |
if i < 0 or i > NUM_CHANNELS_PER_LED: | |
raise ValueError(f"Arg should in 0-{NUM_CHANNELS_PER_LED}, the color index") | |
#x = int(sys.argv[2]) | |
# This sets the max brightness we'll send out | |
x = 255 | |
# Run this code in your async function | |
if THE_MODE == 'sacn': | |
node = SacnNode(IP_ADDR, 5568, max_fps=30) | |
elif THE_MODE == 'artnet': | |
node = ArtNetNode(IP_ADDR, 6454, max_fps=30) | |
else: | |
raise ValueError(f"Mode should only be sacn or artnet") | |
node.set_output_correction(None) | |
if os.getenv("START_UNIVERSE") is not None: | |
next_universe = int(os.getenv("START_UNIVERSE")) | |
else: | |
next_universe = 1 | |
strands = [] | |
for i_connector in range(NUM_CONNECTORS): | |
for i_strand in range(STRANDS_PER_CONNECTOR): | |
universe = node.add_universe(next_universe) | |
print(f"starting universe {next_universe} for strand {i_strand} on connector {i_connector}") | |
next_universe += 1 | |
next_pos_in_universe = 1 | |
channels = [] | |
for i_pixel in range(NUM_PIXEL_PER_STRAND): | |
c = universe.add_channel(start = next_pos_in_universe, width=NUM_CHANNELS_PER_LED) | |
#print(f"universe={next_universe-1} start={next_pos_in_universe} width={NUM_CHANNELS_PER_LED}") | |
channels.append(c) | |
next_pos_in_universe += NUM_CHANNELS_PER_LED | |
if next_pos_in_universe + (NUM_CHANNELS_PER_LED-1) > 512: | |
print(f"filled universe {next_universe-1} because next_pos is {next_pos_in_universe}") | |
next_pos_in_universe = 1 | |
universe = node.add_universe(next_universe) | |
next_universe += 1 | |
print(f"used up to position {next_pos_in_universe} on {next_universe-1}") | |
strands.append(channels) | |
t = 0.9999999 | |
p = 0 | |
spread = 10 | |
falloff = 2 | |
dp = 0.5 | |
dt = -0.001 | |
while True: | |
val = [0] * NUM_CHANNELS_PER_LED | |
for channels in strands: | |
for idx,c in enumerate(channels): | |
if idx != p: | |
dist = spread / math.fabs(idx - p)**falloff | |
else: | |
dist = 1.0 | |
if dist > 1.0: | |
dist = 1.0 | |
elif dist < 0.0: | |
dist = 0.0 | |
val[i] = int(x * dist) | |
c.set_values(val) | |
t += dt | |
if t > 1 or t < 0.2: # brightness between 100% and 20% | |
dt = -dt | |
t += dt | |
p += dp | |
if p > NUM_PIXEL_PER_STRAND or p < 0: # brightness between 100% and 20% | |
dp = -dp | |
p += dp | |
# GRBW | |
#print(f"value is {int(x*t)}") | |
await asyncio.sleep(0.002) | |
await asyncio.sleep(0.2) | |
asyncio.run(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment