JoyPi-RGB-Matrix-RaspberryPi 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- JoyPi_RGB_Matrix_RaspberryPi/RGB_Matrix.py +154 -0
- JoyPi_RGB_Matrix_RaspberryPi/_LEDTransferData.py +156 -0
- JoyPi_RGB_Matrix_RaspberryPi/_PixelStrip.py +292 -0
- JoyPi_RGB_Matrix_RaspberryPi/_RGBW.py +57 -0
- JoyPi_RGB_Matrix_RaspberryPi/__init__.py +3 -0
- joypi_rgb_matrix_raspberrypi-1.0.0.dist-info/METADATA +38 -0
- joypi_rgb_matrix_raspberrypi-1.0.0.dist-info/RECORD +9 -0
- joypi_rgb_matrix_raspberrypi-1.0.0.dist-info/WHEEL +4 -0
- joypi_rgb_matrix_raspberrypi-1.0.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
from ._RGBW import RGBW
|
|
2
|
+
from ._PixelStrip import PixelStrip
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
class RGB_Matrix:
|
|
6
|
+
"""
|
|
7
|
+
New version using the I2C-based PixelStrip instead of rpi_ws281x.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
def __init__(self, bus = None, bus_id = 1, i2c_adress = 0x66, count = 64, brightness = 10,
|
|
11
|
+
right_border = [7,15,23,31,39,47,55,63], left_border = [0,8,16,24,32,40,48,56]):
|
|
12
|
+
"""
|
|
13
|
+
initiliaze LED matrix
|
|
14
|
+
|
|
15
|
+
:param count: amount of LEDs in matrix
|
|
16
|
+
:param brightness: brightness level of all pixels
|
|
17
|
+
:param right_border: reference values for all pixel on the right side
|
|
18
|
+
:param left_border: reference values for all pixel on the left side
|
|
19
|
+
"""
|
|
20
|
+
# LED configuration
|
|
21
|
+
self.LED_COUNT = count
|
|
22
|
+
self.LED_BRIGHTNESS = brightness
|
|
23
|
+
|
|
24
|
+
# For reference if needed
|
|
25
|
+
self.RIGHT_BORDER = right_border
|
|
26
|
+
self.LEFT_BORDER = left_border
|
|
27
|
+
|
|
28
|
+
# Create the I2C-based PixelStrip instance
|
|
29
|
+
self.strip = PixelStrip(num=self.LED_COUNT, brightness=self.LED_BRIGHTNESS,
|
|
30
|
+
bus = bus, bus_id = bus_id, i2c_adress=i2c_adress)
|
|
31
|
+
self.strip.begin()
|
|
32
|
+
|
|
33
|
+
def clean(self):
|
|
34
|
+
"""
|
|
35
|
+
Turn off all pixels
|
|
36
|
+
"""
|
|
37
|
+
self.RGB_off()
|
|
38
|
+
|
|
39
|
+
def setPixel(self, position, colour):
|
|
40
|
+
"""
|
|
41
|
+
set pixel at position to colour
|
|
42
|
+
|
|
43
|
+
:param position: Pixel position index
|
|
44
|
+
:param colour: RGBW value 32 bit integer
|
|
45
|
+
"""
|
|
46
|
+
self.strip.setPixelColor(position, colour)
|
|
47
|
+
|
|
48
|
+
def RGB_on(self, colour):
|
|
49
|
+
"""
|
|
50
|
+
set all pixel of matrix to colour
|
|
51
|
+
|
|
52
|
+
:param colour: RGBW value 32 bit integer
|
|
53
|
+
"""
|
|
54
|
+
for i in range(self.strip.numPixels()):
|
|
55
|
+
self.strip.setPixelColor(i, colour)
|
|
56
|
+
self.strip.show()
|
|
57
|
+
|
|
58
|
+
def RGB_off(self):
|
|
59
|
+
"""
|
|
60
|
+
turn all LEDs in matrix off
|
|
61
|
+
"""
|
|
62
|
+
for i in range(self.strip.numPixels()):
|
|
63
|
+
self.strip.setPixelColor(i, RGBW(0, 0, 0, 0))
|
|
64
|
+
self.strip.show()
|
|
65
|
+
|
|
66
|
+
def wheel(self, pos):
|
|
67
|
+
"""
|
|
68
|
+
generate rainbow colours over positions 0-255
|
|
69
|
+
|
|
70
|
+
:param pos: selected pixel
|
|
71
|
+
"""
|
|
72
|
+
if pos < 85:
|
|
73
|
+
return RGBW(pos * 3, 255 - pos * 3, 0, 0)
|
|
74
|
+
elif pos < 170:
|
|
75
|
+
pos -= 85
|
|
76
|
+
return RGBW(255 - pos * 3, 0, pos * 3, 0)
|
|
77
|
+
else:
|
|
78
|
+
pos -= 170
|
|
79
|
+
return RGBW(0, pos * 3, 255 - pos * 3, 0)
|
|
80
|
+
|
|
81
|
+
def rainbow(self, wait_ms=20, iterations=1):
|
|
82
|
+
"""
|
|
83
|
+
Rainbow effect on all LEDs
|
|
84
|
+
|
|
85
|
+
:param wait_ms: time in between colour change per pixel
|
|
86
|
+
:param iterations: iterations of animation
|
|
87
|
+
"""
|
|
88
|
+
for j in range(256 * iterations):
|
|
89
|
+
for i in range(self.strip.numPixels()):
|
|
90
|
+
self.strip.setPixelColor(i, self.wheel((i + j) & 255))
|
|
91
|
+
self.strip.show()
|
|
92
|
+
time.sleep(wait_ms / 1000.0)
|
|
93
|
+
|
|
94
|
+
def colourWipe(self, color, wait_ms=50):
|
|
95
|
+
"""
|
|
96
|
+
Move colours pixel by pixel over the LEDs with a given colour
|
|
97
|
+
|
|
98
|
+
:param color: RGB value to set pixels to
|
|
99
|
+
:param wait_ms: time between each pixel
|
|
100
|
+
"""
|
|
101
|
+
for i in range(self.strip.numPixels()):
|
|
102
|
+
self.strip.setPixelColor(i, color)
|
|
103
|
+
self.strip.show()
|
|
104
|
+
time.sleep(wait_ms / 1000.0)
|
|
105
|
+
|
|
106
|
+
def theaterChase(self, color, wait_ms=50, iterations=10):
|
|
107
|
+
"""
|
|
108
|
+
Chaser animation with a given colour
|
|
109
|
+
|
|
110
|
+
:param color: RGB value to set pixels to
|
|
111
|
+
:param wait_ms: time in between colour change per pixel
|
|
112
|
+
:param iterations: iterations of animation
|
|
113
|
+
"""
|
|
114
|
+
for j in range(iterations):
|
|
115
|
+
for q in range(3):
|
|
116
|
+
for i in range(0, self.strip.numPixels(), 3):
|
|
117
|
+
self.strip.setPixelColor(i + q, color)
|
|
118
|
+
self.strip.show()
|
|
119
|
+
time.sleep(wait_ms / 1000.0)
|
|
120
|
+
for i in range(0, self.strip.numPixels(), 3):
|
|
121
|
+
self.strip.setPixelColor(i + q, 0)
|
|
122
|
+
|
|
123
|
+
def demo1(self):
|
|
124
|
+
"""
|
|
125
|
+
Simple demo programm
|
|
126
|
+
"""
|
|
127
|
+
self.theaterChase(RGBW(127, 127, 127, 0)) # White chaser
|
|
128
|
+
self.theaterChase(RGBW(127, 0, 0, 0)) # Red chaser
|
|
129
|
+
self.theaterChase(RGBW(0, 0, 127, 0)) # Blue chaser
|
|
130
|
+
self.rainbow()
|
|
131
|
+
self.clean()
|
|
132
|
+
|
|
133
|
+
def show(self):
|
|
134
|
+
"""
|
|
135
|
+
show changes on LED matrix
|
|
136
|
+
"""
|
|
137
|
+
self.strip.show()
|
|
138
|
+
|
|
139
|
+
def demo2(self):
|
|
140
|
+
"""
|
|
141
|
+
More complex demo programm in a continuous loop
|
|
142
|
+
"""
|
|
143
|
+
heart = [1,6,8,9,10,13,14,15,16,17,18,19,20,21,22,23,
|
|
144
|
+
24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
|
|
145
|
+
41,42,43,44,45,46,50,51,52,53,59,60]
|
|
146
|
+
try:
|
|
147
|
+
for i in range(3):
|
|
148
|
+
self.demo1()
|
|
149
|
+
while True:
|
|
150
|
+
for i in heart:
|
|
151
|
+
self.strip.setPixelColor(i, RGBW(255, 0, 0, 0))
|
|
152
|
+
self.strip.show()
|
|
153
|
+
except KeyboardInterrupt:
|
|
154
|
+
self.clean()
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
class LEDTransferData:
|
|
2
|
+
"""
|
|
3
|
+
Data container class used to prepare and store parameters for I2C
|
|
4
|
+
communication with the LED controller.
|
|
5
|
+
|
|
6
|
+
This class encapsulates all fields required to build a command packet,
|
|
7
|
+
including function identifiers, pixel position, color values, brightness,
|
|
8
|
+
and range parameters for bulk operations.
|
|
9
|
+
"""
|
|
10
|
+
def __init__(self, func=0, pos=0, r=0, g=0, b=0, w=0, c=0, bright=5, first=0, count=0):
|
|
11
|
+
"""
|
|
12
|
+
Initialize the data structure for an LED control command
|
|
13
|
+
|
|
14
|
+
:param func: Function ID (see FunctionEnum)
|
|
15
|
+
:param pos: Pixel position index
|
|
16
|
+
:param r: Red color component (0–255)
|
|
17
|
+
:param g: Green color component (0–255)
|
|
18
|
+
:param b: Blue color component (0–255)
|
|
19
|
+
:param w: White color component (for RGBW LEDs)
|
|
20
|
+
:param c: Additional color or control parameter (device-dependent)
|
|
21
|
+
:param bright: Global brightness level
|
|
22
|
+
:param first: First pixel index for range operations
|
|
23
|
+
:param count: Number of pixels affected in range operations
|
|
24
|
+
"""
|
|
25
|
+
self.func = func
|
|
26
|
+
self.pos = pos
|
|
27
|
+
self.r = r
|
|
28
|
+
self.g = g
|
|
29
|
+
self.b = b
|
|
30
|
+
self.w = w
|
|
31
|
+
self.c = c
|
|
32
|
+
self.bright = bright
|
|
33
|
+
self.first = first
|
|
34
|
+
self.count = count
|
|
35
|
+
self.data = 0
|
|
36
|
+
self.data1 = 0
|
|
37
|
+
|
|
38
|
+
def setFunc(self, func=0):
|
|
39
|
+
"""
|
|
40
|
+
set Function ID
|
|
41
|
+
|
|
42
|
+
:param func: Function ID - default = 0 - SHOW
|
|
43
|
+
"""
|
|
44
|
+
self.func = func
|
|
45
|
+
|
|
46
|
+
def setPos(self, pos=0):
|
|
47
|
+
"""
|
|
48
|
+
set Pixel position index
|
|
49
|
+
|
|
50
|
+
:param pos: Pixel position index - default = 0
|
|
51
|
+
"""
|
|
52
|
+
self.pos = pos
|
|
53
|
+
|
|
54
|
+
def setR(self, r=0):
|
|
55
|
+
"""
|
|
56
|
+
set Red color component
|
|
57
|
+
|
|
58
|
+
:param r: Red color component - default = 0
|
|
59
|
+
"""
|
|
60
|
+
self.r = r
|
|
61
|
+
|
|
62
|
+
def setG(self, g=0):
|
|
63
|
+
"""
|
|
64
|
+
set Green color component
|
|
65
|
+
|
|
66
|
+
:param g: Green color component - default = 0
|
|
67
|
+
"""
|
|
68
|
+
self.g = g
|
|
69
|
+
|
|
70
|
+
def setB(self, b=0):
|
|
71
|
+
"""
|
|
72
|
+
set Blue color component
|
|
73
|
+
|
|
74
|
+
:param b: Blue color component - default = 0
|
|
75
|
+
"""
|
|
76
|
+
self.b = b
|
|
77
|
+
|
|
78
|
+
def setW(self, w=0):
|
|
79
|
+
"""
|
|
80
|
+
set White color component
|
|
81
|
+
|
|
82
|
+
:param w: White color component - default = 0
|
|
83
|
+
"""
|
|
84
|
+
self.w = w
|
|
85
|
+
|
|
86
|
+
def setC(self, c=0):
|
|
87
|
+
"""
|
|
88
|
+
set Additional color or control parameter
|
|
89
|
+
|
|
90
|
+
:param c: Additional color or control parameter - default = 0
|
|
91
|
+
"""
|
|
92
|
+
self.c = c
|
|
93
|
+
|
|
94
|
+
def setFirst(self, first=0):
|
|
95
|
+
"""
|
|
96
|
+
set First pixel index for range operations
|
|
97
|
+
|
|
98
|
+
:param first: First pixel index for range operations - default = 0
|
|
99
|
+
"""
|
|
100
|
+
self.first = first
|
|
101
|
+
|
|
102
|
+
def setCount(self, count=0):
|
|
103
|
+
"""
|
|
104
|
+
set Number of pixels affected in range operations
|
|
105
|
+
|
|
106
|
+
:param count: Number of pixels affected in range operations - default = 0
|
|
107
|
+
"""
|
|
108
|
+
self.count = count
|
|
109
|
+
|
|
110
|
+
def setBright(self, bright=0):
|
|
111
|
+
"""
|
|
112
|
+
set Global brightness level
|
|
113
|
+
|
|
114
|
+
:param bright: Global brightness level - default = 0
|
|
115
|
+
"""
|
|
116
|
+
self.bright = bright
|
|
117
|
+
|
|
118
|
+
def setData(self, data=0):
|
|
119
|
+
"""
|
|
120
|
+
Sets the primary data value for the I²C command packet.
|
|
121
|
+
|
|
122
|
+
This value is typically used to store a processed or combined
|
|
123
|
+
parameter (e.g., color value, gamma result, or control data)
|
|
124
|
+
before transmission.
|
|
125
|
+
|
|
126
|
+
:param data: Integer value to be assigned to the primary data field - default = 0
|
|
127
|
+
"""
|
|
128
|
+
self.data = data
|
|
129
|
+
|
|
130
|
+
def setData1(self, data=0):
|
|
131
|
+
"""
|
|
132
|
+
Sets the secondary data value for the I²C command packet.
|
|
133
|
+
|
|
134
|
+
This field is commonly used for additional parameters such as
|
|
135
|
+
high/low bytes, extended data, or supplementary command values.
|
|
136
|
+
|
|
137
|
+
:param data: Integer value to be assigned to the secondary data field - default = 0
|
|
138
|
+
"""
|
|
139
|
+
self.data1 = data
|
|
140
|
+
|
|
141
|
+
def clean(self):
|
|
142
|
+
"""
|
|
143
|
+
Reset all internal fields to zero after transmission
|
|
144
|
+
"""
|
|
145
|
+
self.func = 0
|
|
146
|
+
self.pos = 0
|
|
147
|
+
self.r = 0
|
|
148
|
+
self.g = 0
|
|
149
|
+
self.b = 0
|
|
150
|
+
self.w = 0
|
|
151
|
+
self.c = 0
|
|
152
|
+
self.bright = 0
|
|
153
|
+
self.first = 0
|
|
154
|
+
self.count = 0
|
|
155
|
+
self.data = 0
|
|
156
|
+
self.data1 = 0
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
from ._LEDTransferData import LEDTransferData
|
|
2
|
+
from enum import Enum
|
|
3
|
+
import smbus2
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
class FunctionEnum(Enum):
|
|
7
|
+
"""
|
|
8
|
+
Enumeration of command identifiers used for controlling the LED matrix
|
|
9
|
+
via I2C communication.
|
|
10
|
+
|
|
11
|
+
Each value represents a specific function that can be executed by the
|
|
12
|
+
LED controller firmware, such as pixel manipulation, brightness control,
|
|
13
|
+
gamma correction, color conversion, or data transmission.
|
|
14
|
+
"""
|
|
15
|
+
SHOW = 0
|
|
16
|
+
SETPIXELCOLOR = 1
|
|
17
|
+
FILL = 2
|
|
18
|
+
SETBRIGHTNESS = 3
|
|
19
|
+
WHITEOVERRAINBOW = 4
|
|
20
|
+
GAMMA8 = 5
|
|
21
|
+
GAMMA32 = 6
|
|
22
|
+
NUMPIXEL = 7
|
|
23
|
+
COLORHSV = 8
|
|
24
|
+
CLEAR = 9
|
|
25
|
+
SENDDATA2SHOW = 10
|
|
26
|
+
SENDALLPIXRGB0 = 11
|
|
27
|
+
SENDALLPIXRGB1 = 12
|
|
28
|
+
SENDALLPIXRGB2 = 13
|
|
29
|
+
SENDALLPIXRGB3 = 14
|
|
30
|
+
SENDALLPIXRGB4 = 15
|
|
31
|
+
SENDALLPIXRGB5 = 16
|
|
32
|
+
|
|
33
|
+
class PixelStrip:
|
|
34
|
+
"""
|
|
35
|
+
Controls a strip of LEDs (WS281x / SK6812) via I2C.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def __init__(self, num, brightness=255, bus = None, bus_id = 1, i2c_adress = 0x66):
|
|
39
|
+
"""
|
|
40
|
+
initilize LED controll class
|
|
41
|
+
|
|
42
|
+
:param num: amount of pixel to controll
|
|
43
|
+
:param brightness: brightness of all pixels
|
|
44
|
+
"""
|
|
45
|
+
self.num = num
|
|
46
|
+
self.bus = bus if bus is not None else smbus2.SMBus(bus_id)
|
|
47
|
+
self.Address = i2c_adress
|
|
48
|
+
self.transfer_data = LEDTransferData()
|
|
49
|
+
self.transfer_data.setBright(brightness)
|
|
50
|
+
|
|
51
|
+
def begin(self):
|
|
52
|
+
"""
|
|
53
|
+
Set the initial brightness on the hardware side via I2C
|
|
54
|
+
"""
|
|
55
|
+
self.transfer_data.setFunc(FunctionEnum.SETBRIGHTNESS.value)
|
|
56
|
+
self.send(0x00)
|
|
57
|
+
|
|
58
|
+
def send(self, cmd):
|
|
59
|
+
"""
|
|
60
|
+
Send a block of data to the device using I2C
|
|
61
|
+
|
|
62
|
+
:param cmd: block of data to send
|
|
63
|
+
"""
|
|
64
|
+
self.bus.write_block_data(
|
|
65
|
+
self.Address, cmd, [
|
|
66
|
+
self.transfer_data.func,
|
|
67
|
+
self.transfer_data.pos,
|
|
68
|
+
self.transfer_data.r,
|
|
69
|
+
self.transfer_data.g,
|
|
70
|
+
self.transfer_data.b,
|
|
71
|
+
self.transfer_data.w,
|
|
72
|
+
self.transfer_data.c,
|
|
73
|
+
self.transfer_data.bright,
|
|
74
|
+
self.transfer_data.first,
|
|
75
|
+
self.transfer_data.count,
|
|
76
|
+
self.transfer_data.data,
|
|
77
|
+
self.transfer_data.data1
|
|
78
|
+
]
|
|
79
|
+
)
|
|
80
|
+
time.sleep(0.003) # Hardware timing delay
|
|
81
|
+
self.transfer_data.clean()
|
|
82
|
+
|
|
83
|
+
def __len__(self):
|
|
84
|
+
"""
|
|
85
|
+
Return the total number of pixels
|
|
86
|
+
"""
|
|
87
|
+
return self.num
|
|
88
|
+
|
|
89
|
+
def clear(self):
|
|
90
|
+
"""
|
|
91
|
+
Clear the entire LED strip (turn off all pixels)
|
|
92
|
+
"""
|
|
93
|
+
self.transfer_data.setFunc(FunctionEnum.CLEAR.value)
|
|
94
|
+
self.send(0x00)
|
|
95
|
+
|
|
96
|
+
def show(self):
|
|
97
|
+
"""
|
|
98
|
+
Show updated pixel data on the LED strip
|
|
99
|
+
"""
|
|
100
|
+
self.transfer_data.setFunc(FunctionEnum.SHOW.value)
|
|
101
|
+
self.send(0x00)
|
|
102
|
+
|
|
103
|
+
def getWRGB(self, color):
|
|
104
|
+
"""
|
|
105
|
+
Extract W, R, G, B values from a single color int
|
|
106
|
+
|
|
107
|
+
:param color: single color int
|
|
108
|
+
"""
|
|
109
|
+
return (
|
|
110
|
+
(color >> 24) & 0xff,
|
|
111
|
+
(color >> 16) & 0xff,
|
|
112
|
+
(color >> 8) & 0xff,
|
|
113
|
+
color & 0xff
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
def setPixelColor(self, n, color):
|
|
117
|
+
"""
|
|
118
|
+
Set a single pixel (at index n) to the specified 32-bit color
|
|
119
|
+
|
|
120
|
+
:param n: Pixel position index
|
|
121
|
+
:param color: 32-bit color or tupel of (r,g,b) or (r,g,b,w)
|
|
122
|
+
"""
|
|
123
|
+
self.transfer_data.setPos(n)
|
|
124
|
+
if isinstance(color, tuple):
|
|
125
|
+
if len(color) == 3:
|
|
126
|
+
r, g, b = color
|
|
127
|
+
w = 0
|
|
128
|
+
elif len(color) == 4:
|
|
129
|
+
r, g, b, w = color
|
|
130
|
+
else:
|
|
131
|
+
w, r, g, b = self.getWRGB(color)
|
|
132
|
+
self.setPixelColorRGB(n, r, g, b, w)
|
|
133
|
+
|
|
134
|
+
def setPixelColorRGB(self, n, red, green, blue, white=0):
|
|
135
|
+
"""
|
|
136
|
+
set Pixel colour at specific index
|
|
137
|
+
|
|
138
|
+
:param n: Pixel position index
|
|
139
|
+
:param red: colour value of red
|
|
140
|
+
:param green: colour value of green
|
|
141
|
+
:param blue: colour value of blue
|
|
142
|
+
:param white: colour value of white - default 0
|
|
143
|
+
"""
|
|
144
|
+
self.transfer_data.setPos(n)
|
|
145
|
+
self.transfer_data.setR(red)
|
|
146
|
+
self.transfer_data.setG(green)
|
|
147
|
+
self.transfer_data.setB(blue)
|
|
148
|
+
self.transfer_data.setW(white)
|
|
149
|
+
self.transfer_data.setC(0)
|
|
150
|
+
self.transfer_data.setFunc(FunctionEnum.SETPIXELCOLOR.value)
|
|
151
|
+
self.send(0x00)
|
|
152
|
+
|
|
153
|
+
def sendPos2Show(self, pos, r=0, g=0, b=0):
|
|
154
|
+
"""
|
|
155
|
+
Sends color data to selected pixel positions and immediatly dislpays update
|
|
156
|
+
|
|
157
|
+
:param pos: Pixel position index
|
|
158
|
+
:param r: colour value of red
|
|
159
|
+
:param g: colour value of green
|
|
160
|
+
:param b: colour value of blue
|
|
161
|
+
"""
|
|
162
|
+
self.transfer_data.setR(r)
|
|
163
|
+
self.transfer_data.setG(g)
|
|
164
|
+
self.transfer_data.setB(b)
|
|
165
|
+
for i in pos:
|
|
166
|
+
if 0 <= i <= 7:
|
|
167
|
+
self.transfer_data.pos |= 1 << i
|
|
168
|
+
elif 8 <= i <= 15:
|
|
169
|
+
self.transfer_data.w |= 1 << (i - 8)
|
|
170
|
+
elif 16 <= i <= 23:
|
|
171
|
+
self.transfer_data.c |= 1 << (i - 16)
|
|
172
|
+
elif 24 <= i <= 31:
|
|
173
|
+
self.transfer_data.bright |= 1 << (i - 24)
|
|
174
|
+
elif 32 <= i <= 39:
|
|
175
|
+
self.transfer_data.first |= 1 << (i - 32)
|
|
176
|
+
elif 40 <= i <= 47:
|
|
177
|
+
self.transfer_data.count |= 1 << (i - 40)
|
|
178
|
+
elif 48 <= i <= 55:
|
|
179
|
+
self.transfer_data.data |= 1 << (i - 48)
|
|
180
|
+
elif 56 <= i <= 63:
|
|
181
|
+
self.transfer_data.data1 |= 1 << (i - 56)
|
|
182
|
+
self.transfer_data.setFunc(FunctionEnum.SENDDATA2SHOW.value)
|
|
183
|
+
self.send(0x00)
|
|
184
|
+
|
|
185
|
+
def sendColor2Show(self, pos, color=0):
|
|
186
|
+
"""
|
|
187
|
+
write RGB value onto pixel at specific index
|
|
188
|
+
|
|
189
|
+
:param pos: Pixel position index
|
|
190
|
+
:param color: RGB value to write onto pixel
|
|
191
|
+
"""
|
|
192
|
+
w, r, g, b = self.getWRGB(color)
|
|
193
|
+
self.transfer_data.setR(r)
|
|
194
|
+
self.transfer_data.setG(g)
|
|
195
|
+
self.transfer_data.setB(b)
|
|
196
|
+
self.sendPos2Show(pos, r, g, b)
|
|
197
|
+
|
|
198
|
+
def sendAllPixRGB(self, rgb):
|
|
199
|
+
"""
|
|
200
|
+
Send large RGB data (6 chunks of 32 bytes each) to fill multiple pixels
|
|
201
|
+
|
|
202
|
+
:param self: Description
|
|
203
|
+
:param rgb: RGB value to write onto pixels
|
|
204
|
+
"""
|
|
205
|
+
for i in range(6):
|
|
206
|
+
start = 32 * i
|
|
207
|
+
end = start + 32
|
|
208
|
+
self.bus.write_block_data(
|
|
209
|
+
self.Address,
|
|
210
|
+
FunctionEnum.SENDALLPIXRGB0.value + i,
|
|
211
|
+
rgb[start:end]
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
def fill(self, r=0, g=0, b=0, w=0, first=0, end=64):
|
|
215
|
+
"""
|
|
216
|
+
write same RGB value from pixel with one index to another
|
|
217
|
+
|
|
218
|
+
:param r: colour value of red
|
|
219
|
+
:param g: colour value of green
|
|
220
|
+
:param b: colour value of blue
|
|
221
|
+
:param w: colour value of white
|
|
222
|
+
:param first: index of pixel to begin writing color on
|
|
223
|
+
:param end: index of pixel to end writing colour on
|
|
224
|
+
"""
|
|
225
|
+
self.transfer_data.setR(r)
|
|
226
|
+
self.transfer_data.setG(g)
|
|
227
|
+
self.transfer_data.setB(b)
|
|
228
|
+
self.transfer_data.setW(w)
|
|
229
|
+
self.transfer_data.setFirst(first)
|
|
230
|
+
self.transfer_data.setCount(end - first)
|
|
231
|
+
self.transfer_data.setFunc(FunctionEnum.FILL.value)
|
|
232
|
+
self.send(0x00)
|
|
233
|
+
|
|
234
|
+
def fillColor(self, color, first=0, end=63):
|
|
235
|
+
"""
|
|
236
|
+
write same RGB value from pixel with one index to another
|
|
237
|
+
|
|
238
|
+
:param color: RGBW value to write onto pixels
|
|
239
|
+
:param first: index of pixel to begin writing color on
|
|
240
|
+
:param end: index of pixel to end writing colour on
|
|
241
|
+
"""
|
|
242
|
+
w, r, g, b = self.getWRGB(color)
|
|
243
|
+
self.fill(r, g, b, w, first, end)
|
|
244
|
+
|
|
245
|
+
def setBrightness(self, brightness):
|
|
246
|
+
"""
|
|
247
|
+
Set global brightness for all pixels
|
|
248
|
+
|
|
249
|
+
:param brightness: set brightness to all pixels
|
|
250
|
+
"""
|
|
251
|
+
self.transfer_data.setBright(brightness)
|
|
252
|
+
self.transfer_data.setFunc(FunctionEnum.SETBRIGHTNESS.value)
|
|
253
|
+
self.send(0x00)
|
|
254
|
+
|
|
255
|
+
def numPixels(self):
|
|
256
|
+
"""
|
|
257
|
+
Return the number of pixels in this strip
|
|
258
|
+
"""
|
|
259
|
+
return self.num
|
|
260
|
+
|
|
261
|
+
def getGamma8(self, x):
|
|
262
|
+
"""
|
|
263
|
+
Applies 8-bit gamma correction to the given input value.
|
|
264
|
+
|
|
265
|
+
:param x: 8-bit input value (0-255)
|
|
266
|
+
"""
|
|
267
|
+
self.transfer_data.setFunc(FunctionEnum.GAMMA8.value)
|
|
268
|
+
self.transfer_data.setData(x)
|
|
269
|
+
self.send(0x01)
|
|
270
|
+
return self.bus.read_byte(self.Address)
|
|
271
|
+
|
|
272
|
+
def getGamma32(self, x):
|
|
273
|
+
"""
|
|
274
|
+
Applies 32-bit gamma correction to the given input value.
|
|
275
|
+
|
|
276
|
+
:param x: 32-bit input value
|
|
277
|
+
"""
|
|
278
|
+
self.transfer_data.setFunc(FunctionEnum.GAMMA32.value)
|
|
279
|
+
self.transfer_data.setData(x)
|
|
280
|
+
self.send(0x01)
|
|
281
|
+
return self.bus.read_byte(self.Address)
|
|
282
|
+
|
|
283
|
+
def ColorHSV(self, x):
|
|
284
|
+
"""
|
|
285
|
+
Converts an HSV color value into the device-specific RGB format.
|
|
286
|
+
|
|
287
|
+
:param x: HSV input value (device-dependent encoding)
|
|
288
|
+
"""
|
|
289
|
+
self.transfer_data.setFunc(FunctionEnum.COLORHSV.value)
|
|
290
|
+
self.transfer_data.setData(x)
|
|
291
|
+
self.send(0x01)
|
|
292
|
+
return self.bus.read_byte(self.Address)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
class RGBW(int):
|
|
2
|
+
"""
|
|
3
|
+
Represents a 32-bit RGBW color value.
|
|
4
|
+
|
|
5
|
+
This class allows combining separate red, green, blue, and optional white
|
|
6
|
+
components into a single 32-bit integer while still providing convenient
|
|
7
|
+
access to each color channel via properties.
|
|
8
|
+
|
|
9
|
+
Format (32-bit):
|
|
10
|
+
[ W (8 bit) | R (8 bit) | G (8 bit) | B (8 bit) ]
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def __new__(self, r, g=None, b=None, w=None):
|
|
14
|
+
"""
|
|
15
|
+
Create a new RGBW color value. The object can be initialized in two ways:
|
|
16
|
+
1) With a single integer: RGBW(0xWWRRGGBB)
|
|
17
|
+
2) With individual color components: RGBW(r, g, b, w=0)
|
|
18
|
+
|
|
19
|
+
:param r: Red value (0–255) or packed 32-bit integer
|
|
20
|
+
:param g: Green value (0–255)
|
|
21
|
+
:param b: Blue value (0–255)
|
|
22
|
+
:param w: White value (0–255), optional (default = 0)
|
|
23
|
+
"""
|
|
24
|
+
if (g, b, w) == (None, None, None):
|
|
25
|
+
return int.__new__(self, r)
|
|
26
|
+
else:
|
|
27
|
+
if w is None:
|
|
28
|
+
w = 0
|
|
29
|
+
return int.__new__(self, (w << 24) | (r << 16) | (g << 8) | b)
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def getR(self):
|
|
33
|
+
"""
|
|
34
|
+
get red value
|
|
35
|
+
"""
|
|
36
|
+
return (self >> 16) & 0xff
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def getG(self):
|
|
40
|
+
"""
|
|
41
|
+
get green value
|
|
42
|
+
"""
|
|
43
|
+
return (self >> 8) & 0xff
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def getB(self):
|
|
47
|
+
"""
|
|
48
|
+
get blue value
|
|
49
|
+
"""
|
|
50
|
+
return self & 0xff
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def getW(self):
|
|
54
|
+
"""
|
|
55
|
+
get white value
|
|
56
|
+
"""
|
|
57
|
+
return (self >> 24) & 0xff
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: JoyPi_RGB_Matrix_RaspberryPi
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: This library enables usage of RGB matrix with RP2040 microcontroller chip on the Raspberry Pi.
|
|
5
|
+
Project-URL: Homepage, https://github.com/joy-it/JoyPi_RGB_Matrix_RaspberryPi
|
|
6
|
+
Project-URL: Issues, https://github.com/joy-it/JoyPi_RGB_Matrix_RaspberryPi/issues
|
|
7
|
+
Author-email: Joy-IT <service@joy-it.net>
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Requires-Python: >=3.9
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# JoyPi_RGB_Matrix_RaspberryPi
|
|
15
|
+
This library enables usage of RGB matrix with RP2040 microcontroller chip on the Raspberry Pi.
|
|
16
|
+
|
|
17
|
+
>[!WARNING]
|
|
18
|
+
> This library was written for the usage of the LED matrix of the Joy-Pi Advanced 2 and Joy-Pi Note 2. Both Joy-Pis have the RP2040 microcontroller chip to control the LED matrix. This is to ensure compatibility with the Raspberry Pi 5 because the library which was used beforehand is not compatible up to this date.
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
You can install this library from PyPI.
|
|
22
|
+
To install it for the current user on your Raspberry Pi, use the following command:
|
|
23
|
+
```
|
|
24
|
+
pip install JoyPi_RGB_Matrix_RaspberryPi
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Library Guide
|
|
28
|
+
- `LEDMatrix( count = 64, brightness = 10, right_border = [7,15,23,31,39,47,55,63], left_border = [0,8,16,24,32,40,48,56])`- initialize LED matrix with default values for Joy-Pi
|
|
29
|
+
- `clean()` - clears the LED matrix
|
|
30
|
+
- `setPixel(position, colour)` - sets specific pixel to a selected colour
|
|
31
|
+
- `RGB_on(colour)` - sets the complete matrix to one selected colour
|
|
32
|
+
- `RGB_off()` - turns the complete matrix off
|
|
33
|
+
- `rainbow(wait_ms=20, iterations=1)` - rainbow effect on the whole matrix with default values
|
|
34
|
+
- `colourWipe(colour, wait_ms=50)` - Move selected colour pixel by pixel onto the matrix with default speed
|
|
35
|
+
- `theaterChase( colour, wait_ms=50, iterations=10)` - chaser animation with a selected colour with deafult speed
|
|
36
|
+
- `show()` - displays set pixels
|
|
37
|
+
- `demo1()` - demo program version 1
|
|
38
|
+
- `demo2()` - demo program version 2
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
JoyPi_RGB_Matrix_RaspberryPi/RGB_Matrix.py,sha256=u3bVOw9-weDAANFtf3VnPQMWbJRDDDm86cMlezzUvbM,5114
|
|
2
|
+
JoyPi_RGB_Matrix_RaspberryPi/_LEDTransferData.py,sha256=pFT0s87GIUvcorLBMoP6SaVyG1a4VFFd3ZFemH0SvIw,4612
|
|
3
|
+
JoyPi_RGB_Matrix_RaspberryPi/_PixelStrip.py,sha256=Ogmkn6v5e2GfzOG2qiYrwVhBVukL4JRTNMklIsXcEEI,9584
|
|
4
|
+
JoyPi_RGB_Matrix_RaspberryPi/_RGBW.py,sha256=EcaedZUnIVB30MQiqcV5YPxvjxWJKUdMZLnERE1nLho,1577
|
|
5
|
+
JoyPi_RGB_Matrix_RaspberryPi/__init__.py,sha256=TmM6J8HmbztmrjNjyOO3-xGrS1FeNlc0TZKVW7do4mA,62
|
|
6
|
+
joypi_rgb_matrix_raspberrypi-1.0.0.dist-info/METADATA,sha256=-UXhIi_ysnCUTmjU3gak8aByBLDyoZNLuxRF9LQ6X-M,2051
|
|
7
|
+
joypi_rgb_matrix_raspberrypi-1.0.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
8
|
+
joypi_rgb_matrix_raspberrypi-1.0.0.dist-info/licenses/LICENSE,sha256=huySC1quQxrIchKLo7iaLAiFssUwfkKHjAEcXDJ5XXk,1085
|
|
9
|
+
joypi_rgb_matrix_raspberrypi-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 KeeckAOE
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|