Skip to content

Commit b015674

Browse files
authored
Merge pull request #5 from adafruit/fixgamma
fix gamma curve, it was all broken!
2 parents 3658640 + eddb20c commit b015674

File tree

3 files changed

+36
-22
lines changed

3 files changed

+36
-22
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
./*.pio.h
22
protodemo
33
./build
4+
*.egg-info

examples/playframes.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import glob
1313
import sys
14+
import time
1415

1516
import adafruit_raspberry_pi5_piomatter
1617
import numpy as np
@@ -20,10 +21,15 @@
2021

2122
geometry = adafruit_raspberry_pi5_piomatter.Geometry(width=64, height=32, n_addr_lines=4, rotation=adafruit_raspberry_pi5_piomatter.Orientation.Normal)
2223
framebuffer = np.asarray(Image.open(images[0])) + 0 # Make a mutable copy
24+
nimages = len(images)
2325
matrix = adafruit_raspberry_pi5_piomatter.AdafruitMatrixBonnetRGB888Packed(framebuffer, geometry)
2426

2527
while True:
28+
t0 = time.monotonic()
2629
for i in images:
27-
print(i)
2830
framebuffer[:] = np.asarray(Image.open(i))
2931
matrix.show()
32+
t1 = time.monotonic()
33+
dt = t1 - t0
34+
fps = nimages/dt
35+
print(f"{nimages} frames in {dt}s, {fps}fps")

src/include/piomatter/render.h

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
namespace piomatter {
99

1010
constexpr unsigned DATA_OVERHEAD = 3;
11-
constexpr unsigned CLOCKS_PER_DATA = 2;
11+
// this is ... flatly wrong!? but it's the number that makes the ramp intensity
12+
// correct to my eye
13+
constexpr unsigned CLOCKS_PER_DATA = 128;
1214
constexpr unsigned DELAY_OVERHEAD = 5;
1315
constexpr unsigned CLOCKS_PER_DELAY = 1;
1416

@@ -18,7 +20,7 @@ constexpr uint32_t command_delay = 0;
1820
struct gamma_lut {
1921
gamma_lut(double exponent = 2.2) {
2022
for (int i = 0; i < 256; i++) {
21-
auto v = std::max(i, int(round(1023 * pow(i / 255, exponent))));
23+
auto v = std::max(i, int(round(1023 * pow(i / 255., exponent))));
2224
lut[i] = v;
2325
}
2426
}
@@ -159,10 +161,21 @@ void protomatter_render_rgb10(std::vector<uint32_t> &result,
159161
result.push_back(d);
160162
};
161163

162-
auto do_data_delay = [&](uint32_t d, uint32_t delay) {
164+
int32_t active_time;
165+
166+
auto do_data_active = [&active_time, &do_data](uint32_t d) {
167+
bool active = active_time > 0;
168+
active_time--;
169+
d |= active ? pinout::oe_active : pinout::oe_inactive;
170+
do_data(d);
171+
};
172+
173+
auto do_data_delay = [&prep_data, &do_data, &do_delay](uint32_t d,
174+
int32_t delay) {
163175
prep_data(1);
164176
do_data(d);
165-
do_delay(delay);
177+
if (delay > 0)
178+
do_delay(delay);
166179
};
167180

168181
auto calc_addr_bits = [](int addr) {
@@ -184,11 +197,10 @@ void protomatter_render_rgb10(std::vector<uint32_t> &result,
184197
return data;
185198
};
186199

187-
auto add_pixels = [&do_data, &result](uint32_t addr_bits, bool r0, bool g0,
188-
bool b0, bool r1, bool g1, bool b1,
189-
bool active) {
190-
uint32_t data =
191-
(active ? pinout::oe_active : pinout::oe_inactive) | addr_bits;
200+
auto add_pixels = [&do_data_active, &result](uint32_t addr_bits, bool r0,
201+
bool g0, bool b0, bool r1,
202+
bool g1, bool b1) {
203+
uint32_t data = addr_bits;
192204
if (r0)
193205
data |= (1 << pinout::PIN_RGB[0]);
194206
if (g0)
@@ -202,8 +214,8 @@ void protomatter_render_rgb10(std::vector<uint32_t> &result,
202214
if (b1)
203215
data |= (1 << pinout::PIN_RGB[5]);
204216

205-
do_data(data);
206-
do_data(data | pinout::clk_bit);
217+
do_data_active(data);
218+
do_data_active(data | pinout::clk_bit);
207219
};
208220

209221
int last_bit = 0;
@@ -230,7 +242,7 @@ void protomatter_render_rgb10(std::vector<uint32_t> &result,
230242
// the shortest /OE we can do is one DATA_OVERHEAD...
231243
// TODO: should make sure desired duration of MSB is at least
232244
// `pixels_across`
233-
uint32_t desired_duration = 1 << last_bit;
245+
active_time = 1 << last_bit;
234246
last_bit = bit;
235247

236248
prep_data(2 * pixels_across);
@@ -247,17 +259,12 @@ void protomatter_render_rgb10(std::vector<uint32_t> &result,
247259
auto g1 = pixel1 & g;
248260
auto b1 = pixel1 & b;
249261

250-
add_pixels(addr_bits, r0, g0, b0, r1, g1, b1,
251-
x < desired_duration);
262+
add_pixels(addr_bits, r0, g0, b0, r1, g1, b1);
252263
}
253264

254-
// hold /OE low until desired time has elapsed to illuminate the
255-
// LAST line
256-
int remain = desired_duration - pixels_across;
257-
if (remain > 0) {
258-
do_data_delay(addr_bits | pinout::oe_active,
259-
remain * CLOCKS_PER_DATA - DELAY_OVERHEAD);
260-
}
265+
do_data_delay(addr_bits | pinout::oe_active,
266+
active_time * CLOCKS_PER_DATA / CLOCKS_PER_DELAY -
267+
DELAY_OVERHEAD);
261268

262269
do_data_delay(addr_bits | pinout::oe_inactive,
263270
pinout::post_oe_delay);

0 commit comments

Comments
 (0)