added examples

This commit is contained in:
waltem01 2023-11-22 15:45:55 +01:00
parent bfecec752a
commit 9914cd4b23
13 changed files with 525 additions and 2 deletions

2
.gitignore vendored
View File

@ -1,7 +1,5 @@
API/bin
API/obj
API/deps/samples
.vscode
.idea

81
API/deps/samplebase.py Normal file
View File

@ -0,0 +1,81 @@
import argparse
import time
import sys
import os
# sys.path.append(os.path.abspath(os.path.dirname(__file__) + '/..'))
from rgbmatrix import RGBMatrix, RGBMatrixOptions
class SampleBase(object):
def __init__(self, *args, **kwargs):
self.parser = argparse.ArgumentParser()
self.parser.add_argument("-r", "--led-rows", action="store", help="Display rows. 16 for 16x32, 32 for 32x32. Default: 64", default=64, type=int)
self.parser.add_argument("--led-cols", action="store", help="Panel columns. Typically 32 or 64. (Default: 64)", default=64, type=int)
self.parser.add_argument("-c", "--led-chain", action="store", help="Daisy-chained boards. Default: 1.", default=1, type=int)
self.parser.add_argument("-P", "--led-parallel", action="store", help="For Plus-models or RPi2: parallel chains. 1..3. Default: 1", default=1, type=int)
self.parser.add_argument("-p", "--led-pwm-bits", action="store", help="Bits used for PWM. Something between 1..11. Default: 11", default=11, type=int)
self.parser.add_argument("-b", "--led-brightness", action="store", help="Sets brightness level. Default: 100. Range: 1..100", default=100, type=int)
self.parser.add_argument("-m", "--led-gpio-mapping", help="Hardware Mapping: regular, adafruit-hat, adafruit-hat-pwm", choices=['regular', 'regular-pi1', 'adafruit-hat', 'adafruit-hat-pwm'], default='adafruit-hat', type=str)
self.parser.add_argument("--led-scan-mode", action="store", help="Progressive or interlaced scan. 0 Progressive, 1 Interlaced (default)", default=1, choices=range(2), type=int)
self.parser.add_argument("--led-pwm-lsb-nanoseconds", action="store", help="Base time-unit for the on-time in the lowest significant bit in nanoseconds. Default: 130", default=130, type=int)
self.parser.add_argument("--led-show-refresh", action="store_true", help="Shows the current refresh rate of the LED panel")
self.parser.add_argument("--led-slowdown-gpio", action="store", help="Slow down writing to GPIO. Range: 0..4. Default: 1", default=4, type=int)
self.parser.add_argument("--led-no-hardware-pulse", action="store", help="Don't use hardware pin-pulse generation")
self.parser.add_argument("--led-rgb-sequence", action="store", help="Switch if your matrix has led colors swapped. Default: RGB", default="RGB", type=str)
self.parser.add_argument("--led-pixel-mapper", action="store", help="Apply pixel mappers. e.g \"Rotate:90\"", default="", type=str)
self.parser.add_argument("--led-row-addr-type", action="store", help="0 = default; 1=AB-addressed panels; 2=row direct; 3=ABC-addressed panels; 4 = ABC Shift + DE direct", default=0, type=int, choices=[0,1,2,3,4])
self.parser.add_argument("--led-multiplexing", action="store", help="Multiplexing type: 0=direct; 1=strip; 2=checker; 3=spiral; 4=ZStripe; 5=ZnMirrorZStripe; 6=coreman; 7=Kaler2Scan; 8=ZStripeUneven... (Default: 0)", default=0, type=int)
self.parser.add_argument("--led-panel-type", action="store", help="Needed to initialize special panels. Supported: 'FM6126A'", default="", type=str)
self.parser.add_argument("--led-no-drop-privs", dest="drop_privileges", help="Don't drop privileges from 'root' after initializing the hardware.", action='store_false')
self.parser.set_defaults(drop_privileges=True)
def usleep(self, value):
time.sleep(value / 1000000.0)
def run(self):
print("Running")
def process(self):
self.args = self.parser.parse_args()
options = RGBMatrixOptions()
if self.args.led_gpio_mapping != None:
options.hardware_mapping = self.args.led_gpio_mapping
options.rows = self.args.led_rows
options.cols = self.args.led_cols
options.chain_length = self.args.led_chain
options.parallel = self.args.led_parallel
options.row_address_type = self.args.led_row_addr_type
options.multiplexing = self.args.led_multiplexing
options.pwm_bits = self.args.led_pwm_bits
options.brightness = self.args.led_brightness
options.pwm_lsb_nanoseconds = self.args.led_pwm_lsb_nanoseconds
options.led_rgb_sequence = self.args.led_rgb_sequence
options.pixel_mapper_config = self.args.led_pixel_mapper
options.panel_type = self.args.led_panel_type
if self.args.led_show_refresh:
options.show_refresh_rate = 1
if self.args.led_slowdown_gpio != None:
options.gpio_slowdown = self.args.led_slowdown_gpio
if self.args.led_no_hardware_pulse:
options.disable_hardware_pulsing = True
if not self.args.drop_privileges:
options.drop_privileges=False
self.matrix = RGBMatrix(options = options)
try:
# Start loop
print("Press CTRL-C to stop sample")
self.run()
except KeyboardInterrupt:
print("Exiting\n")
sys.exit(0)
return True

