pimoroni / pimoroni-pico

Libraries and examples to support Pimoroni Pico add-ons in C++ and MicroPython.
https://shop.pimoroni.com/collections/pico
MIT License
1.32k stars 496 forks source link

Interstate 75 Pixel Mapping #249

Open PlatinumFusion opened 2 years ago

PlatinumFusion commented 2 years ago

Is there a way to map pixels to the LED panel?

I've used pixelmatrix's SmartMartix with the Teensy and there is a Matrix Panel Map Definitions file that's used to remap pixels. The LED board that I'm using starts at 0, 8 when addressing 0, 0.

{0, 8, 8}, {0, 24, 8}, {0, 40, 8}, {0, 56, 8}, {4, 0, 8}, {4, 16, 8}, {4, 32, 8}, {4, 48, 8},

I just wanted to know if there would be a place to add this rather than having to program my own mapping. *Or if there is already a way to do this and missed it.

Thanks

Gadgetoid commented 2 years ago

Pixel mapping is currently not supported, but does happen implicitly in set_color so it might be possible to expand upon this: https://github.com/pimoroni/pimoroni-pico/blob/9fafa3edb1e6721a8e3c727e27033220c6697711/drivers/hub75/hub75.cpp#L79-L90

Right now pixels are laid out in memory in the right order for the panel, so rows from the top and bottom half are interleaved:

1, 2, 3, 4, 5, 6, 7, 8

becomes:

1, 5, 2, 6, 3, 7, 4, 8

Passing mappings in from Python and dealing with SmartMatrix's weird (but admittedly very nicely compressed for the job) mapping format would both be quite complicated and potentially hurt draw performance. This library was written with two goals: support the panels we sell, and be fast, and I'd ideally want to avoid compromising on those.

As such I'm biased toward making the assumption that there can't be that many unique panel types and mappings, and think using PanelType to change to the appropriate mapping would make sense.

In fact it looks like SmartMatix has been around in one form or another since 2014 and only collected a handful of panel types - https://github.com/pixelmatix/SmartMatrix/blob/master/src/MatrixPanelMaps.cpp

So the linked code might become something like:

void Hub75::set_color(uint x, uint y, Pixel c) {
    int offset = 0;
    if(panel_type == PANEL_SOME_GOOD_NAME_FOR_PLATINUM_FUSIONS_PANEL) {
        // remap x/y here
    }
    if(x >= width || y >= height) return;
    if(y >= height / 2) {
        y -= height / 2;
        offset = (y * width + x) * 2;
        offset += 1;
    } else {
        offset = (y * width + x) * 2;
    }
    front_buffer[offset] = c;
}

And for your particular panel, you'd pass in the right Panel Type to have it mapped correctly.

Looks like your mapping is this?:

const PanelMappingEntry panelMap32x16Mod4V3[] =
{
    {0, 8, 8},
    {0, 24, 8},
    {0, 40, 8},
    {0, 56, 8},
    {4, 0, 8},
    {4, 16, 8},
    {4, 32, 8},
    {4, 48, 8},
    {0, 0, 0} // last entry is all zeros
};

It's not clear to me how this mapping actually works, and the more I look at the documentation - https://github.com/pixelmatix/SmartMatrix/wiki/Multi-Row-Panels - the less I understand. It's clearly Monday!

It looks like this mapping format is fairly fundamental to how SmartMatrix works and pretty antithetical to how Interstate75 works, so we'd have to come up with our own approach that just fudges the pixel X and Y coordinates before they are turned into a buffer offset.

I don't think we're likely to support this soon so if you do write your own high level mapping in the interim, please let me know how you get on!

Edit: removed note about double buffering, confused with Plasma :roll_eyes:

OliverHoermann commented 2 years ago

https://github.com/hzeller's library https://github.com/hzeller/rpi-rgb-led-matrix got some pixel mappers in https://github.com/hzeller/rpi-rgb-led-matrix/blob/master/lib/pixel-mapper.cc. The're also quite compact and versatile, especially when is use with multiple boards chained. Maybe that helps?