Skip to content

Commit

Permalink
A variant spiral demo now works on active3!
Browse files Browse the repository at this point in the history
.. with 3 64x64 panels.
  • Loading branch information
jepler committed Mar 7, 2025
1 parent 296047a commit 65b8b6f
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 1 deletion.
128 changes: 128 additions & 0 deletions examples/rainbow_spiral_active3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#!/usr/bin/python3
# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
Display a spiral around the display drawn with a rainbow color.
Run like this:
$ python rainbow_spiral.py
"""
import numpy as np
import rainbowio
from PIL import Image, ImageDraw

import adafruit_blinka_raspberry_pi5_piomatter as piomatter

width = 64
n_lanes = 6
n_addr_lines = 5
height = n_lanes << n_addr_lines
pen_radius = 1

def make_pixelmap_multilane(width, height, n_addr_lines, n_lanes):
calc_height = n_lanes << n_addr_lines
if height != calc_height:
raise RuntimeError(f"Calculated height {calc_height} does not match requested height {height}")
n_addr = 1 << n_addr_lines

m = []
for addr in range(n_addr):
for x in range(width):
for lane in range(n_lanes):
y = addr + lane * n_addr
m.append(x + width * y)
print(m)
return m


canvas = Image.new('RGB', (width, height), (0, 0, 0))
draw = ImageDraw.Draw(canvas)

pixelmap = make_pixelmap_multilane(width, height, n_addr_lines, n_lanes)
geometry = piomatter.Geometry(width=width, height=height, n_addr_lines=n_addr_lines, n_planes=8, map=pixelmap, n_lanes=n_lanes)
framebuffer = np.asarray(canvas) + 0 # Make a mutable copy
matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB888Packed,
pinout=piomatter.Pinout.Active3,
framebuffer=framebuffer,
geometry=geometry)

color_index = 0

update_interval = 3
update_counter = 0
def update_matrix():
global update_counter
if (update_counter := update_counter + 1) >= update_interval:
framebuffer[:] = np.asarray(canvas)
matrix.show()
update_counter = 0

def darken_color(hex_color, darkness_factor):
# Convert hex color number to RGB
r = (hex_color >> 16) & 0xFF
g = (hex_color >> 8) & 0xFF
b = hex_color & 0xFF

# Apply darkness factor
r = int(r * (1 - darkness_factor))
g = int(g * (1 - darkness_factor))
b = int(b * (1 - darkness_factor))

# Ensure values are within the valid range
r = max(0, min(255, r))
g = max(0, min(255, g))
b = max(0, min(255, b))

# Convert RGB back to hex number
darkened_hex_color = (r << 16) + (g << 8) + b

return darkened_hex_color

step_count = 4
darkness_factor = 0.5

clearing = False

try:
# step_down_size = pen_radius * 2 + 2

while True:
for step in range(step_count):
step_down_size = step * (pen_radius* 2) + (2 * step)
for x in range(pen_radius + step_down_size, width - pen_radius - step_down_size - 1):
color_index = (color_index + 2) % 256
color = darken_color(rainbowio.colorwheel(color_index), darkness_factor) if not clearing else 0x000000
draw.circle((x, pen_radius + step_down_size), pen_radius, color)
update_matrix()
for y in range(pen_radius + step_down_size, height - pen_radius - step_down_size - 1):
color_index = (color_index + 2) % 256
color = darken_color(rainbowio.colorwheel(color_index), darkness_factor) if not clearing else 0x000000
draw.circle((width - pen_radius - step_down_size -1, y), pen_radius, color)
update_matrix()
for x in range(width - pen_radius - step_down_size - 1, pen_radius + step_down_size, -1):
color_index = (color_index + 2) % 256
color = darken_color(rainbowio.colorwheel(color_index), darkness_factor) if not clearing else 0x000000
draw.circle((x, height - pen_radius - step_down_size - 1), pen_radius, color)
update_matrix()
for y in range(height - pen_radius - step_down_size - 1, pen_radius + ((step+1) * (pen_radius* 2) + (2 * (step+1))) -1, -1):
color_index = (color_index + 2) % 256
color = darken_color(rainbowio.colorwheel(color_index), darkness_factor) if not clearing else 0x000000
draw.circle((pen_radius + step_down_size, y), pen_radius, color)
update_matrix()

if step != step_count-1:
# connect to next iter
for x in range(pen_radius + step_down_size, pen_radius + ((step+1) * (pen_radius* 2) + (2 * (step+1)))):
color_index = (color_index + 2) % 256
color = darken_color(rainbowio.colorwheel(color_index),
darkness_factor) if not clearing else 0x000000
draw.circle((x, pen_radius + ((step+1) * (pen_radius* 2) + (2 * (step+1)))), pen_radius, color)
update_matrix()

clearing = not clearing

except KeyboardInterrupt:
print("Exiting")
3 changes: 3 additions & 0 deletions src/adafruit_blinka_raspberry_pi5_piomatter/click.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def standard_options(
pinout=piomatter.Pinout.AdafruitMatrixBonnet,
n_planes=10,
n_addr_lines=4,
n_lanes=None,
) -> Callable[[], None]:
"""Add standard commandline flags, with the defaults given
Expand Down Expand Up @@ -77,6 +78,8 @@ def wrapper(f: click.decorators.FC):
f = click.option("--num-planes", "n_planes", default=n_planes, help="The number of bit planes (color depth. Lower values can improve refresh rate in frames per second")(f)
if n_addr_lines is not None:
f = click.option("--num-address-lines", "n_addr_lines", default=n_addr_lines, help="The number of address lines used by the panels")(f)
if n_lanes is not None:
f = click.option("--num-lanes", "n_lanes", default=n_lanes, help="The number of lanes used by the panels. One 16-pin connector has two lanes (6 RGB pins)")(f)
return f
if f is None:
return wrapper
Expand Down
3 changes: 2 additions & 1 deletion src/include/piomatter/render.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@ void protomatter_render_rgb10(std::vector<uint32_t> &result,
last_bit = bit;

prep_data(pixels_across);
auto mapiter = matrixmap.map.begin() + 2 * addr * pixels_across;
auto mapiter = matrixmap.map.begin() +
matrixmap.n_lanes * addr * pixels_across;
for (size_t x = 0; x < pixels_across; x++) {
uint32_t data = addr_bits;
for (size_t px = 0; px < matrixmap.n_lanes; px++) {
Expand Down
1 change: 1 addition & 0 deletions src/pymain.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <iostream>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <string>

#include "piomatter/piomatter.h"
Expand Down

0 comments on commit 65b8b6f

Please sign in to comment.