View File

@ -0,0 +1,32 @@
#!/usr/bin/env python
from samplebase import SampleBase
from rgbmatrix import graphics
import time
class GraphicsTest(SampleBase):
def __init__(self, *args, **kwargs):
super(GraphicsTest, self).__init__(*args, **kwargs)
def run(self):
canvas = self.matrix
font = graphics.Font()
font.LoadFont("../../../fonts/7x13.bdf")
red = graphics.Color(255, 0, 0)
graphics.DrawLine(canvas, 5, 5, 22, 13, red)
green = graphics.Color(0, 255, 0)
graphics.DrawCircle(canvas, 15, 15, 10, green)
blue = graphics.Color(0, 0, 255)
graphics.DrawText(canvas, font, 2, 10, blue, "Text")
time.sleep(10) # show display for 10 seconds before exit
# Main function
if __name__ == "__main__":
graphics_test = GraphicsTest()
if (not graphics_test.process()):
graphics_test.print_help()

View File

@ -0,0 +1,39 @@
#!/usr/bin/env python
from samplebase import SampleBase
import time
class GrayscaleBlock(SampleBase):
def __init__(self, *args, **kwargs):
super(GrayscaleBlock, self).__init__(*args, **kwargs)
def run(self):
sub_blocks = 16
width = self.matrix.width
height = self.matrix.height
x_step = max(1, width / sub_blocks)
y_step = max(1, height / sub_blocks)
count = 0
while True:
for y in range(0, height):
for x in range(0, width):
c = sub_blocks * int(y / y_step) + int(x / x_step)
if count % 4 == 0:
self.matrix.SetPixel(x, y, c, c, c)
elif count % 4 == 1:
self.matrix.SetPixel(x, y, c, 0, 0)
elif count % 4 == 2:
self.matrix.SetPixel(x, y, 0, c, 0)
elif count % 4 == 3:
self.matrix.SetPixel(x, y, 0, 0, c)
count += 1
time.sleep(2)
# Main function
if __name__ == "__main__":
grayscale_block = GrayscaleBlock()
if (not grayscale_block.process()):
grayscale_block.print_help()

View File

@ -0,0 +1,48 @@
#!/usr/bin/env python
# (This is an example similar to an example from the Adafruit fork
# to show the similarities. Most important difference currently is, that
# this library wants RGB mode.)
#
# A more complex RGBMatrix example works with the Python Imaging Library,
# demonstrating a few graphics primitives and image loading.
# Note that PIL graphics do not have an immediate effect on the display --
# image is drawn into a separate buffer, which is then copied to the matrix
# using the SetImage() function (see examples below).
# Requires rgbmatrix.so present in the same directory.
# PIL Image module (create or load images) is explained here:
# http://effbot.org/imagingbook/image.htm
# PIL ImageDraw module (draw shapes to images) explained here:
# http://effbot.org/imagingbook/imagedraw.htm
from PIL import Image
from PIL import ImageDraw
import time
from rgbmatrix import RGBMatrix, RGBMatrixOptions
# Configuration for the matrix
options = RGBMatrixOptions()
options.rows = 32
options.chain_length = 1
options.parallel = 1
options.hardware_mapping = 'regular' # If you have an Adafruit HAT: 'adafruit-hat'
matrix = RGBMatrix(options = options)
# RGB example w/graphics prims.
# Note, only "RGB" mode is supported currently.
image = Image.new("RGB", (32, 32)) # Can be larger than matrix if wanted!!
draw = ImageDraw.Draw(image) # Declare Draw instance before prims
# Draw some shapes into image (no immediate effect on matrix)...
draw.rectangle((0, 0, 31, 31), fill=(0, 0, 0), outline=(0, 0, 255))
draw.line((0, 0, 31, 31), fill=(255, 0, 0))
draw.line((0, 31, 31, 0), fill=(0, 255, 0))
# Then scroll image across matrix...
for n in range(-32, 33): # Start off top-left, move off bottom-right
matrix.Clear()
matrix.SetImage(image, n, n)
time.sleep(0.05)
matrix.Clear()

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python
import time
from samplebase import SampleBase
from PIL import Image
class ImageScroller(SampleBase):
def __init__(self, *args, **kwargs):
super(ImageScroller, self).__init__(*args, **kwargs)
self.parser.add_argument("-i", "--image", help="The image to display", default="../../../examples-api-use/runtext.ppm")
def run(self):
if not 'image' in self.__dict__:
self.image = Image.open(self.args.image).convert('RGB')
self.image.resize((self.matrix.width, self.matrix.height), Image.ANTIALIAS)
double_buffer = self.matrix.CreateFrameCanvas()
img_width, img_height = self.image.size
# let's scroll
xpos = 0
while True:
xpos += 1
if (xpos > img_width):
xpos = 0
double_buffer.SetImage(self.image, -xpos)
double_buffer.SetImage(self.image, -xpos + img_width)
double_buffer = self.matrix.SwapOnVSync(double_buffer)
time.sleep(0.01)
# Main function
# e.g. call with
# sudo ./image-scroller.py --chain=4
# if you have a chain of four
if __name__ == "__main__":
image_scroller = ImageScroller()
if (not image_scroller.process()):
image_scroller.print_help()

View File

@ -0,0 +1,34 @@
#!/usr/bin/env python
import time
import sys
from rgbmatrix import RGBMatrix, RGBMatrixOptions
from PIL import Image
if len(sys.argv) < 2:
sys.exit("Require an image argument")
else:
image_file = sys.argv[1]
image = Image.open(image_file)
# Configuration for the matrix
options = RGBMatrixOptions()
options.rows = 32
options.chain_length = 1
options.parallel = 1
options.hardware_mapping = 'regular' # If you have an Adafruit HAT: 'adafruit-hat'
matrix = RGBMatrix(options = options)
# Make image fit our screen.
image.thumbnail((matrix.width, matrix.height), Image.ANTIALIAS)
matrix.SetImage(image.convert('RGB'))
try:
print("Press CTRL-C to stop.")
while True:
time.sleep(100)
except KeyboardInterrupt:
sys.exit(0)

35
API/deps/samples/menu.py Normal file
View File

@ -0,0 +1,35 @@
#!/usr/bin/env python
from samplebase import SampleBase
from rgbmatrix import graphics
import time, keyboard, os
class TextMenu(SampleBase):
def __init__(self, *args, **kwargs):
super(TextMenu, self).__init__(*args, **kwargs)
def run(self):
offscreen_canvas = self.matrix.CreateFrameCanvas()
font = graphics.Font()
font.LoadFont("7x13.bdf")
textColor = graphics.Color(255, 255, 255)
my_text = "hahahahahahah"
while True:
offscreen_canvas.Clear()
len = graphics.DrawText(offscreen_canvas, font, 7, 13, textColor, my_text)
if (keyboard.is_pressed('1')):
os.system('sudo /var/SnakeGame/Client/SnakeGame')
break
elif (keyboard.is_pressed('2')):
os.system('sudo /var/FlappyBird/FlappyBird')
break
time.sleep(0.05)
offscreen_canvas = self.matrix.SwapOnVSync(offscreen_canvas)
# Main function
if __name__ == "__main__":
run_text = TextMenu()
if (not run_text.process()):
run_text.print_help()

View File

@ -0,0 +1,36 @@
#!/usr/bin/env python
from samplebase import SampleBase
class GrayscaleBlock(SampleBase):
def __init__(self, *args, **kwargs):
super(GrayscaleBlock, self).__init__(*args, **kwargs)
def run(self):
max_brightness = self.matrix.brightness
count = 0
c = 255
while (True):
if self.matrix.brightness < 1:
self.matrix.brightness = max_brightness
count += 1
else:
self.matrix.brightness -= 1
if count % 4 == 0:
self.matrix.Fill(c, 0, 0)
elif count % 4 == 1:
self.matrix.Fill(0, c, 0)
elif count % 4 == 2:
self.matrix.Fill(0, 0, c)
elif count % 4 == 3:
self.matrix.Fill(c, c, c)
self.usleep(20 * 1000)
# Main function
if __name__ == "__main__":
grayscale_block = GrayscaleBlock()
if (not grayscale_block.process()):
grayscale_block.print_help()

View File

@ -0,0 +1,42 @@
#!/usr/bin/env python
from samplebase import SampleBase
class PulsingColors(SampleBase):
def __init__(self, *args, **kwargs):
super(PulsingColors, self).__init__(*args, **kwargs)
def run(self):
self.offscreen_canvas = self.matrix.CreateFrameCanvas()
continuum = 0
while True:
self.usleep(5 * 1000)
continuum += 1
continuum %= 3 * 255
red = 0
green = 0
blue = 0
if continuum <= 255:
c = continuum
blue = 255 - c
red = c
elif continuum > 255 and continuum <= 511:
c = continuum - 256
red = 255 - c
green = c
else:
c = continuum - 512
green = 255 - c
blue = c
self.offscreen_canvas.Fill(red, green, blue)
self.offscreen_canvas = self.matrix.SwapOnVSync(self.offscreen_canvas)
# Main function
if __name__ == "__main__":
pulsing_colors = PulsingColors()
if (not pulsing_colors.process()):
pulsing_colors.print_help()

View File

@ -0,0 +1,72 @@
#!/usr/bin/env python
from samplebase import SampleBase
import math
def scale_col(val, lo, hi):
if val < lo:
return 0
if val > hi:
return 255
return 255 * (val - lo) / (hi - lo)
def rotate(x, y, sin, cos):
return x * cos - y * sin, x * sin + y * cos
class RotatingBlockGenerator(SampleBase):
def __init__(self, *args, **kwargs):
super(RotatingBlockGenerator, self).__init__(*args, **kwargs)
def run(self):
cent_x = self.matrix.width / 2
cent_y = self.matrix.height / 2
rotate_square = min(self.matrix.width, self.matrix.height) * 1.41
min_rotate = cent_x - rotate_square / 2
max_rotate = cent_x + rotate_square / 2
display_square = min(self.matrix.width, self.matrix.height) * 0.7
min_display = cent_x - display_square / 2
max_display = cent_x + display_square / 2
deg_to_rad = 2 * 3.14159265 / 360
rotation = 0
# Pre calculate colors
col_table = []
for x in range(int(min_rotate), int(max_rotate)):
col_table.insert(x, scale_col(x, min_display, max_display))
offset_canvas = self.matrix.CreateFrameCanvas()
while True:
rotation += 1
rotation %= 360
# calculate sin and cos once for each frame
angle = rotation * deg_to_rad
sin = math.sin(angle)
cos = math.cos(angle)
for x in range(int(min_rotate), int(max_rotate)):
for y in range(int(min_rotate), int(max_rotate)):
# Our rotate center is always offset by cent_x
rot_x, rot_y = rotate(x - cent_x, y - cent_x, sin, cos)
if x >= min_display and x < max_display and y >= min_display and y < max_display:
x_col = col_table[x]
y_col = col_table[y]
offset_canvas.SetPixel(rot_x + cent_x, rot_y + cent_y, x_col, 255 - y_col, y_col)
else:
offset_canvas.SetPixel(rot_x + cent_x, rot_y + cent_y, 0, 0, 0)
offset_canvas = self.matrix.SwapOnVSync(offset_canvas)
# Main function
if __name__ == "__main__":
rotating_block_generator = RotatingBlockGenerator()
if (not rotating_block_generator.process()):
rotating_block_generator.print_help()

View File

@ -0,0 +1,36 @@
#!/usr/bin/env python
# Display a runtext with double-buffering.
from samplebase import SampleBase
from rgbmatrix import graphics
import time
class RunText(SampleBase):
def __init__(self, *args, **kwargs):
super(RunText, self).__init__(*args, **kwargs)
self.parser.add_argument("-t", "--text", help="The text to scroll on the RGB LED panel", default="Hello world!")
def run(self):
offscreen_canvas = self.matrix.CreateFrameCanvas()
font = graphics.Font()
font.LoadFont("../../../fonts/7x13.bdf")
textColor = graphics.Color(255, 255, 0)
pos = offscreen_canvas.width
my_text = self.args.text
while True:
offscreen_canvas.Clear()
len = graphics.DrawText(offscreen_canvas, font, pos, 10, textColor, my_text)
pos -= 1
if (pos + len < 0):
pos = offscreen_canvas.width
time.sleep(0.05)
offscreen_canvas = self.matrix.SwapOnVSync(offscreen_canvas)
# Main function
if __name__ == "__main__":
run_text = RunText()
if (not run_text.process()):
run_text.print_help()

View File

@ -0,0 +1,30 @@
#!/usr/bin/env python
from samplebase import SampleBase
class SimpleSquare(SampleBase):
def __init__(self, *args, **kwargs):
super(SimpleSquare, self).__init__(*args, **kwargs)
def run(self):
offset_canvas = self.matrix.CreateFrameCanvas()
while True:
for x in range(0, self.matrix.width):
offset_canvas.SetPixel(x, x, 255, 255, 255)
offset_canvas.SetPixel(offset_canvas.height - 1 - x, x, 255, 0, 255)
for x in range(0, offset_canvas.width):
offset_canvas.SetPixel(x, 0, 255, 0, 0)
offset_canvas.SetPixel(x, offset_canvas.height - 1, 255, 255, 0)
for y in range(0, offset_canvas.height):
offset_canvas.SetPixel(0, y, 0, 0, 255)
offset_canvas.SetPixel(offset_canvas.width - 1, y, 0, 255, 0)
offset_canvas = self.matrix.SwapOnVSync(offset_canvas)
# Main function
if __name__ == "__main__":
simple_square = SimpleSquare()
if (not simple_square.process()):
simple_square.print_help()